PNG  IHDRQgAMA a cHRMz&u0`:pQ<bKGDgmIDATxwUﹻ& ^CX(J I@ "% (** BX +*i"]j(IH{~R)[~>h{}gy)I$Ij .I$I$ʊy@}x.: $I$Ii}VZPC)I$IF ^0ʐJ$I$Q^}{"r=OzI$gRZeC.IOvH eKX $IMpxsk.쒷/&r[޳<v| .I~)@$updYRa$I |M.e JaֶpSYR6j>h%IRز if&uJ)M$I vLi=H;7UJ,],X$I1AҒJ$ XY XzI@GNҥRT)E@;]K*Mw;#5_wOn~\ DC&$(A5 RRFkvIR}l!RytRl;~^ǷJj اy뷦BZJr&ӥ8Pjw~vnv X^(I;4R=P[3]J,]ȏ~:3?[ a&e)`e*P[4]T=Cq6R[ ~ޤrXR Հg(t_HZ-Hg M$ãmL5R uk*`%C-E6/%[t X.{8P9Z.vkXŐKjgKZHg(aK9ڦmKjѺm_ \#$5,)-  61eJ,5m| r'= &ڡd%-]J on Xm|{ RҞe $eڧY XYrԮ-a7RK6h>n$5AVڴi*ֆK)mѦtmr1p| q:흺,)Oi*ֺK)ܬ֦K-5r3>0ԔHjJئEZj,%re~/z%jVMڸmrt)3]J,T K֦OvԒgii*bKiNO~%PW0=dii2tJ9Jݕ{7"I P9JKTbu,%r"6RKU}Ij2HKZXJ,妝 XYrP ެ24c%i^IK|.H,%rb:XRl1X4Pe/`x&P8Pj28Mzsx2r\zRPz4J}yP[g=L) .Q[6RjWgp FIH*-`IMRaK9TXcq*I y[jE>cw%gLRԕiFCj-ďa`#e~I j,%r,)?[gp FI˨mnWX#>mʔ XA DZf9,nKҲzIZXJ,L#kiPz4JZF,I,`61%2s $,VOϚ2/UFJfy7K> X+6 STXIeJILzMfKm LRaK9%|4p9LwJI!`NsiazĔ)%- XMq>pk$-$Q2x#N ؎-QR}ᶦHZډ)J,l#i@yn3LN`;nڔ XuX5pF)m|^0(>BHF9(cզEerJI rg7 4I@z0\JIi䵙RR0s;$s6eJ,`n 䂦0a)S)A 1eJ,堌#635RIgpNHuTH_SԕqVe ` &S)>p;S$魁eKIuX`I4춒o}`m$1":PI<[v9^\pTJjriRŭ P{#{R2,`)e-`mgj~1ϣLKam7&U\j/3mJ,`F;M'䱀 .KR#)yhTq;pcK9(q!w?uRR,n.yw*UXj#\]ɱ(qv2=RqfB#iJmmL<]Y͙#$5 uTU7ӦXR+q,`I}qL'`6Kͷ6r,]0S$- [RKR3oiRE|nӦXR.(i:LDLTJjY%o:)6rxzҒqTJjh㞦I.$YR.ʼnGZ\ֿf:%55 I˼!6dKxm4E"mG_ s? .e*?LRfK9%q#uh$)i3ULRfK9yxm܌bj84$i1U^@Wbm4uJ,ҪA>_Ij?1v32[gLRD96oTaR׿N7%L2 NT,`)7&ƝL*꽙yp_$M2#AS,`)7$rkTA29_Iye"|/0t)$n XT2`YJ;6Jx".e<`$) PI$5V4]29SRI>~=@j]lp2`K9Jaai^" Ԋ29ORI%:XV5]JmN9]H;1UC39NI%Xe78t)a;Oi Ҙ>Xt"~G>_mn:%|~ޅ_+]$o)@ǀ{hgN;IK6G&rp)T2i୦KJuv*T=TOSV>(~D>dm,I*Ɛ:R#ۙNI%D>G.n$o;+#RR!.eU˽TRI28t)1LWϚ>IJa3oFbu&:tJ*(F7y0ZR ^p'Ii L24x| XRI%ۄ>S1]Jy[zL$adB7.eh4%%누>WETf+3IR:I3Xה)3אOۦSRO'ٺ)S}"qOr[B7ϙ.edG)^ETR"RtRݜh0}LFVӦDB^k_JDj\=LS(Iv─aTeZ%eUAM-0;~˃@i|l @S4y72>sX-vA}ϛBI!ݎߨWl*)3{'Y|iSlEڻ(5KtSI$Uv02,~ԩ~x;P4ցCrO%tyn425:KMlD ^4JRxSهF_}شJTS6uj+ﷸk$eZO%G*^V2u3EMj3k%)okI]dT)URKDS 7~m@TJR~荪fT"֛L \sM -0T KfJz+nإKr L&j()[E&I ߴ>e FW_kJR|!O:5/2跌3T-'|zX ryp0JS ~^F>-2< `*%ZFP)bSn"L :)+pʷf(pO3TMW$~>@~ū:TAIsV1}S2<%ޟM?@iT ,Eūoz%i~g|`wS(]oȤ8)$ ntu`өe`6yPl IzMI{ʣzʨ )IZ2= ld:5+請M$-ї;U>_gsY$ÁN5WzWfIZ)-yuXIfp~S*IZdt;t>KūKR|$#LcԀ+2\;kJ`]YǔM1B)UbG"IRߊ<xܾӔJ0Z='Y嵤 Leveg)$znV-º^3Ւof#0Tfk^Zs[*I꯳3{)ˬW4Ւ4 OdpbZRS|*I 55#"&-IvT&/윚Ye:i$ 9{LkuRe[I~_\ؠ%>GL$iY8 9ܕ"S`kS.IlC;Ҏ4x&>u_0JLr<J2(^$5L s=MgV ~,Iju> 7r2)^=G$1:3G< `J3~&IR% 6Tx/rIj3O< ʔ&#f_yXJiގNSz; Tx(i8%#4 ~AS+IjerIUrIj362v885+IjAhK__5X%nV%Iͳ-y|7XV2v4fzo_68"S/I-qbf; LkF)KSM$ Ms>K WNV}^`-큧32ŒVؙGdu,^^m%6~Nn&͓3ŒVZMsRpfEW%IwdǀLm[7W&bIRL@Q|)* i ImsIMmKmyV`i$G+R 0tV'!V)֏28vU7͒vHꦼtxꗞT ;S}7Mf+fIRHNZUkUx5SAJㄌ9MqμAIRi|j5)o*^'<$TwI1hEU^c_j?Е$%d`z cyf,XO IJnTgA UXRD }{H}^S,P5V2\Xx`pZ|Yk:$e ~ @nWL.j+ϝYb퇪bZ BVu)u/IJ_ 1[p.p60bC >|X91P:N\!5qUB}5a5ja `ubcVxYt1N0Zzl4]7­gKj]?4ϻ *[bg$)+À*x쳀ogO$~,5 زUS9 lq3+5mgw@np1sso Ӻ=|N6 /g(Wv7U;zωM=wk,0uTg_`_P`uz?2yI!b`kĸSo+Qx%!\οe|އԁKS-s6pu_(ֿ$i++T8=eY; צP+phxWQv*|p1. ά. XRkIQYP,drZ | B%wP|S5`~́@i޾ E;Չaw{o'Q?%iL{u D?N1BD!owPHReFZ* k_-~{E9b-~P`fE{AܶBJAFO wx6Rox5 K5=WwehS8 (JClJ~ p+Fi;ŗo+:bD#g(C"wA^ r.F8L;dzdIHUX݆ϞXg )IFqem%I4dj&ppT{'{HOx( Rk6^C٫O.)3:s(۳(Z?~ٻ89zmT"PLtw䥈5&b<8GZ-Y&K?e8,`I6e(֍xb83 `rzXj)F=l($Ij 2*(F?h(/9ik:I`m#p3MgLaKjc/U#n5S# m(^)=y=đx8ŬI[U]~SцA4p$-F i(R,7Cx;X=cI>{Km\ o(Tv2vx2qiiDJN,Ҏ!1f 5quBj1!8 rDFd(!WQl,gSkL1Bxg''՞^ǘ;pQ P(c_ IRujg(Wz bs#P­rz> k c&nB=q+ؔXn#r5)co*Ũ+G?7< |PQӣ'G`uOd>%Mctz# Ԫڞ&7CaQ~N'-P.W`Oedp03C!IZcIAMPUۀ5J<\u~+{9(FbbyAeBhOSܳ1 bÈT#ŠyDžs,`5}DC-`̞%r&ڙa87QWWp6e7 Rϫ/oY ꇅ Nܶըtc!LA T7V4Jsū I-0Pxz7QNF_iZgúWkG83 0eWr9 X]㾮݁#Jˢ C}0=3ݱtBi]_ &{{[/o[~ \q鯜00٩|cD3=4B_b RYb$óBRsf&lLX#M*C_L܄:gx)WΘsGSbuL rF$9';\4Ɍq'n[%p.Q`u hNb`eCQyQ|l_C>Lb꟟3hSb #xNxSs^ 88|Mz)}:](vbۢamŖ࿥ 0)Q7@0=?^k(*J}3ibkFn HjB׻NO z x}7p 0tfDX.lwgȔhԾŲ }6g E |LkLZteu+=q\Iv0쮑)QٵpH8/2?Σo>Jvppho~f>%bMM}\//":PTc(v9v!gոQ )UfVG+! 35{=x\2+ki,y$~A1iC6#)vC5^>+gǵ@1Hy٪7u;p psϰu/S <aʸGu'tD1ԝI<pg|6j'p:tպhX{o(7v],*}6a_ wXRk,O]Lܳ~Vo45rp"N5k;m{rZbΦ${#)`(Ŵg,;j%6j.pyYT?}-kBDc3qA`NWQū20/^AZW%NQ MI.X#P#,^Ebc&?XR tAV|Y.1!؅⨉ccww>ivl(JT~ u`ٵDm q)+Ri x/x8cyFO!/*!/&,7<.N,YDŽ&ܑQF1Bz)FPʛ?5d 6`kQձ λc؎%582Y&nD_$Je4>a?! ͨ|ȎWZSsv8 j(I&yj Jb5m?HWp=g}G3#|I,5v珿] H~R3@B[☉9Ox~oMy=J;xUVoj bUsl_35t-(ՃɼRB7U!qc+x4H_Qo֮$[GO<4`&č\GOc[.[*Af%mG/ ňM/r W/Nw~B1U3J?P&Y )`ѓZ1p]^l“W#)lWZilUQu`-m|xĐ,_ƪ|9i:_{*(3Gѧ}UoD+>m_?VPۅ15&}2|/pIOʵ> GZ9cmíتmnz)yߐbD >e}:) r|@R5qVSA10C%E_'^8cR7O;6[eKePGϦX7jb}OTGO^jn*媓7nGMC t,k31Rb (vyܴʭ!iTh8~ZYZp(qsRL ?b}cŨʊGO^!rPJO15MJ[c&~Z`"ѓޔH1C&^|Ш|rʼ,AwĴ?b5)tLU)F| &g٣O]oqSUjy(x<Ϳ3 .FSkoYg2 \_#wj{u'rQ>o;%n|F*O_L"e9umDds?.fuuQbIWz |4\0 sb;OvxOSs; G%T4gFRurj(֍ڑb uԖKDu1MK{1^ q; C=6\8FR艇!%\YÔU| 88m)֓NcLve C6z;o&X x59:q61Z(T7>C?gcļxѐ Z oo-08jہ x,`' ҔOcRlf~`jj".Nv+sM_]Zk g( UOPyεx%pUh2(@il0ݽQXxppx-NS( WO+轾 nFߢ3M<;z)FBZjciu/QoF 7R¥ ZFLF~#ȣߨ^<쩡ݛкvџ))ME>ώx4m#!-m!L;vv#~Y[đKmx9.[,UFS CVkZ +ߟrY٧IZd/ioi$%͝ب_ֶX3ܫhNU ZZgk=]=bbJS[wjU()*I =ώ:}-蹞lUj:1}MWm=̛ _ ¾,8{__m{_PVK^n3esw5ӫh#$-q=A̟> ,^I}P^J$qY~Q[ Xq9{#&T.^GVj__RKpn,b=`żY@^՝;z{paVKkQXj/)y TIc&F;FBG7wg ZZDG!x r_tƢ!}i/V=M/#nB8 XxЫ ^@CR<{䤭YCN)eKOSƟa $&g[i3.C6xrOc8TI;o hH6P&L{@q6[ Gzp^71j(l`J}]e6X☉#͕ ׈$AB1Vjh㭦IRsqFBjwQ_7Xk>y"N=MB0 ,C #o6MRc0|$)ف"1!ixY<B9mx `,tA>)5ػQ?jQ?cn>YZe Tisvh# GMމȇp:ԴVuږ8ɼH]C.5C!UV;F`mbBk LTMvPʍϤj?ԯ/Qr1NB`9s"s TYsz &9S%U԰> {<ؿSMxB|H\3@!U| k']$U+> |HHMLޢ?V9iD!-@x TIî%6Z*9X@HMW#?nN ,oe6?tQwڱ.]-y':mW0#!J82qFjH -`ѓ&M0u Uγmxϵ^-_\])@0Rt.8/?ٰCY]x}=sD3ojަЫNuS%U}ԤwHH>ڗjܷ_3gN q7[q2la*ArǓԖ+p8/RGM ]jacd(JhWko6ڎbj]i5Bj3+3!\j1UZLsLTv8HHmup<>gKMJj0@H%,W΃7R) ">c, xixј^ aܖ>H[i.UIHc U1=yW\=S*GR~)AF=`&2h`DzT󑓶J+?W+}C%P:|0H܆}-<;OC[~o.$~i}~HQ TvXΈr=b}$vizL4:ȰT|4~*!oXQR6Lk+#t/g lԁߖ[Jڶ_N$k*". xsxX7jRVbAAʯKҎU3)zSNN _'s?f)6X!%ssAkʱ>qƷb hg %n ~p1REGMHH=BJiy[<5 ǁJҖgKR*倳e~HUy)Ag,K)`Vw6bRR:qL#\rclK/$sh*$ 6덤 KԖc 3Z9=Ɣ=o>X Ώ"1 )a`SJJ6k(<c e{%kϊP+SL'TcMJWRm ŏ"w)qc ef꒵i?b7b('"2r%~HUS1\<(`1Wx9=8HY9m:X18bgD1u ~|H;K-Uep,, C1 RV.MR5άh,tWO8WC$ XRVsQS]3GJ|12 [vM :k#~tH30Rf-HYݺ-`I9%lIDTm\ S{]9gOڒMNCV\G*2JRŨ;Rҏ^ڽ̱mq1Eu?To3I)y^#jJw^Ńj^vvlB_⋌P4x>0$c>K†Aļ9s_VjTt0l#m>E-,,x,-W)سo&96RE XR.6bXw+)GAEvL)͞K4$p=Ũi_ѱOjb HY/+@θH9޼]Nԥ%n{ &zjT? Ty) s^ULlb,PiTf^<À] 62R^V7)S!nllS6~͝V}-=%* ʻ>G DnK<y&>LPy7'r=Hj 9V`[c"*^8HpcO8bnU`4JȪAƋ#1_\ XϘHPRgik(~G~0DAA_2p|J묭a2\NCr]M_0 ^T%e#vD^%xy-n}-E\3aS%yN!r_{ )sAw ڼp1pEAk~v<:`'ӭ^5 ArXOI驻T (dk)_\ PuA*BY]yB"l\ey hH*tbK)3 IKZ򹞋XjN n *n>k]X_d!ryBH ]*R 0(#'7 %es9??ښFC,ՁQPjARJ\Ρw K#jahgw;2$l*) %Xq5!U᢯6Re] |0[__64ch&_}iL8KEgҎ7 M/\`|.p,~`a=BR?xܐrQ8K XR2M8f ?`sgWS%" Ԉ 7R%$ N}?QL1|-эټwIZ%pvL3Hk>,ImgW7{E xPHx73RA @RS CC !\ȟ5IXR^ZxHл$Q[ŝ40 (>+ _C >BRt<,TrT {O/H+˟Pl6 I B)/VC<6a2~(XwV4gnXR ϱ5ǀHٻ?tw똤Eyxp{#WK qG%5],(0ӈH HZ])ג=K1j&G(FbM@)%I` XRg ʔ KZG(vP,<`[ Kn^ SJRsAʠ5xՅF`0&RbV tx:EaUE/{fi2;.IAwW8/tTxAGOoN?G}l L(n`Zv?pB8K_gI+ܗ #i?ޙ.) p$utc ~DžfՈEo3l/)I-U?aԅ^jxArA ΧX}DmZ@QLےbTXGd.^|xKHR{|ΕW_h] IJ`[G9{).y) 0X YA1]qp?p_k+J*Y@HI>^?gt.06Rn ,` ?);p pSF9ZXLBJPWjgQ|&)7! HjQt<| ؅W5 x W HIzYoVMGP Hjn`+\(dNW)F+IrS[|/a`K|ͻ0Hj{R,Q=\ (F}\WR)AgSG`IsnAR=|8$}G(vC$)s FBJ?]_u XRvύ6z ŨG[36-T9HzpW̞ú Xg큽=7CufzI$)ki^qk-) 0H*N` QZkk]/tnnsI^Gu't=7$ Z;{8^jB% IItRQS7[ϭ3 $_OQJ`7!]W"W,)Iy W AJA;KWG`IY{8k$I$^%9.^(`N|LJ%@$I}ֽp=FB*xN=gI?Q{٥4B)mw $Igc~dZ@G9K X?7)aK%݅K$IZ-`IpC U6$I\0>!9k} Xa IIS0H$I H ?1R.Чj:4~Rw@p$IrA*u}WjWFPJ$I➓/6#! LӾ+ X36x8J |+L;v$Io4301R20M I$-E}@,pS^ޟR[/s¹'0H$IKyfŸfVOπFT*a$I>He~VY/3R/)>d$I>28`Cjw,n@FU*9ttf$I~<;=/4RD~@ X-ѕzἱI$: ԍR a@b X{+Qxuq$IЛzo /~3\8ڒ4BN7$IҀj V]n18H$IYFBj3̵̚ja pp $Is/3R Ӻ-Yj+L;.0ŔI$Av? #!5"aʄj}UKmɽH$IjCYs?h$IDl843.v}m7UiI=&=0Lg0$I4: embe` eQbm0u? $IT!Sƍ'-sv)s#C0:XB2a w I$zbww{."pPzO =Ɔ\[ o($Iaw]`E).Kvi:L*#gР7[$IyGPI=@R 4yR~̮´cg I$I/<tPͽ hDgo 94Z^k盇΄8I56^W$I^0̜N?4*H`237}g+hxoq)SJ@p|` $I%>-hO0eO>\ԣNߌZD6R=K ~n($I$y3D>o4b#px2$yڪtzW~a $I~?x'BwwpH$IZݑnC㧄Pc_9sO gwJ=l1:mKB>Ab<4Lp$Ib o1ZQ@85b̍ S'F,Fe,^I$IjEdù{l4 8Ys_s Z8.x m"+{~?q,Z D!I$ϻ'|XhB)=…']M>5 rgotԎ 獽PH$IjIPhh)n#cÔqA'ug5qwU&rF|1E%I$%]!'3AFD/;Ck_`9 v!ٴtPV;x`'*bQa w I$Ix5 FC3D_~A_#O݆DvV?<qw+I$I{=Z8".#RIYyjǪ=fDl9%M,a8$I$Ywi[7ݍFe$s1ՋBVA?`]#!oz4zjLJo8$I$%@3jAa4(o ;p,,dya=F9ً[LSPH$IJYЉ+3> 5"39aZ<ñh!{TpBGkj}Sp $IlvF.F$I z< '\K*qq.f<2Y!S"-\I$IYwčjF$ w9 \ߪB.1v!Ʊ?+r:^!I$BϹB H"B;L'G[ 4U#5>੐)|#o0aڱ$I>}k&1`U#V?YsV x>{t1[I~D&(I$I/{H0fw"q"y%4 IXyE~M3 8XψL}qE$I[> nD?~sf ]o΁ cT6"?'_Ἣ $I>~.f|'!N?⟩0G KkXZE]ޡ;/&?k OۘH$IRۀwXӨ<7@PnS04aӶp.:@\IWQJ6sS%I$e5ڑv`3:x';wq_vpgHyXZ 3gЂ7{{EuԹn±}$I$8t;b|591nءQ"P6O5i }iR̈́%Q̄p!I䮢]O{H$IRϻ9s֧ a=`- aB\X0"+5"C1Hb?߮3x3&gşggl_hZ^,`5?ߎvĸ%̀M!OZC2#0x LJ0 Gw$I$I}<{Eb+y;iI,`ܚF:5ܛA8-O-|8K7s|#Z8a&><a&/VtbtLʌI$I$I$I$I$I$IRjDD%tEXtdate:create2022-05-31T04:40:26+00:00!Î%tEXtdate:modify2022-05-31T04:40:26+00:00|{2IENDB`Mini Shell

HOME


Mini Shell 1.0
DIR:/home/austenwhite.co.uk/www/dev/pub/static/adminhtml/Magento/backend/en_US/js/bundle/
Upload File :
Current File : /home/austenwhite.co.uk/www/dev/pub/static/adminhtml/Magento/backend/en_US/js/bundle/bundle4.js
require.config({"config": {
        "jsbuild":{"Magento_Ui/js/grid/filters/filters.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'underscore',\n    'mageUtils',\n    'uiLayout',\n    'uiCollection',\n    'mage/translate',\n    'jquery'\n], function (_, utils, layout, Collection, $t, $) {\n    'use strict';\n\n    /**\n     * Extracts and formats preview of an element.\n     *\n     * @param {Object} elem - Element whose preview should be extracted.\n     * @returns {Object} Formatted data.\n     */\n    function extractPreview(elem) {\n        return {\n            label: elem.label,\n            preview: elem.getPreview(),\n            elem: elem\n        };\n    }\n\n    /**\n     * Removes empty properties from the provided object.\n     *\n     * @param {Object} data - Object to be processed.\n     * @returns {Object}\n     */\n    function removeEmpty(data) {\n        var result = utils.mapRecursive(data, utils.removeEmptyValues.bind(utils));\n\n        return utils.mapRecursive(result, function (value) {\n            return _.isString(value) ? value.trim() : value;\n        });\n    }\n\n    return Collection.extend({\n        defaults: {\n            template: 'ui/grid/filters/filters',\n            stickyTmpl: 'ui/grid/sticky/filters',\n            _processed: [],\n            columnsProvider: 'ns = ${ $.ns }, componentType = columns',\n            bookmarksProvider: 'ns = ${ $.ns }, componentType = bookmark',\n            applied: {\n                placeholder: true\n            },\n            filters: {\n                placeholder: true\n            },\n            templates: {\n                filters: {\n                    base: {\n                        parent: '${ $.$data.filters.name }',\n                        name: '${ $.$data.column.index }',\n                        provider: '${ $.$data.filters.name }',\n                        dataScope: '${ $.$data.column.index }',\n                        label: '${ $.$data.column.label }',\n                        imports: {\n                            visible: '${ $.$data.column.name }:visible'\n                        }\n                    },\n                    text: {\n                        component: 'Magento_Ui/js/form/element/abstract',\n                        template: 'ui/grid/filters/field'\n                    },\n                    select: {\n                        component: 'Magento_Ui/js/form/element/select',\n                        template: 'ui/grid/filters/field',\n                        options: '${ JSON.stringify($.$data.column.options) }',\n                        caption: ' '\n                    },\n                    dateRange: {\n                        component: 'Magento_Ui/js/grid/filters/range',\n                        rangeType: 'date'\n                    },\n                    datetimeRange: {\n                        component: 'Magento_Ui/js/grid/filters/range',\n                        rangeType: 'datetime'\n                    },\n                    textRange: {\n                        component: 'Magento_Ui/js/grid/filters/range',\n                        rangeType: 'text'\n                    }\n                }\n            },\n            chipsConfig: {\n                name: '${ $.name }_chips',\n                provider: '${ $.chipsConfig.name }',\n                component: 'Magento_Ui/js/grid/filters/chips'\n            },\n            listens: {\n                active: 'updatePreviews',\n                applied: 'cancel updateActive'\n            },\n            statefull: {\n                applied: true\n            },\n            exports: {\n                applied: '${ $.provider }:params.filters'\n            },\n            imports: {\n                onColumnsUpdate: '${ $.columnsProvider }:elems',\n                onBackendError: '${ $.provider }:lastError',\n                bookmarksActiveIndex: '${ $.bookmarksProvider }:activeIndex'\n            },\n            modules: {\n                columns: '${ $.columnsProvider }',\n                chips: '${ $.chipsConfig.provider }'\n            }\n        },\n\n        /**\n         * Initializes filters component.\n         *\n         * @returns {Filters} Chainable.\n         */\n        initialize: function (config) {\n            if (typeof config.options !== 'undefined' && config.options.dateFormat) {\n                this.constructor.defaults.templates.filters.dateRange.dateFormat = config.options.dateFormat;\n            }\n            _.bindAll(this, 'updateActive');\n\n            this._super()\n                .initChips()\n                .cancel();\n\n            return this;\n        },\n\n        /**\n         * Initializes observable properties.\n         *\n         * @returns {Filters} Chainable.\n         */\n        initObservable: function () {\n            this._super()\n                .track({\n                    active: [],\n                    previews: []\n                });\n\n            return this;\n        },\n\n        /**\n         * Initializes chips component.\n         *\n         * @returns {Filters} Chainable.\n         */\n        initChips: function () {\n            layout([this.chipsConfig]);\n\n            this.chips('insertChild', this.name);\n\n            return this;\n        },\n\n        /**\n         * Called when another element was added to filters collection.\n         *\n         * @returns {Filters} Chainable.\n         */\n        initElement: function (elem) {\n            this._super();\n\n            elem.on('elems', this.updateActive);\n\n            this.updateActive();\n\n            return this;\n        },\n\n        /**\n         * Clears filters data.\n         *\n         * @param {Object} [filter] - If provided, then only specified\n         *      filter will be cleared. Otherwise, clears all data.\n         * @returns {Filters} Chainable.\n         */\n        clear: function (filter) {\n            filter ?\n                filter.clear() :\n                _.invoke(this.active, 'clear');\n\n            this.apply();\n\n            return this;\n        },\n\n        /**\n         * Sets filters data to the applied state.\n         *\n         * @returns {Filters} Chainable.\n         */\n        apply: function () {\n            if (typeof $('body').notification === 'function') {\n                $('body').notification('clear');\n            }\n            this.set('applied', removeEmpty(this.filters));\n            return this;\n        },\n\n        /**\n         * Resets filters to the last applied state.\n         *\n         * @returns {Filters} Chainable.\n         */\n        cancel: function () {\n            this.set('filters', utils.copy(this.applied));\n\n            return this;\n        },\n\n        /**\n         * Sets provided data to filter components (without applying it).\n         *\n         * @param {Object} data - Filters data.\n         * @param {Boolean} [partial=false] - Flag that defines whether\n         *      to completely replace current filters data or to extend it.\n         * @returns {Filters} Chainable.\n         */\n        setData: function (data, partial) {\n            var filters = partial ? this.filters : {};\n\n            data = utils.extend({}, filters, data);\n\n            this.set('filters', data);\n\n            return this;\n        },\n\n        /**\n         * Creates instance of a filter associated with the provided column.\n         *\n         * @param {Column} column - Column component for which to create a filter.\n         * @returns {Filters} Chainable.\n         */\n        addFilter: function (column) {\n            var index       = column.index,\n                processed   = this._processed,\n                filter;\n\n            if (!column.filter || _.contains(processed, index)) {\n                return this;\n            }\n\n            filter = this.buildFilter(column);\n\n            processed.push(index);\n\n            layout([filter]);\n\n            return this;\n        },\n\n        /**\n         * Creates filter component configuration associated with the provided column.\n         *\n         * @param {Column} column - Column component with a basic filter declaration.\n         * @returns {Object} Filters' configuration.\n         */\n        buildFilter: function (column) {\n            var filters = this.templates.filters,\n                filter  = column.filter,\n                type    = filters[filter.filterType];\n\n            if (_.isObject(filter) && type) {\n                filter = utils.extend({}, type, filter);\n            } else if (_.isString(filter)) {\n                filter = filters[filter];\n            }\n\n            filter = utils.extend({}, filters.base, filter);\n            //Accepting labels as is.\n            filter.__disableTmpl = {\n                label: 1,\n                options: 1\n            };\n\n            filter = utils.template(filter, {\n                filters: this,\n                column: column\n            }, true, true);\n\n            filter.__disableTmpl = {\n                label: true\n            };\n\n            return filter;\n        },\n\n        /**\n         * Returns an array of range filters.\n         *\n         * @returns {Array}\n         */\n        getRanges: function () {\n            return this.elems.filter(function (filter) {\n                return filter.isRange;\n            });\n        },\n\n        /**\n         * Returns an array of non-range filters.\n         *\n         * @returns {Array}\n         */\n        getPlain: function () {\n            return this.elems.filter(function (filter) {\n                return !filter.isRange;\n            });\n        },\n\n        /**\n         * Tells wether specified filter should be visible.\n         *\n         * @param {Object} filter\n         * @returns {Boolean}\n         */\n        isFilterVisible: function (filter) {\n            return filter.visible() || this.isFilterActive(filter);\n        },\n\n        /**\n         * Checks if specified filter is active.\n         *\n         * @param {Object} filter\n         * @returns {Boolean}\n         */\n        isFilterActive: function (filter) {\n            return _.contains(this.active, filter);\n        },\n\n        /**\n         * Checks if collection has visible filters.\n         *\n         * @returns {Boolean}\n         */\n        hasVisible: function () {\n            return this.elems.some(this.isFilterVisible, this);\n        },\n\n        /**\n         * Finds filters with a not empty data\n         * and sets them to the 'active' filters array.\n         *\n         * @returns {Filters} Chainable.\n         */\n        updateActive: function () {\n            var applied = _.keys(this.applied);\n\n            this.active = this.elems.filter(function (elem) {\n                return _.contains(applied, elem.index);\n            });\n\n            return this;\n        },\n\n        /**\n         * Returns number of applied filters.\n         *\n         * @returns {Number}\n         */\n        countActive: function () {\n            return this.active.length;\n        },\n\n        /**\n         * Extract previews of a specified filters.\n         *\n         * @param {Array} filters - Filters to be processed.\n         * @returns {Filters} Chainable.\n         */\n        updatePreviews: function (filters) {\n            var previews = filters.map(extractPreview);\n\n            this.previews = _.compact(previews);\n\n            return this;\n        },\n\n        /**\n         * Listener of the columns provider children array changes.\n         *\n         * @param {Array} columns - Current columns list.\n         */\n        onColumnsUpdate: function (columns) {\n            columns.forEach(this.addFilter, this);\n        },\n\n        /**\n         * Provider ajax error listener.\n         *\n         * @param {bool} isError - Selected index of the filter.\n         */\n        onBackendError: function (isError) {\n            var defaultMessage = 'Something went wrong with processing the default view and we have restored the ' +\n                    'filter to its original state.',\n                customMessage  = 'Something went wrong with processing current custom view and filters have been ' +\n                    'reset to its original state. Please edit filters then click apply.';\n\n            if (isError) {\n                this.clear();\n\n                $('body').notification('clear')\n                    .notification('add', {\n                        error: true,\n                        message: $.mage.__(this.bookmarksActiveIndex !== 'default' ? customMessage : defaultMessage),\n\n                        /**\n                         * @param {String} message\n                         */\n                        insertMethod: function (message) {\n                            var $wrapper = $('<div></div>').html(message);\n\n                            $('.page-main-actions').after($wrapper);\n                        }\n                    });\n            }\n        }\n    });\n});\n","Magento_Ui/js/grid/filters/elements/ui-select.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'Magento_Ui/js/form/element/ui-select',\n    'jquery',\n    'underscore'\n], function (Select, $, _) {\n    'use strict';\n\n    return Select.extend({\n        defaults: {\n            bookmarkProvider: 'ns = ${ $.ns }, index = bookmarks',\n            filterChipsProvider: 'componentType = filters, ns = ${ $.ns }',\n            validationUrl: false,\n            loadedOption: [],\n            validationLoading: true,\n            imports: {\n                applied: '${ $.filterChipsProvider }:applied',\n                activeIndex: '${ $.bookmarkProvider }:activeIndex'\n            },\n            modules: {\n                filterChips: '${ $.filterChipsProvider }'\n            },\n            listens: {\n                activeIndex: 'validateInitialValue',\n                applied: 'validateInitialValue'\n            }\n\n        },\n\n        /**\n         * Initializes UiSelect component.\n         *\n         * @returns {UiSelect} Chainable.\n         */\n        initialize: function () {\n            this._super();\n\n            this.validateInitialValue();\n\n            return this;\n        },\n\n        /**\n         * Validate initial value actually exists\n         */\n        validateInitialValue: function () {\n            if (_.isEmpty(this.value())) {\n                this.validationLoading(false);\n\n                return;\n            }\n\n            $.ajax({\n                url: this.validationUrl,\n                type: 'GET',\n                dataType: 'json',\n                context: this,\n                data: {\n                    ids: this.value()\n                },\n\n                /** @param {Object} response */\n                success: function (response) {\n                    if (!_.isEmpty(response)) {\n                        this.options([]);\n                        this.success({\n                            options: response\n                        });\n                    }\n                    this.filterChips().updateActive();\n                },\n\n                /** set empty array if error occurs */\n                error: function () {\n                    this.options([]);\n                },\n\n                /** stop loader */\n                complete: function () {\n                    this.validationLoading(false);\n                    this.setCaption();\n                }\n            });\n        }\n    });\n});\n","Magento_Ui/js/grid/sticky/sticky.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'Magento_Ui/js/lib/view/utils/async',\n    'underscore',\n    'uiComponent',\n    'Magento_Ui/js/lib/view/utils/raf'\n], function ($, _, Component, raf) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            listingSelector: '${ $.listingProvider }::not([data-role = \"sticky-el-root\"])',\n            toolbarSelector: '${ $.toolbarProvider }::not([data-role = \"sticky-el-root\"])',\n            bulkRowSelector: '[data-role = \"data-grid-bulk-row\"]',\n            bulkRowHeaderSelector: '.data-grid-info-panel:visible',\n            tableSelector: 'table',\n            columnSelector: 'thead tr th',\n            rowSelector: 'tbody tr',\n            toolbarCollapsiblesSelector: '[data-role=\"toolbar-menu-item\"]',\n            toolbarCollapsiblesActiveClass: '_active',\n            template: 'ui/grid/sticky/sticky',\n            stickyContainerSelector: '.sticky-header',\n            stickyElementSelector: '[data-role = \"sticky-el-root\"]',\n            leftDataGridCapSelector: '.data-grid-cap-left',\n            rightDataGridCapSelector: '.data-grid-cap-right',\n            visible: false,\n            enableToolbar: true,\n            enableHeader: true,\n            modules: {\n                toolbar: '${ $.toolbarProvider }',\n                listing: '${ $.listingProvider }'\n            },\n            otherStickyElsSize: 77,\n            containerNode: null,\n            listingNode: null,\n            toolbarNode: null,\n            stickyListingNode: null,\n            stickyToolbarNode: null,\n            storedOriginalToolbarElements: [],\n            cache: {},\n            flags: {},\n            dirtyFlag: 'dirty'\n        },\n\n        /**\n         * Initializes Sticky component.\n         *\n         * @returns {Object} Chainable.\n         */\n        initialize: function () {\n            this._super();\n            _.bindAll(this,\n                'adjustStickyElems',\n                'initListingNode',\n                'initToolbarNode',\n                'initContainerNode',\n                'initColumns',\n                'initStickyListingNode',\n                'initStickyToolbarNode',\n                'initLeftDataGridCap',\n                'initRightDataGridCap'\n            );\n\n            $.async(this.listingSelector,\n                this.initListingNode);\n            $.async(this.toolbarSelector,\n                this.initToolbarNode);\n\n            $.async(this.stickyContainerSelector,\n                this,\n                this.initContainerNode);\n\n            return this;\n        },\n\n        /**\n         * Init observables\n         *\n         * @returns {Object} Chainable.\n         */\n        initObservable: function () {\n            this._super()\n                .track('visible');\n\n            return this;\n        },\n\n        /**\n         * Init original listing node\n         *\n         * @param {HTMLElement} node\n         */\n        initListingNode: function (node) {\n            if ($(node).is(this.stickyElementSelector)) {\n                return;\n            }\n            this.listingNode = $(node);\n            $.async(this.columnSelector, node, this.initColumns);\n        },\n\n        /**\n         * Init original toolbar node\n         *\n         * @param {HTMLElement} node\n         */\n        initToolbarNode: function (node) {\n            if ($(node).is(this.stickyElementSelector)) {\n                return;\n            }\n            this.toolbarNode = $(node);\n        },\n\n        /**\n         * Init sticky listing node\n         *\n         * @param {HTMLElement} node\n         */\n        initStickyListingNode: function (node) {\n            this.stickyListingNode = $(node);\n            this.checkPos();\n            this.initListeners();\n        },\n\n        /**\n         * Init sticky toolbar node\n         *\n         * @param {HTMLElement} node\n         */\n        initStickyToolbarNode: function (node) {\n            this.stickyToolbarNode = $(node);\n        },\n\n        /**\n         * Init sticky header container node\n         *\n         * @param {HTMLElement} node\n         */\n        initContainerNode: function (node) {\n            this.containerNode = $(node);\n\n            $.async(this.leftDataGridCapSelector,\n                node,\n                this.initLeftDataGridCap);\n            $.async(this.rightDataGridCapSelector,\n                node,\n                this.initRightDataGridCap);\n\n            $.async(this.stickyElementSelector,\n                this.listing(),\n                this.initStickyListingNode);\n            $.async(this.stickyElementSelector,\n                this.toolbar(),\n                this.initStickyToolbarNode);\n        },\n\n        /**\n         * Init columns (each time when amount of columns is changed)\n         *\n         */\n        initColumns: function () {\n            this.columns = this.listingNode.find(this.columnSelector);\n        },\n\n        /**\n         * Init left DataGridCap\n         *\n         * @param {HTMLElement} node\n         */\n        initLeftDataGridCap: function (node) {\n            this.leftDataGridCap = $(node);\n        },\n\n        /**\n         * Init right DataGridCap\n         *\n         * @param {HTMLElement} node\n         */\n        initRightDataGridCap: function (node) {\n            this.rightDataGridCap = $(node);\n        },\n\n        /**\n         * Init listeners\n         *\n         * @returns {Object} Chainable.\n         */\n        initListeners: function () {\n            this.adjustStickyElems();\n            this.initOnResize()\n                .initOnScroll()\n                .initOnListingScroll();\n\n            return this;\n        },\n\n        /**\n         * Start to listen to window scroll event\n         *\n         * @returns {Object} Chainable.\n         */\n        initOnScroll: function () {\n            this.lastHorizontalScrollPos = $(window).scrollLeft();\n            document.addEventListener('scroll', function () {\n                this.flags.scrolled = true;\n            }.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Start to listen to original listing scroll event\n         *\n         * @returns {Object} Chainable.\n         */\n        initOnListingScroll: function () {\n            $(this.listingNode).on('scroll', function (e) {\n                this.flags.listingScrolled = true;\n                this.flags.listingScrolledValue = $(e.target).scrollLeft();\n            }.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Start to listen to window resize event\n         *\n         * @returns {Object} Chainable.\n         */\n        initOnResize: function () {\n            $(window).on('resize', function () {\n                this.flags.resized = true;\n            }.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Adjust sticky header elements according to flags of the events that have happened in the endless RAF loop\n         */\n        adjustStickyElems: function () {\n            if (this.flags.resized ||\n                this.flags.scrolled) {\n                this.checkPos();\n            }\n\n            if (this.visible) {\n                this.checkTableElemsWidth();\n\n                if (this.flags.originalWidthChanged) {\n                    this.adjustContainerElemsWidth();\n                }\n\n                if (this.flags.resized) {\n                    this.onResize();\n                }\n\n                if (this.flags.scrolled) {\n                    this.onWindowScroll();\n                }\n\n                if (this.flags.listingScrolled) {\n                    this.onListingScroll(this.flags.listingScrolledValue);\n                }\n            }\n            _.each(this.flags, function (val, key) {\n                if (val === this.dirtyFlag) {\n                    this.flags[key] = false;\n                } else if (val) {\n                    this.flags[key] = this.dirtyFlag;\n                }\n            }, this);\n\n            raf(this.adjustStickyElems);\n        },\n\n        /**\n         * Handles window scroll\n         */\n        onWindowScroll: function () {\n            var scrolled = $(window).scrollLeft(),\n                horizontal = this.lastHorizontalScrollPos !== scrolled;\n\n            if (horizontal) {\n                this.adjustOffset()\n                    .adjustDataGridCapPositions();\n                this.lastHorizontalScrollPos = scrolled;\n            } else {\n                this.checkPos();\n            }\n        },\n\n        /**\n         * Handles original listing scroll\n         *\n         * @param {Number} scrolled\n         */\n        onListingScroll: function (scrolled) {\n            this.adjustOffset(scrolled);\n        },\n\n        /**\n         * Handles window resize\n         */\n        onResize: function () {\n            this.checkPos();\n            this.adjustContainerElemsWidth()\n                .adjustDataGridCapPositions();\n        },\n\n        /**\n         * Check if original table or columns change it dimensions and sets appropriate flag\n         */\n        checkTableElemsWidth: function () {\n            var newWidth = this.getTableWidth();\n\n            if (this.cache.tableWidth !== newWidth) {\n                this.cache.tableWidth = newWidth;\n                this.flags.originalWidthChanged = true;\n            } else if (this.cache.colChecksum !== this.getColsChecksum()) {\n                this.cache.colChecksum = this.getColsChecksum();\n                this.flags.originalWidthChanged = true;\n            }\n        },\n\n        /**\n         * Get the checksum of original columns width\n         *\n         * @returns {Number}.\n         */\n        getColsChecksum: function () {\n            return _.reduce(this.columns,\n            function (pv, cv) {\n                return ($(pv).width() || pv) + '' + $(cv).width();\n            });\n        },\n\n        /**\n         * Get the width of the sticky table wrapper\n         *\n         * @returns {Number}.\n         */\n        getListingWidth: function () {\n            return this.listingNode.width();\n        },\n\n        /**\n         * Get the width of the original table\n         *\n         * @returns {Number}.\n         */\n        getTableWidth: function () {\n            return this.listingNode.find(this.tableSelector).width();\n        },\n\n        /**\n         * Get the top elem: header or toolbar\n         *\n         * @returns {HTMLElement}.\n         */\n        getTopElement: function () {\n            return this.toolbarNode || this.listingNode;\n        },\n\n        /**\n         * Get the height of the other sticky elem (Page header)\n         *\n         * @returns {Number}.\n         */\n        getOtherStickyElementsSize: function () {\n            return this.otherStickyElsSize;\n        },\n\n        /**\n         * Get original bulk row height, if is visible\n         *\n         * @returns {Number}.\n         */\n        getBulkRowHeight: function () {\n            return this.listingNode.find(this.bulkRowSelector).filter(':visible').height();\n        },\n\n        /**\n         * Get top Y coord of the sticky header\n         *\n         * @returns {Number}.\n         */\n        getListingTopYCoord: function () {\n            var bulkRowHeight = this.getBulkRowHeight();\n\n            return this.listingNode.find('tbody').offset().top -\n                this.containerNode.height() -\n                $(window).scrollTop() +\n                bulkRowHeight;\n        },\n\n        /**\n         * Check if sticky header must be visible\n         *\n         * @returns {Boolean}.\n         */\n        getMustBeSticky: function () {\n            var stickyTopCondition = this.getListingTopYCoord() - this.getOtherStickyElementsSize(),\n                stickyBottomCondition = this.listingNode.offset().top +\n                    this.listingNode.height() -\n                    $(window).scrollTop() +\n                    this.getBulkRowHeight() -\n                    this.getOtherStickyElementsSize();\n\n            return stickyTopCondition < 0 && stickyBottomCondition > 0;\n        },\n\n        /**\n         * Resize sticky header and cols\n         *\n         * @returns {Object} Chainable.\n         */\n        adjustContainerElemsWidth: function () {\n            this.resizeContainer()\n                .resizeCols()\n                .resizeBulk();\n\n            return this;\n        },\n\n        /**\n         * Resize sticky header\n         *\n         * @returns {Object} Chainable.\n         */\n        resizeContainer: function () {\n            var listingWidth = this.getListingWidth();\n\n            this.stickyListingNode.innerWidth(listingWidth);\n            this.stickyListingNode.find(this.tableSelector).innerWidth(this.getTableWidth());\n\n            if (this.stickyToolbarNode) {\n                this.stickyToolbarNode.innerWidth(listingWidth);\n            }\n\n            return this;\n        },\n\n        /**\n         * Resize sticky cols\n         *\n         * @returns {Object} Chainable.\n         */\n        resizeCols: function () {\n            var cols = this.listingNode.find(this.columnSelector);\n\n            this.stickyListingNode.find(this.columnSelector).each(function (ind) {\n                var originalColWidth =  $(cols[ind]).width();\n\n                $(this).width(originalColWidth);\n            });\n\n            return this;\n        },\n\n        /**\n         * Resize bulk row header\n         *\n         * @returns {Object} Chainable.\n         */\n        resizeBulk: function () {\n            var bulk = this.containerNode.find(this.bulkRowHeaderSelector)[0];\n\n            if (bulk) {\n                $(bulk).innerWidth(this.getListingWidth());\n            }\n\n            return this;\n        },\n\n        /**\n         * Reset viewport to the top of listing\n         */\n        resetToTop: function () {\n            var posOfTopEl = this.getTopElement().offset().top - this.getOtherStickyElementsSize() || 0;\n\n            $(window).scrollTop(posOfTopEl);\n        },\n\n        /**\n         * Adjust sticky header offset\n         *\n         * @param {Number} val\n         * @returns {Object} Chainable.\n         */\n        adjustOffset: function (val) {\n            val = val || this.listingNode.scrollLeft();\n            this.stickyListingNode.offset({\n                left: this.listingNode.offset().left - val\n            });\n\n            return this;\n        },\n\n        /**\n         * Adjust both DataGridCap position\n         *\n         * @returns {Object} Chainable.\n         */\n        adjustDataGridCapPositions: function () {\n            this.adjustLeftDataGridCapPos()\n                .adjustRightDataGridCapPos();\n\n            return this;\n        },\n\n        /**\n         * Adjust left DataGridCap position\n         *\n         * @returns {Object} Chainable.\n         */\n        adjustLeftDataGridCapPos: function () {\n            this.leftDataGridCap.offset({\n                left: this.listingNode.offset().left - this.leftDataGridCap.width()\n            });\n\n            return this;\n        },\n\n        /**\n         * Adjust right DataGridCap position\n         *\n         * @returns {Object} Chainable.\n         */\n        adjustRightDataGridCapPos: function () {\n            this.rightDataGridCap.offset({\n                left: this.listingNode.offset().left + this.listingNode.width()\n            });\n\n            return this;\n        },\n\n        /**\n         * Hides the oiginal toolbar opened dropdowns/collapsibles etc\n         */\n        collapseOriginalElements: function () {\n            this.toolbarNode\n                .find(this.toolbarCollapsiblesSelector)\n                .css('visibility', 'hidden');\n            $(this.listingNode.find(this.bulkRowSelector)[0]).css('visibility', 'hidden');\n        },\n\n        /**\n         * Restores the oiginal toolbar opened dropdowns/collapsibles etc\n         */\n        restoreOriginalElements: function () {\n            this.toolbarNode\n                .find(this.toolbarCollapsiblesSelector)\n                .css('visibility', 'visible');\n            $(this.listingNode.find(this.bulkRowSelector)[0]).css('visibility', 'visible');\n        },\n\n        /**\n         * Toggle the visibility of sticky header\n         *\n         * @returns {Object} Chainable.\n         */\n        toggleContainerVisibility: function () {\n            this.visible = !this.visible;\n\n            return this;\n        },\n\n        /**\n         * Checks position of the listing to know if need to show/hide sticky header\n         *\n         * @returns {Boolean} whether the visibility of the sticky header was toggled.\n         */\n        checkPos: function () {\n            var isSticky = this.visible,\n                mustBeSticky = this.getMustBeSticky(),\n                needChange = isSticky !== mustBeSticky;\n\n            if (needChange) {\n                if (mustBeSticky) {\n                    this.collapseOriginalElements();\n                    this.toggleContainerVisibility();\n                    this.adjustContainerElemsWidth()\n                        .adjustOffset()\n                        .adjustDataGridCapPositions();\n\n                } else {\n                    this.toggleContainerVisibility();\n                    this.restoreOriginalElements();\n                }\n            }\n\n            return needChange;\n        }\n    });\n});\n","Magento_Ui/js/grid/search/search.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'underscore',\n    'uiLayout',\n    'mage/translate',\n    'mageUtils',\n    'uiElement',\n    'jquery'\n], function (_, layout, $t, utils, Element, $) {\n    'use strict';\n\n    return Element.extend({\n        defaults: {\n            template: 'ui/grid/search/search',\n            placeholder: $t('Search by keyword'),\n            label: $t('Keyword'),\n            value: '',\n            keywordUpdated: false,\n            previews: [],\n            chipsProvider: 'componentType = filtersChips, ns = ${ $.ns }',\n            statefull: {\n                value: true\n            },\n            tracks: {\n                value: true,\n                previews: true,\n                inputValue: true,\n                focused: true,\n                keywordUpdated: true\n            },\n            imports: {\n                inputValue: 'value',\n                updatePreview: 'value',\n                focused: false\n            },\n            exports: {\n                value: '${ $.provider }:params.search',\n                keywordUpdated: '${ $.provider }:params.keywordUpdated'\n            },\n            modules: {\n                chips: '${ $.chipsProvider }'\n            }\n        },\n\n        /**\n         * Initializes search component.\n         *\n         * @returns {Search} Chainable.\n         */\n        initialize: function () {\n            var urlParams = window.location.href.slice(window.location.href.search('[\\&\\?](search=)')).split('&'),\n                searchTerm = [];\n\n            this._super()\n                .initChips();\n\n            if (urlParams[0]) {\n                searchTerm = urlParams[0].split('=');\n\n                if (searchTerm[1]) {\n                    this.apply(decodeURIComponent(searchTerm[1]));\n                }\n            }\n\n            return this;\n        },\n\n        /**\n         * Initializes chips component.\n         *\n         * @returns {Search} Chainbale.\n         */\n        initChips: function () {\n            this.chips('insertChild', this, 0);\n\n            return this;\n        },\n\n        /**\n         * Clears search.\n         *\n         * @returns {Search} Chainable.\n         */\n        clear: function () {\n            this.value = '';\n\n            return this;\n        },\n\n        /**\n         * Click To ScrollTop.\n         */\n        scrollTo: function ($data) {\n            $('html, body').animate({\n                scrollTop: 0\n            }, 'slow', function () {\n                $data.focused = false;\n                $data.focused = true;\n            });\n        },\n\n        /**\n         * Resets input value to the last applied state.\n         *\n         * @returns {Search} Chainable.\n         */\n        cancel: function () {\n            this.inputValue = this.value;\n\n            return this;\n        },\n\n        /**\n         * Applies search query.\n         *\n         * @param {String} [value=inputValue] - If not specified, then\n         *      value of the input field will be used.\n         * @returns {Search} Chainable.\n         */\n        apply: function (value) {\n            value = value || this.inputValue;\n\n            this.keywordUpdated = this.value !== value;\n            this.value = this.inputValue = value.trim();\n\n            return this;\n        },\n\n        /**\n         * Updates preview data.\n         *\n         * @returns {Search} Chainable.\n         */\n        updatePreview: function () {\n            var preview = [];\n\n            if (this.value) {\n                preview.push({\n                    elem: this,\n                    label: this.label,\n                    preview: this.value\n                });\n            }\n\n            this.previews = preview;\n\n            return this;\n        }\n    });\n});\n","Magento_Ui/js/grid/controls/columns.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'underscore',\n    'mageUtils',\n    'mage/translate',\n    'uiCollection'\n], function (_, utils, $t, Collection) {\n    'use strict';\n\n    return Collection.extend({\n        defaults: {\n            template: 'ui/grid/controls/columns',\n            minVisible: 1,\n            maxVisible: 30,\n            viewportSize: 18,\n            displayArea: 'dataGridActions',\n            columnsProvider: 'ns = ${ $.ns }, componentType = columns',\n            imports: {\n                addColumns: '${ $.columnsProvider }:elems'\n            },\n            templates: {\n                headerMsg: $t('${ $.visible } out of ${ $.total } visible')\n            }\n        },\n\n        /**\n         * Resets columns visibility to theirs default state.\n         *\n         * @returns {Columns} Chainable.\n         */\n        reset: function () {\n            this.elems.each('applyState', 'default', 'visible');\n\n            return this;\n        },\n\n        /**\n         * Applies last saved state of columns visibility.\n         *\n         * @returns {Columns} Chainable.\n         */\n        cancel: function () {\n            this.elems.each('applyState', '', 'visible');\n\n            return this;\n        },\n\n        /**\n         * Adds columns whose visibility can be controlled to the component.\n         *\n         * @param {Array} columns - Elements array that will be added to component.\n         * @returns {Columns} Chainable.\n         */\n        addColumns: function (columns) {\n            columns = _.where(columns, {\n                controlVisibility: true\n            });\n\n            this.insertChild(columns);\n\n            return this;\n        },\n\n        /**\n         * Defines whether child elements array length\n         * is greater than the 'viewportSize' property.\n         *\n         * @returns {Boolean}\n         */\n        hasOverflow: function () {\n            return this.elems().length > this.viewportSize;\n        },\n\n        /**\n         * Helper, checks\n         *  - if less than one item choosen\n         *  - if more then viewportMaxSize choosen\n         *\n         * @param {Object} elem\n         * @returns {Boolean}\n         */\n        isDisabled: function (elem) {\n            var visible = this.countVisible();\n\n            return elem.visible ?\n                    visible === this.minVisible :\n                    visible === this.maxVisible;\n        },\n\n        /**\n         * Counts number of visible columns.\n         *\n         * @returns {Number}\n         */\n        countVisible: function () {\n            return this.elems.filter('visible').length;\n        },\n\n        /**\n         * Compile header message from headerMessage setting.\n         *\n         * @returns {String}\n         */\n        getHeaderMessage: function () {\n            return utils.template(this.templates.headerMsg, {\n                visible: this.countVisible(),\n                total: this.elems().length\n            });\n        }\n    });\n});\n","Magento_Ui/js/grid/controls/bookmarks/storage.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'mageUtils',\n    'Magento_Ui/js/lib/core/storage/local',\n    'uiClass'\n], function ($, utils, storage, Class) {\n    'use strict';\n\n    /**\n     * Removes ns prefix for path.\n     *\n     * @param {String} ns\n     * @param {String} path\n     * @returns {String}\n     */\n    function removeNs(ns, path) {\n        return path.replace(ns + '.', '');\n    }\n\n    return Class.extend({\n        defaults: {\n            ajaxSettings: {\n                method: 'POST',\n                data: {\n                    namespace: '${ $.namespace }'\n                }\n            }\n        },\n\n        /**\n         * Delegates call to the localStorage adapter.\n         */\n        get: function () {\n            return {};\n        },\n\n        /**\n         * Sends request to store specified data.\n         *\n         * @param {String} path - Path by which data should be stored.\n         * @param {*} value - Value to be sent.\n         */\n        set: function (path, value) {\n            var property = removeNs(this.namespace, path),\n                data = {},\n                config;\n\n            utils.nested(data, property, value);\n\n            config = utils.extend({\n                url: this.saveUrl,\n                data: {\n                    data: JSON.stringify(data)\n                }\n            }, this.ajaxSettings);\n\n            $.ajax(config);\n        },\n\n        /**\n         * Sends request to remove specified data.\n         *\n         * @param {String} path - Path to the property to be removed.\n         */\n        remove: function (path) {\n            var property = removeNs(this.namespace, path),\n                config;\n\n            config = utils.extend({\n                url: this.deleteUrl,\n                data: {\n                    data: property\n                }\n            }, this.ajaxSettings);\n\n            $.ajax(config);\n        }\n    });\n});\n","Magento_Ui/js/grid/controls/bookmarks/bookmarks.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'underscore',\n    'mageUtils',\n    'mage/translate',\n    'rjsResolver',\n    'uiLayout',\n    'uiCollection'\n], function (_, utils, $t, resolver, layout, Collection) {\n    'use strict';\n\n    /**\n     * Removes 'current' namespace from a 'path' string.\n     *\n     * @param {String} path\n     * @returns {String} Path without namespace.\n     */\n    function removeStateNs(path) {\n        path = typeof path == 'string' ? path.split('.') : [];\n\n        if (path[0] === 'current') {\n            path.shift();\n        }\n\n        return path.join('.');\n    }\n\n    return Collection.extend({\n        defaults: {\n            template: 'ui/grid/controls/bookmarks/bookmarks',\n            viewTmpl: 'ui/grid/controls/bookmarks/view',\n            newViewLabel: $t('New View'),\n            defaultIndex: 'default',\n            activeIndex: 'default',\n            viewsArray: [],\n            storageConfig: {\n                provider: '${ $.storageConfig.name }',\n                name: '${ $.name }_storage',\n                component: 'Magento_Ui/js/grid/controls/bookmarks/storage'\n            },\n            views: {\n                default: {\n                    label: $t('Default View'),\n                    index: 'default',\n                    editable: false\n                }\n            },\n            tracks: {\n                editing: true,\n                viewsArray: true,\n                activeView: true,\n                hasChanges: true,\n                customLabel: true,\n                customVisible: true\n            },\n            listens: {\n                activeIndex: 'onActiveIndexChange',\n                activeView: 'checkState',\n                current: 'onStateChange'\n            }\n        },\n\n        /**\n         * Initializes bookmarks component.\n         *\n         * @returns {Bookmarks} Chainable.\n         */\n        initialize: function () {\n            utils.limit(this, 'checkState', 5);\n            utils.limit(this, 'saveState', 2000);\n\n            this._super()\n                .restore()\n                .initStorage()\n                .initViews();\n\n            return this;\n        },\n\n        /**\n         * Creates custom storage instance.\n         *\n         * @returns {Bookmarks} Chainable.\n         */\n        initStorage: function () {\n            layout([this.storageConfig]);\n\n            return this;\n        },\n\n        /**\n         * Defines default data if it wasn't gathered previously.\n         *\n         * @private\n         * @returns {Bookmarks} Chainbale.\n         */\n        initDefaultView: function () {\n            var data = this.getViewData(this.defaultIndex);\n\n            if (!_.size(data) && (this.current.columns && this.current.positions)) {\n                    this.setViewData(this.defaultIndex, this.current)\n                        .saveView(this.defaultIndex);\n                    this.defaultDefined = true;\n            }\n\n            return this;\n        },\n\n        /**\n         * Creates instances of a previously saved views.\n         *\n         * @returns {Bookmarks} Chainable.\n         */\n        initViews: function () {\n            _.each(this.views, function (config) {\n                this.addView(config);\n            }, this);\n\n            this.activeView = this.getActiveView();\n\n            return this;\n        },\n\n        /**\n         * Creates complete configuration for a view.\n         *\n         * @param {Object} [config] - Additional configuration object.\n         * @returns {Object}\n         */\n        buildView: function (config) {\n            var view = {\n                label: this.newViewLabel,\n                index: '_' + Date.now(),\n                editable: true\n            };\n\n            utils.extend(view, config || {});\n\n            view.data   = view.data || utils.copy(this.current);\n            view.value  = view.label;\n\n            this.observe.call(view, true, 'label value');\n\n            return view;\n        },\n\n        /**\n         * Creates instance of a view with a provided configuration.\n         *\n         * @param {Object} [config] - View configuration.\n         * @param {Boolean} [saveView=false] - Whether to save created view automatically or not.\n         * @param {Boolean} [applyView=false] - Whether to apply created view automatically or not.\n         * @returns {View} Created view.\n         */\n        addView: function (config, saveView, applyView) {\n            var view    = this.buildView(config),\n                index   = view.index;\n\n            this.views[index] = view;\n\n            if (saveView) {\n                this.saveView(index);\n            }\n\n            if (applyView) {\n                this.applyView(index);\n            }\n\n            this.updateArray();\n\n            return view;\n        },\n\n        /**\n         * Removes specified view.\n         *\n         * @param {String} index - Index of a view to be removed.\n         * @returns {Bookmarks} Chainable.\n         */\n        removeView: function (index) {\n            var viewPath = this.getViewPath(index);\n\n            if (this.isViewActive(index)) {\n                this.applyView(this.defaultIndex);\n            }\n\n            this.endEdit(index)\n                .remove(viewPath)\n                .removeStored(viewPath)\n                .updateArray();\n\n            return this;\n        },\n\n        /**\n         * Saves data of a specified view.\n         *\n         * @param {String} index - Index of a view to be saved.\n         * @returns {Bookmarks} Chainable.\n         */\n        saveView: function (index) {\n            var viewPath = this.getViewPath(index);\n\n            this.updateViewLabel(index)\n                .endEdit(index)\n                .store(viewPath)\n                .checkState();\n\n            return this;\n        },\n\n        /**\n         * Sets specified view as active\n         * and applies its' state.\n         *\n         * @param {String} index - Index of a view to be applied.\n         * @returns {Bookmarks} Chainable.\n         */\n        applyView: function (index) {\n            this.applyStateOf(index)\n                .set('activeIndex', index);\n\n            return this;\n        },\n\n        /**\n         * Updates data of a specified view if it's\n         * currently active and saves its' data.\n         *\n         * @param {String} index - Index of a view.\n         * @returns {Bookmarks} Chainable.\n         */\n        updateAndSave: function (index) {\n            if (this.isViewActive(index)) {\n                this.updateActiveView(index);\n            }\n\n            this.saveView(index);\n\n            return this;\n        },\n\n        /**\n         * Returns instance of a specified view.\n         *\n         * @param {String} index - Index of a view to be retrieved.\n         * @returns {View}\n         */\n        getView: function (index) {\n            return this.views[index];\n        },\n\n        /**\n         * Returns instance of an active view.\n         *\n         * @returns {View}\n         */\n        getActiveView: function () {\n            return this.views[this.activeIndex];\n        },\n\n        /**\n         * Checks if specified view is active.\n         *\n         * @param {String} index - Index of a view to be checked.\n         * @returns {Boolean}\n         */\n        isViewActive: function (index) {\n            return this.activeView === this.getView(index);\n        },\n\n        /**\n         * Sets current state as a data of an active view.\n         *\n         * @returns {Bookmarks} Chainable.\n         */\n        updateActiveView: function () {\n            this.setViewData(this.activeIndex, this.current);\n\n            return this;\n        },\n\n        /**\n         * Replaces label a view with a provided one.\n         * If new label is not specified, then views'\n         * 'value' property will be taken.\n         *\n         * @param {String} index - Index of a view.\n         * @param {String} [label=view.value] - New labels' value.\n         * @returns {Bookmarks} Chainable.\n         */\n        updateViewLabel: function (index, label) {\n            var view    = this.getView(index),\n                current = view.label;\n\n            label = (label || view.value).trim() || current;\n            label = this.uniqueLabel(label, current);\n\n            view.label = view.value = label;\n\n            return this;\n        },\n\n        /**\n         * Retrieves data of a specified view.\n         *\n         * @param {String} index - Index of a view whose data should be retrieved.\n         * @param {String} [property] - If not specified then whole views' data will be retrieved.\n         * @returns {Object} Views' data.\n         */\n        getViewData: function (index, property) {\n            var view = this.getView(index),\n                data = view.data;\n\n            if (property) {\n                data = utils.nested(data, property);\n            }\n\n            return utils.copy(data);\n        },\n\n        /**\n         * Sets data to the specified view.\n         *\n         * @param {String} index - Index of a view whose data will be replaced.\n         * @param {Object} data - New view data.\n         * @returns {Bookmarks} Chainable.\n         */\n        setViewData: function (index, data) {\n            var path = this.getViewPath(index) + '.data';\n\n            this.set(path, utils.copy(data));\n\n            return this;\n        },\n\n        /**\n         * Starts editing of a specified view.\n         *\n         * @param {String} index - Index of a view.\n         * @returns {Bookmarks} Chainable.\n         */\n        editView: function (index) {\n            this.editing = index;\n\n            return this;\n        },\n\n        /**\n         * Ends editing of specified view\n         * and restores its' label.\n         *\n         * @param {String} index - Index of a view.\n         * @returns {Bookmarks} Chainable.\n         */\n        endEdit: function (index) {\n            var view;\n\n            if (!this.isEditing(index)) {\n                return this;\n            }\n\n            index   = index || this.editing;\n            view    = this.getView(index);\n\n            view.value = view.label;\n\n            this.editing = false;\n\n            return this;\n        },\n\n        /**\n         * Checks if specified view is in editing state.\n         *\n         * @param {String} index - Index of a view to be checked.\n         * @returns {Boolean}\n         */\n        isEditing: function (index) {\n            return this.editing === index;\n        },\n\n        /**\n         * Generates label unique among present views, based\n         * on the incoming label pattern.\n         *\n         * @param {String} [label=this.newViewLabel] - Label pattern.\n         * @param {String} [exclude]\n         * @returns {String}\n         */\n        uniqueLabel: function (label, exclude) {\n            var labels      = _.pluck(this.views, 'label'),\n                hasParenth  = _.last(label) === ')',\n                index       = 2,\n                result,\n                suffix;\n\n            labels = _.without(labels, exclude);\n            result = label = label || this.newViewLabel;\n\n            for (index = 2; _.contains(labels, result); index++) {\n                suffix = '(' + index + ')';\n\n                if (!hasParenth) {\n                    suffix = ' ' + suffix;\n                }\n\n                result = label + suffix;\n            }\n\n            return result;\n        },\n\n        /**\n         * Applies state of a specified view, without\n         * making it active.\n         *\n         * @param {String} [state=this.activeIndex]\n         * @param {String} [property]\n         * @returns {Bookmarks} Chainable.\n         */\n        applyStateOf: function (state, property) {\n            var index    = state || this.activeIndex,\n                dataPath = removeStateNs(property),\n                viewData = this.getViewData(index, dataPath);\n\n            dataPath = dataPath ?\n                'current.' + dataPath :\n                'current';\n\n            this.set(dataPath, viewData);\n\n            return this;\n        },\n\n        /**\n         * Saves current state.\n         *\n         * @returns {Bookmarks} Chainable.\n         */\n        saveState: function () {\n            this.store('current');\n            return this;\n        },\n\n        /**\n         * Applies state of an active view.\n         *\n         * @returns {Bookmarks} Chainable.\n         */\n        resetState: function () {\n            this.applyStateOf(this.activeIndex);\n\n            return this;\n        },\n\n        /**\n         * Checks if current state is different\n         * from the state of an active view.\n         *\n         * @returns {Bookmarks} Chainable.\n         */\n        checkState: function () {\n            var viewData = this.getViewData(this.activeIndex),\n                diff     = utils.compare(viewData, this.current);\n\n            this.hasChanges = !diff.equal;\n\n            return this;\n        },\n\n        /**\n         * Returns path to the view instance,\n         * based on a provided index.\n         *\n         * @param {String} index - Index of a view.\n         * @returns {String}\n         */\n        getViewPath: function (index) {\n            return 'views.' + index;\n        },\n\n        /**\n         * Updates the array of views.\n         *\n         * @returns {Bookmarks} Chainable\n         */\n        updateArray: function () {\n            this.viewsArray = _.values(this.views);\n\n            return this;\n        },\n\n        /**\n         * Shows custom view field and creates unique label for it.\n         *\n         * @returns {Bookmarks} Chainable.\n         */\n        showCustom: function () {\n            this.customLabel    = this.uniqueLabel();\n            this.customVisible  = true;\n\n            return this;\n        },\n\n        /**\n         * Hides custom view field.\n         *\n         * @returns {Bookmarks} Chainable.\n         */\n        hideCustom: function () {\n            this.customVisible = false;\n\n            return this;\n        },\n\n        /**\n         * Checks if custom view field is visible.\n         *\n         * @returns {Boolean}\n         */\n        isCustomVisible: function () {\n            return this.customVisible;\n        },\n\n        /**\n         * Creates new view instance with a label specified\n         * in a custom view field.\n         *\n         * @returns {Bookmarks} Chainable.\n         */\n        applyCustom: function () {\n            var label = this.customLabel.trim();\n\n            this.hideCustom()\n                .addView({\n                    label: this.uniqueLabel(label)\n                }, true, true);\n\n            return this;\n        },\n\n        /**\n         * Listener of the activeIndex property.\n         */\n        onActiveIndexChange: function () {\n            this.activeView = this.getActiveView();\n            this.updateActiveView();\n            this.store('activeIndex');\n        },\n\n        /**\n         * Listener of the activeIndex property.\n         */\n        onStateChange: function () {\n            this.checkState();\n            this.saveState();\n\n            if (!this.defaultDefined) {\n                resolver(this.initDefaultView, this);\n            }\n        }\n    });\n});\n","Magento_Ui/js/grid/controls/button/split.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery'\n], function ($) {\n    'use strict';\n\n    return function (data, element) {\n\n        $(element).on('click.splitDefault', '.action-default', function () {\n            $(this).siblings('.dropdown-menu').find('.item-default').trigger('click');\n        });\n    };\n});\n","Magento_Ui/js/grid/editing/record.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'underscore',\n    'mageUtils',\n    'uiLayout',\n    'uiCollection'\n], function (_, utils, layout, Collection) {\n    'use strict';\n\n    return Collection.extend({\n        defaults: {\n            active: true,\n            hasChanges: false,\n            fields: [],\n            errorsCount: 0,\n            fieldTmpl: 'ui/grid/editing/field',\n            rowTmpl: 'ui/grid/editing/row',\n            templates: {\n                fields: {\n                    base: {\n                        parent: '${ $.$data.record.name }',\n                        name: '${ $.$data.column.index }',\n                        provider: '${ $.$data.record.name }',\n                        dataScope: 'data.${ $.$data.column.index }',\n                        imports: {\n                            disabled: '${ $.$data.record.parentName }:fields.${ $.$data.column.index }.disabled'\n                        },\n                        isEditor: true\n                    },\n                    text: {\n                        component: 'Magento_Ui/js/form/element/abstract',\n                        template: 'ui/form/element/input'\n                    },\n                    date: {\n                        component: 'Magento_Ui/js/form/element/date',\n                        template: 'ui/form/element/date',\n                        dateFormat: 'MMM d, y h:mm:ss a'\n                    },\n                    select: {\n                        component: 'Magento_Ui/js/form/element/select',\n                        template: 'ui/form/element/select',\n                        options: '${ JSON.stringify($.$data.column.options) }'\n                    }\n                }\n            },\n            ignoreTmpls: {\n                data: true\n            },\n            listens: {\n                elems: 'updateFields',\n                data: 'updateState'\n            },\n            imports: {\n                onColumnsUpdate: '${ $.columnsProvider }:elems'\n            },\n            modules: {\n                columns: '${ $.columnsProvider }',\n                editor: '${ $.editorProvider }'\n            }\n        },\n\n        /**\n         * Initializes record component.\n         *\n         * @returns {Record} Chainable.\n         */\n        initialize: function () {\n            _.bindAll(this, 'countErrors');\n            utils.limit(this, 'updateState', 10);\n\n            return this._super();\n        },\n\n        /**\n         * Initializes observable properties.\n         *\n         * @returns {Record} Chainable.\n         */\n        initObservable: function () {\n            this._super()\n                .track('errorsCount hasChanges')\n                .observe('active fields');\n\n            return this;\n        },\n\n        /**\n         * Adds listeners on a field.\n         *\n         * @returns {Record} Chainable.\n         */\n        initElement: function (field) {\n            field.on('error', this.countErrors);\n\n            return this._super();\n        },\n\n        /**\n         * Creates new instance of a field.\n         *\n         * @param {Column} column - Column instance which contains field definition.\n         * @returns {Record} Chainable.\n         */\n        initField: function (column) {\n            var field = this.buildField(column);\n\n            layout([field]);\n\n            return this;\n        },\n\n        /**\n         * Builds fields' configuration described in a provided column.\n         *\n         * @param {Column} column - Column instance which contains field definition.\n         * @returns {Object} Complete fields' configuration.\n         */\n        buildField: function (column) {\n            var fields = this.templates.fields,\n                field  = column.editor;\n\n            if (_.isObject(field) && field.editorType) {\n                field = utils.extend({}, fields[field.editorType], field);\n            } else if (_.isString(field)) {\n                field = fields[field];\n            }\n\n            field = utils.extend({}, fields.base, field);\n\n            return utils.template(field, {\n                record: this,\n                column: column\n            }, true, true);\n        },\n\n        /**\n         * Creates fields for the specified columns.\n         *\n         * @param {Array} columns - An array of column instances.\n         * @returns {Record} Chainable.\n         */\n        createFields: function (columns) {\n            columns.forEach(function (column) {\n                if (column.editor && !this.hasChild(column.index)) {\n                    this.initField(column);\n                }\n            }, this);\n\n            return this;\n        },\n\n        /**\n         * Returns instance of a column found by provided index.\n         *\n         * @param {String} index - Index of a column (e.g. 'title').\n         * @returns {Column}\n         */\n        getColumn: function (index) {\n            return this.columns().getChild(index);\n        },\n\n        /**\n         * Returns records' current data object.\n         *\n         * @returns {Object}\n         */\n        getData: function () {\n            return this.filterData(this.data);\n        },\n\n        /**\n         * Returns saved records' data. Data will be processed\n         * with a 'filterData' and 'normalizeData' methods.\n         *\n         * @returns {Object} Saved records' data.\n         */\n        getSavedData: function () {\n            var editor      = this.editor(),\n                savedData   = editor.getRowData(this.index);\n\n            savedData = this.filterData(savedData);\n\n            return this.normalizeData(savedData);\n        },\n\n        /**\n         * Replaces current records' data with the provided one.\n         *\n         * @param {Object} data - New records data.\n         * @param {Boolean} [partial=false] - Flag that defines whether\n         *      to completely replace current data or to extend it.\n         * @returns {Record} Chainable.\n         */\n        setData: function (data, partial) {\n            var currentData = partial ? this.data : {};\n\n            data = this.normalizeData(data);\n            data = utils.extend({}, currentData, data);\n\n            this.set('data', data)\n                .updateState();\n\n            return this;\n        },\n\n        /**\n         * Filters provided object extracting from it values\n         * that can be matched with an existing fields.\n         *\n         * @param {Object} data - Object to be processed.\n         * @returns {Object}\n         */\n        filterData: function (data) {\n            var fields = _.pluck(this.elems(), 'index');\n\n            _.each(this.preserveFields, function (enabled, field) {\n                if (enabled && !_.contains(fields, field)) {\n                    fields.push(field);\n                }\n            });\n\n            return _.pick(data, fields);\n        },\n\n        /**\n         * Parses values of a provided object with\n         * a 'normalizeData' method of a corresponding field.\n         *\n         * @param {Object} data - Data to be processed.\n         * @returns {Object}\n         */\n        normalizeData: function (data) {\n            var index;\n\n            this.elems.each(function (elem) {\n                index = elem.index;\n\n                if (data.hasOwnProperty(index)) {\n                    data[index] = elem.normalizeData(data[index]);\n                }\n            });\n\n            return data;\n        },\n\n        /**\n         * Clears values of all fields.\n         *\n         * @returns {Record} Chainable.\n         */\n        clear: function () {\n            this.elems.each('clear');\n\n            return this;\n        },\n\n        /**\n         * Validates all of the available fields.\n         *\n         * @returns {Array} An array with validation results.\n         */\n        validate: function () {\n            return this.elems.map('validate');\n        },\n\n        /**\n         * Checks if all fields are valid.\n         *\n         * @returns {Boolean}\n         */\n        isValid: function () {\n            return _.every(this.validate(), 'valid');\n        },\n\n        /**\n         * Counts total errors amount across all fields.\n         *\n         * @returns {Number}\n         */\n        countErrors: function () {\n            var errorsCount = this.elems.filter('error').length;\n\n            this.errorsCount = errorsCount;\n\n            return errorsCount;\n        },\n\n        /**\n         * Returns difference between current data and its'\n         * initial state, retrieved from the records collection.\n         *\n         * @returns {Object} Object with changes descriptions.\n         */\n        checkChanges: function () {\n            var savedData   = this.getSavedData(),\n                data        = this.normalizeData(this.getData());\n\n            return utils.compare(savedData, data);\n        },\n\n        /**\n         * Updates 'fields' array filling it with available editors\n         * or with column instances if associated field is not present.\n         *\n         * @returns {Record} Chainable.\n         */\n        updateFields: function () {\n            var fields;\n\n            fields = this.columns().elems.map(function (column) {\n                return this.getChild(column.index) || column;\n            }, this);\n\n            this.fields(fields);\n\n            return this;\n        },\n\n        /**\n         * Updates state of a 'hasChanges' property.\n         *\n         * @returns {Record} Chainable.\n         */\n        updateState: function () {\n            var diff = this.checkChanges(),\n                changed = {};\n\n            this.hasChanges = !diff.equal;\n            changed[this.index] = this.data;\n            this.editor().set('changed', [changed]);\n\n            return this;\n        },\n\n        /**\n         * Checks if provided column is an actions column.\n         *\n         * @param {Column} column - Column to be checked.\n         * @returns {Boolean}\n         */\n        isActionsColumn: function (column) {\n            return column.dataType === 'actions';\n        },\n\n        /**\n         * Listener of columns provider child array changes.\n         *\n         * @param {Array} columns - Modified child elements array.\n         */\n        onColumnsUpdate: function (columns) {\n            this.createFields(columns)\n                .updateFields();\n        }\n    });\n});\n","Magento_Ui/js/grid/editing/editor.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'underscore',\n    'mageUtils',\n    'uiLayout',\n    'mage/translate',\n    'uiCollection'\n], function (_, utils, layout, $t, Collection) {\n    'use strict';\n\n    return Collection.extend({\n        defaults: {\n            rowButtonsTmpl: 'ui/grid/editing/row-buttons',\n            headerButtonsTmpl: 'ui/grid/editing/header-buttons',\n            successMsg: $t('You have successfully saved your edits.'),\n            errorsCount: 0,\n            bulkEnabled: true,\n            multiEditingButtons: true,\n            singleEditingButtons: true,\n            isMultiEditing: false,\n            isSingleEditing: false,\n            permanentlyActive: false,\n            rowsData: [],\n            fields: {},\n\n            templates: {\n                record: {\n                    parent: '${ $.$data.editor.name }',\n                    name: '${ $.$data.recordId }',\n                    component: 'Magento_Ui/js/grid/editing/record',\n                    columnsProvider: '${ $.$data.editor.columnsProvider }',\n                    editorProvider: '${ $.$data.editor.name }',\n                    preserveFields: {\n                        '${ $.$data.editor.indexField }': true\n                    }\n                }\n            },\n            bulkConfig: {\n                component: 'Magento_Ui/js/grid/editing/bulk',\n                name: '${ $.name }_bulk',\n                editorProvider: '${ $.name }',\n                columnsProvider: '${ $.columnsProvider }'\n            },\n            clientConfig: {\n                component: 'Magento_Ui/js/grid/editing/client',\n                name: '${ $.name }_client'\n            },\n            viewConfig: {\n                component: 'Magento_Ui/js/grid/editing/editor-view',\n                name: '${ $.name }_view',\n                model: '${ $.name }',\n                columnsProvider: '${ $.columnsProvider }'\n            },\n            imports: {\n                rowsData: '${ $.dataProvider }:data.items'\n            },\n            listens: {\n                '${ $.dataProvider }:reloaded': 'cancel',\n                '${ $.selectProvider }:selected': 'onSelectionsChange'\n            },\n            modules: {\n                source: '${ $.dataProvider }',\n                client: '${ $.clientConfig.name }',\n                columns: '${ $.columnsProvider }',\n                bulk: '${ $.bulkConfig.name }',\n                selections: '${ $.selectProvider }'\n            }\n        },\n\n        /**\n         * Initializes editor component.\n         *\n         * @returns {Editor} Chainable.\n         */\n        initialize: function () {\n            _.bindAll(this, 'updateState', 'countErrors', 'onDataSaved', 'onSaveError');\n\n            this._super()\n                .initBulk()\n                .initClient()\n                .initView();\n\n            return this;\n        },\n\n        /**\n         * Initializes observable properties.\n         *\n         * @returns {Editor} Chainable.\n         */\n        initObservable: function () {\n            this._super()\n                .track([\n                    'errorsCount',\n                    'isMultiEditing',\n                    'isSingleEditing',\n                    'isSingleColumnEditing',\n                    'changed'\n                ])\n                .observe({\n                    canSave: true,\n                    activeRecords: [],\n                    messages: []\n                });\n\n            return this;\n        },\n\n        /**\n         * Initializes bulk editing component.\n         *\n         * @returns {Editor} Chainable.\n         */\n        initBulk: function () {\n            if (this.bulkEnabled) {\n                layout([this.bulkConfig]);\n            }\n\n            return this;\n        },\n\n        /**\n         * Initializes editors' view component.\n         *\n         * @returns {Editor} Chainable.\n         */\n        initView: function () {\n            layout([this.viewConfig]);\n\n            return this;\n        },\n\n        /**\n         * Initializes client component.\n         *\n         * @returns {Editor} Chainable.\n         */\n        initClient: function () {\n            layout([this.clientConfig]);\n\n            return this;\n        },\n\n        /**\n         * Creates instance of a new record.\n         *\n         * @param {(Number|String)} id - See 'getId' method.\n         * @param {Boolean} [isIndex=false] - See 'getId' method.\n         * @returns {Editor} Chainable.\n         */\n        initRecord: function (id, isIndex) {\n            var record = this.buildRecord(id, isIndex);\n\n            layout([record]);\n\n            return this;\n        },\n\n        /**\n         * Adds listeners on a new record.\n         *\n         * @param {Record} record\n         * @returns {Editor} Chainable.\n         */\n        initElement: function (record) {\n            record.on({\n                'active': this.updateState,\n                'errorsCount': this.countErrors\n            });\n\n            this.updateState();\n\n            return this._super();\n        },\n\n        /**\n         * Creates configuration for a new record associated with a row data.\n         *\n         * @param {(Number|String)} id - See 'getId' method.\n         * @param {Boolean} [isIndex=false] - See 'getId' method.\n         * @returns {Object} Record configuration.\n         */\n        buildRecord: function (id, isIndex) {\n            var recordId = this.getId(id, isIndex),\n                recordTmpl = this.templates.record,\n                record;\n\n            if (this.getRecord(recordId)) {\n                return this;\n            }\n\n            record = utils.template(recordTmpl, {\n                editor: this,\n                recordId: id\n            });\n\n            record.recordId = id;\n            record.data     = this.getRowData(id);\n\n            return record;\n        },\n\n        /**\n         * Starts editing of a specified record. If records'\n         * instance doesn't exist, than it will be created.\n         *\n         * @param {(Number|String)} id - See 'getId' method.\n         * @param {Boolean} [isIndex=false] - See 'getId' method.\n         * @returns {Editor} Chainable.\n         */\n        edit: function (id, isIndex) {\n            var recordId = this.getId(id, isIndex),\n                record   = this.getRecord(recordId);\n\n            record ?\n                record.active(true) :\n                this.initRecord(recordId);\n\n            return this;\n        },\n\n        /**\n         * Drops list of selections while activating only the specified record.\n         *\n         * @param {(Number|String)} id - See 'getId' method.\n         * @param {Boolean} [isIndex=false] - See 'getId' method.\n         * @returns {Editor} Chainable.\n         */\n        startEdit: function (id, isIndex) {\n            var recordId = this.getId(id, isIndex);\n\n            this.selections()\n                .deselectAll()\n                .select(recordId);\n\n            return this.edit(recordId);\n        },\n\n        /**\n         * Hides records and resets theirs data.\n         *\n         * @returns {Editor} Chainable.\n         */\n        cancel: function () {\n            this.reset()\n                .hide()\n                .clearMessages()\n                .bulk('clear');\n\n            return this;\n        },\n\n        /**\n         * Hides records.\n         *\n         * @returns {Editor} Chainable.\n         */\n        hide: function () {\n            this.activeRecords.each('active', false);\n\n            return this;\n        },\n\n        /**\n         * Resets active records.\n         *\n         * @returns {Editor} Chainable.\n         */\n        reset: function () {\n            this.elems.each(function (record) {\n                this.resetRecord(record.recordId);\n            }, this);\n\n            return this;\n        },\n\n        /**\n         * Validates and saves data of active records.\n         *\n         * @returns {Editor} Chainable.\n         */\n        save: function () {\n            var data;\n\n            if (!this.isValid()) {\n                return this;\n            }\n\n            data = {\n                items: this.getData()\n            };\n\n            this.clearMessages()\n                .columns('showLoader');\n\n            this.client()\n                .save(data)\n                .done(this.onDataSaved)\n                .fail(this.onSaveError);\n\n            return this;\n        },\n\n        /**\n         * Validates all active records.\n         *\n         * @returns {Array} An array of records and theirs validation results.\n         */\n        validate: function () {\n            return this.activeRecords.map(function (record) {\n                return {\n                    target: record,\n                    valid: record.isValid()\n                };\n            });\n        },\n\n        /**\n         * Checks if all active records are valid.\n         *\n         * @returns {Boolean}\n         */\n        isValid: function () {\n            return _.every(this.validate(), 'valid');\n        },\n\n        /**\n         * Returns active records data, indexed by a theirs ids.\n         *\n         * @returns {Object} Collection of records data.\n         */\n        getData: function () {\n            var data = this.activeRecords.map(function (record) {\n                var elemKey,\n                    recordData = record.getData();\n\n                for (elemKey in recordData) {\n                    if (_.isUndefined(recordData[elemKey])) {\n                        recordData[elemKey] = null;\n                    }\n                }\n\n                return recordData;\n            });\n\n            return _.indexBy(data, this.indexField);\n        },\n\n        /**\n         * Sets provided data to all active records.\n         *\n         * @param {Object} data - See 'setData' method of a 'Record'.\n         * @param {Boolean} partial - See 'setData' method of a 'Record'.\n         * @returns {Editor} Chainable.\n         */\n        setData: function (data, partial) {\n            this.activeRecords.each('setData', data, partial);\n\n            return this;\n        },\n\n        /**\n         * Resets specific records' data\n         * to the data present in associated row.\n         *\n         * @param {(Number|String)} id - See 'getId' method.\n         * @param {Boolean} [isIndex=false] - See 'getId' method.\n         * @returns {Editor} Chainable.\n         */\n        resetRecord: function (id, isIndex) {\n            var record  = this.getRecord(id, isIndex),\n                data    = this.getRowData(id, isIndex);\n\n            if (record && data) {\n                record.setData(data);\n            }\n\n            return this;\n        },\n\n        /**\n         * Returns instance of a specified record.\n         *\n         * @param {(Number|String)} id - See 'getId' method.\n         * @param {Boolean} [isIndex=false] - See 'getId' method.\n         * @returns {Record}\n         */\n        getRecord: function (id, isIndex) {\n            return this.elems.findWhere({\n                recordId: this.getId(id, isIndex)\n            });\n        },\n\n        /**\n         * Creates record name based on a provided id.\n         *\n         * @param {(Number|String)} id - See 'getId' method.\n         * @param {Boolean} [isIndex=false] - See 'getId' method.\n         * @returns {String}\n         */\n        formRecordName: function (id, isIndex) {\n            id = this.getId(id, isIndex);\n\n            return this.name + '.' + id;\n        },\n\n        /**\n         * Disables editing of specified fields.\n         *\n         * @param {Array} fields - An array of fields indexes to be disabled.\n         * @returns {Editor} Chainable.\n         */\n        disableFields: function (fields) {\n            var columns = this.columns().elems(),\n                data    = utils.copy(this.fields);\n\n            columns.forEach(function (column) {\n                var index = column.index,\n                    field = data[index] = data[index] || {};\n\n                field.disabled = _.contains(fields, index);\n            });\n\n            this.set('fields', data);\n\n            return this;\n        },\n\n        /**\n         * Converts index of a row into the record id.\n         *\n         * @param {(Number|String)} id - Records' identifier or its' index in the rows array.\n         * @param {Boolean} [isIndex=false] - Flag that indicates if first\n         *      parameter is an index or identifier.\n         * @returns {String} Records' id.\n         */\n        getId: function (id, isIndex) {\n            var rowsData = this.rowsData,\n                record;\n\n            if (isIndex === true) {\n                record  = rowsData[id];\n                id      = record ? record[this.indexField] : false;\n            }\n\n            return id;\n        },\n\n        /**\n         * Returns data of a specified row.\n         *\n         * @param {(Number|String)} id - See 'getId' method.\n         * @param {Boolean} [isIndex=false] - See 'getId' method.\n         * @returns {Object}\n         */\n        getRowData: function (id, isIndex) {\n            id = this.getId(id, isIndex);\n\n            return _.find(this.rowsData, function (row) {\n                return row[this.indexField] === id;\n            }, this);\n        },\n\n        /**\n         * Checks if specified record is active.\n         *\n         * @param {(Number|String)} id - See 'getId' method.\n         * @param {Boolean} [isIndex=false] - See'getId' method.\n         * @returns {Boolean}\n         */\n        isActive: function (id, isIndex) {\n            var record = this.getRecord(id, isIndex);\n\n            return _.contains(this.activeRecords(), record);\n        },\n\n        /**\n         * Checks if editor has active records.\n         *\n         * @returns {Boolean}\n         */\n        hasActive: function () {\n            return !!this.activeRecords().length || this.permanentlyActive;\n        },\n\n        /**\n         * Counts number of active records.\n         *\n         * @returns {Number}\n         */\n        countActive: function () {\n            return this.activeRecords().length;\n        },\n\n        /**\n         * Counts number of invalid fields across all active records.\n         *\n         * @returns {Number}\n         */\n        countErrors: function () {\n            var errorsCount = 0;\n\n            this.activeRecords.each(function (record) {\n                errorsCount += record.errorsCount;\n            });\n\n            this.errorsCount = errorsCount;\n\n            return errorsCount;\n        },\n\n        /**\n         * Translatable error message text.\n         *\n         * @returns {String}\n         */\n        countErrorsMessage: function () {\n            return $t('There are {placeholder} messages requires your attention.')\n                .replace('{placeholder}', this.countErrors());\n        },\n\n        /**\n         * Checks if editor has any errors.\n         *\n         * @returns {Boolean}\n         */\n        hasErrors: function () {\n            return !!this.countErrors();\n        },\n\n        /**\n         * Handles changes of the records 'active' property.\n         *\n         * @returns {Editor} Chainable.\n         */\n        updateState: function () {\n            var active      = this.elems.filter('active'),\n                activeCount = active.length,\n                columns     = this.columns().elems;\n\n            columns.each('disableAction', !!activeCount);\n\n            this.isMultiEditing = activeCount > 1;\n            this.isSingleEditing = activeCount === 1;\n\n            this.activeRecords(active);\n\n            return this;\n        },\n\n        /**\n         * Returns list of selections from a current page.\n         *\n         * @returns {Array}\n         */\n        getSelections: function () {\n            return this.selections().getPageSelections();\n        },\n\n        /**\n         * Starts editing of selected records. If record\n         * is not in the selections list, then it will get hidden.\n         *\n         * @returns {Editor} Chainable.\n         */\n        editSelected: function () {\n            var selections = this.getSelections();\n\n            this.elems.each(function (record) {\n                if (!_.contains(selections, record.recordId)) {\n                    record.active(false);\n                }\n            });\n\n            selections.forEach(function (id) {\n                this.edit(id);\n            }, this);\n\n            return this;\n        },\n\n        /**\n         * Checks if there is any additional messages.\n         *\n         * @returns {Boolean}\n         */\n        hasMessages: function () {\n            return this.messages().length;\n        },\n\n        /**\n         * Adds new additional message or a set of messages.\n         *\n         * @param {(Object|Array)} message - Messages to be added.\n         * @returns {Editor} Chainable.\n         */\n        addMessage: function (message) {\n            var messages = this.messages();\n\n            Array.isArray(message) ?\n                messages.push.apply(messages, message) :\n                messages.push(message);\n\n            this.messages(messages);\n\n            return this;\n        },\n\n        /**\n         * Removes all additional messages.\n         *\n         * @returns {Editor} Chainable.\n         */\n        clearMessages: function () {\n            this.messages.removeAll();\n\n            return this;\n        },\n\n        /**\n         * Listener of the selections data changes.\n         */\n        onSelectionsChange: function () {\n            if (this.hasActive()) {\n                this.editSelected();\n            }\n        },\n\n        /**\n         * Handles successful save request.\n         */\n        onDataSaved: function () {\n            var msg = {\n                type: 'success',\n                message: this.successMsg\n            };\n\n            this.addMessage(msg)\n                .source('reload', {\n                    refresh: true\n                });\n        },\n\n        /**\n         * Handles failed save request.\n         *\n         * @param {(Array|Object)} errors - List of errors or a single error object.\n         */\n        onSaveError: function (errors) {\n            this.addMessage(errors)\n                .columns('hideLoader');\n        }\n    });\n});\n","Magento_Ui/js/grid/editing/bulk.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'underscore',\n    'mageUtils',\n    './record'\n], function (_, utils, Record) {\n    'use strict';\n\n    /**\n     * Removes empty properties from the provided object.\n     *\n     * @param {Object} data - Object to be processed.\n     * @returns {Object}\n     */\n    function removeEmpty(data) {\n        data = utils.flatten(data);\n        data = _.omit(data, utils.isEmpty);\n\n        return utils.unflatten(data);\n    }\n\n    return Record.extend({\n        defaults: {\n            template: 'ui/grid/editing/bulk',\n            active: false,\n            templates: {\n                fields: {\n                    select: {\n                        caption: ' '\n                    }\n                }\n            },\n            imports: {\n                active: '${ $.editorProvider }:isMultiEditing'\n            },\n            listens: {\n                data: 'updateState',\n                active: 'updateState'\n            }\n        },\n\n        /**\n         * Initializes observable properties.\n         *\n         * @returns {Bulk} Chainable.\n         */\n        initObservable: function () {\n            this._super()\n                .track({\n                    hasData: false\n                });\n\n            return this;\n        },\n\n        /**\n         * Extends original method to disable possible\n         * 'required-entry' validation rule.\n         *\n         * @returns {Object} Columns' field definition.\n         */\n        buildField: function () {\n            var field = this._super(),\n                rules = field.validation;\n\n            if (rules) {\n                delete rules['required-entry'];\n            }\n\n            return field;\n        },\n\n        /**\n         * Applies current data to all active records.\n         *\n         * @returns {Bulk} Chainable.\n         */\n        apply: function () {\n            if (this.isValid()) {\n                this.applyData()\n                    .clear();\n            }\n\n            return this;\n        },\n\n        /**\n         * Sets available data to all active records.\n         *\n         * @param {Object} [data] -  If not specified, then current fields data will be used.\n         * @returns {Bulk} Chainable.\n         */\n        applyData: function (data) {\n            data = data || this.getData();\n\n            this.editor('setData', data, true);\n\n            return this;\n        },\n\n        /**\n         * Returns data of all non-empty fields.\n         *\n         * @returns {Object} Fields data without empty values.\n         */\n        getData: function () {\n            return removeEmpty(this._super());\n        },\n\n        /**\n         * Updates own 'hasData' property and defines\n         * whether regular rows editing can be resumed.\n         *\n         * @returns {Bulk} Chainable.\n         */\n        updateState: function () {\n            var fields  = _.keys(this.getData()),\n                hasData = !!fields.length;\n\n            this.hasData = hasData;\n\n            if (!this.active()) {\n                fields = [];\n            }\n\n            this.editor('disableFields', fields);\n            this.editor('canSave', !fields.length);\n\n            return this;\n        }\n    });\n});\n","Magento_Ui/js/grid/editing/editor-view.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'ko',\n    'Magento_Ui/js/lib/view/utils/async',\n    'underscore',\n    'uiRegistry',\n    'uiClass'\n], function (ko, $, _, registry, Class) {\n    'use strict';\n\n    return Class.extend({\n        defaults: {\n            rootSelector: '${ $.columnsProvider }:.admin__data-grid-wrap',\n            tableSelector: '${ $.rootSelector } -> table',\n            rowSelector: '${ $.tableSelector } tbody tr.data-row',\n            headerButtonsTmpl:\n                '<!-- ko template: headerButtonsTmpl --><!-- /ko -->',\n            bulkTmpl:\n                '<!-- ko scope: bulk -->' +\n                    '<!-- ko template: getTemplate() --><!-- /ko -->' +\n                '<!-- /ko -->',\n            rowTmpl:\n                '<!-- ko with: _editor -->' +\n                    '<!-- ko if: isActive($row()._rowIndex, true) -->' +\n                        '<!-- ko with: getRecord($row()._rowIndex, true) -->' +\n                            '<!-- ko template: rowTmpl --><!-- /ko -->' +\n                        '<!-- /ko -->' +\n                        '<!-- ko if: isSingleEditing && singleEditingButtons -->' +\n                            '<!-- ko template: rowButtonsTmpl --><!-- /ko -->' +\n                        '<!-- /ko -->' +\n                    '<!-- /ko -->' +\n               '<!-- /ko -->'\n        },\n\n        /**\n         * Initializes view component.\n         *\n         * @returns {View} Chainable.\n         */\n        initialize: function () {\n            _.bindAll(\n                this,\n                'initRoot',\n                'initTable',\n                'initRow',\n                'rowBindings',\n                'tableBindings'\n            );\n\n            this._super();\n\n            this.model = registry.get(this.model);\n\n            $.async(this.rootSelector, this.initRoot);\n            $.async(this.tableSelector, this.initTable);\n            $.async(this.rowSelector, this.initRow);\n\n            return this;\n        },\n\n        /**\n         * Initializes columns root container.\n         *\n         * @param {HTMLElement} node\n         * @returns {View} Chainable.\n         */\n        initRoot: function (node) {\n            $(this.headerButtonsTmpl)\n                .insertBefore(node)\n                .applyBindings(this.model);\n\n            return this;\n        },\n\n        /**\n         * Initializes table element.\n         *\n         * @param {HTMLTableElement} table\n         * @returns {View} Chainable.\n         */\n        initTable: function (table) {\n            $(table).bindings(this.tableBindings);\n\n            this.initBulk(table);\n\n            return this;\n        },\n\n        /**\n         * Initializes bulk editor element\n         * for the provided table.\n         *\n         * @param {HTMLTableElement} table\n         * @returns {View} Chainable.\n         */\n        initBulk: function (table) {\n            var tableBody = $('tbody', table)[0];\n\n            $(this.bulkTmpl)\n                .prependTo(tableBody)\n                .applyBindings(this.model);\n\n            return this;\n        },\n\n        /**\n         * Initializes table row.\n         *\n         * @param {HTMLTableRowElement} row\n         * @returns {View} Chainable.\n         */\n        initRow: function (row) {\n            var $editingRow;\n\n            $(row).extendCtx({\n                    _editor: this.model\n                }).bindings(this.rowBindings);\n\n            $editingRow = $(this.rowTmpl)\n                .insertBefore(row)\n                .applyBindings(row);\n\n            ko.utils.domNodeDisposal.addDisposeCallback(row, this.removeEditingRow.bind(this, $editingRow));\n\n            return this;\n        },\n\n        /**\n         * Returns row bindings.\n         *\n         * @param {Object} ctx - Current context of a row.\n         * @returns {Object}\n         */\n        rowBindings: function (ctx) {\n            var model = this.model;\n\n            return {\n                visible: ko.computed(function () {\n                    var record = ctx.$row(),\n                        index = record && record._rowIndex;\n\n                    return !model.isActive(index, true);\n                })\n            };\n        },\n\n        /**\n         * Returns table bindings.\n         *\n         * @returns {Object}\n         */\n        tableBindings: function () {\n            var model = this.model;\n\n            return {\n                css: {\n                    '_in-edit': ko.computed(function () {\n                        return model.hasActive() && !model.permanentlyActive;\n                    })\n                }\n            };\n        },\n\n        /**\n         * Removes specified array of nodes.\n         *\n         * @param {ArrayLike} row\n         */\n        removeEditingRow: function (row) {\n            _.toArray(row).forEach(ko.removeNode);\n        }\n    });\n});\n","Magento_Ui/js/grid/editing/client.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'underscore',\n    'mageUtils',\n    'uiClass'\n], function ($, _, utils, Class) {\n    'use strict';\n\n    return Class.extend({\n        defaults: {\n            validateBeforeSave: true,\n            requestConfig: {\n                dataType: 'json',\n                type: 'POST'\n            }\n        },\n\n        /**\n         * Initializes client instance.\n         *\n         * @returns {Client} Chainable.\n         */\n        initialize: function () {\n            _.bindAll(this, 'onSuccess', 'onError');\n\n            return this._super();\n        },\n\n        /**\n         * Sends XMLHttpRequest with a provided configuration.\n         *\n         * @param {Object} config - Configuration of request.\n         * @returns {jQueryPromise}\n         */\n        send: function (config) {\n            var deffer  = $.Deferred();\n\n            config = utils.extend({}, this.requestConfig, config);\n\n            $.ajax(config)\n                .done(_.partial(this.onSuccess, deffer))\n                .fail(_.partial(this.onError, deffer));\n\n            return deffer.promise();\n        },\n\n        /**\n         * Proxy save method which might invoke\n         * data validation prior to its' saving.\n         *\n         * @param {Object} data - Data to be processed.\n         * @returns {jQueryPromise}\n         */\n        save: function (data) {\n            var save = this._save.bind(this, data);\n\n            return this.validateBeforeSave ?\n                this.validate(data).pipe(save) :\n                save();\n        },\n\n        /**\n         * Sends request to validate provided data.\n         *\n         * @param {Object} data - Data to be validated.\n         * @returns {jQueryPromise}\n         */\n        validate: function (data) {\n            return this.send({\n                url: this.validateUrl,\n                data: data\n            });\n        },\n\n        /**\n         * Sends request to save provided data.\n         *\n         * @private\n         * @param {Object} data - Data to be validated.\n         * @returns {jQueryPromise}\n         */\n        _save: function (data) {\n            return this.send({\n                url: this.saveUrl,\n                data: data\n            });\n        },\n\n        /**\n         * Creates error object with a provided message.\n         *\n         * @param {String} msg - Errors' message.\n         * @returns {Object}\n         */\n        createError: function (msg) {\n            return {\n                type: 'error',\n                message: msg\n            };\n        },\n\n        /**\n         * Handles ajax error callback.\n         *\n         * @param {jQueryPromise} promise - Promise to be rejected.\n         * @param {jQueryXHR} xhr - See 'jquery' ajax error callback.\n         * @param {String} status - See 'jquery' ajax error callback.\n         * @param {(String|Object)} err - See 'jquery' ajax error callback.\n         */\n        onError: function (promise, xhr, status, err) {\n            var msg;\n\n            msg = xhr.status !== 200 ?\n                xhr.status + ' (' + xhr.statusText + ')' :\n                err;\n\n            promise.reject(this.createError(msg));\n        },\n\n        /**\n         * Handles ajax success callback.\n         *\n         * @param {jQueryPromise} promise - Promise to be resolved.\n         * @param {*} data - See 'jquery' ajax success callback.\n         */\n        onSuccess: function (promise, data) {\n            var errors;\n\n            if (data.error) {\n                errors = _.map(data.messages, this.createError, this);\n\n                promise.reject(errors);\n            } else {\n                promise.resolve(data);\n            }\n        }\n    });\n});\n","Magento_Ui/js/grid/columns/column.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'underscore',\n    'uiRegistry',\n    'mageUtils',\n    'uiElement'\n], function (_, registry, utils, Element) {\n    'use strict';\n\n    return Element.extend({\n        defaults: {\n            headerTmpl: 'ui/grid/columns/text',\n            bodyTmpl: 'ui/grid/cells/text',\n            disableAction: false,\n            controlVisibility: true,\n            sortable: true,\n            sorting: false,\n            visible: true,\n            draggable: true,\n            fieldClass: {},\n            ignoreTmpls: {\n                fieldAction: true\n            },\n            statefull: {\n                visible: true,\n                sorting: true\n            },\n            imports: {\n                exportSorting: 'sorting'\n            },\n            listens: {\n                '${ $.provider }:params.sorting.field': 'onSortChange'\n            },\n            modules: {\n                source: '${ $.provider }'\n            }\n        },\n\n        /**\n         * Initializes column component.\n         *\n         * @returns {Column} Chainable.\n         */\n        initialize: function () {\n            this._super()\n                .initFieldClass();\n\n            return this;\n        },\n\n        /**\n         * Initializes observable properties.\n         *\n         * @returns {Column} Chainable.\n         */\n        initObservable: function () {\n            this._super()\n                .track([\n                    'visible',\n                    'sorting',\n                    'disableAction'\n                ])\n                .observe([\n                    'dragging'\n                ]);\n\n            return this;\n        },\n\n        /**\n         * Extends list of field classes.\n         *\n         * @returns {Column} Chainable.\n         */\n        initFieldClass: function () {\n            _.extend(this.fieldClass, {\n                _dragging: this.dragging\n            });\n\n            return this;\n        },\n\n        /**\n         * Applies specified stored state of a column or one of its' properties.\n         *\n         * @param {String} state - Defines what state should be used: saved or default.\n         * @param {String} [property] - Defines what columns' property should be applied.\n         *      If not specified, then all columns stored properties will be used.\n         * @returns {Column} Chainable.\n         */\n        applyState: function (state, property) {\n            var namespace = this.storageConfig.root;\n\n            if (property) {\n                namespace += '.' + property;\n            }\n\n            this.storage('applyStateOf', state, namespace);\n\n            return this;\n        },\n\n        /**\n         * Sets columns' sorting. If column is currently sorted,\n         * than its' direction will be toggled.\n         *\n         * @param {*} [enable=true] - If false, than sorting will\n         *      be removed from a column.\n         * @returns {Column} Chainable.\n         */\n        sort: function (enable) {\n            if (!this.sortable) {\n                return this;\n            }\n\n            enable !== false ?\n                this.toggleSorting() :\n                this.sorting = false;\n\n            return this;\n        },\n\n        /**\n         * Sets descending columns' sorting.\n         *\n         * @returns {Column} Chainable.\n         */\n        sortDescending: function () {\n            if (this.sortable) {\n                this.sorting = 'desc';\n            }\n\n            return this;\n        },\n\n        /**\n         * Sets ascending columns' sorting.\n         *\n         * @returns {Column} Chainable.\n         */\n        sortAscending: function () {\n            if (this.sortable) {\n                this.sorting = 'asc';\n            }\n\n            return this;\n        },\n\n        /**\n         * Toggles sorting direction.\n         *\n         * @returns {Column} Chainable.\n         */\n        toggleSorting: function () {\n            this.sorting === 'asc' ?\n                this.sortDescending() :\n                this.sortAscending();\n\n            return this;\n        },\n\n        /**\n         * Checks if column is sorted.\n         *\n         * @returns {Boolean}\n         */\n        isSorted: function () {\n            return !!this.sorting;\n        },\n\n        /**\n         * Exports sorting data to the dataProvider if\n         * sorting of a column is enabled.\n         */\n        exportSorting: function () {\n            if (!this.sorting) {\n                return;\n            }\n\n            this.source('set', 'params.sorting', {\n                field: this.index,\n                direction: this.sorting\n            });\n        },\n\n        /**\n         * Checks if column has an assigned action that will\n         * be performed when clicking on one of its' fields.\n         *\n         * @returns {Boolean}\n         */\n        hasFieldAction: function () {\n            return !!this.fieldAction || !!this.fieldActions;\n        },\n\n        /**\n         * Applies action described in a 'fieldAction' property\n         * or actions described in 'fieldActions' property.\n         *\n         * @param {Number} rowIndex - Index of a row which initiates action.\n         * @returns {Column} Chainable.\n         *\n         * @example Example of fieldAction definition, which is equivalent to\n         *      referencing to external component named 'listing.multiselect'\n         *      and calling its' method 'toggleSelect' with params [rowIndex, true] =>\n         *\n         *      {\n         *          provider: 'listing.multiselect',\n         *          target: 'toggleSelect',\n         *          params: ['${ $.$data.rowIndex }', true]\n         *      }\n         */\n        applyFieldAction: function (rowIndex) {\n            if (!this.hasFieldAction() || this.disableAction) {\n                return this;\n            }\n\n            if (this.fieldActions) {\n                this.fieldActions.forEach(this.applySingleAction.bind(this, rowIndex), this);\n            } else {\n                this.applySingleAction(rowIndex);\n            }\n\n            return this;\n        },\n\n        /**\n         * Applies single action\n         *\n         * @param {Number} rowIndex - Index of a row which initiates action.\n         * @param {Object} action - Action (fieldAction) to be applied\n         *\n         */\n        applySingleAction: function (rowIndex, action) {\n            var callback;\n\n            action = action || this.fieldAction;\n            action = utils.template(action, {\n                column: this,\n                rowIndex: rowIndex\n            }, true);\n\n            callback = this._getFieldCallback(action);\n\n            if (_.isFunction(callback)) {\n                callback();\n            }\n        },\n\n        /**\n         * Returns field action handler if it was specified.\n         *\n         * @param {Object} record - Record object with which action is associated.\n         * @returns {Function|Undefined}\n         */\n        getFieldHandler: function (record) {\n            if (this.hasFieldAction()) {\n                return this.applyFieldAction.bind(this, record._rowIndex);\n            }\n        },\n\n        /**\n         * Creates action callback based on its' data.\n         *\n         * @param {Object} action - Actions' object.\n         * @returns {Function|Boolean} Callback function or false\n         *      value if it was impossible create a callback.\n         */\n        _getFieldCallback: function (action) {\n            var args     = action.params || [],\n                callback = action.target;\n\n            if (action.provider && action.target) {\n                args.unshift(action.target);\n\n                callback = registry.async(action.provider);\n            }\n\n            if (!_.isFunction(callback)) {\n                return false;\n            }\n\n            return function () {\n                callback.apply(callback, args);\n            };\n        },\n\n        /**\n         * Ment to preprocess data associated with a current columns' field.\n         *\n         * @param {Object} record - Data to be preprocessed.\n         * @returns {String}\n         */\n        getLabel: function (record) {\n            return record[this.index];\n        },\n\n        /**\n         * UnsanitizedHtml version of getLabel.\n         *\n         * @param {Object} record - Data to be preprocessed.\n         * @returns {String}\n         */\n        getLabelUnsanitizedHtml: function (record) {\n            return this.getLabel(record);\n        },\n\n        /**\n         * Returns list of classes that should be applied to a field.\n         *\n         * @returns {Object}\n         */\n        getFieldClass: function () {\n            return this.fieldClass;\n        },\n\n        /**\n         * Returns path to the columns' header template.\n         *\n         * @returns {String}\n         */\n        getHeader: function () {\n            return this.headerTmpl;\n        },\n\n        /**\n         * Returns path to the columns' body template.\n         *\n         * @returns {String}\n         */\n        getBody: function () {\n            return this.bodyTmpl;\n        },\n\n        /**\n         * Listener of the providers' sorting state changes.\n         *\n         * @param {Srting} field - Field by which current sorting is performed.\n         */\n        onSortChange: function (field) {\n            if (field !== this.index) {\n                this.sort(false);\n            }\n        }\n    });\n});\n","Magento_Ui/js/grid/columns/expandable.js":"/**\n * Copyright \u00a9 2016 Magento. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    './column',\n    'underscore'\n], function (Column, _) {\n    'use strict';\n\n    return Column.extend({\n        defaults: {\n            bodyTmpl: 'ui/grid/cells/expandable',\n            tooltipTmpl: 'ui/grid/cells/expandable/content',\n            visibeItemsLimit: 5,\n            tooltipTitle: ''\n        },\n\n        /**\n         * Gets label from full options array.\n         *\n         * @param {Object} record - Record object.\n         * @returns {String}\n         */\n        getFullLabel: function (record) {\n            return this.getLabelsArray(record).join(', ');\n        },\n\n        /**\n         * Gets label from options array limited by 'visibeItemsLimit'.\n         *\n         * @param {Object} record - Record object.\n         * @returns {String}\n         */\n        getShortLabel: function (record) {\n            return this.getLabelsArray(record).slice(0, this.visibeItemsLimit).join(', ');\n        },\n\n        /**\n         * Extracts array of labels associated with provided values and sort it alphabetically.\n         *\n         * @param {Object} record - Record object.\n         * @returns {Array}\n         */\n        getLabelsArray: function (record) {\n            var values = this.getLabel(record),\n                options = this.options || [],\n                labels = [];\n\n            if (_.isString(values)) {\n                values = values.split(',');\n            }\n\n            if (!Array.isArray(values)) {\n                values = [values];\n            }\n\n            values = values.map(function (value) {\n                return value + '';\n            });\n\n            options = this.flatOptions(options);\n\n            options.forEach(function (item) {\n                if (_.contains(values, item.value + '')) {\n                    labels.push(item.label);\n                }\n            });\n\n            return labels.sort(\n                function (labelFirst, labelSecond) {\n                    return labelFirst.toLowerCase().localeCompare(labelSecond.toLowerCase());\n                }\n            );\n        },\n\n        /**\n         * Transformation tree options structure to liner array.\n         *\n         * @param {Array} options\n         * @returns {Array}\n         */\n        flatOptions: function (options) {\n            var self = this;\n\n            return options.reduce(function (opts, option) {\n                if (_.isArray(option.value)) {\n                    opts = opts.concat(self.flatOptions(option.value));\n                } else {\n                    opts.push(option);\n                }\n\n                return opts;\n            }, []);\n        },\n\n        /**\n         * Checks if amount of options is more than limit value.\n         *\n         * @param {Object} record - Data to be preprocessed.\n         * @returns {Boolean}\n         */\n        isExpandable: function (record) {\n            return this.getLabel(record).length > this.visibeItemsLimit;\n        }\n    });\n});\n","Magento_Ui/js/grid/columns/image-preview.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/* eslint-disable no-undef */\ndefine([\n    'jquery',\n    'underscore',\n    'Magento_Ui/js/grid/columns/column',\n    'Magento_Ui/js/lib/key-codes'\n], function ($, _, Column, keyCodes) {\n    'use strict';\n\n    return Column.extend({\n        defaults: {\n            bodyTmpl: 'ui/grid/columns/image-preview',\n            previewImageSelector: '[data-image-preview]',\n            visibleRecord: null,\n            height: 0,\n            displayedRecord: {},\n            lastOpenedImage: false,\n            fields: {\n                previewUrl: 'preview_url',\n                title: 'title'\n            },\n            modules: {\n                masonry: '${ $.parentName }',\n                thumbnailComponent: '${ $.parentName }.thumbnail_url'\n            },\n            statefull: {\n                sorting: true,\n                lastOpenedImage: true\n            },\n            listens: {\n                '${ $.provider }:params.filters': 'hide',\n                '${ $.provider }:params.search': 'hide',\n                '${ $.provider }:params.paging': 'hide',\n                '${ $.provider }:data.items': 'updateDisplayedRecord'\n            },\n            exports: {\n                height: '${ $.parentName }.thumbnail_url:previewHeight'\n            }\n        },\n\n        /**\n         * Initialize image preview component\n         *\n         * @returns {Object}\n         */\n        initialize: function () {\n            this._super();\n            $(document).on('keydown', this.handleKeyDown.bind(this));\n\n            this.lastOpenedImage.subscribe(function (newValue) {\n\n                if (newValue === false && _.isNull(this.visibleRecord())) {\n                    return;\n                }\n\n                if (newValue === this.visibleRecord()) {\n                    return;\n                }\n\n                if (newValue === false) {\n                    this.hide();\n\n                    return;\n                }\n\n                this.show(this.masonry().rows()[newValue]);\n            }.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Init observable variables\n         * @return {Object}\n         */\n        initObservable: function () {\n            this._super()\n                .observe([\n                    'visibleRecord',\n                    'height',\n                    'displayedRecord',\n                    'lastOpenedImage'\n                ]);\n\n            return this;\n        },\n\n        /**\n         * Next image preview\n         *\n         * @param {Object} record\n         */\n        next: function (record) {\n            var recordToShow;\n\n            if (record._rowIndex + 1 === this.masonry().rows().length) {\n                return;\n            }\n\n            recordToShow = this.getRecord(record._rowIndex + 1);\n            recordToShow.rowNumber = record.lastInRow ? record.rowNumber + 1 : record.rowNumber;\n            this.show(recordToShow);\n        },\n\n        /**\n         * Previous image preview\n         *\n         * @param {Object} record\n         */\n        prev: function (record) {\n            var recordToShow;\n\n            if (record._rowIndex === 0) {\n                return;\n            }\n            recordToShow = this.getRecord(record._rowIndex - 1);\n\n            recordToShow.rowNumber = record.firstInRow ? record.rowNumber - 1 : record.rowNumber;\n            this.show(recordToShow);\n        },\n\n        /**\n         * Get record\n         *\n         * @param {Integer} recordIndex\n         *\n         * @return {Object}\n         */\n        getRecord: function (recordIndex) {\n            return this.masonry().rows()[recordIndex];\n        },\n\n        /**\n         * Set selected row id\n         *\n         * @param {Number} rowId\n         * @private\n         */\n        _selectRow: function (rowId) {\n            this.thumbnailComponent().previewRowId(rowId);\n        },\n\n        /**\n         * Show image preview\n         *\n         * @param {Object} record\n         */\n        show: function (record) {\n            if (record._rowIndex === this.visibleRecord()) {\n                this.hide();\n\n                return;\n            }\n\n            this.hide();\n            this.displayedRecord(record);\n            this._selectRow(record.rowNumber || null);\n            this.visibleRecord(record._rowIndex);\n\n            this.lastOpenedImage(record._rowIndex);\n            this.updateImageData();\n        },\n\n        /**\n         * Update image data when image preview is opened\n         */\n        updateImageData: function () {\n            var img = $(this.previewImageSelector + ' img'), self;\n\n            if (!img.get(0)) {\n                setTimeout(function () {\n                    this.updateImageData();\n                }.bind(this), 100);\n            } else if (img.get(0).complete) {\n                this.updateHeight();\n                this.scrollToPreview();\n            } else {\n                self = this;\n\n                img.on('load', function () {\n                    self.updateHeight();\n                    self.scrollToPreview();\n                });\n            }\n        },\n\n        /**\n         * Update preview displayed record data from the new items data if the preview is expanded\n         *\n         * @param {Array} items\n         */\n        updateDisplayedRecord: function (items) {\n            if (!_.isNull(this.visibleRecord())) {\n                this.displayedRecord(items[this.visibleRecord()]);\n            }\n        },\n\n        /**\n         * Update image preview section height\n         */\n        updateHeight: function () {\n            this.height($(this.previewImageSelector).height() + 'px');\n        },\n\n        /**\n         * Close image preview\n         */\n        hide: function () {\n            this.lastOpenedImage(false);\n            this.visibleRecord(null);\n            this.height(0);\n            this._selectRow(null);\n        },\n\n        /**\n         * Returns visibility for given record.\n         *\n         * @param {Object} record\n         * @return {*|bool}\n         */\n        isVisible: function (record) {\n            if (this.lastOpenedImage() === record._rowIndex &&\n                this.visibleRecord() === null\n            ) {\n                this.show(record);\n            }\n\n            return this.visibleRecord() === record._rowIndex || false;\n        },\n\n        /**\n         * Returns preview image url for a given record.\n         *\n         * @param {Object} record\n         * @return {String}\n         */\n        getUrl: function (record) {\n            return record[this.fields.previewUrl];\n        },\n\n        /**\n         * Returns image title for a given record.\n         *\n         * @param {Object} record\n         * @return {String}\n         */\n        getTitle: function (record) {\n            return record[this.fields.title];\n        },\n\n        /**\n         * Get styles for preview\n         *\n         * @returns {Object}\n         */\n        getStyles: function () {\n            return {\n                'margin-top': '-' + this.height()\n            };\n        },\n\n        /**\n         * Scroll to preview window\n         */\n        scrollToPreview: function () {\n            $(this.previewImageSelector).get(0).scrollIntoView({\n                behavior: 'smooth',\n                block: 'center',\n                inline: 'nearest'\n            });\n        },\n\n        /**\n         * Handle keyboard navigation for image preview\n         *\n         * @param {Object} e\n         */\n        handleKeyDown: function (e) {\n            var key = keyCodes[e.keyCode];\n\n            if (this.visibleRecord() !== null && document.activeElement.tagName !== 'INPUT') {\n                if (key === 'pageLeftKey') {\n                    this.prev(this.displayedRecord());\n                } else if (key === 'pageRightKey') {\n                    this.next(this.displayedRecord());\n                }\n            }\n        }\n    });\n});\n","Magento_Ui/js/grid/columns/link.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    './column',\n    'mageUtils'\n], function (Column, utils) {\n    'use strict';\n\n    return Column.extend({\n        defaults: {\n            link: 'link',\n            bodyTmpl: 'ui/grid/cells/link'\n        },\n\n        /**\n         * Returns link to given record.\n         *\n         * @param {Object} record - Data to be preprocessed.\n         * @returns {String}\n         */\n        getLink: function (record) {\n            return utils.nested(record, this.link);\n        },\n\n        /**\n         * Check if link parameter exist in record.\n         * @param {Object} record - Data to be preprocessed.\n         * @returns {Boolean}\n         */\n        isLink: function (record) {\n            return !!utils.nested(record, this.link);\n        }\n    });\n});\n","Magento_Ui/js/grid/columns/onoff.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'underscore',\n    'mage/translate',\n    './multiselect',\n    'uiRegistry'\n], function (_, $t, Column, registry) {\n    'use strict';\n\n    return Column.extend({\n        defaults: {\n            headerTmpl: 'ui/grid/columns/onoff',\n            bodyTmpl: 'ui/grid/cells/onoff',\n            fieldClass: {\n                'admin__scope-old': true,\n                'data-grid-onoff-cell': true,\n                'data-grid-checkbox-cell': false\n            },\n            imports: {\n                selectedData: '${ $.provider }:data.selectedData'\n            },\n            listens: {\n                '${ $.provider }:reloaded': 'setDefaultSelections'\n            }\n        },\n\n        /**\n         * @param {Number} id\n         * @returns {*}\n         */\n        getLabel: function (id) {\n            return this.selected.indexOf(id) !== -1 ? $t('On') : $t('Off');\n        },\n\n        /**\n         * Sets the ids for preselected elements\n         * @returns void\n         */\n        setDefaultSelections: function () {\n            var positionCacheValid = registry.get('position_cache_valid'),\n                selectedFromCache = registry.get('selected_cache'),\n                key,\n                i;\n\n            if (positionCacheValid && this.selected().length === 0) {\n                // Check selected data\n                selectedFromCache = JSON.parse(selectedFromCache);\n\n                for (i = 0; i < selectedFromCache.length; i++) {\n                    this.selected.push(selectedFromCache[i]);\n                }\n\n                registry.set('position_cache_valid', true);\n                registry.set('selected_cache', JSON.stringify(this.selected()));\n\n                return;\n            }\n\n            if (positionCacheValid && this.selected().length > 0) {\n                registry.set('position_cache_valid', true);\n                registry.set('selected_cache', JSON.stringify(this.selected()));\n\n                return;\n            }\n\n            if (this.selectedData.length === 0) {\n                registry.set('position_cache_valid', true);\n                registry.set('selected_cache', JSON.stringify([]));\n\n                return;\n            }\n\n            // Check selected data\n            for (key in this.selectedData) {\n                if (this.selectedData.hasOwnProperty(key) && this.selected().indexOf(key) === -1) {\n                    this.selected.push(key);\n                }\n            }\n            // Uncheck unselected data\n            for (i = 0; i < this.selected().length; i++) {\n                key = this.selected()[i];\n                this.selectedData.hasOwnProperty(key) || this.selected.splice(this.selected().indexOf(key), 1);\n                this.selectedData.hasOwnProperty(key) || i--;\n            }\n            registry.set('position_cache_valid', true);\n            registry.set('selected_cache', JSON.stringify(this.selected()));\n        },\n\n        /**\n         * Show/hide action in the massaction menu\n         * @param {Number} actionId\n         * @returns {Boolean}\n         */\n        isActionRelevant: function (actionId) {\n            var relevant = true;\n\n            switch (actionId) {\n                case 'selectPage':\n                    relevant = !this.isPageSelected(true);\n                    break;\n\n                case 'deselectPage':\n                    relevant =  this.isPageSelected();\n                    break;\n            }\n\n            return relevant;\n        },\n\n        /**\n         * Updates values of the 'allSelected'\n         * and 'indetermine' properties.\n         *\n         * @returns {Object} Chainable.\n         */\n        updateState: function () {\n            var positionCacheValid = registry.get('position_cache_valid'),\n                totalRecords    = this.totalRecords(),\n                selected        = this.selected().length,\n                excluded        = this.excluded().length,\n                totalSelected   = this.totalSelected(),\n                allSelected;\n\n            if (positionCacheValid && this.selected().length > 0) {\n                registry.set('position_cache_valid', true);\n                registry.set('selected_cache', JSON.stringify(this.selected()));\n            }\n\n            // When filters are enabled then totalRecords is unknown\n            if (this.getFiltering()) {\n                if (this.getFiltering().search !== '') {\n                    totalRecords = -1;\n                }\n            }\n\n            allSelected = totalRecords && totalSelected === totalRecords;\n\n            if (this.excludeMode()) {\n                if (excluded === totalRecords) {\n                    this.deselectAll();\n                }\n            } else if (totalRecords && selected === totalRecords) {\n                this.selectAll();\n            }\n\n            this.allSelected(allSelected);\n            this.indetermine(totalSelected && !allSelected);\n\n            return this;\n        }\n    });\n});\n","Magento_Ui/js/grid/columns/overlay.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'Magento_Ui/js/grid/columns/column'\n], function (Column) {\n    'use strict';\n\n    return Column.extend({\n        defaults: {\n            bodyTmpl: 'ui/grid/columns/overlay'\n        },\n\n        /**\n         * If overlay should be visible\n         *\n         * @param {Object} row\n         * @returns {Boolean}\n         */\n        isVisible: function (row) {\n            return !!row[this.index];\n        },\n\n        /**\n         * Get overlay label\n         *\n         * @param {Object} row\n         * @returns {String}\n         */\n        getLabel: function (row) {\n            return row[this.index];\n        }\n    });\n});\n","Magento_Ui/js/grid/columns/actions.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'underscore',\n    'mageUtils',\n    'uiRegistry',\n    './column',\n    'Magento_Ui/js/modal/confirm',\n    'mage/dataPost'\n], function (_, utils, registry, Column, confirm, dataPost) {\n    'use strict';\n\n    return Column.extend({\n        defaults: {\n            bodyTmpl: 'ui/grid/cells/actions',\n            sortable: false,\n            draggable: false,\n            actions: [],\n            rows: [],\n            rowsProvider: '${ $.parentName }',\n            fieldClass: {\n                'data-grid-actions-cell': true\n            },\n            templates: {\n                actions: {}\n            },\n            imports: {\n                rows: '${ $.rowsProvider }:rows'\n            },\n            listens: {\n                rows: 'updateActions'\n            }\n        },\n\n        /**\n         * Initializes observable properties.\n         *\n         * @returns {ActionsColumn} Chainable.\n         */\n        initObservable: function () {\n            this._super()\n                .track('actions');\n\n            return this;\n        },\n\n        /**\n         * Returns specific action of a specified row\n         * or all action objects associated with it.\n         *\n         * @param {Number} rowIndex - Index of a row.\n         * @param {String} [actionIndex] - Action identifier.\n         * @returns {Array|Object}\n         */\n        getAction: function (rowIndex, actionIndex) {\n            var rowActions = this.actions[rowIndex];\n\n            return rowActions && actionIndex ?\n                rowActions[actionIndex] :\n                rowActions;\n        },\n\n        /**\n         * Returns visible actions for a specified row.\n         *\n         * @param {Number} rowIndex - Index of a row.\n         * @returns {Array} Visible actions.\n         */\n        getVisibleActions: function (rowIndex) {\n            var rowActions = this.getAction(rowIndex);\n\n            return _.filter(rowActions, this.isActionVisible, this);\n        },\n\n        /**\n         * Adds new action. If an action with the specified identifier\n         * already exists, then the original will be overridden.\n         *\n         * @param {String} index - Actions' identifier.\n         * @param {Object} action - Actions' data.\n         * @returns {ActionsColumn} Chainable.\n         */\n        addAction: function (index, action) {\n            var actionTmpls = this.templates.actions;\n\n            actionTmpls[index] = action;\n\n            this.updateActions();\n\n            return this;\n        },\n\n        /**\n         * Recreates actions for each row.\n         *\n         * @returns {ActionsColumn} Chainable.\n         */\n        updateActions: function () {\n            this.actions = this.rows.map(this._formatActions, this);\n\n            return this;\n        },\n\n        /**\n         * Processes actions, setting additional information to them and\n         * evaluating their properties as string templates.\n         *\n         * @private\n         * @param {Object} row - Row object.\n         * @param {Number} rowIndex - Index of a row.\n         * @returns {Array}\n         */\n        _formatActions: function (row, rowIndex) {\n            var rowActions      = row[this.index] || {},\n                recordId        = row[this.indexField],\n                customActions   = this.templates.actions;\n\n            /**\n             * Actions iterator.\n             */\n            function iterate(action, index) {\n                action = utils.extend({\n                    index: index,\n                    rowIndex: rowIndex,\n                    recordId: recordId\n                }, action);\n\n                return utils.template(action, row, true);\n            }\n\n            rowActions      = _.mapObject(rowActions, iterate);\n            customActions   = _.map(customActions, iterate);\n\n            customActions.forEach(function (action) {\n                rowActions[action.index] = action;\n            });\n\n            return rowActions;\n        },\n\n        /**\n         * Applies specified action.\n         *\n         * @param {String} actionIndex - Actions' identifier.\n         * @param {Number} rowIndex - Index of a row.\n         * @returns {ActionsColumn} Chainable.\n         */\n        applyAction: function (actionIndex, rowIndex) {\n            var action = this.getAction(rowIndex, actionIndex),\n                callback = this._getCallback(action);\n\n            action.confirm ?\n                this._confirm(action, callback) :\n                callback();\n\n            return this;\n        },\n\n        /**\n         * Creates handler for the provided action if it's required.\n         *\n         * @param {Object} action - Action object.\n         * @returns {Function|Undefined}\n         */\n        getActionHandler: function (action) {\n            var index = action.index,\n                rowIndex = action.rowIndex;\n\n            if (this.isHandlerRequired(index, rowIndex)) {\n                return this.applyAction.bind(this, index, rowIndex);\n            }\n        },\n\n        /**\n         * Returns target of action if it's been set.\n         *\n         * @param {Object} action - Action object.\n         * @returns {String}\n         */\n        getTarget: function (action) {\n            if (action.target) {\n                return action.target;\n            }\n\n            return '_self';\n        },\n\n        /**\n         * Checks if specified action requires a handler function.\n         *\n         * @param {String} actionIndex - Actions' identifier.\n         * @param {Number} rowIndex - Index of a row.\n         * @returns {Boolean}\n         */\n        isHandlerRequired: function (actionIndex, rowIndex) {\n            var action = this.getAction(rowIndex, actionIndex);\n\n            return _.isObject(action.callback) || action.confirm || !action.href;\n        },\n\n        /**\n         * Creates action callback based on it's data. If the action doesn't specify\n         * a callback function than the default one will be used.\n         *\n         * @private\n         * @param {Object} action - Action's object.\n         * @returns {Function} Callback function.\n         */\n        _getCallback: function (action) {\n            var args = [action.index, action.recordId, action],\n                callback = action.callback;\n\n            if (utils.isObject(callback)) {\n                args.unshift(callback.target);\n\n                callback = registry.async(callback.provider);\n            } else if (_.isArray(callback)) {\n                return this._getCallbacks(action);\n            } else if (!_.isFunction(callback)) {\n                callback = this.defaultCallback.bind(this);\n            }\n\n            return function () {\n                callback.apply(callback, args);\n            };\n        },\n\n        /**\n         * Creates action callback for multiple actions.\n         *\n         * @private\n         * @param {Object} action - Action's object.\n         * @returns {Function} Callback function.\n         */\n        _getCallbacks: function (action) {\n            var callback = action.callback,\n                callbacks = [],\n                tmpCallback;\n\n            _.each(callback, function (cb) {\n                tmpCallback = {\n                    action: registry.async(cb.provider),\n                    args: _.compact([cb.target, cb.params])\n                };\n                callbacks.push(tmpCallback);\n            });\n\n            return function () {\n                _.each(callbacks, function (cb) {\n                    cb.action.apply(cb.action, cb.args);\n                });\n            };\n        },\n\n        /**\n         * Default action callback. Redirects to\n         * the specified in action's data url.\n         *\n         * @param {String} actionIndex - Action's identifier.\n         * @param {(Number|String)} recordId - Id of the record associated\n         *      with a specified action.\n         * @param {Object} action - Action's data.\n         */\n        defaultCallback: function (actionIndex, recordId, action) {\n            if (action.post) {\n                dataPost().postData({\n                    action: action.href,\n                    data: {}\n                });\n            } else {\n                window.location.href = action.href;\n            }\n        },\n\n        /**\n         * Shows actions' confirmation window.\n         *\n         * @param {Object} action - Action's data.\n         * @param {Function} callback - Callback that will be\n         *      invoked if action is confirmed.\n         */\n        _confirm: function (action, callback) {\n            var confirmData = action.confirm;\n\n            confirm({\n                title: confirmData.title,\n                content: confirmData.message,\n                actions: {\n                    confirm: callback\n                }\n            });\n        },\n\n        /**\n         * Checks if row has only one visible action.\n         *\n         * @param {Number} rowIndex - Row index.\n         * @returns {Boolean}\n         */\n        isSingle: function (rowIndex) {\n            return this.getVisibleActions(rowIndex).length === 1;\n        },\n\n        /**\n         * Checks if row has more than one visible action.\n         *\n         * @param {Number} rowIndex - Row index.\n         * @returns {Boolean}\n         */\n        isMultiple: function (rowIndex) {\n            return this.getVisibleActions(rowIndex).length > 1;\n        },\n\n        /**\n         * Checks if action should be displayed.\n         *\n         * @param {Object} action - Action object.\n         * @returns {Boolean}\n         */\n        isActionVisible: function (action) {\n            return action.hidden !== true;\n        },\n\n        /**\n         * Overrides base method, because this component\n         * can't have global field action.\n         *\n         * @returns {Boolean} False.\n         */\n        hasFieldAction: function () {\n            return false;\n        }\n    });\n});\n","Magento_Ui/js/grid/columns/thumbnail.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    './column',\n    'jquery',\n    'mage/template',\n    'text!Magento_Ui/templates/grid/cells/thumbnail/preview.html',\n    'underscore',\n    'Magento_Ui/js/modal/modal',\n    'mage/translate'\n], function (Column, $, mageTemplate, thumbnailPreviewTemplate, _) {\n    'use strict';\n\n    return Column.extend({\n        defaults: {\n            bodyTmpl: 'ui/grid/cells/thumbnail',\n            fieldClass: {\n                'data-grid-thumbnail-cell': true\n            }\n        },\n\n        /**\n         * Get image source data per row.\n         *\n         * @param {Object} row\n         * @returns {String}\n         */\n        getSrc: function (row) {\n            return row[this.index + '_src'];\n        },\n\n        /**\n         * Get original image source data per row.\n         *\n         * @param {Object} row\n         * @returns {String}\n         */\n        getOrigSrc: function (row) {\n            return row[this.index + '_orig_src'];\n        },\n\n        /**\n         * Get link data per row.\n         *\n         * @param {Object} row\n         * @returns {String}\n         */\n        getLink: function (row) {\n            return row[this.index + '_link'];\n        },\n\n        /**\n         * Get alternative text data per row.\n         *\n         * @param {Object} row\n         * @returns {String}\n         */\n        getAlt: function (row) {\n            return _.escape(row[this.index + '_alt']);\n        },\n\n        /**\n         * Check if preview available.\n         *\n         * @returns {Boolean}\n         */\n        isPreviewAvailable: function () {\n            return this['has_preview'] || false;\n        },\n\n        /**\n         * Build preview.\n         *\n         * @param {Object} row\n         */\n        preview: function (row) {\n            var modalHtml = mageTemplate(\n                    thumbnailPreviewTemplate,\n                    {\n                        src: this.getOrigSrc(row), alt: this.getAlt(row), link: this.getLink(row),\n                        linkText: $.mage.__('Go to Details Page')\n                    }\n                ),\n                previewPopup = $('<div></div>').html(modalHtml);\n\n            previewPopup.modal({\n                title: this.getAlt(row),\n                innerScroll: true,\n                modalClass: '_image-box',\n                buttons: []\n            }).trigger('openModal');\n        },\n\n        /**\n         * Get field handler per row.\n         *\n         * @param {Object} row\n         * @returns {Function}\n         */\n        getFieldHandler: function (row) {\n            if (this.isPreviewAvailable()) {\n                return this.preview.bind(this, row);\n            }\n        }\n    });\n});\n","Magento_Ui/js/grid/columns/select.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'underscore',\n    './column'\n], function (_, Column) {\n    'use strict';\n\n    return Column.extend({\n        /**\n         * Retrieves label associated with a provided value.\n         *\n         * @returns {String}\n         */\n        getLabel: function () {\n            var options = this.options || [],\n                values = this._super(),\n                label = [];\n\n            if (_.isString(values)) {\n                values = values.split(',');\n            }\n\n            if (!_.isArray(values)) {\n                values = [values];\n            }\n\n            values = values.map(function (value) {\n                return value + '';\n            });\n\n            options = this.flatOptions(options);\n\n            options.forEach(function (item) {\n                if (_.contains(values, item.value + '')) {\n                    label.push(item.label);\n                }\n            });\n\n            return label.join(', ');\n        },\n\n        /**\n         * Transformation tree options structure to liner array.\n         *\n         * @param {Array} options\n         * @returns {Array}\n         */\n        flatOptions: function (options) {\n            var self = this;\n\n            if (!_.isArray(options)) {\n                options = _.values(options);\n            }\n\n            return options.reduce(function (opts, option) {\n                if (_.isArray(option.value)) {\n                    opts = opts.concat(self.flatOptions(option.value));\n                } else {\n                    opts.push(option);\n                }\n\n                return opts;\n            }, []);\n        }\n    });\n});\n","Magento_Ui/js/grid/columns/multiselect.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'underscore',\n    'mage/translate',\n    './column'\n], function (_, $t, Column) {\n    'use strict';\n\n    return Column.extend({\n        defaults: {\n            headerTmpl: 'ui/grid/columns/multiselect',\n            bodyTmpl: 'ui/grid/cells/multiselect',\n            controlVisibility: false,\n            sortable: false,\n            draggable: false,\n            menuVisible: false,\n            excludeMode: false,\n            allSelected: false,\n            indetermine: false,\n            preserveSelectionsOnFilter: false,\n            disabled: [],\n            selected: [],\n            excluded: [],\n            fieldClass: {\n                'data-grid-checkbox-cell': true\n            },\n            actions: [{\n                value: 'selectAll',\n                label: $t('Select All')\n            }, {\n                value: 'deselectAll',\n                label: $t('Deselect All')\n            }, {\n                value: 'selectPage',\n                label: $t('Select All on This Page')\n            }, {\n                value: 'deselectPage',\n                label: $t('Deselect All on This Page')\n            }],\n\n            imports: {\n                totalRecords: '${ $.provider }:data.totalRecords',\n                showTotalRecords: '${ $.provider }:data.showTotalRecords',\n                rows: '${ $.provider }:data.items'\n            },\n\n            listens: {\n                '${ $.provider }:params.filters': 'onFilter',\n                '${ $.provider }:params.search': 'onSearch',\n                selected: 'onSelectedChange',\n                rows: 'onRowsChange'\n            },\n\n            modules: {\n                source: '${ $.provider }'\n            }\n        },\n\n        /**\n         * Initializes observable properties.\n         *\n         * @returns {Multiselect} Chainable.\n         */\n        initObservable: function () {\n            this._super()\n                .observe([\n                    'disabled',\n                    'selected',\n                    'excluded',\n                    'excludeMode',\n                    'totalSelected',\n                    'allSelected',\n                    'indetermine',\n                    'totalRecords',\n                    'showTotalRecords',\n                    'rows'\n                ]);\n\n            return this;\n        },\n\n        /**\n         * Selects specified record.\n         *\n         * @param {*} id - See definition of 'getId' method.\n         * @param {Boolean} [isIndex=false] - See definition of 'getId' method.\n         * @returns {Multiselect} Chainable.\n         */\n        select: function (id, isIndex) {\n            this._setSelection(id, isIndex, true);\n\n            return this;\n        },\n\n        /**\n         * Deselects specified record.\n         *\n         * @param {*} id - See definition of 'getId' method.\n         * @param {Boolean} [isIndex=false] - See definition of 'getId' method.\n         * @returns {Multiselect} Chainable.\n         */\n        deselect: function (id, isIndex) {\n            this._setSelection(id, isIndex, false);\n\n            return this;\n        },\n\n        /**\n         * Toggles selection of a specified record.\n         *\n         * @param {*} id - See definition of 'getId' method.\n         * @param {Boolean} [isIndex=false] - See definition of 'getId' method.\n         * @returns {Multiselect} Chainable.\n         */\n        toggleSelect: function (id, isIndex) {\n            this._setSelection(id, isIndex, !this.isSelected(id, isIndex));\n\n            return this;\n        },\n\n        /**\n         * Checks if specified record is selected.\n         *\n         * @param {*} id - See definition of 'getId' method.\n         * @param {Boolean} [isIndex=false] - See definition of 'getId' method.\n         * @returns {Boolean}\n         */\n        isSelected: function (id, isIndex) {\n            id = this.getId(id, isIndex);\n\n            return this.selected.contains(id);\n        },\n\n        /**\n         * Selects/deselects specified record base on a 'select' parameter value.\n         *\n         * @param {*} id - See definition of 'getId' method.\n         * @param {Boolean} [isIndex=false] - See definition of 'getId' method.\n         * @param {Boolean} select - Whether to select/deselect record.\n         * @returns {Multiselect} Chainable.\n         */\n        _setSelection: function (id, isIndex, select) {\n            var selected = this.selected;\n\n            id = this.getId(id, isIndex);\n\n            if (!select && this.isSelected(id)) {\n                selected.remove(id);\n            } else if (select) {\n                selected.push(id);\n            }\n\n            return this;\n        },\n\n        /**\n         * Selects all records, even those that\n         * are not visible on the page.\n         *\n         * @returns {Multiselect} Chainable.\n         */\n        selectAll: function () {\n            this.excludeMode(true);\n\n            this.clearExcluded()\n                .selectPage();\n\n            return this;\n        },\n\n        /**\n         * Deselects all records.\n         *\n         * @returns {Multiselect} Chainable.\n         */\n        deselectAll: function () {\n            this.excludeMode(false);\n\n            this.clearExcluded();\n            this.selected.removeAll();\n\n            return this;\n        },\n\n        /**\n         * Selects or deselects all records.\n         *\n         * @returns {Multiselect} Chainable.\n         */\n        toggleSelectAll: function () {\n            this.allSelected() ?\n                this.deselectAll() :\n                this.selectAll();\n\n            return this;\n        },\n\n        /**\n         * Selects all records on the current page.\n         *\n         * @returns {Multiselect} Chainable.\n         */\n        selectPage: function () {\n            var selected = _.union(this.selected(), this.getIds());\n\n            selected = _.difference(selected, this.disabled());\n\n            this.selected(selected);\n\n            return this;\n        },\n\n        /**\n         * Deselects all records on the current page.\n         *\n         * @returns {Multiselect} Chainable.\n         */\n        deselectPage: function () {\n            var pageIds = this.getIds();\n\n            this.selected.remove(function (value) {\n                return !!~pageIds.indexOf(value);\n            });\n\n            return this;\n        },\n\n        /**\n        * Selects or deselects all records on the current page.\n        *\n        * @returns {Multiselect} Chainable.\n        */\n        togglePage: function () {\n            return this.isPageSelected() && !this.excluded().length ? this.deselectPage() : this.selectPage();\n        },\n\n        /**\n         * Clears the array of not selected records.\n         *\n         * @returns {Multiselect} Chainable.\n         */\n        clearExcluded: function () {\n            this.excluded.removeAll();\n\n            return this;\n        },\n\n        /**\n         * Retrieve all id's from available records.\n         *\n         * @param {Boolean} [exclude] - Whether to exclude not selected ids' from result.\n         * @returns {Array} An array of ids'.\n         */\n        getIds: function (exclude) {\n            var items = this.rows(),\n                ids = _.pluck(items, this.indexField);\n\n            return exclude ?\n                _.difference(ids, this.excluded()) :\n                ids;\n        },\n\n        /**\n         * Returns identifier of a record.\n         *\n         * @param {*} id - Id of a record or its' index in a rows array.\n         * @param {Boolean} [isIndex=false] - Flag that specifies with what\n         *      kind of identifier we are dealing with.\n         * @returns {*}\n         */\n        getId: function (id, isIndex) {\n            var record = this.rows()[id];\n\n            if (isIndex && record) {\n                id = record[this.indexField];\n            }\n\n            return id;\n        },\n\n        /**\n         * Recalculates list of the excluded records.\n         * Changes value of `excluded`.\n         *\n         * @param {Array} selected - List of the currently selected records.\n         * @returns {Multiselect} Chainable.\n         */\n        updateExcluded: function (selected) {\n            var excluded = this.excluded(),\n                fromPage = _.difference(this.getIds(), selected);\n\n            excluded = _.union(excluded, fromPage);\n            excluded = _.difference(excluded, selected);\n\n            this.excluded(excluded);\n\n            return this;\n        },\n\n        /**\n         * Calculates number of selected records and\n         * updates 'totalSelected' property.\n         *\n         * @returns {Multiselect} Chainable.\n         */\n        countSelected: function () {\n            var total = this.totalRecords(),\n                excluded = this.excluded().length,\n                selected = this.selected().length;\n\n            if (this.excludeMode()) {\n                selected = total - excluded;\n            }\n\n            this.totalSelected(selected);\n\n            return this;\n        },\n\n        /**\n         * Returns selected items on a current page.\n         *\n         * @returns {Array}\n         */\n        getPageSelections: function () {\n            var ids = this.getIds();\n\n            return this.selected.filter(function (id) {\n                return _.contains(ids, id);\n            });\n        },\n\n        /**\n         * Returns selections data.\n         *\n         * @returns {Object}\n         */\n        getSelections: function () {\n            return {\n                excluded: this.excluded(),\n                selected: this.selected(),\n                total: this.totalSelected(),\n                showTotalRecords: this.showTotalRecords(),\n                excludeMode: this.excludeMode(),\n                params: this.getFiltering()\n            };\n        },\n\n        /**\n         * Extracts filtering data from data provider.\n         *\n         * @returns {Object} Current filters state.\n         */\n        getFiltering: function () {\n            var source = this.source(),\n                keys = ['filters', 'search', 'namespace'];\n\n            if (!source) {\n                return {};\n            }\n\n            return _.pick(source.get('params'), keys);\n        },\n\n        /**\n         * Defines if provided select/deselect actions is relevant.\n         * E.g. there is no need in a 'select page' action if only one\n         * page is available.\n         *\n         * @param {String} actionId - Id of the action to be checked.\n         * @returns {Boolean}\n         */\n        isActionRelevant: function (actionId) {\n            var pageIds         = this.getIds().length,\n                multiplePages   = pageIds < this.totalRecords(),\n                relevant        = true;\n\n            switch (actionId) {\n                case 'selectPage':\n                    relevant = multiplePages && !this.isPageSelected(true);\n                    break;\n\n                case 'deselectPage':\n                    relevant =  multiplePages && this.isPageSelected();\n                    break;\n\n                case 'selectAll':\n                    relevant = !this.allSelected();\n                    break;\n\n                case 'deselectAll':\n                    relevant = this.totalSelected() > 0;\n            }\n\n            return relevant;\n        },\n\n        /**\n         * Checks if current page has selected records.\n         *\n         * @param {Boolean} [all=false] - If set to 'true' checks that every\n         *      record on the page is selected. Otherwise checks that\n         *      page has some selected records.\n         * @returns {Boolean}\n         */\n        isPageSelected: function (all) {\n            var pageIds = this.getIds(),\n                selected = this.selected(),\n                excluded = this.excluded(),\n                iterator = all ? 'every' : 'some';\n\n            if (this.allSelected()) {\n                return true;\n            }\n\n            if (this.excludeMode()) {\n                return pageIds[iterator](function (id) {\n                    return !~excluded.indexOf(id);\n                });\n            }\n\n            return pageIds[iterator](function (id) {\n                return !!~selected.indexOf(id);\n            });\n        },\n\n        /**\n         * Updates values of the 'allSelected'\n         * and 'indetermine' properties.\n         *\n         * @returns {Multiselect} Chainable.\n         */\n        updateState: function () {\n            var selected        = this.selected().length,\n                excluded        = this.excluded().length,\n                totalSelected   = this.totalSelected(),\n                totalRecords    = this.totalRecords(),\n                allSelected     = totalRecords && totalSelected === totalRecords;\n\n            if (this.excludeMode()) {\n                if (excluded === totalRecords && !this.preserveSelectionsOnFilter) {\n                    this.deselectAll();\n                }\n            } else if (totalRecords && selected === totalRecords && !this.preserveSelectionsOnFilter) {\n                this.selectAll();\n            }\n\n            this.allSelected(allSelected);\n            this.indetermine(totalSelected && !allSelected);\n\n            return this;\n        },\n\n        /**\n         * Overrides base method, because this component\n         * can't have global field action.\n         *\n         * @returns {Boolean} False.\n         */\n        hasFieldAction: function () {\n            return false;\n        },\n\n        /**\n         * Callback method to handle changes of selected items.\n         *\n         * @param {Array} selected - An array of currently selected items.\n         */\n        onSelectedChange: function (selected) {\n            this.updateExcluded(selected)\n                .countSelected()\n                .updateState();\n        },\n\n        /**\n         * Is invoked when rows has changed. Recalculates selected items\n         * based on \"selectMode\" property.\n         */\n        onRowsChange: function () {\n            var newSelections;\n\n            if (this.excludeMode()) {\n                newSelections = _.union(this.getIds(true), this.selected());\n\n                this.selected(newSelections);\n            }\n        },\n\n        /**\n         * Is invoked when filtration is applied or removed\n         */\n        onFilter: function () {\n            if (!this.preserveSelectionsOnFilter) {\n                this.deselectAll();\n            }\n        },\n\n        /**\n         * Is invoked when search is applied or removed\n         */\n        onSearch: function () {\n            this.onFilter();\n        }\n    });\n});\n","Magento_Ui/js/grid/columns/image.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'Magento_Ui/js/grid/columns/column'\n], function (Column) {\n    'use strict';\n\n    return Column.extend({\n        defaults: {\n            bodyTmpl: 'ui/grid/columns/image',\n            modules: {\n                masonry: '${ $.parentName }',\n                previewComponent: '${ $.parentName }.preview'\n            },\n            previewRowId: null,\n            previewHeight: 0,\n            fields: {\n                id: 'id',\n                url: 'url'\n            }\n        },\n\n        /**\n         * Init observable variables\n         * @return {Object}\n         */\n        initObservable: function () {\n            this._super()\n                .observe([\n                    'previewRowId',\n                    'previewHeight'\n                ]);\n\n            return this;\n        },\n\n        /**\n         * Updates styles when image loaded.\n         *\n         * @param {Object} record\n         */\n        updateStyles: function (record) {\n            !record.lastInRow || this.masonry().updateStyles();\n        },\n\n        /**\n         * Returns url to given record.\n         *\n         * @param {Object} record - Data to be preprocessed.\n         * @returns {String}\n         */\n        getUrl: function (record) {\n            return record[this.fields.url];\n        },\n\n        /**\n         * Returns id to given record.\n         *\n         * @param {Object} record - Data to be preprocessed.\n         * @returns {Number}\n         */\n        getId: function (record) {\n            return record[this.fields.id];\n        },\n\n        /**\n         * Returns container styles to given record.\n         *\n         * @param {Object} record - Data to be preprocessed.\n         * @returns {Object}\n         */\n        getStyles: function (record) {\n            var styles = record.styles();\n\n            styles['margin-bottom'] = this.previewRowId() === record.rowNumber ? this.previewHeight : 0;\n            record.styles(styles);\n\n            return record.styles;\n        },\n\n        /**\n         * Returns class list to given record.\n         *\n         * @param {Object} record - Data to be preprocessed.\n         * @returns {Object}\n         */\n        getClasses: function (record) {\n            return record.css || {};\n        },\n\n        /**\n         * Get is active record\n         *\n         * @param {Object} record - Data to be preprocessed.\n         *\n         * @returns {Boolean}\n         */\n        getIsActive: function (record) {\n            return this.previewComponent().visibleRecord() === record._rowIndex || false;\n        },\n\n        /**\n         * Expand image preview\n         */\n        expandPreview: function (record) {\n            this.previewComponent().show(record);\n        }\n    });\n});\n","Magento_Ui/js/grid/columns/date.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'mageUtils',\n    'moment',\n    './column',\n    'underscore',\n    'moment-timezone-with-data'\n], function (utils, moment, Column, _) {\n    'use strict';\n\n    return Column.extend({\n        defaults: {\n            dateFormat: 'MMM d, YYYY h:mm:ss A',\n            calendarConfig: []\n        },\n\n        /**\n         * Overrides base method to normalize date format\n         *\n         * @returns {DateColumn} Chainable\n         */\n        initConfig: function () {\n            this._super();\n\n            this.dateFormat = utils.normalizeDate(this.dateFormat ? this.dateFormat : this.options.dateFormat);\n\n            return this;\n        },\n\n        /**\n         * Formats incoming date based on the 'dateFormat' property.\n         *\n         * @returns {String} Formatted date.\n         */\n        getLabel: function (value, format) {\n            var date;\n\n            if (this.storeLocale !== undefined) {\n                moment.locale(this.storeLocale, utils.extend({}, this.calendarConfig));\n            }\n\n            date = moment.utc(this._super());\n\n            if (!_.isUndefined(this.timezone) && moment.tz.zone(this.timezone) !== null) {\n                date = date.tz(this.timezone);\n            }\n\n            date = date.isValid() && value[this.index] ?\n                date.format(format || this.dateFormat) :\n                '';\n\n            return date;\n        }\n    });\n});\n","Magento_Ui/js/grid/cells/sanitizedHtml.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'Magento_Ui/js/grid/columns/column',\n    'escaper'\n], function (Column, escaper) {\n    'use strict';\n\n    return Column.extend({\n        defaults: {\n            allowedTags: ['div', 'span', 'b', 'strong', 'i', 'em', 'u', 'a']\n        },\n\n        /**\n         * Name column.\n         *\n         * @param {String} label\n         * @returns {String}\n         */\n        getSafeHtml: function (label) {\n            return escaper.escapeHtml(label, this.allowedTags);\n        },\n\n        /**\n         * UnsanitizedHtml version of getSafeHtml.\n         *\n         * @param {String} label\n         * @returns {String}\n         */\n        getSafeUnsanitizedHtml: function (label) {\n            return this.getSafeHtml(label);\n        }\n    });\n});\n","Magento_Ui/js/lib/step-wizard.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiRegistry',\n    'uiComponent',\n    'jquery',\n    'underscore',\n    'ko',\n    'mage/backend/notification',\n    'mage/translate'\n], function (uiRegistry, Component, $, _, ko) {\n    'use strict';\n\n    var Wizard;\n\n    ko.utils.domNodeDisposal.cleanExternalData = _.wrap(\n        ko.utils.domNodeDisposal.cleanExternalData,\n        function (func, node) {\n            if (!$(node).closest('[data-type=skipKO]').length) {\n                func(node);\n            }\n        }\n    );\n\n    /**\n     * Wizard constructor.\n     *\n     * @param {Array} steps\n     * @param {String} modalClass\n     * @constructor\n     */\n    Wizard = function (steps, modalClass) {\n        this.steps = steps;\n        this.index = 0;\n        this.data = {};\n        this.nextLabelText = $.mage.__('Next');\n        this.prevLabelText = $.mage.__('Back');\n        this.elementSelector = '[data-role=steps-wizard-main]';\n        this.element = modalClass ? $('.' + modalClass + this.elementSelector) : $(this.elementSelector);\n        this.nextLabel = '[data-role=\"step-wizard-next\"]';\n        this.prevLabel = '[data-role=\"step-wizard-prev\"]';\n        this.element.notification();\n\n        /**\n         * Move to newIndex.\n         *\n         * @param {Number} newIndex\n         * @return {String}\n         */\n        this.move = function (newIndex) {\n            if (!this.preventSwitch(newIndex)) {\n                if (newIndex > this.index) {\n                    this._next(newIndex);\n                } else if (newIndex < this.index) {\n                    this._prev(newIndex);\n                }\n            }\n            this.updateLabels(this.getStep());\n            this.showNotificationMessage();\n\n            return this.getStep().name;\n        };\n\n        /**\n         * Move wizard to next step.\n         *\n         * @return {String}\n         */\n        this.next = function () {\n            this.move(this.index + 1);\n\n            return this.getStep().name;\n        };\n\n        /**\n         * Move wizard to previous step.\n         *\n         * @return {String}\n         */\n        this.prev = function () {\n            this.move(this.index - 1);\n\n            return this.getStep().name;\n        };\n\n        /**\n         * @return {*}\n         */\n        this.preventSwitch = function (newIndex) {\n            return newIndex < 0 || (newIndex - this.index) > 1;//eslint-disable-line no-extra-parens\n        };\n\n        /**\n         * @param {Number} newIndex\n         * @return {Boolean}\n         * @private\n         */\n        this._next = function (newIndex) {\n            newIndex = _.isNumber(newIndex) ? newIndex : this.index + 1;\n\n            try {\n                this.getStep().force(this);\n\n                if (newIndex >= steps.length) {\n                    return false;\n                }\n            } catch (e) {\n                this.setNotificationMessage(e.message, true);\n\n                return false;\n            }\n            this.cleanErrorNotificationMessage();\n            this.index = newIndex;\n            this.cleanNotificationMessage();\n            this.render();\n        };\n\n        /**\n         * @param {Number} newIndex\n         * @private\n         */\n        this._prev = function (newIndex) {\n            newIndex = _.isNumber(newIndex) ? newIndex : this.index - 1;\n            this.getStep().back(this);\n            this.index = newIndex;\n        };\n\n        /**\n         * @param {Number} stepIndex\n         * @return {Object}\n         */\n        this.getStep = function (stepIndex) {\n            return this.steps[stepIndex || this.index] || {};\n        };\n\n        /**\n         * @param {String} message\n         * @param {String} error\n         */\n        this.notifyMessage = function (message, error) {\n            $(this.element).notification('clear').notification('add', {\n                error: error,\n                message: message\n            });\n        };\n\n        /**\n         * @param {Object} step\n         */\n        this.updateLabels = function (step) {\n            this.element.find(this.nextLabel).find('button').text(step.nextLabelText || this.nextLabelText);\n            this.element.find(this.prevLabel).find('button').text(step.prevLabelText || this.prevLabelText);\n        };\n\n        /**\n         * Show notification message.\n         */\n        this.showNotificationMessage = function () {\n            if (!_.isEmpty(this.getStep())) {\n                this.hideNotificationMessage();\n\n                if (this.getStep().notificationMessage.text !== null) {\n                    this.notifyMessage(\n                        this.getStep().notificationMessage.text,\n                        this.getStep().notificationMessage.error\n                    );\n                }\n            }\n        };\n\n        /**\n         * Remove notification message.\n         */\n        this.cleanNotificationMessage = function () {\n            this.getStep().notificationMessage.text = null;\n            this.hideNotificationMessage();\n        };\n\n        /**\n         * Remove error message.\n         */\n        this.cleanErrorNotificationMessage = function () {\n            if (this.getStep().notificationMessage.error === true) {\n                this.cleanNotificationMessage();\n            }\n        };\n\n        /**\n         * @param {String} text\n         * @param {String} error\n         */\n        this.setNotificationMessage = function (text, error) {\n            error = error !== undefined;\n\n            if (!_.isEmpty(this.getStep())) {\n                this.getStep().notificationMessage.text = text;\n                this.getStep().notificationMessage.error = error;\n                this.showNotificationMessage();\n            }\n        };\n\n        /**\n         * Hide notification message.\n         */\n        this.hideNotificationMessage = function () {\n            $(this.element).notification('clear');\n        };\n\n        /**\n         * Render step.\n         */\n        this.render = function () {\n            this.hideNotificationMessage();\n            this.getStep().render(this);\n        };\n\n        /**\n         * Initialize step.\n         */\n        this.init = function () {\n            this.updateLabels(this.getStep());\n            this.render();\n        };\n        this.init();\n    };\n\n    return Component.extend({\n        defaults: {\n            modalClass: '',\n            initData: [],\n            stepsNames: [],\n            selectedStep: '',\n            steps: [],\n            disabled: true\n        },\n\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n            this.selectedStep.subscribe(this.wrapDisabledBackButton.bind(this));\n        },\n\n        /** @inheritdoc */\n        initElement: function (step) {\n            step.initData = this.initData;\n            step.mode = _.all(this.initData, _.isEmpty) ? 'create' : 'edit';\n            this.steps[this.getStepIndexByName(step.name)] = step;\n        },\n\n        /** @inheritdoc */\n        initObservable: function () {\n            this._super().observe([\n                'selectedStep',\n                'disabled'\n            ]);\n\n            return this;\n        },\n\n        /** @inheritdoc */\n        destroy: function () {\n            _.each(this.steps, function (step) {\n                step.destroy();\n            });\n\n            this._super();\n        },\n\n        /**\n         * Toggle disable property.\n         *\n         * @param {String} stepName\n         */\n        wrapDisabledBackButton: function (stepName) {\n            if (_.first(this.stepsNames) === stepName) {\n                this.disabled(true);\n            } else {\n                this.disabled(false);\n            }\n        },\n\n        /**\n         * Get step by index name.\n         *\n         * @param {String} stepName\n         */\n        getStepIndexByName: function (stepName) {\n            return _.indexOf(this.stepsNames, stepName);\n        },\n        //controls, todo to another object\n        /**\n         * Select next step.\n         */\n        next: function () {\n            this.selectedStep(this.wizard.next());\n        },\n\n        /**\n         * Select previous step.\n         */\n        back: function () {\n            this.selectedStep(this.wizard.prev());\n        },\n\n        /**\n         * Open wizard.\n         */\n        open: function () {\n            this.selectedStep(this.stepsNames.first());\n            this.wizard = new Wizard(this.steps, this.modalClass);\n        },\n\n        /**\n         * Close wizard.\n         */\n        close: function () {\n            var modal =  uiRegistry.get(this.initData.configurableModal);\n\n            if (!_.isUndefined(modal)) {\n                modal.closeModal();\n            }\n        },\n\n        /**\n         * @param {Object} data\n         * @param {Object} event\n         */\n        showSpecificStep: function (data, event) {\n            var index = _.indexOf(this.stepsNames, event.target.hash.substr(1)),\n                stepName = this.wizard.move(index);\n\n            this.selectedStep(stepName);\n        }\n    });\n});\n","Magento_Ui/js/lib/key-codes.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([], function () {\n    'use strict';\n\n    return {\n        13: 'enterKey',\n        27: 'escapeKey',\n        40: 'pageDownKey',\n        38: 'pageUpKey',\n        32: 'spaceKey',\n        9:  'tabKey',\n        37: 'pageLeftKey',\n        39: 'pageRightKey',\n        17: 'ctrlKey',\n        18: 'altKey',\n        16: 'shiftKey',\n        191: 'forwardSlashKey',\n        66: 'bKey',\n        73: 'iKey',\n        85: 'uKey'\n    };\n});\n","Magento_Ui/js/lib/spinner.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery'\n], function ($) {\n    'use strict';\n\n    var selector = '[data-role=\"spinner\"]',\n        spinner = $(selector);\n\n    return {\n        /**\n         * Show spinner.\n         */\n        show: function () {\n            spinner.show();\n        },\n\n        /**\n         * Hide spinner.\n         */\n        hide: function () {\n            spinner.hide();\n        },\n\n        /**\n         * Get spinner by selector.\n         *\n         * @param {String} id\n         * @return {jQuery}\n         */\n        get: function (id) {\n            return $(selector + '[data-component=\"' + id + '\"]');\n        }\n    };\n});\n","Magento_Ui/js/lib/collapsible.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'uiComponent'\n], function (Component) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            opened: false,\n            collapsible: true\n        },\n\n        /**\n         * Initializes observable properties.\n         *\n         * @returns {Collapsible} Chainable.\n         */\n        initObservable: function () {\n            this._super()\n                .observe('opened');\n\n            return this;\n        },\n\n        /**\n         * Toggles value of the 'opened' property.\n         *\n         * @returns {Collapsible} Chainable.\n         */\n        toggleOpened: function () {\n            this.opened() ?\n                this.close() :\n                this.open();\n\n            return this;\n        },\n\n        /**\n         * Sets 'opened' flag to false.\n         *\n         * @returns {Collapsible} Chainable.\n         */\n        close: function () {\n            if (this.collapsible) {\n                this.opened(false);\n            }\n\n            return this;\n        },\n\n        /**\n         * Sets 'opened' flag to true.\n         *\n         * @returns {Collapsible} Chainable.\n         */\n        open: function () {\n            if (this.collapsible) {\n                this.opened(true);\n            }\n\n            return this;\n        }\n    });\n});\n","Magento_Ui/js/lib/validation/utils.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine(function () {\n    'use strict';\n\n    var utils = {\n        /**\n         * Check if string is empty with trim.\n         *\n         * @param {String} value\n         * @return {Boolean}\n         */\n        isEmpty: function (value) {\n            return value === '' || value == null || value.length === 0 || /^\\s+$/.test(value);\n        },\n\n        /**\n         * Check if string is empty no trim.\n         *\n         * @param {String} value\n         * @return {Boolean}\n         */\n        isEmptyNoTrim: function (value) {\n            return value === '' || value == null || value.length === 0;\n        },\n\n        /**\n         * Checks if {value} is between numbers {from} and {to}.\n         *\n         * @param {String} value\n         * @param {String} from\n         * @param {String} to\n         * @return {Boolean}\n         */\n        isBetween: function (value, from, to) {\n            return (from === null || from === '' || value >= utils.parseNumber(from)) &&\n                   (to === null || to === '' || value <= utils.parseNumber(to));\n        },\n\n        /**\n         * Parse price string.\n         *\n         * @param {String} value\n         * @return {Number}\n         */\n        parseNumber: function (value) {\n            var isDot, isComa;\n\n            if (typeof value !== 'string') {\n                return parseFloat(value);\n            }\n            isDot = value.indexOf('.');\n            isComa = value.indexOf(',');\n\n            if (isDot !== -1 && isComa !== -1) {\n                if (isComa > isDot) {\n                    value = value.replace('.', '').replace(',', '.');\n                } else {\n                    value = value.replace(',', '');\n                }\n            } else if (isComa !== -1) {\n                value = value.replace(',', '.');\n            }\n\n            return parseFloat(value);\n        },\n\n        /**\n         * Removes HTML tags and space characters, numbers and punctuation.\n         *\n         * @param {String} value -  Value being stripped.\n         * @return {String}\n         */\n        stripHtml: function (value) {\n            return value.replace(/<.[^<>]*?>/g, ' ').replace(/&nbsp;|&#160;/gi, ' ')\n                .replace(/[0-9.(),;:!?%#$'\"_+=\\/-]*/g, '');\n        }\n    };\n\n    return utils;\n});\n","Magento_Ui/js/lib/validation/rules.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'underscore',\n    './utils',\n    'moment',\n    'tinycolor',\n    'jquery/validate',\n    'mage/translate'\n], function ($, _, utils, moment, tinycolor) {\n    'use strict';\n\n    /**\n     * validate credit card number using mod10\n     * @param {String} s\n     * @return {Boolean}\n     */\n    function validateCreditCard(s) {\n        // remove non-numerics\n        var v = '0123456789',\n            w = '',\n            i, j, k, m, c, a, x;\n\n        for (i = 0; i < s.length; i++) {\n            x = s.charAt(i);\n\n            if (v.indexOf(x, 0) !== -1) {\n                w += x;\n            }\n        }\n        // validate number\n        j = w.length / 2;\n        k = Math.floor(j);\n        m = Math.ceil(j) - k;\n        c = 0;\n\n        for (i = 0; i < k; i++) {\n            a = w.charAt(i * 2 + m) * 2;\n            c += a > 9 ? Math.floor(a / 10 + a % 10) : a;\n        }\n\n        for (i = 0; i < k + m; i++) {\n            c += w.charAt(i * 2 + 1 - m) * 1;\n        }\n\n        return c % 10 === 0;\n    }\n\n    /**\n     * Collection of validation rules including rules from additional-methods.js\n     * @type {Object}\n     */\n    return _.mapObject({\n        'min_text_length': [\n            function (value, params) {\n                return _.isUndefined(value) || value.length === 0 || value.length >= +params;\n            },\n            $.mage.__('Please enter more or equal than {0} symbols.')\n        ],\n        'max_text_length': [\n            function (value, params) {\n                return !_.isUndefined(value) && value.length <= +params;\n            },\n            $.mage.__('Please enter less or equal than {0} symbols.')\n        ],\n        'max-words': [\n            function (value, params) {\n                return utils.isEmpty(value) || utils.stripHtml(value).match(/\\b\\w+\\b/g).length < params;\n            },\n            $.mage.__('Please enter {0} words or less.')\n        ],\n        'min-words': [\n            function (value, params) {\n                return utils.isEmpty(value) || utils.stripHtml(value).match(/\\b\\w+\\b/g).length >= params;\n            },\n            $.mage.__('Please enter at least {0} words.')\n        ],\n        'range-words': [\n            function (value, params) {\n                var match = utils.stripHtml(value).match(/\\b\\w+\\b/g) || [];\n\n                return utils.isEmpty(value) || match.length >= params[0] &&\n                    match.length <= params[1];\n            },\n            $.mage.__('Please enter between {0} and {1} words.')\n        ],\n        'letters-with-basic-punc': [\n            function (value) {\n                return utils.isEmpty(value) || /^[a-z\\-.,()\\u0027\\u0022\\s]+$/i.test(value);\n            },\n            $.mage.__('Letters or punctuation only please')\n        ],\n        'alphanumeric': [\n            function (value) {\n                return utils.isEmpty(value) || /^\\w+$/i.test(value);\n            },\n            $.mage.__('Letters, numbers, spaces or underscores only please')\n        ],\n        'letters-only': [\n            function (value) {\n                return utils.isEmpty(value) || /^[a-z]+$/i.test(value);\n            },\n            $.mage.__('Letters only please')\n        ],\n        'no-whitespace': [\n            function (value) {\n                return utils.isEmpty(value) || /^\\S+$/i.test(value);\n            },\n            $.mage.__('No white space please')\n        ],\n        'no-marginal-whitespace': [\n            function (value) {\n                return !/^\\s+|\\s+$/i.test(value);\n            },\n            $.mage.__('No marginal white space please')\n        ],\n        'zip-range': [\n            function (value) {\n                return utils.isEmpty(value) || /^90[2-5]-\\d{2}-\\d{4}$/.test(value);\n            },\n            $.mage.__('Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx')\n        ],\n        'integer': [\n            function (value) {\n                return utils.isEmpty(value) || /^-?\\d+$/.test(value);\n            },\n            $.mage.__('A positive or negative non-decimal number please')\n        ],\n        'vinUS': [\n            function (value) {\n                if (utils.isEmpty(value)) {\n                    return true;\n                }\n\n                if (value.length !== 17) {\n                    return false;\n                }\n                var i, n, d, f, cd, cdv,//eslint-disable-line vars-on-top\n                    LL = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'],//eslint-disable-line max-len\n                    VL = [1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 7, 9, 2, 3, 4, 5, 6, 7, 8, 9],\n                    FL = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2],\n                    rs = 0;\n\n                for (i = 0; i < 17; i++) {\n                    f = FL[i];\n                    d = value.slice(i, i + 1);\n\n                    if (i === 8) {\n                        cdv = d;\n                    }\n\n                    if (!isNaN(d)) {\n                        d *= f;\n                    } else {\n                        for (n = 0; n < LL.length; n++) {//eslint-disable-line max-depth\n                            if (d.toUpperCase() === LL[n]) {//eslint-disable-line max-depth\n                                d = VL[n];\n                                d *= f;\n\n                                if (isNaN(cdv) && n === 8) {//eslint-disable-line max-depth\n                                    cdv = LL[n];\n                                }\n                                break;\n                            }\n                        }\n                    }\n                    rs += d;\n                }\n                cd = rs % 11;\n\n                if (cd === 10) {\n                    cd = 'X';\n                }\n\n                if (cd === cdv) {\n                    return true;\n                }\n\n                return false;\n            },\n            $.mage.__('The specified vehicle identification number (VIN) is invalid.')\n        ],\n        'dateITA': [\n            function (value) {\n                var check = false,\n                    re = /^\\d{1,2}\\/\\d{1,2}\\/\\d{4}$/,\n                    adata, gg, mm, aaaa, xdata;\n\n                if (re.test(value)) {\n                    adata = value.split('/');\n                    gg = parseInt(adata[0], 10);\n                    mm = parseInt(adata[1], 10);\n                    aaaa = parseInt(adata[2], 10);\n                    xdata = new Date(aaaa, mm - 1, gg);\n\n                    if (xdata.getFullYear() === aaaa &&\n                        xdata.getMonth() === mm - 1 &&\n                        xdata.getDate() === gg\n                    ) {\n                        check = true;\n                    } else {\n                        check = false;\n                    }\n                } else {\n                    check = false;\n                }\n\n                return check;\n            },\n            $.mage.__('Please enter a correct date')\n        ],\n        'dateNL': [\n            function (value) {\n                return /^\\d\\d?[\\.\\/-]\\d\\d?[\\.\\/-]\\d\\d\\d?\\d?$/.test(value);\n            },\n            $.mage.__('Vul hier een geldige datum in.')\n        ],\n        'time': [\n            function (value) {\n                return utils.isEmpty(value) || /^([01]\\d|2[0-3])(:[0-5]\\d){0,2}$/.test(value);\n            },\n            $.mage.__('Please enter a valid time, between 00:00 and 23:59')\n        ],\n        'time12h': [\n            function (value) {\n                return utils.isEmpty(value) || /^((0?[1-9]|1[012])(:[0-5]\\d){0,2}(\\s[AP]M))$/i.test(value);\n            },\n            $.mage.__('Please enter a valid time, between 00:00 am and 12:00 pm')\n        ],\n        'phoneUS': [\n            function (value) {\n                value = value.replace(/\\s+/g, '');\n\n                return utils.isEmpty(value) || value.length > 9 &&\n                    value.match(/^(1-?)?(\\([2-9]\\d{2}\\)|[2-9]\\d{2})-?[2-9]\\d{2}-?\\d{4}$/);\n            },\n            $.mage.__('Please specify a valid phone number')\n        ],\n        'phoneUK': [\n            function (value) {\n                return utils.isEmpty(value) || value.length > 9 &&\n                    value.match(/^(\\(?(0|\\+44)[1-9]{1}\\d{1,4}?\\)?\\s?\\d{3,4}\\s?\\d{3,4})$/);\n            },\n            $.mage.__('Please specify a valid phone number')\n        ],\n        'mobileUK': [\n            function (value) {\n                return utils.isEmpty(value) || value.length > 9 && value.match(/^((0|\\+44)7\\d{3}\\s?\\d{6})$/);\n            },\n            $.mage.__('Please specify a valid mobile number')\n        ],\n        'stripped-min-length': [\n            function (value, param) {\n                return _.isUndefined(value) || value.length === 0 || utils.stripHtml(value).length >= param;\n            },\n            $.mage.__('Please enter at least {0} characters')\n        ],\n        'email2': [\n            function (value) {\n                return utils.isEmpty(value) || /^((([a-z]|\\d|[!#\\$%&\\u0027\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&\\u0027\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\u0022)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\u0022)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)*(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?$/i.test(value);//eslint-disable-line max-len\n            },\n            $.validator.messages.email\n        ],\n        'url2': [\n            function (value) {\n                return utils.isEmpty(value) || /^(https?|ftp):\\/\\/(((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\\u0027\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)*(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\\u0027\\(\\)\\*\\+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\\u0027\\(\\)\\*\\+,;=]|:|@)*)*)?)?(\\?((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\\u0027\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(\\#((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&\\u0027\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$/i.test(value);//eslint-disable-line max-len\n            },\n            $.validator.messages.url\n        ],\n        'credit-card-types': [\n            function (value, param) {\n                var validTypes;\n\n                if (utils.isEmpty(value)) {\n                    return true;\n                }\n\n                if (/[^0-9-]+/.test(value)) {\n                    return false;\n                }\n                value = value.replace(/\\D/g, '');\n                validTypes = 0x0000;\n\n                if (param.mastercard) {\n                    validTypes |= 0x0001;\n                }\n\n                if (param.visa) {\n                    validTypes |= 0x0002;\n                }\n\n                if (param.amex) {\n                    validTypes |= 0x0004;\n                }\n\n                if (param.dinersclub) {\n                    validTypes |= 0x0008;\n                }\n\n                if (param.enroute) {\n                    validTypes |= 0x0010;\n                }\n\n                if (param.discover) {\n                    validTypes |= 0x0020;\n                }\n\n                if (param.jcb) {\n                    validTypes |= 0x0040;\n                }\n\n                if (param.unknown) {\n                    validTypes |= 0x0080;\n                }\n\n                if (param.all) {\n                    validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;\n                }\n\n                if (validTypes & 0x0001 && /^(51|52|53|54|55)/.test(value)) { //mastercard\n                    return value.length === 16;\n                }\n\n                if (validTypes & 0x0002 && /^(4)/.test(value)) { //visa\n                    return value.length === 16;\n                }\n\n                if (validTypes & 0x0004 && /^(34|37)/.test(value)) { //amex\n                    return value.length === 15;\n                }\n\n                if (validTypes & 0x0008 && /^(300|301|302|303|304|305|36|38)/.test(value)) { //dinersclub\n                    return value.length === 14;\n                }\n\n                if (validTypes & 0x0010 && /^(2014|2149)/.test(value)) { //enroute\n                    return value.length === 15;\n                }\n\n                if (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover\n                    return value.length === 16;\n                }\n\n                if (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb\n                    return value.length === 16;\n                }\n\n                if (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb\n                    return value.length === 15;\n                }\n\n                if (validTypes & 0x0080) { //unknown\n                    return true;\n                }\n\n                return false;\n            },\n            $.mage.__('Please enter a valid credit card number.')\n        ],\n        'ipv4': [\n            function (value) {\n                return utils.isEmpty(value) || /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i.test(value);//eslint-disable-line max-len\n            },\n            $.mage.__('Please enter a valid IP v4 address.')\n        ],\n        'ipv6': [\n            function (value) {\n                return utils.isEmpty(value) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(value);//eslint-disable-line max-len\n            },\n            $.mage.__('Please enter a valid IP v6 address.')\n        ],\n        'pattern': [\n            function (value, param) {\n                return utils.isEmpty(value) || new RegExp(param).test(value);\n            },\n            $.mage.__('Invalid format.')\n        ],\n        'validate-no-html-tags': [\n            function (value) {\n                return !/<(\\/)?\\w+/.test(value);\n            },\n            $.mage.__('HTML tags are not allowed.')\n        ],\n        'validate-select': [\n            function (value) {\n                return value !== 'none' && value != null && value.length !== 0;\n            },\n            $.mage.__('Please select an option.')\n        ],\n        'validate-no-empty': [\n            function (value) {\n                return !utils.isEmpty(value);\n            },\n            $.mage.__('Empty Value.')\n        ],\n        'validate-alphanum-with-spaces': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^[a-zA-Z0-9 ]+$/.test(value);\n            },\n            $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9) or spaces only in this field.')\n        ],\n        'validate-data': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^[A-Za-z]+[A-Za-z0-9_]+$/.test(value);\n            },\n            $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.')//eslint-disable-line max-len\n        ],\n        'validate-street': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) ||\n                    /^[ \\w]{3,}([A-Za-z]\\.)?([ \\w]*\\#\\d+)?(\\r\\n| )[ \\w]{3,}/.test(value);\n            },\n            $.mage.__('Please use only letters (a-z or A-Z), numbers (0-9), spaces and \"#\" in this field.')\n        ],\n        'validate-phoneStrict': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^(\\()?\\d{3}(\\))?(-|\\s)?\\d{3}(-|\\s)\\d{4}$/.test(value);\n            },\n            $.mage.__('Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.')\n        ],\n        'validate-phoneLax': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) ||\n                    /^((\\d[\\-. ]?)?((\\(\\d{3}\\))|\\d{3}))?[\\-. ]?\\d{3}[\\-. ]?\\d{4}$/.test(value);\n            },\n            $.mage.__('Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.')\n        ],\n        'validate-fax': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^(\\()?\\d{3}(\\))?(-|\\s)?\\d{3}(-|\\s)\\d{4}$/.test(value);\n            },\n            $.mage.__('Please enter a valid fax number (Ex: 123-456-7890).')\n        ],\n        'validate-email': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^([a-z0-9,!\\#\\$%&'\\*\\+\\/=\\?\\^_`\\{\\|\\}~-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z0-9,!\\#\\$%&'\\*\\+\\/=\\?\\^_`\\{\\|\\}~-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*@([a-z0-9-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z0-9-]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*\\.(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]){2,})$/i.test(value);//eslint-disable-line max-len\n            },\n            $.mage.__('Please enter a valid email address (Ex: johndoe@domain.com).')\n        ],\n        'validate-emailSender': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^[\\S ]+$/.test(value);\n            },\n            $.mage.__('Please enter a valid email address (Ex: johndoe@domain.com).')\n        ],\n        'validate-password': [\n            function (value) {\n                var pass;\n\n                if (value == null) {\n                    return false;\n                }\n\n                pass = value.trim();\n\n                if (!pass.length) {\n                    return true;\n                }\n\n                return !(pass.length > 0 && pass.length < 6);\n            },\n            $.mage.__('Please enter 6 or more characters. Leading and trailing spaces will be ignored.')\n        ],\n        'validate-admin-password': [\n            function (value) {\n                var pass;\n\n                if (value == null) {\n                    return false;\n                }\n\n                pass = value.trim();\n\n                if (pass.length === 0) {\n                    return true;\n                }\n\n                if (!/[a-z]/i.test(value) || !/[0-9]/.test(value)) {\n                    return false;\n                }\n\n                if (pass.length < 7) {\n                    return false;\n                }\n\n                return true;\n            },\n            $.mage.__('Please enter 7 or more characters, using both numeric and alphabetic.')\n        ],\n        'validate-customer-password': [\n            function (v, elm) {\n                var validator = this,\n                    counter = 0,\n                    passwordMinLength = $(elm).data('password-min-length'),\n                    passwordMinCharacterSets = $(elm).data('password-min-character-sets'),\n                    pass = v.trim(),\n                    result = pass.length >= passwordMinLength;\n\n                if (result === false) {\n                    validator.passwordErrorMessage = $.mage.__('Minimum length of this field must be equal or greater than %1 symbols. Leading and trailing spaces will be ignored.').replace('%1', passwordMinLength);//eslint-disable-line max-len\n\n                    return result;\n                }\n\n                if (pass.match(/\\d+/)) {\n                    counter++;\n                }\n\n                if (pass.match(/[a-z]+/)) {\n                    counter++;\n                }\n\n                if (pass.match(/[A-Z]+/)) {\n                    counter++;\n                }\n\n                if (pass.match(/[^a-zA-Z0-9]+/)) {\n                    counter++;\n                }\n\n                if (counter < passwordMinCharacterSets) {\n                    result = false;\n                    validator.passwordErrorMessage = $.mage.__('Minimum of different classes of characters in password is %1. Classes of characters: Lower Case, Upper Case, Digits, Special Characters.').replace('%1', passwordMinCharacterSets);//eslint-disable-line max-len\n                }\n\n                return result;\n            }, function () {\n                return this.passwordErrorMessage;\n            }\n        ],\n        'validate-url': [\n            function (value) {\n                if (utils.isEmptyNoTrim(value)) {\n                    return true;\n                }\n                value = (value || '').replace(/^\\s+/, '').replace(/\\s+$/, '');\n\n                return (/^(http|https|ftp):\\/\\/(([A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))(\\.[A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))*)(:(\\d+))?(\\/[A-Z0-9~](([A-Z0-9_~-]|\\.)*[A-Z0-9~]|))*\\/?(.*)?$/i).test(value);//eslint-disable-line max-len\n\n            },\n            $.mage.__('Please enter a valid URL. Protocol is required (http://, https:// or ftp://).')\n        ],\n        'validate-clean-url': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^(http|https|ftp):\\/\\/(([A-Z0-9][A-Z0-9_-]*)(\\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\\d+))?\\/?/i.test(value) || /^(www)((\\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\\d+))?\\/?/i.test(value);//eslint-disable-line max-len\n\n            },\n            $.mage.__('Please enter a valid URL. For example http://www.example.com or www.example.com.')\n        ],\n        'validate-xml-identifier': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^[A-Z][A-Z0-9_\\/-]*$/i.test(value);\n\n            },\n            $.mage.__('Please enter a valid XML-identifier (Ex: something_1, block5, id-4).')\n        ],\n        'validate-ssn': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^\\d{3}-?\\d{2}-?\\d{4}$/.test(value);\n\n            },\n            $.mage.__('Please enter a valid social security number (Ex: 123-45-6789).')\n        ],\n        'validate-zip-us': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /(^\\d{5}$)|(^\\d{5}-\\d{4}$)/.test(value);\n\n            },\n            $.mage.__('Please enter a valid zip code (Ex: 90602 or 90602-1234).')\n        ],\n        'validate-date-au': [\n            function (value) {\n                var regex = /^(\\d{2})\\/(\\d{2})\\/(\\d{4})$/,\n                    d;\n\n                if (utils.isEmptyNoTrim(value)) {\n                    return true;\n                }\n\n                if (utils.isEmpty(value) || !regex.test(value)) {\n                    return false;\n                }\n                d = new Date(value.replace(regex, '$2/$1/$3'));\n\n                return parseInt(RegExp.$2, 10) === 1 + d.getMonth() &&\n                    parseInt(RegExp.$1, 10) === d.getDate() &&\n                    parseInt(RegExp.$3, 10) === d.getFullYear();\n\n            },\n            $.mage.__('Please use this date format: dd/mm/yyyy. For example 17/03/2006 for the 17th of March, 2006.')\n        ],\n        'validate-currency-dollar': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^\\$?\\-?([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}\\d*(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$/.test(value);//eslint-disable-line max-len\n\n            },\n            $.mage.__('Please enter a valid $ amount. For example $100.00.')\n        ],\n        'validate-not-negative-number': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || !isNaN(utils.parseNumber(value))\n                    && value >= 0 && (/^\\s*-?\\d+([,.]\\d+)*\\s*%?\\s*$/).test(value);\n\n            },\n            $.mage.__('Please enter a number 0 or greater, without comma in this field.')\n        ],\n        // validate-not-negative-number should be replaced in all places with this one and then removed\n        'validate-zero-or-greater': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || !isNaN(utils.parseNumber(value))\n                    && value >= 0 && (/^\\s*-?\\d+([,.]\\d+)*\\s*%?\\s*$/).test(value);\n            },\n            $.mage.__('Please enter a number 0 or greater, without comma in this field.')\n        ],\n        'validate-greater-than-zero': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || !isNaN(utils.parseNumber(value))\n                    && value > 0 && (/^\\s*-?\\d+([,.]\\d+)*\\s*%?\\s*$/).test(value);\n            },\n            $.mage.__('Please enter a number greater than 0, without comma in this field.')\n        ],\n        'validate-css-length': [\n            function (value) {\n                if (value !== '') {\n                    return (/^[0-9]*\\.*[0-9]+(px|pc|pt|ex|em|mm|cm|in|%)?$/).test(value);\n                }\n\n                return true;\n            },\n            $.mage.__('Please input a valid CSS-length (Ex: 100px, 77pt, 20em, .5ex or 50%).')\n        ],\n        'validate-number': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) ||\n                    !isNaN(utils.parseNumber(value)) &&\n                    /^\\s*-?\\d*(?:[.,|'|\\s]\\d+)*(?:[.,|'|\\s]\\d{2})?-?\\s*$/.test(value);\n            },\n            $.mage.__('Please enter a valid number in this field.')\n        ],\n        'validate-integer': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || !isNaN(utils.parseNumber(value)) && /^\\s*-?\\d*\\s*$/.test(value);\n            },\n            $.mage.__('Please enter a valid integer in this field.')\n        ],\n        'validate-number-range': [\n            function (value, param) {\n                var numValue, dataAttrRange, result, range, m;\n\n                if (utils.isEmptyNoTrim(value)) {\n                    return true;\n                }\n\n                numValue = utils.parseNumber(value);\n\n                if (isNaN(numValue)) {\n                    return false;\n                }\n\n                dataAttrRange = /^(-?[\\d.,]+)?-(-?[\\d.,]+)?$/;\n                result = true;\n                range = param;\n\n                if (range) {\n                    m = dataAttrRange.exec(range);\n\n                    if (m) {\n                        result = result && utils.isBetween(numValue, m[1], m[2]);\n                    }\n                }\n\n                return result;\n            },\n            $.mage.__('The value is not within the specified range.')\n        ],\n        'validate-positive-percent-decimal': [\n            function (value) {\n                var numValue;\n\n                if (utils.isEmptyNoTrim(value) || !/^\\s*-?\\d*(\\.\\d*)?\\s*$/.test(value)) {\n                    return false;\n                }\n\n                numValue = utils.parseNumber(value);\n\n                if (isNaN(numValue)) {\n                    return false;\n                }\n\n                return utils.isBetween(numValue, 0.01, 100);\n            },\n            $.mage.__('Please enter a valid percentage discount value greater than 0.')\n        ],\n        'validate-digits': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || !/[^\\d]/.test(value);\n            },\n            $.mage.__('Please enter a valid number in this field.')\n        ],\n        'validate-digits-range': [\n            function (value, param) {\n                var numValue, dataAttrRange, result, range, m;\n\n                if (utils.isEmptyNoTrim(value)) {\n                    return true;\n                }\n\n                numValue = utils.parseNumber(value);\n\n                if (isNaN(numValue)) {\n                    return false;\n                }\n\n                dataAttrRange = /^(-?\\d+)?-(-?\\d+)?$/;\n                result = true;\n                range = param;\n\n                if (range) {\n                    m = dataAttrRange.exec(range);\n\n                    if (m) {\n                        result = result && utils.isBetween(numValue, m[1], m[2]);\n                    }\n                }\n\n                return result;\n            },\n            $.mage.__('The value is not within the specified range.')\n        ],\n        'validate-range': [\n            function (value) {\n                var minValue, maxValue, ranges;\n\n                if (utils.isEmptyNoTrim(value)) {\n                    return true;\n                } else if ($.validator.methods['validate-digits'] && $.validator.methods['validate-digits'](value)) {\n                    minValue = maxValue = utils.parseNumber(value);\n                } else {\n                    ranges = /^(-?\\d+)?-(-?\\d+)?$/.exec(value);\n\n                    if (ranges) {\n                        minValue = utils.parseNumber(ranges[1]);\n                        maxValue = utils.parseNumber(ranges[2]);\n\n                        if (minValue > maxValue) {//eslint-disable-line max-depth\n                            return false;\n                        }\n                    } else {\n                        return false;\n                    }\n                }\n            },\n            $.mage.__('The value is not within the specified range.')\n        ],\n        'validate-alpha': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^[a-zA-Z]+$/.test(value);\n            },\n            $.mage.__('Please use letters only (a-z or A-Z) in this field.')\n        ],\n        'validate-code': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^[a-z]+[a-z0-9_]+$/.test(value);\n            },\n            $.mage.__('Please use only lowercase letters (a-z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.')//eslint-disable-line max-len\n        ],\n        'validate-alphanum': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^[a-zA-Z0-9]+$/.test(value);\n            },\n            $.mage.__('Please use only letters (a-z or A-Z) or numbers (0-9) in this field. No spaces or other characters are allowed.')//eslint-disable-line max-len\n        ],\n        'validate-not-number-first': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^[^0-9-\\.].*$/.test(value.trim());\n            },\n            $.mage.__('First character must be letter.')\n        ],\n        'validate-date': [\n            function (value, params, additionalParams) {\n                var test = moment(value, additionalParams.dateFormat);\n\n                return utils.isEmptyNoTrim(value) || test.isValid();\n            },\n            $.mage.__('Please enter a valid date.')\n        ],\n        'validate-date-range': [\n            function (value, params) {\n                var fromDate = $('input[name*=\"' + params + '\"]').val();\n\n                return moment.utc(value).unix() >= moment.utc(fromDate).unix() || isNaN(moment.utc(value).unix());\n            },\n            $.mage.__('Make sure the To Date is later than or the same as the From Date.')\n        ],\n        'validate-identifier': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^[a-z0-9][a-z0-9_\\/-]+(\\.[a-z0-9_-]+)?$/.test(value);\n            },\n            $.mage.__('Please enter a valid URL Key (Ex: \"example-page\", \"example-page.html\" or \"anotherlevel/example-page\").')//eslint-disable-line max-len\n        ],\n        'validate-trailing-hyphen': [\n            function (value) {\n                return utils.isEmptyNoTrim(value) || /^(?!-)(?!.*-$).+$/.test(value);\n            },\n            $.mage.__('Trailing hyphens are not allowed.')\n        ],\n        'validate-zip-international': [\n\n            /*function(v) {\n            // @TODO: Cleanup\n            return Validation.get('IsEmpty').test(v) || /(^[A-z0-9]{2,10}([\\s]{0,1}|[\\-]{0,1})[A-z0-9]{2,10}$)/.test(v);\n            }*/\n            function () {\n                return true;\n            },\n            $.mage.__('Please enter a valid zip code.')\n        ],\n        'validate-state': [\n            function (value) {\n                return value !== 0;\n            },\n            $.mage.__('Please select State/Province.')\n        ],\n        'less-than-equals-to': [\n            function (value, params) {\n                value = utils.parseNumber(value);\n\n                if (isNaN(parseFloat(params))) {\n                    params = $(params).val();\n                }\n\n                params = utils.parseNumber(params);\n\n                if (!isNaN(params) && !isNaN(value)) {\n                    this.lteToVal = params;\n\n                    return value <= params;\n                }\n\n                return true;\n            },\n            function () {\n                return $.mage.__('Please enter a value less than or equal to %s.').replace('%s', this.lteToVal);\n            }\n        ],\n        'greater-than-equals-to': [\n            function (value, params) {\n                value = utils.parseNumber(value);\n\n                if (isNaN(parseFloat(params))) {\n                    params = $(params).val();\n                }\n\n                params = utils.parseNumber(params);\n\n                if (!isNaN(params) && !isNaN(value)) {\n                    this.gteToVal = params;\n\n                    return value >= params;\n                }\n\n                return true;\n            },\n            function () {\n                return $.mage.__('Please enter a value greater than or equal to %s.').replace('%s', this.gteToVal);\n            }\n        ],\n        'validate-emails': [\n            function (value) {\n                var validRegexp, emails, i;\n\n                if (utils.isEmpty(value)) {\n                    return true;\n                }\n                validRegexp = /^[a-z0-9\\._-]{1,30}@([a-z0-9_-]{1,30}\\.){1,5}[a-z]{2,4}$/i;\n                emails = value.split(/[\\s\\n\\,]+/g);\n\n                for (i = 0; i < emails.length; i++) {\n                    if (!validRegexp.test(emails[i].strip())) {\n                        return false;\n                    }\n                }\n\n                return true;\n            },\n            $.mage.__('Please enter valid email addresses, separated by commas. For example, johndoe@domain.com, johnsmith@domain.com.')//eslint-disable-line max-len\n        ],\n        'validate-cc-number': [\n\n            /**\n             * Validate credit card number based on mod 10.\n             *\n             * @param {String} value - credit card number\n             * @return {Boolean}\n             */\n            function (value) {\n                if (value) {\n                    return validateCreditCard(value);\n                }\n\n                return true;\n            },\n            $.mage.__('Please enter a valid credit card number.')\n        ],\n        'validate-cc-ukss': [\n\n            /**\n             * Validate Switch/Solo/Maestro issue number and start date is filled.\n             *\n             * @param {String} value - input field value\n             * @return {*}\n             */\n            function (value) {\n                return value;\n            },\n            $.mage.__('Please enter issue number or start date for switch/solo card type.')\n        ],\n        'required-entry': [\n            function (value) {\n                return !utils.isEmpty(value);\n            },\n            $.mage.__('This is a required field.')\n        ],\n        'checked': [\n            function (value) {\n                return value;\n            },\n            $.mage.__('This is a required field.')\n        ],\n        'not-negative-amount': [\n            function (value) {\n                if (value.length) {\n                    return (/^\\s*\\d+([,.]\\d+)*\\s*%?\\s*$/).test(value);\n                }\n\n                return true;\n            },\n            $.mage.__('Please enter positive number in this field.')\n        ],\n        'validate-per-page-value-list': [\n            function (value) {\n                var isValid = true,\n                    values = value.split(','),\n                    i;\n\n                if (utils.isEmpty(value)) {\n                    return isValid;\n                }\n\n                for (i = 0; i < values.length; i++) {\n                    if (!/^[0-9]+$/.test(values[i])) {\n                        isValid = false;\n                    }\n                }\n\n                return isValid;\n            },\n            $.mage.__('Please enter a valid value, ex: 10,20,30')\n        ],\n        'validate-new-password': [\n            function (value) {\n                if ($.validator.methods['validate-password'] && !$.validator.methods['validate-password'](value)) {\n                    return false;\n                }\n\n                if (utils.isEmpty(value) && value !== '') {\n                    return false;\n                }\n\n                return true;\n            },\n            $.mage.__('Please enter 6 or more characters. Leading and trailing spaces will be ignored.')\n        ],\n        'validate-item-quantity': [\n            function (value, params) {\n                var validator = this,\n                    result = false,\n                    // obtain values for validation\n                    qty = utils.parseNumber(value),\n                    isMinAllowedValid = typeof params.minAllowed === 'undefined' ||\n                        qty >= utils.parseNumber(params.minAllowed),\n                    isMaxAllowedValid = typeof params.maxAllowed === 'undefined' ||\n                        qty <= utils.parseNumber(params.maxAllowed),\n                    isQtyIncrementsValid = typeof params.qtyIncrements === 'undefined' ||\n                        qty % utils.parseNumber(params.qtyIncrements) === 0;\n\n                result = qty > 0;\n\n                if (result === false) {\n                    validator.itemQtyErrorMessage = $.mage.__('Please enter a quantity greater than 0.');//eslint-disable-line max-len\n\n                    return result;\n                }\n\n                result = isMinAllowedValid;\n\n                if (result === false) {\n                    validator.itemQtyErrorMessage = $.mage.__('The fewest you may purchase is %1.').replace('%1', params.minAllowed);//eslint-disable-line max-len\n\n                    return result;\n                }\n\n                result = isMaxAllowedValid;\n\n                if (result === false) {\n                    validator.itemQtyErrorMessage = $.mage.__('The maximum you may purchase is %1.').replace('%1', params.maxAllowed);//eslint-disable-line max-len\n\n                    return result;\n                }\n\n                result = isQtyIncrementsValid;\n\n                if (result === false) {\n                    validator.itemQtyErrorMessage = $.mage.__('You can buy this product only in quantities of %1 at a time.').replace('%1', params.qtyIncrements);//eslint-disable-line max-len\n\n                    return result;\n                }\n\n                return result;\n            }, function () {\n                return this.itemQtyErrorMessage;\n            }\n        ],\n        'equalTo': [\n            function (value, param) {\n                return value === $(param).val();\n            },\n            $.validator.messages.equalTo\n        ],\n        'validate-file-type': [\n            function (name, types) {\n                var extension = name.split('.').pop().toLowerCase();\n\n                if (types && typeof types === 'string') {\n                    types = types.split(' ');\n                }\n\n                return !types || !types.length || ~types.indexOf(extension);\n            },\n            $.mage.__('We don\\'t recognize or support this file extension type.')\n        ],\n        'validate-max-size': [\n            function (size, maxSize) {\n                return maxSize === false || size < maxSize;\n            },\n            $.mage.__('File you are trying to upload exceeds maximum file size limit.')\n        ],\n        'validate-if-tag-script-exist': [\n            function (value) {\n                return !value || (/<script\\b[^>]*>([\\s\\S]*?)<\\/script>$/ig).test(value);\n            },\n            $.mage.__('Please use tag SCRIPT with SRC attribute or with proper content to include JavaScript to the document.')//eslint-disable-line max-len\n        ],\n        'date_range_min': [\n            function (value, minValue, params) {\n                return moment.utc(value, params.dateFormat).unix() >= minValue;\n            },\n            $.mage.__('The date is not within the specified range.')\n        ],\n        'date_range_max': [\n            function (value, maxValue, params) {\n                return moment.utc(value, params.dateFormat).unix() <= maxValue;\n            },\n            $.mage.__('The date is not within the specified range.')\n        ],\n        'validate-color': [\n            function (value) {\n                if (value === '') {\n                    return true;\n                }\n\n                return tinycolor(value).isValid();\n            },\n            $.mage.__('Wrong color format. Please specify color in HEX, RGBa, HSVa, HSLa or use color name.')\n        ],\n        'blacklist-url': [\n            function (value, param) {\n                return new RegExp(param).test(value);\n            },\n            $.mage.__('This link is not allowed.')\n        ],\n        'validate-dob': [\n            function (value, param, params) {\n                if (value === '') {\n                    return true;\n                }\n\n                return moment.utc(value, params.dateFormat).isSameOrBefore(moment.utc());\n            },\n            $.mage.__('The Date of Birth should not be greater than today.')\n        ],\n        'validate-no-utf8mb4-characters': [\n            function (value) {\n                var validator = this,\n                    message = $.mage.__('Please remove invalid characters: {0}.'),\n                    matches = value.match(/(?:[\\uD800-\\uDBFF][\\uDC00-\\uDFFF])/g),\n                    result = matches === null;\n\n                if (!result) {\n                    validator.charErrorMessage = message.replace('{0}', matches.join());\n                }\n\n                return result;\n            }, function () {\n                return this.charErrorMessage;\n            }\n        ]\n    }, function (data) {\n        return {\n            handler: data[0],\n            message: data[1]\n        };\n    });\n});\n","Magento_Ui/js/lib/validation/validator.js":"/*\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'underscore',\n    './rules'\n], function (_, rulesList) {\n    'use strict';\n\n    /**\n     * Validates provided value be the specified rule.\n     *\n     * @param {String} id - Rule identifier.\n     * @param {*} value - Value to be checked.\n     * @param {*} [params]\n     * @param {*} additionalParams - additional validation params set by method caller\n     * @returns {Object}\n     */\n    function validate(id, value, params, additionalParams) {\n        var rule,\n            message,\n            valid,\n            result = {\n                rule: id,\n                passed: true,\n                message: ''\n            };\n\n        if (_.isObject(params)) {\n            message = params.message || '';\n        }\n\n        if (!rulesList[id]) {\n            return result;\n        }\n\n        rule    = rulesList[id];\n        message = message || rule.message;\n        valid   = rule.handler(value, params, additionalParams);\n\n        if (!valid) {\n            params = Array.isArray(params) ?\n                params :\n                [params];\n\n            if (typeof message === 'function') {\n                message = message.call(rule);\n            }\n\n            message = params.reduce(function (msg, param, idx) {\n                return msg.replace(new RegExp('\\\\{' + idx + '\\\\}', 'g'), param);\n            }, message);\n\n            result.passed = false;\n            result.message = message;\n        }\n\n        return result;\n    }\n\n    /**\n     * Validates provided value by a specified set of rules.\n     *\n     * @param {(String|Object)} rules - One or many validation rules.\n     * @param {*} value - Value to be checked.\n     * @param {*} additionalParams - additional validation params set by method caller\n     * @returns {Object}\n     */\n    function validator(rules, value, additionalParams) {\n        var result;\n\n        if (typeof rules === 'object') {\n            result = {\n                passed: true\n            };\n\n            _.every(rules, function (ruleParams, id) {\n                if (ruleParams.validate || ruleParams !== false || additionalParams) {\n                    result = validate(id, value, ruleParams, additionalParams);\n\n                    return result.passed;\n                }\n\n                return true;\n            });\n\n            return result;\n        }\n\n        return validate.apply(null, arguments);\n    }\n\n    /**\n     * Adds new validation rule.\n     *\n     * @param {String} id - Rule identifier.\n     * @param {Function} handler - Validation function.\n     * @param {String} message - Error message.\n     */\n    validator.addRule = function (id, handler, message) {\n        rulesList[id] = {\n            handler: handler,\n            message: message\n        };\n    };\n\n    /**\n     * Returns rule object found by provided identifier.\n     *\n     * @param {String} id - Rule identifier.\n     * @returns {Object}\n     */\n    validator.getRule = function (id) {\n        return rulesList[id];\n    };\n\n    return validator;\n});\n","Magento_Ui/js/lib/logger/levels-pool.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore'\n], function (_) {\n    'use strict';\n\n    var LEVELS,\n        CODE_MAP;\n\n    LEVELS = {\n        NONE: 0,\n        ERROR: 1,\n        WARN: 2,\n        INFO: 3,\n        DEBUG: 4,\n        ALL: 5\n    };\n\n    CODE_MAP = _.invert(LEVELS);\n\n    return {\n        /**\n         * Returns the list of available log levels.\n         *\n         * @returns {Object}\n         */\n        getLevels: function () {\n            return LEVELS;\n        },\n\n        /**\n         * Returns name of the log level that matches to the provided code.\n         *\n         * @returns {String}\n         */\n        getNameByCode: function (code) {\n            return CODE_MAP[code];\n        }\n    };\n});\n","Magento_Ui/js/lib/logger/logger-utils.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([], function () {\n    'use strict';\n\n    /**\n     * Utils methods for logger\n     * @param {Logger} logger\n     */\n    function LogUtils(logger) {\n        this.logger = logger;\n\n    }\n\n    /**\n     * Method for logging asynchronous operations\n     * @param {Promise} promise\n     * @param {Object} config\n     */\n    LogUtils.prototype.asyncLog = function (promise, config) {\n        var levels,\n            messages,\n            wait;\n\n        config = config || {};\n        levels = config.levels || this.createLevels();\n        messages = config.messages || this.createMessages();\n        wait = config.wait || 5000;\n\n        this.logger[levels.requested](messages.requested, config.data);\n        setTimeout(function () {\n            promise.state() === 'pending' ?\n                this.logger[levels.failed](messages.failed, config.data) :\n                this.logger[levels.loaded](messages.loaded, config.data);\n        }.bind(this), wait);\n    };\n\n    /**\n     * Method that creates object of messages\n     * @param {String} requested - log message that showing that request for class is started\n     * @param {String} loaded - log message that show when requested class is loaded\n     * @param {String} failed - log message that show when requested class is failed\n     * @returns {Object}\n     */\n    LogUtils.prototype.createMessages = function (requested, loaded, failed) {\n        return {\n            requested: requested || '',\n            loaded: loaded || '',\n            failed: failed || ''\n        };\n    };\n\n    /**\n     * Method that creates object of log levels\n     * @param {String} requested - log message that showing that request for class is started\n     * @param {String} loaded - log message that show when requested class is loaded\n     * @param {String} failed - log message that show when requested class is failed\n     * @returns {Object}\n     */\n    LogUtils.prototype.createLevels = function (requested, loaded, failed) {\n        return {\n            requested: requested || 'info',\n            loaded: loaded || 'info',\n            failed: failed || 'warn'\n        };\n    };\n\n    return LogUtils;\n});\n","Magento_Ui/js/lib/logger/entry-factory.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    './entry'\n], function (LogEntry) {\n    'use strict';\n\n    return {\n        /**\n         * @param {String} message\n         * @param {Number} level\n         * @param {Object} [messageData]\n         * @returns {LogEntry}\n         */\n        createEntry: function (message, level, messageData) {\n            return new LogEntry(message, level, messageData);\n        }\n    };\n});\n","Magento_Ui/js/lib/logger/console-output-handler.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    './levels-pool'\n], function (logLevels) {\n    'use strict';\n\n    var levels = logLevels.getLevels();\n\n    /**\n     * @param {LogFormatter} formatter\n     */\n    function ConsoleOutputHandler(formatter) {\n        /**\n         * @protected\n         * @type {LogFormatter}\n         */\n        this.formatter_ = formatter;\n    }\n\n    /**\n     * Display data of the provided entry to the console.\n     *\n     * @param {LogEntry} entry - Entry to be displayed.\n     */\n    ConsoleOutputHandler.prototype.show = function (entry) {\n        var displayString = this.formatter_.process(entry);\n\n        switch (entry.level) {\n            case levels.ERROR:\n                console.error(displayString);\n                break;\n\n            case levels.WARN:\n                console.warn(displayString);\n                break;\n\n            case levels.INFO:\n                console.info(displayString);\n                break;\n\n            case levels.DEBUG:\n                console.log(displayString);\n                break;\n        }\n    };\n\n    /**\n     * Displays the array of entries.\n     *\n     * @param {Array<LogEntry>} entries\n     */\n    ConsoleOutputHandler.prototype.dump = function (entries) {\n        entries.forEach(this.show, this);\n    };\n\n    return ConsoleOutputHandler;\n});\n","Magento_Ui/js/lib/logger/entry.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    './levels-pool'\n], function (logLevels) {\n    'use strict';\n\n    /**\n     * @param {String} message\n     * @param {Number} level\n     * @param {Object} [data]\n     */\n    function LogEntry(message, level, data) {\n        /**\n         * @readonly\n         * @type {Number}\n         */\n        this.timestamp = Date.now();\n\n        /**\n         * @readonly\n         * @type {Number}\n         */\n        this.level = level;\n\n        /**\n         * @readonly\n         * @type {String}\n         */\n        this.levelName = logLevels.getNameByCode(level);\n\n        /**\n         * @readonly\n         * @type {Object}\n         */\n        this.data = data;\n\n        /**\n         * @readonly\n         * @type {String}\n         */\n        this.message = message;\n    }\n\n    return LogEntry;\n});\n","Magento_Ui/js/lib/logger/message-pool.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(function () {\n    'use strict';\n\n    var MESSAGES = {\n        templateStartLoading:\n            'The \"${ $.template }\" template requested by  the \"${$.component}\" component started loading.',\n        templateLoadedFromServer:\n            'The \"${ $.template }\" template requested by the \"${$.component}\" component  was loaded from server.\"',\n        templateLoadedFromCache:\n            'The \"${ $.template }\" template  requested by the \"${$.component}\" component was loaded from cache.\"',\n        templateLoadingFail: 'Failed to load the \"${ $.template }\" template requested by \"${$.component}\".',\n        componentStartInitialization:\n            'Component \"${$.component}\" start initialization with instance name \"${$.componentName}\".',\n        componentStartLoading: ' Started loading the \"${$.component}\" component.',\n        componentFinishLoading: 'The \"${$.component}\" component was loaded.',\n        componentLoadingFail: 'Failed to load the \"${$.component}\" component.',\n        depsLoadingFail: 'Could not get the declared \"${$.deps}\" dependency for the \"${$.component}\" instance.',\n        depsStartRequesting: 'Requesting the \"${$.deps}\" dependency for the \"${$.component}\" instance.',\n        depsFinishRequesting: 'The \"${$.deps}\" dependency for the \"${$.component}\" instance was received.',\n        requestingComponent: 'Requesting the \"${$.component}\" component.',\n        requestingComponentIsLoaded: 'The requested \"${$.component}\" component was received.',\n        requestingComponentIsFailed: 'Could not get the requested \"${$.component}\" component.'\n    };\n\n    return {\n        /**\n         * Returns message that matches the provided code.\n         *\n         * @param {String} code - Message's identifier\n         * @returns {String}\n         */\n        getMessage: function (code) {\n            return MESSAGES[code];\n        },\n\n        /**\n         * Adds a new message to the poll.\n         *\n         * @param {String} code - Message's identifier.\n         * @param {String} message - Text of the message\n         */\n        addMessage: function (code, message) {\n            MESSAGES[code] = message;\n        },\n\n        /**\n         * Tells whether message with provide code exists in the poll.\n         *\n         * @param {String} code - Message's identifier.\n         * @returns {Boolean}\n         */\n        hasMessage: function (code) {\n            return MESSAGES.hasOwnProperty(code);\n        }\n    };\n});\n","Magento_Ui/js/lib/logger/console-logger.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    './logger',\n    './entry-factory',\n    './console-output-handler',\n    './formatter',\n    './message-pool',\n    './levels-pool',\n    'Magento_Ui/js/lib/core/storage/local',\n    'underscore',\n    './logger-utils'\n], function (Logger, entryFactory, ConsoleHandler, Formatter, messagePoll, levelsPoll, storage, _, LoggerUtils) {\n    'use strict';\n\n    var STORAGE_NAMESPACE = 'CONSOLE_LOGGER';\n\n    /**\n     * Singleton Logger's sub-class instance of which is configured to display its\n     * messages to the console. It also provides the support of predefined messages\n     * and persists its display level.\n     */\n    function ConsoleLogger() {\n        var formatter = new Formatter(),\n            consoleHandler = new ConsoleHandler(formatter),\n            savedLevel = storage.get(STORAGE_NAMESPACE),\n            utils = new LoggerUtils(this);\n\n        Logger.call(this, consoleHandler, entryFactory);\n\n        if (savedLevel) {\n            this.displayLevel_ = savedLevel;\n        }\n\n        this.utils = utils;\n        this.messages = messagePoll;\n        this.levels = levelsPoll.getLevels();\n    }\n\n    _.extend(ConsoleLogger, Logger);\n\n    ConsoleLogger.prototype = Object.create(Logger.prototype);\n    ConsoleLogger.prototype.constructor = ConsoleLogger;\n\n    /**\n     * Overrides parent method to save the provided display level.\n     *\n     * @override\n     */\n    ConsoleLogger.prototype.setDisplayLevel = function (level) {\n        Logger.prototype.setDisplayLevel.call(this, level);\n\n        storage.set(STORAGE_NAMESPACE, level);\n    };\n\n    /**\n     * Adds the support of predefined messages.\n     *\n     * @protected\n     * @override\n     */\n    ConsoleLogger.prototype.createEntry_ = function (message, level, data) {\n        var code;\n\n        if (messagePoll.hasMessage(message)) {\n            data = data || {};\n            code = message;\n            message = messagePoll.getMessage(code);\n\n            data.messageCode = code;\n        }\n\n        return Logger.prototype.createEntry_.call(this, message, level, data);\n    };\n\n    return new ConsoleLogger();\n});\n","Magento_Ui/js/lib/logger/formatter.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'moment',\n    'mage/utils/template'\n], function (moment, mageTemplate) {\n    'use strict';\n\n    /**\n     * @param {String} dateFormat\n     * @param {String} template\n     */\n    function LogFormatter(dateFormat, template) {\n        /**\n         * @protected\n         * @type {String}\n         */\n        this.dateFormat_ = 'YYYY-MM-DD hh:mm:ss';\n\n        /**\n         * @protected\n         * @type {String}\n         */\n        this.template_ = '[${ $.date }] [${ $.entry.levelName }] ${ $.message }';\n\n        if (dateFormat) {\n            this.dateFormat_ = dateFormat;\n        }\n\n        if (template) {\n            this.template_ = template;\n        }\n    }\n\n    /**\n     * @param {LogEntry} entry\n     * @returns {String}\n     */\n    LogFormatter.prototype.process = function (entry) {\n        var message = mageTemplate.template(entry.message, entry.data),\n            date = moment(entry.timestamp).format(this.dateFormat_);\n\n        return mageTemplate.template(this.template_, {\n            date: date,\n            entry: entry,\n            message: message\n        });\n    };\n\n    return LogFormatter;\n});\n","Magento_Ui/js/lib/logger/logger.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    './levels-pool'\n], function (logLevels) {\n    'use strict';\n\n    var levels = logLevels.getLevels();\n\n    /**\n     * @param {LogOutputHandler} outputHandler\n     * @param {LogEntryFactory} entryFactory\n     */\n    function Logger(outputHandler, entryFactory) {\n        /**\n         * An array of log entries.\n         *\n         * @protected\n         * @type {Array<LogEntry>}\n         */\n        this.entries_ = [];\n\n        /**\n         * Current display level.\n         *\n         * @protected\n         * @type {Number}\n         */\n        this.displayLevel_ = levels.ERROR;\n\n        /**\n         * An array of display criteria.\n         *\n         * @protected\n         * @type {Array<LogCriteria>}\n         */\n        this.displayCriteria_ = [];\n\n        /**\n         * @protected\n         * @type {LogEntryFactory}\n         */\n        this.entryFactory_ = entryFactory;\n\n        /**\n         * @protected\n         * @type {Array<LogOutputHandler>}\n         */\n        this.outputHandlers_ = [outputHandler];\n\n        this.addDisplayCriteria(this.matchesLevel_);\n    }\n\n    /**\n     * Swaps current display level with the provided one.\n     *\n     * @param {Number} level - Level's code.\n     */\n    Logger.prototype.setDisplayLevel = function (level) {\n        var levelName = logLevels.getNameByCode(level);\n\n        if (!levelName) {\n            throw new TypeError('The provided level is not defined in the levels list.');\n        }\n\n        this.displayLevel_ = level;\n    };\n\n    /**\n     * Sets up the criteria by which log entries will be filtered out from the output.\n     *\n     * @param {LogCriteria} criteria\n     */\n    Logger.prototype.addDisplayCriteria = function (criteria) {\n        this.displayCriteria_.push(criteria);\n    };\n\n    /**\n     * Removes previously defined criteria.\n     *\n     * @param {LogCriteria} criteria\n     */\n    Logger.prototype.removeDisplayCriteria = function (criteria) {\n        var index = this.displayCriteria_.indexOf(criteria);\n\n        if (~index) {\n            this.displayCriteria_.splice(index, 1);\n        }\n    };\n\n    /**\n     * @param {String} message\n     * @param {Object} [messageData]\n     * @returns {LogEntry}\n     */\n    Logger.prototype.error = function (message, messageData) {\n        return this.log_(message, levels.ERROR, messageData);\n    };\n\n    /**\n     * @param {String} message\n     * @param {Object} [messageData]\n     * @returns {LogEntry}\n     */\n    Logger.prototype.warn = function (message, messageData) {\n        return this.log_(message, levels.WARN, messageData);\n    };\n\n    /**\n     * @param {String} message\n     * @param {Object} [messageData]\n     * @returns {LogEntry}\n     */\n    Logger.prototype.info = function (message, messageData) {\n        return this.log_(message, levels.INFO, messageData);\n    };\n\n    /**\n     * @param {String} message\n     * @param {Object} [messageData]\n     * @returns {LogEntry}\n     */\n    Logger.prototype.debug = function (message, messageData) {\n        return this.log_(message, levels.DEBUG, messageData);\n    };\n\n    /**\n     * @protected\n     * @param {String} message\n     * @param {Number} level\n     * @param {Object} [messageData]\n     * @returns {LogEntry}\n     */\n    Logger.prototype.log_ = function (message, level, messageData) {\n        var entry = this.createEntry_(message, level, messageData);\n\n        this.entries_.push(entry);\n\n        if (this.matchesCriteria_(entry)) {\n            this.processOutput_(entry);\n        }\n\n        return entry;\n    };\n\n    /**\n     * @protected\n     * @param {String} message\n     * @param {Number} level\n     * @param {Object} [messageData]\n     * @returns {LogEntry}\n     */\n    Logger.prototype.createEntry_ = function (message, level, messageData) {\n        return this.entryFactory_.createEntry(message, level, messageData);\n    };\n\n    /**\n     * Returns an array of log entries that have been added to the logger.\n     *\n     * @param {LogCriteria} [criteria] - Optional filter criteria.\n     * @returns {Array<LogEntry>}\n     */\n    Logger.prototype.getEntries = function (criteria) {\n        if (criteria) {\n            return this.entries_.filter(criteria);\n        }\n\n        return this.entries_;\n    };\n\n    /**\n     * @param {LogCriteria} [criteria]\n     */\n    Logger.prototype.dump = function (criteria) {\n        var entries;\n\n        if (!criteria) {\n            criteria = this.matchesCriteria_;\n        }\n\n        entries = this.entries_.filter(criteria, this);\n\n        this.outputHandlers_.forEach(function (handler) {\n            handler.dump(entries);\n        });\n    };\n\n    /**\n     * @protected\n     * @param {LogEntry} entry\n     */\n    Logger.prototype.processOutput_ = function (entry) {\n        this.outputHandlers_.forEach(function (handler) {\n            handler.show(entry);\n        });\n    };\n\n    /**\n     * @protected\n     * @param {LogEntry} entry\n     * @returns {Boolean}\n     */\n    Logger.prototype.matchesCriteria_ = function (entry) {\n        return this.displayCriteria_.every(function (criteria) {\n            return criteria.call(this, entry);\n        }, this);\n    };\n\n    /**\n     * Checks that the level of provided entry passes the \"displayLevel_\" threshold.\n     *\n     * @protected\n     * @param {LogEntry} entry - Entry to be checked.\n     * @returns {Boolean}\n     */\n    Logger.prototype.matchesLevel_ = function (entry) {\n        return entry.level <= this.displayLevel_;\n    };\n\n    return Logger;\n});\n","Magento_Ui/js/lib/registry/registry.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'underscore'\n], function ($, _) {\n    'use strict';\n\n    var privateData = new WeakMap();\n\n    /**\n     * Extracts private item storage associated\n     * with a provided registry instance.\n     *\n     * @param {Object} container\n     * @returns {Object}\n     */\n    function getItems(container) {\n        return privateData.get(container).items;\n    }\n\n    /**\n     * Extracts private requests array associated\n     * with a provided registry instance.\n     *\n     * @param {Object} container\n     * @returns {Array}\n     */\n    function getRequests(container) {\n        return privateData.get(container).requests;\n    }\n\n    /**\n     * Wrapper function used for convenient access to the elements.\n     * See 'async' method for examples of usage and comparison\n     * with a regular 'get' method.\n     *\n     * @param {(String|Object|Function)} name - Key of the requested element.\n     * @param {Registry} registry - Instance of a registry\n     *      where to search for the element.\n     * @param {(Function|String)} [method] - Optional callback function\n     *      or a name of the elements' method which\n     *      will be invoked when element is available in registry.\n     * @returns {*}\n     */\n    function async(name, registry, method) {\n        var args = _.toArray(arguments).slice(3);\n\n        if (_.isString(method)) {\n            registry.get(name, function (component) {\n                component[method].apply(component, args);\n            });\n        } else if (_.isFunction(method)) {\n            registry.get(name, method);\n        } else if (!args.length) {\n            return registry.get(name);\n        }\n    }\n\n    /**\n     * Checks that every property of the query object\n     * is present and equal to the corresponding\n     * property in target object.\n     * Note that non-strict comparison is used.\n     *\n     * @param {Object} query - Query object.\n     * @param {Object} target - Target object.\n     * @returns {Boolean}\n     */\n    function compare(query, target) {\n        var matches = true,\n            index,\n            keys,\n            key;\n\n        if (!_.isObject(query) || !_.isObject(target)) {\n            return false;\n        }\n\n        keys = Object.getOwnPropertyNames(query);\n        index = keys.length;\n\n        while (matches && index--) {\n            key = keys[index];\n\n            /* eslint-disable eqeqeq */\n            if (target[key] != query[key]) {\n                matches = false;\n            }\n\n            /* eslint-enable eqeqeq */\n        }\n\n        return matches;\n    }\n\n    /**\n     * Explodes incoming string into object if\n     * string is defined as a set of key = value pairs.\n     *\n     * @param {(String|*)} query - String to be processed.\n     * @returns {Object|*} Either created object or an unmodified incoming\n     *      value if conversion was not possible.\n     * @example Sample conversions.\n     *      'key = value, key2 = value2'\n     *      => {key: 'value', key2: 'value2'}\n     */\n    function explode(query) {\n        var result = {},\n            index,\n            data;\n\n        if (typeof query !== 'string' || !~query.indexOf('=')) {\n            return query;\n        }\n\n        query = query.split(',');\n        index = query.length;\n\n        while (index--) {\n            data = query[index].split('=');\n\n            result[data[0].trim()] = data[1].trim();\n        }\n\n        return result;\n    }\n\n    /**\n     * Extracts items from the provided data object\n     * which matches specified search criteria.\n     *\n     * @param {Object} data - Data object where to perform a lookup.\n     * @param {(String|Object|Function)} query - Search criteria.\n     * @param {Boolean} findAll - Flag that defines whether to\n     *      search for all applicable items or to stop on a first found entry.\n     * @returns {Array|Object|*}\n     */\n    function find(data, query, findAll) {\n        var iterator,\n            item;\n\n        query = explode(query);\n\n        if (typeof query === 'string') {\n            item = data[query];\n\n            if (findAll) {\n                return item ? [item] : [];\n            }\n\n            return item;\n        }\n\n        iterator = !_.isFunction(query) ?\n            compare.bind(null, query) :\n            query;\n\n        return findAll ?\n            _.filter(data, iterator) :\n            _.find(data, iterator);\n    }\n\n    /**\n     * @constructor\n     */\n    function Registry() {\n        var data = {\n            items: {},\n            requests: []\n        };\n\n        this._updateRequests = _.debounce(this._updateRequests.bind(this), 10);\n        privateData.set(this, data);\n    }\n\n    Registry.prototype = {\n        constructor: Registry,\n\n        /**\n         * Retrieves item from registry which matches specified search criteria.\n         *\n         * @param {(Object|String|Function|Array)} query - Search condition (see examples).\n         * @param {Function} [callback] - Callback that will be invoked when\n         *      all of the requested items are available.\n         * @returns {*}\n         *\n         * @example Requesting item by it's name.\n         *      var obj = {index: 'test', sample: true};\n         *\n         *      registry.set('first', obj);\n         *      registry.get('first') === obj;\n         *      => true\n         *\n         * @example Requesting item with a specific properties.\n         *      registry.get('sample = 1, index = test') === obj;\n         *      => true\n         *      registry.get('sample = 0, index = foo') === obj;\n         *      => false\n         *\n         * @example Declaring search criteria as an object.\n         *      registry.get({sample: true}) === obj;\n         *      => true;\n         *\n         * @example Providing custom search handler.\n         *      registry.get(function (item) { return item.sample === true; }) === obj;\n         *      => true\n         *\n         * @example Sample asynchronous request declaration.\n         *      registry.get('index = test', function (item) {});\n         *\n         * @example Requesting multiple elements.\n         *      registry.set('second', {index: 'test2'});\n         *      registry.get(['first', 'second'], function (first, second) {});\n         */\n        get: function (query, callback) {\n            if (typeof callback !== 'function') {\n                return find(getItems(this), query);\n            }\n\n            this._addRequest(query, callback);\n        },\n\n        /**\n         * Sets provided item to the registry.\n         *\n         * @param {String} id - Item's identifier.\n         * @param {*} item - Item's data.\n         * returns {Registry} Chainable.\n         */\n        set: function (id, item) {\n            getItems(this)[id] = item;\n\n            this._updateRequests();\n\n            return this;\n        },\n\n        /**\n         * Removes specified item from registry.\n         * Note that search query is not applicable.\n         *\n         * @param {String} id - Item's identifier.\n         * @returns {Registry} Chainable.\n         */\n        remove: function (id) {\n            delete getItems(this)[id];\n\n            return this;\n        },\n\n        /**\n         * Retrieves a collection of elements that match\n         * provided search criteria.\n         *\n         * @param {(Object|String|Function)} query - Search query.\n         *      See 'get' method for the syntax examples.\n         * @returns {Array} Found elements.\n         */\n        filter: function (query) {\n            return find(getItems(this), query, true);\n        },\n\n        /**\n         * Checks that at least one element in collection\n         * matches provided search criteria.\n         *\n         * @param {(Object|String|Function)} query - Search query.\n         *      See 'get' method for the syntax examples.\n         * @returns {Boolean}\n         */\n        has: function (query) {\n            return !!this.get(query);\n        },\n\n        /**\n         * Checks that registry contains a provided item.\n         *\n         * @param {*} item - Item to be checked.\n         * @returns {Boolean}\n         */\n        contains: function (item) {\n            return _.contains(getItems(this), item);\n        },\n\n        /**\n         * Extracts identifier of an item if it's present in registry.\n         *\n         * @param {*} item - Item whose identifier will be extracted.\n         * @returns {String|Undefined}\n         */\n        indexOf: function (item) {\n            return _.findKey(getItems(this), function (elem) {\n                return item === elem;\n            });\n        },\n\n        /**\n         * Same as a 'get' method except that it returns\n         * a promise object instead of invoking provided callback.\n         *\n         * @param {(String|Function|Object|Array)} query - Search query.\n         *      See 'get' method for the syntax examples.\n         * @returns {jQueryPromise}\n         */\n        promise: function (query) {\n            var defer    = $.Deferred(),\n                callback = defer.resolve.bind(defer);\n\n            this.get(query, callback);\n\n            return defer.promise();\n        },\n\n        /**\n         * Creates a wrapper function over the provided search query\n         * in order to provide somehow more convenient access to the\n         * registry's items.\n         *\n         * @param {(String|Object|Function)} query - Search criteria.\n         *      See 'get' method for the syntax examples.\n         * @returns {Function}\n         *\n         * @example Comparison with a 'get' method on retrieving items.\n         *      var module = registry.async('name');\n         *\n         *      module();\n         *      => registry.get('name');\n         *\n         * @example Asynchronous request.\n         *      module(function (component) {});\n         *      => registry.get('name', function (component) {});\n         *\n         * @example Requesting item and invoking it's method with specified parameters.\n         *      module('trigger', true);\n         *      => registry.get('name', function (component) {\n         *          component.trigger(true);\n         *      });\n         */\n        async: function (query) {\n            return async.bind(null, query, this);\n        },\n\n        /**\n         * Creates new instance of a Registry.\n         *\n         * @returns {Registry} New instance.\n         */\n        create: function () {\n            return new Registry;\n        },\n\n        /**\n         * Adds new request to the queue or resolves it immediately\n         * if all of the required items are available.\n         *\n         * @private\n         * @param {(Object|String|Function|Array)} queries - Search criteria.\n         *      See 'get' method for the syntax examples.\n         * @param {Function} callback - Callback that will be invoked when\n         *      all of the requested items are available.\n         * @returns {Registry}\n         */\n        _addRequest: function (queries, callback) {\n            var request;\n\n            if (!Array.isArray(queries)) {\n                queries = queries ? [queries] : [];\n            }\n\n            request = {\n                queries: queries.map(explode),\n                callback: callback\n            };\n\n            this._canResolve(request) ?\n                this._resolveRequest(request) :\n                getRequests(this).push(request);\n\n            return this;\n        },\n\n        /**\n         * Updates requests list resolving applicable items.\n         *\n         * @private\n         * @returns {Registry} Chainable.\n         */\n        _updateRequests: function () {\n            getRequests(this)\n                .filter(this._canResolve, this)\n                .forEach(this._resolveRequest, this);\n\n            return this;\n        },\n\n        /**\n         * Resolves provided request invoking it's callback\n         * with items specified in query parameters.\n         *\n         * @private\n         * @param {Object} request - Request object.\n         * @returns {Registry} Chainable.\n         */\n        _resolveRequest: function (request) {\n            var requests = getRequests(this),\n                items    = request.queries.map(this.get, this),\n                index    = requests.indexOf(request);\n\n            request.callback.apply(null, items);\n\n            if (~index) {\n                requests.splice(index, 1);\n            }\n\n            return this;\n        },\n\n        /**\n         * Checks if provided request can be resolved.\n         *\n         * @private\n         * @param {Object} request - Request object.\n         * @returns {Boolean}\n         */\n        _canResolve: function (request) {\n            var queries = request.queries;\n\n            return queries.every(this.has, this);\n        }\n    };\n\n    return new Registry;\n});\n","Magento_Ui/js/lib/view/utils/dom-observer.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'underscore',\n    'domReady!'\n], function ($, _) {\n    'use strict';\n\n    var counter = 1,\n        watchers,\n        globalObserver,\n        disabledNodes = [];\n\n    watchers = {\n        selectors: {},\n        nodes: {}\n    };\n\n    /**\n     * Checks if node represents an element node (nodeType === 1).\n     *\n     * @param {HTMLElement} node\n     * @returns {Boolean}\n     */\n    function isElementNode(node) {\n        return node.nodeType === 1;\n    }\n\n    /**\n     * Extracts all child descendant\n     * elements of a specified node.\n     *\n     * @param {HTMLElement} node\n     * @returns {Array}\n     */\n    function extractChildren(node) {\n        var children = node.querySelectorAll('*');\n\n        return _.toArray(children);\n    }\n\n    /**\n     * Extracts node identifier. If ID is not specified,\n     * then it will be created for the provided node.\n     *\n     * @param {HTMLElement} node\n     * @returns {Number}\n     */\n    function getNodeId(node) {\n        var id = node._observeId;\n\n        if (!id) {\n            id = node._observeId = counter++;\n        }\n\n        return id;\n    }\n\n    /**\n     * Invokes callback passing node to it.\n     *\n     * @param {HTMLElement} node\n     * @param {Object} data\n     */\n    function trigger(node, data) {\n        var id = getNodeId(node),\n            ids = data.invoked;\n\n        if (_.contains(ids, id)) {\n            return;\n        }\n\n        data.callback(node);\n        data.invoked.push(id);\n    }\n\n    /**\n     * Adds node to the observer list.\n     *\n     * @param {HTMLElement} node\n     * @returns {Object}\n     */\n    function createNodeData(node) {\n        var nodes   = watchers.nodes,\n            id      = getNodeId(node);\n\n        nodes[id] = nodes[id] || {};\n\n        return nodes[id];\n    }\n\n    /**\n     * Returns data associated with a specified node.\n     *\n     * @param {HTMLElement} node\n     * @returns {Object|Undefined}\n     */\n    function getNodeData(node) {\n        var nodeId = node._observeId;\n\n        return watchers.nodes[nodeId];\n    }\n\n    /**\n     * Removes data associated with a specified node.\n     *\n     * @param {HTMLElement} node\n     */\n    function removeNodeData(node) {\n        var nodeId = node._observeId;\n\n        delete watchers.nodes[nodeId];\n    }\n\n    /**\n     * Adds removal listener for a specified node.\n     *\n     * @param {HTMLElement} node\n     * @param {Object} data\n     */\n    function addRemovalListener(node, data) {\n        var nodeData = createNodeData(node);\n\n        (nodeData.remove = nodeData.remove || []).push(data);\n    }\n\n    /**\n     * Adds listener for the nodes which matches specified selector.\n     *\n     * @param {String} selector - CSS selector.\n     * @param {Object} data\n     */\n    function addSelectorListener(selector, data) {\n        var storage = watchers.selectors;\n\n        (storage[selector] = storage[selector] || []).push(data);\n    }\n\n    /**\n     * Calls handlers associated with an added node.\n     * Adds listeners for the node removal.\n     *\n     * @param {HTMLElement} node - Added node.\n     */\n    function processAdded(node) {\n        _.each(watchers.selectors, function (listeners, selector) {\n            listeners.forEach(function (data) {\n                if (!data.ctx.contains(node) || !$(node, data.ctx).is(selector)) {\n                    return;\n                }\n\n                if (data.type === 'add') {\n                    trigger(node, data);\n                } else if (data.type === 'remove') {\n                    addRemovalListener(node, data);\n                }\n            });\n        });\n    }\n\n    /**\n     * Calls handlers associated with a removed node.\n     *\n     * @param {HTMLElement} node - Removed node.\n     */\n    function processRemoved(node) {\n        var nodeData    = getNodeData(node),\n            listeners   = nodeData && nodeData.remove;\n\n        if (!listeners) {\n            return;\n        }\n\n        listeners.forEach(function (data) {\n            trigger(node, data);\n        });\n\n        removeNodeData(node);\n    }\n\n    /**\n     * Removes all non-element nodes from provided array\n     * and appends to it descendant elements.\n     *\n     * @param {Array} nodes\n     * @returns {Array}\n     */\n    function formNodesList(nodes) {\n        var result = [],\n            children;\n\n        nodes = _.toArray(nodes).filter(isElementNode);\n\n        nodes.forEach(function (node) {\n            result.push(node);\n\n            children = extractChildren(node);\n            result   = result.concat(children);\n        });\n\n        return result;\n    }\n\n    /**\n     * Collects all removed and added nodes from\n     * mutation records into separate arrays\n     * while removing duplicates between both types of changes.\n     *\n     * @param {Array} mutations - An array of mutation records.\n     * @returns {Object} Object with 'removed' and 'added' nodes arrays.\n     */\n    function formChangesLists(mutations) {\n        var removed = [],\n            added = [];\n\n        mutations.forEach(function (record) {\n            removed = removed.concat(_.toArray(record.removedNodes));\n            added   = added.concat(_.toArray(record.addedNodes));\n        });\n\n        removed = removed.filter(function (node) {\n            var addIndex = added.indexOf(node),\n                wasAdded = !!~addIndex;\n\n            if (wasAdded) {\n                added.splice(addIndex, 1);\n            }\n\n            return !wasAdded;\n        });\n\n        return {\n            removed: formNodesList(removed),\n            added: formNodesList(added)\n        };\n    }\n\n    /**\n     * Verify if the DOM node is a child of a defined disabled node, if so we shouldn't observe provided mutation.\n     *\n     * @param {Object} mutation - a single mutation\n     * @returns {Boolean}\n     */\n    function shouldObserveMutation(mutation) {\n        var isDisabled;\n\n        if (disabledNodes.length > 0) {\n            // Iterate through the disabled nodes and determine if this mutation is occurring inside one of them\n            isDisabled = _.find(disabledNodes, function (node) {\n                return node === mutation.target || $.contains(node, mutation.target);\n            });\n\n            // If we find a matching node we should not observe the mutation\n            return !isDisabled;\n        }\n\n        return true;\n    }\n\n    /**\n     * Should we observe these mutations? Check the first and last mutation to determine if this is a disabled mutation,\n     * we check both the first and last in case one has been removed from the DOM during the process of the mutation.\n     *\n     * @param {Array} mutations - An array of mutation records.\n     * @returns {Boolean}\n     */\n    function shouldObserveMutations(mutations) {\n        var firstMutation,\n            lastMutation;\n\n        if (mutations.length > 0) {\n            firstMutation = mutations[0];\n            lastMutation = mutations[mutations.length - 1];\n\n            return shouldObserveMutation(firstMutation) && shouldObserveMutation(lastMutation);\n        }\n\n        return true;\n    }\n\n    globalObserver = new MutationObserver(function (mutations) {\n        var changes;\n\n        if (shouldObserveMutations(mutations)) {\n            changes = formChangesLists(mutations);\n\n            changes.removed.forEach(processRemoved);\n            changes.added.forEach(processAdded);\n        }\n    });\n\n    globalObserver.observe(document.body, {\n        subtree: true,\n        childList: true\n    });\n\n    return {\n        /**\n         * Disable a node from being observed by the mutations, you may want to disable specific aspects of the\n         * application which are heavy on DOM changes. The observer running on some actions could cause significant\n         * delays and degrade the performance of that specific part of the application exponentially.\n         *\n         * @param {HTMLElement} node - a HTML node within the document\n         */\n        disableNode: function (node) {\n            disabledNodes.push(node);\n        },\n\n        /**\n         * Adds listener for the appearance of nodes that matches provided\n         * selector and which are inside of the provided context. Callback will be\n         * also invoked on elements which a currently present.\n         *\n         * @param {String} selector - CSS selector.\n         * @param {Function} callback - Function that will invoked when node appears.\n         * @param {HTMLElement} [ctx=document.body] - Context inside of which to search for the node.\n         */\n        get: function (selector, callback, ctx) {\n            var data,\n                nodes;\n\n            data = {\n                ctx: ctx || document.body,\n                type: 'add',\n                callback: callback,\n                invoked: []\n            };\n\n            nodes = $(selector, data.ctx).toArray();\n\n            nodes.forEach(function (node) {\n                trigger(node, data);\n            });\n\n            addSelectorListener(selector, data);\n        },\n\n        /**\n         * Adds listener for the nodes removal.\n         *\n         * @param {(jQueryObject|HTMLElement|Array|String)} selector\n         * @param {Function} callback - Function that will invoked when node is removed.\n         * @param {HTMLElement} [ctx=document.body] - Context inside of which to search for the node.\n         */\n        remove: function (selector, callback, ctx) {\n            var nodes = [],\n                data;\n\n            data = {\n                ctx: ctx || document.body,\n                type: 'remove',\n                callback: callback,\n                invoked: []\n            };\n\n            if (typeof selector === 'object') {\n                nodes = !_.isUndefined(selector.length) ?\n                    _.toArray(selector) :\n                    [selector];\n            } else if (_.isString(selector)) {\n                nodes = $(selector, ctx).toArray();\n\n                addSelectorListener(selector, data);\n            }\n\n            nodes.forEach(function (node) {\n                addRemovalListener(node, data);\n            });\n        },\n\n        /**\n         * Removes listeners.\n         *\n         * @param {String} selector\n         * @param {Function} [fn]\n         */\n        off: function (selector, fn) {\n            var selectors = watchers.selectors,\n                listeners = selectors[selector];\n\n            if (selector && !fn) {\n                delete selectors[selector];\n            } else if (listeners && fn) {\n                selectors[selector] = listeners.filter(function (data) {\n                    return data.callback !== fn;\n                });\n            }\n        }\n    };\n});\n","Magento_Ui/js/lib/view/utils/bindings.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'ko',\n    'jquery',\n    'underscore'\n], function (ko, $, _) {\n    'use strict';\n\n    /**\n     * Checks if provided  value is a dom element.\n     *\n     * @param {*} node - Value to be checked.\n     * @returns {Boolean}\n     */\n    function isDomElement(node) {\n        return typeof node === 'object' && node.tagName && node.nodeType;\n    }\n\n    /**\n     * Removes from the provided array all non-root nodes located inside\n     * of the comment element as long as the closing comment tags.\n     *\n     * @param {(Array|ArrayLike)} nodes - An array of nodes to be processed.\n     * @returns {Array}\n     */\n    function normalize(nodes) {\n        var result;\n\n        nodes   = _.toArray(nodes);\n        result  = nodes.slice();\n\n        nodes.forEach(function (node) {\n            if (node.nodeType === 8) {\n                result = !ko.virtualElements.hasBindingValue(node) ?\n                    _.without(result, node) :\n                    _.difference(result, ko.virtualElements.childNodes(node));\n            }\n        });\n\n        return result;\n    }\n\n    /**\n     * Extends binding context of each item in the collection.\n     *\n     * @param {...Object} extenders - Multiple extender objects to be applied to the context.\n     * @returns {jQueryCollection} Chainable.\n     */\n    $.fn.extendCtx = function () {\n        var nodes       = normalize(this),\n            extenders   = _.toArray(arguments);\n\n        nodes.forEach(function (node) {\n            var ctx  = ko.contextFor(node),\n                data = [ctx].concat(extenders);\n\n            _.extend.apply(_, data);\n        });\n\n        return this;\n    };\n\n    /**\n     * Evaluates bindings specified in each DOM element of collection.\n     *\n     * @param {(HTMLElement|Object)} [ctx] - Context to use for bindings evaluation.\n     *      If not specified then current context of a collections' item will be used.\n     * @returns {jQueryCollection} Chainable.\n     */\n    $.fn.applyBindings = function (ctx) {\n        var nodes = normalize(this),\n            nodeCtx;\n\n        if (isDomElement(ctx)) {\n            ctx = ko.contextFor(ctx);\n        }\n\n        nodes.forEach(function (node) {\n            nodeCtx = ctx || ko.contextFor(node);\n\n            ko.applyBindings(nodeCtx, node);\n        });\n\n        return this;\n    };\n\n    /**\n     * Adds specified bindings to each DOM element in\n     * collection and evaluates them with provided context.\n     *\n     * @param {(Object|Function)} data - Either bindings object or a function\n     *      which returns bindings data for each element in collection.\n     * @param {(HTMLElement|Object)} [ctx] - Context to use for bindings evaluation.\n     *      If not specified then current context of a collections' item will be used.\n     * @returns {jQueryCollection} Chainable.\n     */\n    $.fn.bindings = function (data, ctx) {\n        var nodes    = normalize(this),\n            bindings = data,\n            nodeCtx;\n\n        if (isDomElement(ctx)) {\n            ctx = ko.contextFor(ctx);\n        }\n\n        nodes.forEach(function (node) {\n            nodeCtx = ctx || ko.contextFor(node);\n\n            if (_.isFunction(data)) {\n                bindings = data(nodeCtx, node);\n            }\n\n            ko.applyBindingsToNode(node, bindings, nodeCtx);\n        });\n\n        return this;\n    };\n});\n","Magento_Ui/js/lib/view/utils/raf.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([], function () {\n    'use strict';\n\n    var processMap = new WeakMap(),\n        origRaf,\n        raf;\n\n    origRaf = window.requestAnimationFrame ||\n        window.webkitRequestAnimationFrame ||\n        window.mozRequestAnimationFrame ||\n        window.onRequestAnimationFrame ||\n        window.msRequestAnimationFrame ||\n        function (callback) {\n            if (typeof callback != 'function') {\n                throw new Error('raf argument \"callback\" must be of type function');\n            }\n            window.setTimeout(callback, 1000 / 60);\n        };\n\n    /**\n     * Creates new process object or extracts the\n     * the existing one.\n     *\n     * @param {*} id - Process identifier.\n     * @param {Number} fps - Required FPS count.\n     * @returns {Object}\n     */\n    function getProcess(id, fps) {\n        var process = processMap.get(id);\n\n        if (!process) {\n            process = {};\n            processMap.set(id, process);\n        }\n\n        if (process.fps !== fps) {\n            process.fps        = fps;\n            process.interval   = 1000 / fps;\n            process.update     = Date.now();\n        }\n\n        return process;\n    }\n\n    /**\n     * Proxy method which delegates call to the 'requestAnimationFrame'\n     * function and optionally can keep track of the FPS with which\n     * provided function is called.\n     *\n     * @param {Function} callback - Callback function to be passed to 'requestAnimationFrame'.\n     * @param {Number} [fps] - If specified, will update FPS counter for the provided function.\n     * @returns {Number|Boolean} ID of request or a flag which indicates\n     *      whether callback fits specified FPS.\n     */\n    raf = function (callback, fps) {\n        var rafId = origRaf(callback);\n\n        return fps ? raf.tick(callback, fps) : rafId;\n    };\n\n    /**\n     * Updates FPS counter for the specified process\n     * and returns a flag which indicates whether\n     * counter value is equal or greater than the required FPS.\n     *\n     * @param {*} id - Process identifier.\n     * @param {Number} fps - Required FPS count.\n     * @returns {Boolean}\n     */\n    raf.tick = function (id, fps) {\n        var process  = getProcess(id, fps),\n            now      = Date.now(),\n            delta    = now - process.update,\n            interval = process.interval;\n\n        if (fps >= 60 || delta >= interval) {\n            process.update = now - delta % interval;\n\n            return true;\n        }\n\n        return false;\n    };\n\n    return raf;\n});\n","Magento_Ui/js/lib/view/utils/async.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'ko',\n    'jquery',\n    'underscore',\n    'uiRegistry',\n    './dom-observer',\n    'Magento_Ui/js/lib/knockout/extender/bound-nodes',\n    './bindings'\n], function (ko, $, _, registry, domObserver, boundedNodes) {\n    'use strict';\n\n    /**\n     * Checks if provided value is a dom element.\n     *\n     * @param {*} node - Value to be checked.\n     * @returns {Boolean}\n     */\n    function isDomElement(node) {\n        return typeof node === 'object' && node.tagName && node.nodeType;\n    }\n\n    /**\n     * Parses provided string and extracts\n     * component, context and selector data from it.\n     *\n     * @param {String} str - String to be processed.\n     * @returns {Object} Data retrieved from string.\n     *\n     * @example Sample format.\n     *      '{{component}}:{{ctx}} -> {{selector}}'\n     *\n     *      component - Name of component.\n     *      ctx - Selector of the root node upon which component is binded.\n     *      selector - Selector of DOM elements located\n     *          inside of a previously specified context.\n     */\n    function parseSelector(str) {\n        var data    = str.trim().split('->'),\n            result  = {},\n            componentData;\n\n        if (data.length === 1) {\n            if (!~data[0].indexOf(':')) {\n                result.selector = data[0];\n            } else {\n                componentData = data[0];\n            }\n        } else {\n            componentData   = data[0];\n            result.selector = data[1];\n        }\n\n        if (componentData) {\n            componentData = componentData.split(':');\n\n            result.component = componentData[0];\n            result.ctx = componentData[1];\n        }\n\n        _.each(result, function (value, key) {\n            result[key] = value.trim();\n        });\n\n        return result;\n    }\n\n    /**\n     * Internal method used to normalize argumnets passed\n     * to 'async' module methods.\n     *\n     * @param {(String|Object)} selector\n     * @param {(HTMLElement|Object|String)} [ctx]\n     * @returns {Object}\n     */\n    function parseData(selector, ctx) {\n        var data = {};\n\n        if (arguments.length === 2) {\n            data.selector = selector;\n\n            if (isDomElement(ctx)) {\n                data.ctx = ctx;\n            } else {\n                data.component = ctx;\n                data.ctx = '*';\n            }\n        } else {\n            data = _.isString(selector) ?\n                parseSelector(selector) :\n                selector;\n        }\n\n        return data;\n    }\n\n    /**\n     * Creates promise that will be resolved\n     * when requested component is registred.\n     *\n     * @param {String} name - Name of component.\n     * @returns {jQueryPromise}\n     */\n    function waitComponent(name) {\n        var deffer = $.Deferred();\n\n        if (_.isString(name)) {\n            registry.get(name, function (component) {\n                deffer.resolve(component);\n            });\n        } else {\n            deffer.resolve(name);\n        }\n\n        return deffer.promise();\n    }\n\n    /**\n     * Creates listener for the nodes binded to provided component.\n     *\n     * @param {Object} data - Listener data.\n     * @param {Object} component - Associated with nodes component.\n     */\n    function setRootListener(data, component) {\n        boundedNodes.get(component, function (root) {\n            if (!$(root).is(data.ctx || '*')) {\n                return;\n            }\n\n            data.selector ?\n                domObserver.get(data.selector, data.fn, root) :\n                data.fn(root);\n        });\n    }\n\n    /*eslint-disable no-unused-vars*/\n    /**\n     * Sets listener for the appearance of elements which\n     * matches specified selector data.\n     *\n     * @param {(String|Object)} selector - Valid css selector or a string\n     *      in format acceptable by 'parseSelector' method or an object with\n     *      'component', 'selector' and 'ctx' properties.\n     * @param {(HTMLElement|Object|String)} [ctx] - Optional context parameter\n     *      which might be a DOM element, component instance or components' name.\n     * @param {Function} fn - Callback that will be invoked\n     *      when required DOM element appears.\n     *\n     * @example\n     *      Creating listener of the 'span' nodes appearance,\n     *      located inside of 'div' nodes, which are binded to 'cms_page_listing' component:\n     *\n     *      $.async('cms_page_listing:div -> span', function (node) {});\n     *\n     * @example Another syntaxes of the previous example.\n     *      $.async({\n     *          component: 'cms_page_listing',\n     *          ctx: 'div',\n     *          selector: 'span'\n     *       }, function (node) {});\n     *\n     * @example Listens for appearance of any child node inside of specified component.\n     *      $.async('> *', 'cms_page_lsiting', function (node) {});\n     *\n     * @example Listens for appearance of 'span' nodes inside of specific context.\n     *      $.async('span', document.getElementById('test'), function (node) {});\n     */\n    $.async = function (selector, ctx, fn) {\n        var args = _.toArray(arguments),\n            data = parseData.apply(null, _.initial(args));\n\n        data.fn = _.last(args);\n\n        if (data.component) {\n            waitComponent(data.component)\n                .then(setRootListener.bind(null, data));\n        } else {\n            domObserver.get(data.selector, data.fn, data.ctx);\n        }\n    };\n\n    /*eslint-enable no-unused-vars*/\n\n    _.extend($.async, {\n\n        /*eslint-disable no-unused-vars*/\n        /**\n         * Returns collection of elements found by provided selector data.\n         *\n         * @param {(String|Object)} selector - See 'async' definition.\n         * @param {(HTMLElement|Object|String)} [ctx] - See 'async' definition.\n         * @returns {Array} An array of DOM elements.\n         */\n        get: function (selector, ctx) {\n            var data        = parseData.apply(null, arguments),\n                component   = data.component,\n                nodes;\n\n            if (!component) {\n                return $(data.selector, data.ctx).toArray();\n            } else if (_.isString(component)) {\n                component = registry.get(component);\n            }\n\n            if (!component) {\n                return [];\n            }\n\n            nodes = boundedNodes.get(component);\n            nodes = $(nodes).filter(data.ctx).toArray();\n\n            return data.selector ?\n                $(data.selector, nodes).toArray() :\n                nodes;\n        },\n\n        /*eslint-enable no-unused-vars*/\n\n        /**\n         * Sets removal listener of the specified nodes.\n         *\n         * @param {(HTMLElement|Array|ArrayLike)} nodes - Nodes whose removal to track.\n         * @param {Function} fn - Callback that will be invoked when node is removed.\n         */\n        remove: function (nodes, fn) {\n            domObserver.remove(nodes, fn);\n        },\n\n        parseSelector: parseSelector\n    });\n\n    return $;\n});\n","Magento_Ui/js/lib/knockout/bootstrap.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/** Loads all available knockout bindings, sets custom template engine, initializes knockout on page */\n\ndefine([\n    'ko',\n    './template/engine',\n    'knockoutjs/knockout-es5',\n    './bindings/bootstrap',\n    './extender/observable_array',\n    './extender/bound-nodes',\n    'domReady!'\n], function (ko, templateEngine) {\n    'use strict';\n\n    ko.uid = 0;\n\n    ko.setTemplateEngine(templateEngine);\n    ko.applyBindings();\n});\n","Magento_Ui/js/lib/knockout/template/loader.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery'\n], function ($) {\n    'use strict';\n\n    var licenseRegExp   = /<!--[\\s\\S]*?-->/,\n        defaultPlugin   = 'text',\n        defaultExt      = 'html';\n\n    /**\n     * Checks of provided string contains a file extension.\n     *\n     * @param {String} str - String to be checked.\n     * @returns {Boolean}\n     */\n    function hasFileExtension(str) {\n        return !!~str.indexOf('.') && !!str.split('.').pop();\n    }\n\n    /**\n     * Checks if provided string contains a requirejs's plugin reference.\n     *\n     * @param {String} str - String to be checked.\n     * @returns {Boolean}\n     */\n    function hasPlugin(str) {\n        return !!~str.indexOf('!');\n    }\n\n    /**\n     * Checks if provided string is a full path to the file.\n     *\n     * @param {String} str - String to be checked.\n     * @returns {Boolean}\n     */\n    function isFullPath(str) {\n        return !!~str.indexOf('://');\n    }\n\n    /**\n     * Removes license comment from the provided string.\n     *\n     * @param {String} content - String to be processed.\n     * @returns {String}\n     */\n    function removeLicense(content) {\n        return content.replace(licenseRegExp, function (match) {\n            return ~match.indexOf('/**') ? '' : match;\n        });\n    }\n\n    return {\n\n        /**\n         * Attempts to extract template by provided path from\n         * a DOM element and falls back to a file loading if\n         * none of the DOM nodes was found.\n         *\n         * @param {String} path - Path to the template or a DOM selector.\n         * @returns {jQueryPromise}\n         */\n        loadTemplate: function (path) {\n            var content = this.loadFromNode(path),\n                defer;\n\n            if (content) {\n                defer = $.Deferred();\n\n                defer.resolve(content);\n\n                return defer.promise();\n            }\n\n            return this.loadFromFile(path);\n        },\n\n        /**\n         * Loads template from external file by provided\n         * path, which will be preliminary formatted.\n         *\n         * @param {String} path - Path to the template.\n         * @returns {jQueryPromise}\n         */\n        loadFromFile: function (path) {\n            var loading = $.Deferred();\n\n            path = this.formatPath(path);\n\n            require([path], function (template) {\n                template = removeLicense(template);\n                loading.resolve(template);\n            }, function (err) {\n                loading.reject(err);\n            });\n\n            return loading.promise();\n        },\n\n        /**\n         * Attempts to extract content of a node found by provided selector.\n         *\n         * @param {String} selector - Node's selector (not necessary valid).\n         * @returns {String|Boolean} If specified node doesn't exists\n         *      'false' will be returned, otherwise returns node's content.\n         */\n        loadFromNode: function (selector) {\n            var node;\n\n            try {\n                node =\n                    document.getElementById(selector) ||\n                    document.querySelector(selector);\n\n                return node ? node.innerHTML : false;\n            } catch (e) {\n                return false;\n            }\n        },\n\n        /**\n         * Adds requirejs's plugin and file extension to\n         * to the provided string if it's necessary.\n         *\n         * @param {String} path - Path to be processed.\n         * @returns {String} Formatted path.\n         */\n        formatPath: function (path) {\n            var result = path;\n\n            if (!hasPlugin(path)) {\n                result = defaultPlugin + '!' + result;\n            }\n\n            if (isFullPath(path)) {\n                return result;\n            }\n\n            if (!hasFileExtension(path)) {\n                result += '.' + defaultExt;\n            }\n\n            return result.replace(/^([^\\/]+)/g, '$1/template');\n        }\n    };\n});\n","Magento_Ui/js/lib/knockout/template/engine.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'ko',\n    'underscore',\n    './observable_source',\n    './renderer',\n    '../../logger/console-logger'\n], function ($, ko, _, Source, renderer, consoleLogger) {\n    'use strict';\n\n    var RemoteTemplateEngine,\n        NativeTemplateEngine = ko.nativeTemplateEngine,\n        sources = {};\n\n    /**\n     * Remote template engine class. Is used to be able to load remote templates via knockout template binding.\n     */\n    RemoteTemplateEngine = function () {\n        // Instance reference for closure.\n        var engine = this,\n        // Decorate the builtin Knockout \"template\" binding to track synchronous template renders.\n        origUpdate = ko.bindingHandlers.template.update;\n\n        /**\n         * Counter to track the number of currently running render tasks (both synchronous and asynchronous).\n         * @type {Number}\n         * @private\n         */\n        this._rendersOutstanding = 0;\n\n        /**\n         * Use a jQuery object as an event bus (but any event emitter with on/off/emit methods could work)\n         * @type {jQuery}\n         * @private\n         */\n        this._events = $(this);\n\n        /**\n         * Rendered templates\n         * @type {Object}\n         * @private\n         */\n        this._templatesRendered = {};\n\n        /*eslint-disable no-unused-vars*/\n        /**\n         * Decorate update method\n         *\n         * @param {HTMLElement} element\n         * @param {Function} valueAccessor\n         * @param {Object} allBindings\n         * @param {Object} viewModel\n         * @param {ko.bindingContext} bindingContext\n         * @returns {*}\n         */\n        ko.bindingHandlers.template.update = function (element, valueAccessor, allBindings, viewModel, bindingContext) {\n            /*eslint-enable no-unused-vars*/\n            var options = ko.utils.peekObservable(valueAccessor()),\n                templateName,\n                isSync,\n                updated;\n\n            if (typeof options === 'object') {\n                if (options.templateEngine && options.templateEngine !== engine) {\n                    return origUpdate.apply(this, arguments);\n                }\n\n                if (!options.name) {\n                    consoleLogger.error('Could not find template name', options);\n                }\n                templateName = options.name;\n            } else if (typeof options === 'string') {\n                templateName = options;\n            } else {\n                consoleLogger.error('Could not build a template binding', options);\n            }\n            engine._trackRender(templateName);\n            isSync = engine._hasTemplateLoaded(templateName);\n            updated = origUpdate.apply(this, arguments);\n\n            if (isSync) {\n                engine._releaseRender(templateName, 'sync');\n            }\n\n            return updated;\n        };\n    };\n\n    /**\n     * Creates unique template identifier based on template name and it's extenders (optional)\n     * @param  {String} templateName\n     * @return {String} - unique template identifier\n     */\n    function createTemplateIdentifier(templateName) {\n        return templateName;\n    }\n\n    RemoteTemplateEngine.prototype = new NativeTemplateEngine;\n    RemoteTemplateEngine.prototype.constructor = RemoteTemplateEngine;\n\n    /**\n     * When an asynchronous render task begins, increment the internal counter for tracking when renders are complete.\n     * @private\n     */\n    RemoteTemplateEngine.prototype._trackRender = function (templateName) {\n        var rendersForTemplate = this._templatesRendered[templateName] !== undefined ?\n            this._templatesRendered[templateName] : 0;\n\n        this._rendersOutstanding++;\n        this._templatesRendered[templateName] = rendersForTemplate + 1;\n        this._resolveRenderWaits();\n    };\n\n    /**\n     * When an asynchronous render task ends, decrement the internal counter for tracking when renders are complete.\n     * @private\n     */\n    RemoteTemplateEngine.prototype._releaseRender = function (templateName) {\n        var rendersForTemplate = this._templatesRendered[templateName];\n\n        this._rendersOutstanding--;\n        this._templatesRendered[templateName] = rendersForTemplate - 1;\n        this._resolveRenderWaits();\n    };\n\n    /**\n     * Check to see if renders are complete and trigger events for listeners.\n     * @private\n     */\n    RemoteTemplateEngine.prototype._resolveRenderWaits = function () {\n        if (this._rendersOutstanding === 0) {\n            this._events.triggerHandler('finishrender');\n        }\n    };\n\n    /**\n     * Get a promise for the end of the current run of renders, both sync and async.\n     * @return {jQueryPromise} - promise that resolves when render completes\n     */\n    RemoteTemplateEngine.prototype.waitForFinishRender = function () {\n        var defer = $.Deferred();\n\n        this._events.one('finishrender', defer.resolve);\n\n        return defer.promise();\n    };\n\n    /**\n     * Returns true if this template has already been asynchronously loaded and will be synchronously rendered.\n     * @param {String} templateName\n     * @returns {Boolean}\n     * @private\n     */\n    RemoteTemplateEngine.prototype._hasTemplateLoaded = function (templateName) {\n        // Sources object will have cached template once makeTemplateSource has run\n        return sources.hasOwnProperty(templateName);\n    };\n\n    /**\n     * Overrided method of native knockout template engine.\n     * Caches template after it's unique name and renders in once.\n     * If template name is not typeof string, delegates work to knockout.templateSources.anonymousTemplate.\n     * @param  {*} template\n     * @param  {HTMLElement} templateDocument - document\n     * @param  {Object} options - options, passed to template binding\n     * @param  {ko.bindingContext} bindingContext\n     * @returns {TemplateSource} Object with methods 'nodes' and 'data'.\n     */\n    RemoteTemplateEngine.prototype.makeTemplateSource = function (template, templateDocument, options, bindingContext) {\n        var engine = this,\n            source,\n            templateId;\n\n        if (typeof template === 'string') {\n            templateId = createTemplateIdentifier(template);\n            source = sources[templateId];\n\n            if (!source) {\n                source = new Source(template);\n                source.requestedBy = bindingContext.$data.name;\n                sources[templateId] = source;\n\n                consoleLogger.info('templateStartLoading', {\n                    template: templateId,\n                    component: bindingContext.$data.name\n                });\n\n                renderer.render(template).then(function (rendered) {\n                    consoleLogger.info('templateLoadedFromServer', {\n                        template: templateId,\n                        component: bindingContext.$data.name\n                    });\n                    source.nodes(rendered);\n                    engine._releaseRender(templateId, 'async');\n                }).fail(function () {\n                    consoleLogger.error('templateLoadingFail', {\n                        template: templateId,\n                        component: bindingContext.$data.name\n                    });\n                });\n            }\n\n            if (source.requestedBy !== bindingContext.$data.name) {\n                consoleLogger.info('templateLoadedFromCache', {\n                    template: templateId,\n                    component: bindingContext.$data.name\n                });\n            }\n\n            return source;\n        } else if (template.nodeType === 1 || template.nodeType === 8) {\n            source = new ko.templateSources.anonymousTemplate(template);\n\n            return source;\n        }\n\n        throw new Error('Unknown template type: ' + template);\n    };\n\n    /**\n     * Overrided method of native knockout template engine.\n     * Should return array of html elements.\n     * @param  {TemplateSource} templateSource - object with methods 'nodes' and 'data'.\n     * @return {Array} - array of html elements\n     */\n    RemoteTemplateEngine.prototype.renderTemplateSource = function (templateSource) {\n        var nodes = templateSource.nodes();\n\n        return ko.utils.cloneNodes(nodes);\n    };\n\n    /**\n     * Overrided method of native knockout template engine.\n     * Created in order to invoke makeTemplateSource method with custom set of params.\n     * @param  {*} template - template identifier\n     * @param  {ko.bindingContext} bindingContext\n     * @param  {Object} options - options, passed to template binding\n     * @param  {HTMLElement} templateDocument - document\n     * @return {Array} - array of html elements\n     */\n    RemoteTemplateEngine.prototype.renderTemplate = function (template, bindingContext, options, templateDocument) {\n        var templateSource = this.makeTemplateSource(template, templateDocument, options, bindingContext);\n\n        return this.renderTemplateSource(templateSource);\n    };\n\n    return new RemoteTemplateEngine;\n});\n","Magento_Ui/js/lib/knockout/template/renderer.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'underscore',\n    './loader'\n], function ($, _, loader) {\n    'use strict';\n\n    var colonReg       = /\\\\:/g,\n        renderedTemplatePromises = {},\n        attributes     = {},\n        elements       = {},\n        globals        = [],\n        renderer,\n        preset;\n\n    renderer = {\n\n        /**\n         * Loads template by provided path and\n         * than converts it's content to html.\n         *\n         * @param {String} tmplPath - Path to the template.\n         * @returns {jQueryPromise}\n         * @alias getRendered\n         */\n        render: function (tmplPath) {\n            var cachedPromise = renderedTemplatePromises[tmplPath];\n\n            if (!cachedPromise) {\n                cachedPromise = renderedTemplatePromises[tmplPath] = loader\n                    .loadTemplate(tmplPath)\n                    .then(renderer.parseTemplate);\n            }\n\n            return cachedPromise;\n        },\n\n        /**\n         * @ignore\n         */\n        getRendered: function (tmplPath) {\n            return renderer.render(tmplPath);\n        },\n\n        /**\n         * Parses provided string as html content\n         * and returns an array of DOM elements.\n         *\n         * @param {String} html - String to be processed.\n         * @returns {Array}\n         */\n        parseTemplate: function (html) {\n            var fragment = document.createDocumentFragment();\n\n            $(fragment).append(html);\n\n            return renderer.normalize(fragment);\n        },\n\n        /**\n         * Processes custom attributes and nodes of provided DOM element.\n         *\n         * @param {HTMLElement} content - Element to be processed.\n         * @returns {Array} An array of content's child nodes.\n         */\n        normalize: function (content) {\n            globals.forEach(function (handler) {\n                handler(content);\n            });\n\n            return _.toArray(content.childNodes);\n        },\n\n        /**\n         * Adds new global content handler.\n         *\n         * @param {Function} handler - Function which will be invoked for\n         *      an every content passed to 'normalize' method.\n         * @returns {Renderer} Chainable.\n         */\n        addGlobal: function (handler) {\n            if (!_.contains(globals, handler)) {\n                globals.push(handler);\n            }\n\n            return this;\n        },\n\n        /**\n         * Removes specified global content handler.\n         *\n         * @param {Function} handler - Handler to be removed.\n         * @returns {Renderer} Chainable.\n         */\n        removeGlobal: function (handler) {\n            var index = globals.indexOf(handler);\n\n            if (~index) {\n                globals.splice(index, 1);\n            }\n\n            return this;\n        },\n\n        /**\n         * Adds new custom attribute handler.\n         *\n         * @param {String} id - Attribute identifier.\n         * @param {(Object|Function)} [config={}]\n         * @returns {Renderer} Chainable.\n         */\n        addAttribute: function (id, config) {\n            var data = {\n                name: id,\n                binding: id,\n                handler: renderer.handlers.attribute\n            };\n\n            if (_.isFunction(config)) {\n                data.handler = config;\n            } else if (_.isObject(config)) {\n                _.extend(data, config);\n            }\n\n            data.id = id;\n            attributes[id] = data;\n\n            return this;\n        },\n\n        /**\n         * Removes specified attribute handler.\n         *\n         * @param {String} id - Attribute identifier.\n         * @returns {Renderer} Chainable.\n         */\n        removeAttribute: function (id) {\n            delete attributes[id];\n\n            return this;\n        },\n\n        /**\n         * Adds new custom node handler.\n         *\n         * @param {String} id - Node identifier.\n         * @param {(Object|Function)} [config={}]\n         * @returns {Renderer} Chainable.\n         */\n        addNode: function (id, config) {\n            var data = {\n                name: id,\n                binding: id,\n                handler: renderer.handlers.node\n            };\n\n            if (_.isFunction(config)) {\n                data.handler = config;\n            } else if (_.isObject(config)) {\n                _.extend(data, config);\n            }\n\n            data.id = id;\n            elements[id] = data;\n\n            return this;\n        },\n\n        /**\n         * Removes specified custom node handler.\n         *\n         * @param {String} id - Node identifier.\n         * @returns {Renderer} Chainable.\n         */\n        removeNode: function (id) {\n            delete elements[id];\n\n            return this;\n        },\n\n        /**\n         * Checks if provided DOM element is a custom node.\n         *\n         * @param {HTMLElement} node - Node to be checked.\n         * @returns {Boolean}\n         */\n        isCustomNode: function (node) {\n            return _.some(elements, function (elem) {\n                return elem.name.toUpperCase() === node.tagName;\n            });\n        },\n\n        /**\n         * Processes custom attributes of a content's child nodes.\n         *\n         * @param {HTMLElement} content - DOM element to be processed.\n         */\n        processAttributes: function (content) {\n            var repeat;\n\n            repeat = _.some(attributes, function (attr) {\n                var attrName = attr.name,\n                    nodes    = content.querySelectorAll('[' + attrName + ']'),\n                    handler  = attr.handler;\n\n                return _.toArray(nodes).some(function (node) {\n                    var data = node.getAttribute(attrName);\n\n                    return handler(node, data, attr) === true;\n                });\n            });\n\n            if (repeat) {\n                renderer.processAttributes(content);\n            }\n        },\n\n        /**\n         * Processes custom nodes of a provided content.\n         *\n         * @param {HTMLElement} content - DOM element to be processed.\n         */\n        processNodes: function (content) {\n            var repeat;\n\n            repeat = _.some(elements, function (element) {\n                var nodes   = content.querySelectorAll(element.name),\n                    handler = element.handler;\n\n                return _.toArray(nodes).some(function (node) {\n                    var data = node.getAttribute('args');\n\n                    return handler(node, data, element) === true;\n                });\n            });\n\n            if (repeat) {\n                renderer.processNodes(content);\n            }\n        },\n\n        /**\n         * Wraps provided string in curly braces if it's necessary.\n         *\n         * @param {String} args - String to be wrapped.\n         * @returns {String} Wrapped string.\n         */\n        wrapArgs: function (args) {\n            if (~args.indexOf('\\\\:')) {\n                args = args.replace(colonReg, ':');\n            } else if (~args.indexOf(':') && !~args.indexOf('}')) {\n                args = '{' + args + '}';\n            }\n\n            return args;\n        },\n\n        /**\n         * Wraps child nodes of provided DOM element\n         * with knockout's comment tag.\n         *\n         * @param {HTMLElement} node - Node whose children should be wrapped.\n         * @param {String} binding - Name of the binding for the opener comment tag.\n         * @param {String} data - Data associated with a binding.\n         *\n         * @example\n         *      <div id=\"example\"><span/></div>\n         *      wrapChildren(document.getElementById('example'), 'foreach', 'data');\n         *      =>\n         *      <div id=\"example\">\n         *      <!-- ko foreach: data -->\n         *          <span></span>\n         *      <!-- /ko -->\n         *      </div>\n         */\n        wrapChildren: function (node, binding, data) {\n            var tag = this.createComment(binding, data),\n                $node = $(node);\n\n            $node.prepend(tag.open);\n            $node.append(tag.close);\n        },\n\n        /**\n         * Wraps specified node with knockout's comment tag.\n         *\n         * @param {HTMLElement} node - Node to be wrapped.\n         * @param {String} binding - Name of the binding for the opener comment tag.\n         * @param {String} data - Data associated with a binding.\n         *\n         * @example\n         *      <div id=\"example\"></div>\n         *      wrapNode(document.getElementById('example'), 'foreach', 'data');\n         *      =>\n         *      <!-- ko foreach: data -->\n         *          <div id=\"example\"></div>\n         *      <!-- /ko -->\n         */\n        wrapNode: function (node, binding, data) {\n            var tag = this.createComment(binding, data),\n                $node = $(node);\n\n            $node.before(tag.open);\n            $node.after(tag.close);\n        },\n\n        /**\n         * Creates knockouts' comment tag for the provided binding.\n         *\n         * @param {String} binding - Name of the binding.\n         * @param {String} data - Data associated with a binding.\n         * @returns {Object} Object with an open and close comment elements.\n         */\n        createComment: function (binding, data) {\n            return {\n                open: document.createComment(' ko ' + binding + ': ' + data + ' '),\n                close: document.createComment(' /ko ')\n            };\n        }\n    };\n\n    renderer.handlers = {\n\n        /**\n         * Basic node handler. Replaces custom nodes\n         * with a corresponding knockout's comment tag.\n         *\n         * @param {HTMLElement} node - Node to be processed.\n         * @param {String} data\n         * @param {Object} element\n         * @returns {Boolean} True\n         *\n         * @example Sample syntaxes conversions.\n         *      <with args=\"model\">\n         *          <span/>\n         *      </with>\n         *      =>\n         *      <!-- ko with: model-->\n         *          <span/>\n         *      <!-- /ko -->\n         */\n        node: function (node, data, element) {\n            data = renderer.wrapArgs(data);\n\n            renderer.wrapNode(node, element.binding, data);\n            $(node).replaceWith(node.childNodes);\n\n            return true;\n        },\n\n        /**\n         * Base attribute handler. Replaces custom attributes with\n         * a corresponding knockouts' data binding.\n         *\n         * @param {HTMLElement} node - Node to be processed.\n         * @param {String} data - Data associated with a binding.\n         * @param {Object} attr - Attribute definition.\n         *\n         * @example Sample syntaxes conversions.\n         *      <div text=\"label\"></div>\n         *      =>\n         *      <div data-bind=\"text: label\"></div>\n         */\n        attribute: function (node, data, attr) {\n            data = renderer.wrapArgs(data);\n\n            renderer.bindings.add(node, attr.binding, data);\n            node.removeAttribute(attr.name);\n        },\n\n        /**\n         * Wraps provided node with a knockouts' comment tag.\n         *\n         * @param {HTMLElement} node - Node that will be wrapped.\n         * @param {String} data - Data associated with a binding.\n         * @param {Object} attr - Attribute definition.\n         *\n         * @example\n         *      <div outereach=\"data\" class=\"test\"></div>\n         *      =>\n         *      <!-- ko foreach: data -->\n         *          <div class=\"test\"></div>\n         *      <!-- /ko -->\n         */\n        wrapAttribute: function (node, data, attr) {\n            data = renderer.wrapArgs(data);\n\n            renderer.wrapNode(node, attr.binding, data);\n            node.removeAttribute(attr.name);\n        }\n    };\n\n    renderer.bindings = {\n\n        /**\n         * Appends binding string to the current\n         * 'data-bind' attribute of provided node.\n         *\n         * @param {HTMLElement} node - DOM element whose 'data-bind' attribute will be extended.\n         * @param {String} name - Name of a binding.\n         * @param {String} data - Data associated with the binding.\n         */\n        add: function (node, name, data) {\n            var bindings = this.get(node);\n\n            if (bindings) {\n                bindings += ', ';\n            }\n\n            bindings += name;\n\n            if (data) {\n                bindings += ': ' + data;\n            }\n\n            this.set(node, bindings);\n        },\n\n        /**\n         * Extracts value of a 'data-bind' attribute from provided node.\n         *\n         * @param {HTMLElement} node - Node whose attribute to be extracted.\n         * @returns {String}\n         */\n        get: function (node) {\n            return node.getAttribute('data-bind') || '';\n        },\n\n        /**\n         * Sets 'data-bind' attribute of the specified node\n         * to the provided value.\n         *\n         * @param {HTMLElement} node - Node whose attribute will be altered.\n         * @param {String} bindings - New value of 'data-bind' attribute.\n         */\n        set: function (node, bindings) {\n            node.setAttribute('data-bind', bindings);\n        }\n    };\n\n    renderer\n        .addGlobal(renderer.processAttributes)\n        .addGlobal(renderer.processNodes);\n\n    /**\n     * Collection of default binding conversions.\n     */\n    preset = {\n        nodes: _.object([\n            'if',\n            'text',\n            'with',\n            'scope',\n            'ifnot',\n            'foreach',\n            'component'\n        ], Array.prototype),\n        attributes: _.object([\n            'css',\n            'attr',\n            'html',\n            'with',\n            'text',\n            'click',\n            'event',\n            'submit',\n            'enable',\n            'disable',\n            'options',\n            'visible',\n            'template',\n            'hasFocus',\n            'textInput',\n            'component',\n            'uniqueName',\n            'optionsText',\n            'optionsValue',\n            'checkedValue',\n            'selectedOptions'\n        ], Array.prototype)\n    };\n\n    _.extend(preset.attributes, {\n        if: renderer.handlers.wrapAttribute,\n        ifnot: renderer.handlers.wrapAttribute,\n        innerif: {\n            binding: 'if'\n        },\n        innerifnot: {\n            binding: 'ifnot'\n        },\n        outereach: {\n            binding: 'foreach',\n            handler: renderer.handlers.wrapAttribute\n        },\n        foreach: {\n            name: 'each'\n        },\n        value: {\n            name: 'ko-value'\n        },\n        style: {\n            name: 'ko-style'\n        },\n        checked: {\n            name: 'ko-checked'\n        },\n        disabled: {\n            name: 'ko-disabled',\n            binding: 'disable'\n        },\n        focused: {\n            name: 'ko-focused',\n            binding: 'hasFocus'\n        },\n\n        /**\n         * Custom 'render' attribute handler function. Wraps child elements\n         * of a node with knockout's 'ko template:' comment tag.\n         *\n         * @param {HTMLElement} node - Element to be processed.\n         * @param {String} data - Data specified in 'render' attribute of a node.\n         */\n        render: function (node, data) {\n            data = data || 'getTemplate()';\n            data = renderer.wrapArgs(data);\n\n            renderer.wrapChildren(node, 'template', data);\n            node.removeAttribute('render');\n        }\n    });\n\n    _.extend(preset.nodes, {\n        foreach: {\n            name: 'each'\n        },\n\n        /**\n         * Custom 'render' node handler function.\n         * Replaces node with knockout's 'ko template:' comment tag.\n         *\n         * @param {HTMLElement} node - Element to be processed.\n         * @param {String} data - Data specified in 'args' attribute of a node.\n         */\n        render: function (node, data) {\n            data = data || 'getTemplate()';\n            data = renderer.wrapArgs(data);\n\n            renderer.wrapNode(node, 'template', data);\n            $(node).replaceWith(node.childNodes);\n        }\n    });\n\n    _.each(preset.attributes, function (data, id) {\n        renderer.addAttribute(id, data);\n    });\n\n    _.each(preset.nodes, function (data, id) {\n        renderer.addNode(id, data);\n    });\n\n    return renderer;\n});\n","Magento_Ui/js/lib/knockout/template/observable_source.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/**\n * Is being used by knockout template engine to store template to.\n */\ndefine([\n    'ko',\n    'uiClass'\n], function (ko, Class) {\n    'use strict';\n\n    return Class.extend({\n\n        /**\n         * Initializes templateName, _data, nodes properties.\n         *\n         * @param  {template} template - identifier of template\n         */\n        initialize: function (template) {\n            this.templateName = template;\n            this._data = {};\n            this.nodes = ko.observable([]);\n        },\n\n        /**\n         * Data setter. If only one arguments passed, returns corresponding value.\n         * Else, writes into it.\n         * @param  {String} key - key to write to or to read from\n         * @param  {*} value\n         * @return {*} - if 1 arg provided, Returns _data[key] property\n         */\n        data: function (key, value) {\n            if (arguments.length === 1) {\n                return this._data[key];\n            }\n\n            this._data[key] = value;\n        }\n    });\n});\n","Magento_Ui/js/lib/knockout/bindings/mage-init.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'ko',\n    'underscore',\n    'mage/apply/main'\n], function (ko, _, mage) {\n    'use strict';\n\n    ko.bindingHandlers.mageInit = {\n        /**\n         * Initializes components assigned to HTML elements.\n         *\n         * @param {HTMLElement} el\n         * @param {Function} valueAccessor\n         */\n        init: function (el, valueAccessor) {\n            var data = valueAccessor();\n\n            _.each(data, function (config, component) {\n                mage.applyFor(el, config, component);\n            });\n        }\n    };\n});\n","Magento_Ui/js/lib/knockout/bindings/i18n.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'ko',\n    'module',\n    '../template/renderer',\n    'mage/translate'\n], function ($, ko, module, renderer) {\n    'use strict';\n\n    var locations = {\n            'legend': 'Caption for the fieldset element',\n            'label': 'Label for an input element.',\n            'button': 'Push button',\n            'a': 'Link label',\n            'b': 'Bold text',\n            'strong': 'Strong emphasized text',\n            'i': 'Italic text',\n            'em': 'Emphasized text',\n            'u': 'Underlined text',\n            'sup': 'Superscript text',\n            'sub': 'Subscript text',\n            'span': 'Span element',\n            'small': 'Smaller text',\n            'big': 'Bigger text',\n            'address': 'Contact information',\n            'blockquote': 'Long quotation',\n            'q': 'Short quotation',\n            'cite': 'Citation',\n            'caption': 'Table caption',\n            'abbr': 'Abbreviated phrase',\n            'acronym': 'An acronym',\n            'var': 'Variable part of a text',\n            'dfn': 'Term',\n            'strike': 'Strikethrough text',\n            'del': 'Deleted text',\n            'ins': 'Inserted text',\n            'h1': 'Heading level 1',\n            'h2': 'Heading level 2',\n            'h3': 'Heading level 3',\n            'h4': 'Heading level 4',\n            'h5': 'Heading level 5',\n            'h6': 'Heading level 6',\n            'center': 'Centered text',\n            'select': 'List options',\n            'img': 'Image',\n            'input': 'Form element'\n        },\n\n        /**\n         * Generates [data-translate] attribute's value\n         * @param {Object} translationData\n         * @param {String} location\n         */\n        composeTranslateAttr = function (translationData, location) {\n            var obj = [{\n                'shown': translationData.shown,\n                'translated': translationData.translated,\n                'original': translationData.original,\n                'location': locations[location] || 'Text'\n            }];\n\n            return JSON.stringify(obj);\n        },\n\n        /**\n         * Sets text for the element\n         * @param {Object} el\n         * @param {String} text\n         */\n        setText = function (el, text) {\n            $(el).text(text);\n        },\n\n        /**\n         * Sets [data-translate] attribute for the element\n         * @param {Object} el - The element which is binded\n         * @param {String} original - The original value of the element\n         */\n        setTranslateProp = function (el, original) {\n            var location = $(el).prop('tagName').toLowerCase(),\n                translated = $.mage.__(original),\n                translationData = {\n                    shown: translated,\n                    translated: translated,\n                    original: original\n                },\n                translateAttr = composeTranslateAttr(translationData, location);\n\n            $(el).attr('data-translate', translateAttr);\n\n            setText(el, translationData.shown);\n        },\n\n        /**\n         * Checks if node represents ko virtual node (nodeType === 8, nodeName === '#comment').\n         *\n         * @param {HTMLElement} node\n         * @returns {Boolean}\n         */\n        isVirtualElement = function (node) {\n            return node.nodeType === 8;\n        },\n\n        /**\n        * Checks if it's real DOM element\n        * in case of virtual element, returns span wrapper\n        * @param {Object} el\n        * @param {bool} isUpdate\n        * @return {Object} el\n        */\n        getRealElement = function (el, isUpdate) {\n            if (isVirtualElement(el)) {\n                if (isUpdate) {\n                    return $(el).next('span');\n                }\n\n                return $('<span></span>').insertAfter(el);\n            }\n\n            return el;\n        },\n\n        /**\n         * execute i18n binding\n         * @param {Object} element\n         * @param {Function} valueAccessor\n         * @param {bool} isUpdate\n         */\n        execute = function (element, valueAccessor, isUpdate) {\n            var original = ko.unwrap(valueAccessor() || ''),\n                el = getRealElement(element, isUpdate),\n                inlineTranslation = (module.config() || {}).inlineTranslation;\n\n            if (inlineTranslation) {\n                setTranslateProp(el, original);\n            } else {\n                setText(el, $.mage.__(original));\n            }\n        };\n\n    /**\n     * i18n binding\n     * @property {Function}  init\n     * @property {Function}  update\n     */\n    ko.bindingHandlers.i18n = {\n\n        /**\n         * init i18n binding\n         * @param {Object} element\n         * @param {Function} valueAccessor\n         */\n        init: function (element, valueAccessor) {\n            execute(element, valueAccessor);\n        },\n\n        /**\n         * update i18n binding\n         * @param {Object} element\n         * @param {Function} valueAccessor\n         */\n        update: function (element, valueAccessor) {\n            execute(element, valueAccessor, true);\n        }\n    };\n\n    ko.virtualElements.allowedBindings.i18n = true;\n\n    renderer\n        .addNode('translate', {\n            binding: 'i18n'\n        })\n        .addAttribute('translate', {\n            binding: 'i18n'\n        });\n});\n","Magento_Ui/js/lib/knockout/bindings/color-picker.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'ko',\n    'jquery',\n    '../template/renderer',\n    'spectrum',\n    'tinycolor'\n], function (ko, $, renderer, spectrum, tinycolor) {\n    'use strict';\n\n    /**\n     * Change color picker status to be enabled or disabled\n     *\n     * @param {HTMLElement} element - Element to apply colorpicker enable/disable status to.\n     * @param {Object} viewModel - Object, which represents view model binded to el.\n     */\n    function changeColorPickerStateBasedOnViewModel(element, viewModel) {\n        $(element).spectrum(viewModel.disabled() ? 'disable' : 'enable');\n    }\n\n    ko.bindingHandlers.colorPicker = {\n        /**\n         * Binding init callback.\n         *\n         * @param {*} element\n         * @param {Function} valueAccessor\n         * @param {Function} allBindings\n         * @param {Object} viewModel\n         */\n        init: function (element, valueAccessor, allBindings, viewModel) {\n            var config = valueAccessor(),\n\n                /** change value */\n                changeValue = function (value) {\n                    if (value == null) {\n                        value = '';\n                    }\n                    config.value(value.toString());\n                };\n\n            config.change = changeValue;\n\n            config.hide = changeValue;\n\n            /** show value */\n            config.show = function () {\n                if (!viewModel.focused()) {\n                    viewModel.focused(true);\n                }\n\n                return true;\n            };\n\n            $(element).spectrum(config);\n\n            changeColorPickerStateBasedOnViewModel(element, viewModel);\n        },\n\n        /**\n         * Reads params passed to binding, parses component declarations.\n         * Fetches for those found and attaches them to the new context.\n         *\n         * @param {HTMLElement} element - Element to apply bindings to.\n         * @param {Function} valueAccessor - Function that returns value, passed to binding.\n         * @param {Object} allBindings - Object, which represents all bindings applied to element.\n         * @param {Object} viewModel - Object, which represents view model binded to element.\n         */\n        update: function (element, valueAccessor, allBindings, viewModel) {\n            var config = valueAccessor();\n\n            /** Initialise value as empty if it is undefined when color picker input is reset **/\n            if (config.value() === undefined) {\n                config.value('');\n            }\n\n            if (tinycolor(config.value()).isValid() || config.value() === '') {\n                $(element).spectrum('set', config.value());\n\n                if (config.value() !== '') {\n                    config.value($(element).spectrum('get').toString());\n                }\n            }\n\n            changeColorPickerStateBasedOnViewModel(element, viewModel);\n        }\n    };\n\n    renderer.addAttribute('colorPicker');\n});\n","Magento_Ui/js/lib/knockout/bindings/bootstrap.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine(function (require) {\n    'use strict';\n\n    var renderer = require('../template/renderer');\n\n    renderer.addAttribute('repeat', renderer.handlers.wrapAttribute);\n\n    renderer.addAttribute('outerfasteach', {\n        binding: 'fastForEach',\n        handler: renderer.handlers.wrapAttribute\n    });\n\n    renderer\n        .addNode('repeat')\n        .addNode('fastForEach');\n\n    return {\n        resizable:      require('./resizable'),\n        i18n:           require('./i18n'),\n        scope:          require('./scope'),\n        range:          require('./range'),\n        mageInit:       require('./mage-init'),\n        keyboard:       require('./keyboard'),\n        optgroup:       require('./optgroup'),\n        afterRender:     require('./after-render'),\n        autoselect:     require('./autoselect'),\n        datepicker:     require('./datepicker'),\n        outerClick:     require('./outer_click'),\n        fadeVisible:    require('./fadeVisible'),\n        collapsible:    require('./collapsible'),\n        staticChecked:  require('./staticChecked'),\n        simpleChecked:  require('./simple-checked'),\n        bindHtml:       require('./bind-html'),\n        tooltip:        require('./tooltip'),\n        repeat:         require('knockoutjs/knockout-repeat'),\n        fastForEach:    require('knockoutjs/knockout-fast-foreach'),\n        colorPicker:    require('./color-picker')\n    };\n});\n","Magento_Ui/js/lib/knockout/bindings/fadeVisible.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'ko'\n], function ($, ko) {\n    'use strict';\n\n    ko.bindingHandlers.fadeVisible = {\n        /**\n         * Initially set the element to be instantly visible/hidden depending on the value.\n         *\n         * @param {HTMLElement} element\n         * @param {Function} valueAccessor\n         */\n        init: function (element, valueAccessor) {\n            var value = valueAccessor();\n\n            // Use \"unwrapObservable\" so we can handle values that may or may not be observable\n            $(element).toggle(ko.unwrap(value));\n        },\n\n        /**\n         * Whenever the value subsequently changes, slowly fade the element in or out.\n         *\n         * @param {HTMLElement} element\n         * @param {Function} valueAccessor\n         */\n        update: function (element, valueAccessor) {\n            var value = valueAccessor();\n\n            ko.unwrap(value) ? $(element).fadeIn() : $(element).fadeOut();\n        }\n    };\n});\n","Magento_Ui/js/lib/knockout/bindings/optgroup.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'ko',\n    'mageUtils'\n    ], function (ko, utils) {\n    'use strict';\n\n    var captionPlaceholder = {},\n        optgroupTmpl = '<optgroup label=\"${ $.label }\"></optgroup>',\n        nbspRe = /&nbsp;/g,\n        optionsText,\n        optionsValue,\n        optionTitle;\n\n    ko.bindingHandlers.optgroup = {\n        /**\n         * @param {*} element\n         */\n        init: function (element) {\n            if (ko.utils.tagNameLower(element) !== 'select') {\n                throw new Error('options binding applies only to SELECT elements');\n            }\n\n            // Remove all existing <option>s.\n            while (element.length > 0) {\n                element.remove(0);\n            }\n        },\n\n        /**\n         * @param {*} element\n         * @param {*} valueAccessor\n         * @param {*} allBindings\n         */\n        update: function (element, valueAccessor, allBindings) {\n            var selectWasPreviouslyEmpty = element.length === 0,\n                previousScrollTop = !selectWasPreviouslyEmpty && element.multiple ? element.scrollTop : null,\n                includeDestroyed = allBindings.get('optionsIncludeDestroyed'),\n                arrayToDomNodeChildrenOptions = {},\n                captionValue,\n                unwrappedArray = ko.utils.unwrapObservable(valueAccessor()),\n                filteredArray,\n                previousSelectedValues,\n                itemUpdate = false,\n                callback = setSelectionCallback,//eslint-disable-line no-use-before-define\n                nestedOptionsLevel = -1;\n\n            optionsText = ko.utils.unwrapObservable(allBindings.get('optionsText')) || 'text';\n            optionsValue = ko.utils.unwrapObservable(allBindings.get('optionsValue')) || 'value';\n            optionTitle = optionsText + 'title';\n\n            if (element.multiple) {\n                previousSelectedValues = ko.utils.arrayMap(\n                    selectedOptions(),//eslint-disable-line no-use-before-define\n                    ko.selectExtensions.readValue\n                );\n            } else {\n                previousSelectedValues = element.selectedIndex >= 0 ?\n                    [ko.selectExtensions.readValue(element.options[element.selectedIndex])] :\n                    [];\n            }\n\n            if (unwrappedArray) {\n                if (typeof unwrappedArray.length === 'undefined') { // Coerce single value into array\n                    unwrappedArray = [unwrappedArray];\n                }\n\n                // Filter out any entries marked as destroyed\n                filteredArray = ko.utils.arrayFilter(unwrappedArray, function (item) {\n                    if (item && !item.label) {\n                        return false;\n                    }\n\n                    return includeDestroyed ||\n                        item === undefined ||\n                        item === null ||\n                        !ko.utils.unwrapObservable(item._destroy);\n                });\n                filteredArray.map(recursivePathBuilder, null);//eslint-disable-line no-use-before-define\n            }\n\n            /**\n             * @param {*} option\n             */\n            arrayToDomNodeChildrenOptions.beforeRemove = function (option) {\n                element.removeChild(option);\n            };\n\n            if (allBindings.has('optionsAfterRender')) {\n\n                /**\n                 * @param {*} arrayEntry\n                 * @param {*} newOptions\n                 */\n                callback = function (arrayEntry, newOptions) {\n                    setSelectionCallback(arrayEntry, newOptions);//eslint-disable-line no-use-before-define\n                    ko.dependencyDetection.ignore(\n                        allBindings.get('optionsAfterRender'),\n                        null,\n                        [newOptions[0],\n                        arrayEntry !== captionPlaceholder ? arrayEntry : undefined]\n                    );\n                };\n            }\n\n            filteredArray = formatOptions(filteredArray);//eslint-disable-line no-use-before-define\n            ko.utils.setDomNodeChildrenFromArrayMapping(\n                element,\n                filteredArray,\n                optionNodeFromArray,//eslint-disable-line no-use-before-define\n                arrayToDomNodeChildrenOptions,\n                callback\n            );\n\n            ko.dependencyDetection.ignore(function () {\n                var selectionChanged;\n\n                if (allBindings.get('valueAllowUnset') && allBindings.has('value')) {\n                    // The model value is authoritative, so make sure its value is the one selected\n                    ko.selectExtensions.writeValue(\n                        element,\n                        ko.utils.unwrapObservable(allBindings.get('value')),\n                        true /* allowUnset */\n                    );\n                } else {\n                    // Determine if the selection has changed as a result of updating the options list\n                    if (element.multiple) {\n                        // For a multiple-select box, compare the new selection count to the previous one\n                        // But if nothing was selected before, the selection can't have changed\n                        selectionChanged = previousSelectedValues.length &&\n                            selectedOptions().length < //eslint-disable-line no-use-before-define\n                            previousSelectedValues.length;\n                    } else {\n                        // For a single-select box, compare the current value to the previous value\n                        // But if nothing was selected before or nothing is selected now,\n                        // just look for a change in selection\n                        selectionChanged = previousSelectedValues.length && element.selectedIndex >= 0 ?\n                            ko.selectExtensions.readValue(element.options[element.selectedIndex]) !==\n                            previousSelectedValues[0] : previousSelectedValues.length || element.selectedIndex >= 0;\n                    }\n\n                    // Ensure consistency between model value and selected option.\n                    // If the dropdown was changed so that selection is no longer the same,\n                    // notify the value or selectedOptions binding.\n                    if (selectionChanged) {\n                        ko.utils.triggerEvent(element, 'change');\n                    }\n                }\n            });\n\n            /*eslint-enable max-len, no-use-before-define*/\n\n            if (previousScrollTop && Math.abs(previousScrollTop - element.scrollTop) > 20) {\n                element.scrollTop = previousScrollTop;\n            }\n\n            /**\n             * @returns {*}\n             */\n            function selectedOptions() {\n                return ko.utils.arrayFilter(element.options, function (node) {\n                    return node.selected;\n                });\n            }\n\n            /**\n             * @param {*} object\n             * @param {*} predicate\n             * @param {*} defaultValue\n             * @returns {*}\n             */\n            function applyToObject(object, predicate, defaultValue) {\n                var predicateType = typeof predicate;\n\n                if (predicateType === 'function') {   // run it against the data value\n                    return predicate(object);\n                } else if (predicateType === 'string') { // treat it as a property name on the data value\n                    return object[predicate];\n                }\n\n                return defaultValue;\n            }\n\n            /**\n             * @param {*} obj\n             */\n            function recursivePathBuilder(obj) {\n\n                obj[optionTitle] = (this && this[optionTitle] ? this[optionTitle] + '/' : '') + obj[optionsText].trim();\n\n                if (Array.isArray(obj[optionsValue])) {\n                    obj[optionsValue].map(recursivePathBuilder, obj);\n                }\n            }\n\n            /**\n             * @param {Array} arrayEntry\n             * @param {*} oldOptions\n             * @returns {*[]}\n             */\n            function optionNodeFromArray(arrayEntry, oldOptions) {\n                var option;\n\n                if (oldOptions.length) {\n                    previousSelectedValues = oldOptions[0].selected ?\n                        [ko.selectExtensions.readValue(oldOptions[0])] : [];\n                    itemUpdate = true;\n                }\n\n                if (arrayEntry === captionPlaceholder) { // empty value, label === caption\n                    option = element.ownerDocument.createElement('option');\n                    ko.utils.setTextContent(option, allBindings.get('optionsCaption'));\n                    ko.selectExtensions.writeValue(option, undefined);\n                } else if (typeof arrayEntry[optionsValue] === 'undefined') { // empty value === optgroup\n                    if (arrayEntry.__disableTmpl) {\n                        option = '<optgroup label=\"' + arrayEntry[optionsText] + '\"></optgroup>';\n                    } else {\n                        option = utils.template(optgroupTmpl, {\n                            label: arrayEntry[optionsText],\n                            title: arrayEntry[optionsText + 'title']\n                        });\n                    }\n                    option = ko.utils.parseHtmlFragment(option)[0];\n\n                } else {\n                    option = element.ownerDocument.createElement('option');\n                    option.setAttribute('data-title', arrayEntry[optionsText + 'title']);\n                    ko.selectExtensions.writeValue(option, arrayEntry[optionsValue]);\n                    ko.utils.setTextContent(option, arrayEntry[optionsText]);\n                }\n\n                return [option];\n            }\n\n            /**\n             * @param {*} newOptions\n             */\n            function setSelectionCallback(newOptions) {\n                var isSelected;\n\n                // IE6 doesn't like us to assign selection to OPTION nodes before they're added to the document.\n                // That's why we first added them without selection. Now it's time to set the selection.\n                if (previousSelectedValues.length && newOptions.value) {\n                    isSelected = ko.utils.arrayIndexOf(\n                        previousSelectedValues,\n                        ko.selectExtensions.readValue(newOptions.value)\n                    ) >= 0;\n\n                    ko.utils.setOptionNodeSelectionState(newOptions.value, isSelected);\n\n                    // If this option was changed from being selected during a single-item update, notify the change\n                    if (itemUpdate && !isSelected) {\n                        ko.dependencyDetection.ignore(ko.utils.triggerEvent, null, [element, 'change']);\n                    }\n                }\n            }\n\n            /**\n             * @param {*} string\n             * @param {Number} times\n             * @returns {Array}\n             */\n            function strPad(string, times) {\n                return new Array(times + 1).join(string);\n            }\n\n            /**\n             * @param {*} options\n             * @returns {Array}\n             */\n            function formatOptions(options) {\n                var res = [];\n\n                nestedOptionsLevel++;\n\n                if (!nestedOptionsLevel) { // zero level\n                    // If caption is included, add it to the array\n                    if (allBindings.has('optionsCaption')) {\n                        captionValue = ko.utils.unwrapObservable(allBindings.get('optionsCaption'));\n                        // If caption value is null or undefined, don't show a caption\n                        if (//eslint-disable-line max-depth\n                            captionValue !== null &&\n                            captionValue !== undefined &&\n                            captionValue !== false\n                        ) {\n                            res.push(captionPlaceholder);\n                        }\n                    }\n                }\n\n                ko.utils.arrayForEach(options, function (option) {\n                    var value = applyToObject(option, optionsValue, option),\n                        label = applyToObject(option, optionsText, value) || '',\n                        disabled = applyToObject(option, 'disabled', false) || false,\n                        obj = {},\n                        space = '\\u2007\\u2007\\u2007';\n\n                    obj[optionTitle] = applyToObject(option, optionsText + 'title', value);\n\n                    if (disabled) {\n                        obj.disabled = disabled;\n                    }\n\n                    if (option.hasOwnProperty('__disableTmpl')) {\n                        obj.__disableTmpl = option.__disableTmpl;\n                    }\n\n                    label = label.replace(nbspRe, '').trim();\n\n                    if (Array.isArray(value)) {\n                        obj[optionsText] = strPad('&nbsp;', nestedOptionsLevel * 4) + label;\n                        res.push(obj);\n                        res = res.concat(formatOptions(value));\n                    } else {\n                        obj[optionsText] = strPad(space, nestedOptionsLevel * 2) + label;\n                        obj[optionsValue] = value;\n                        res.push(obj);\n                    }\n                });\n                nestedOptionsLevel--;\n\n                return res;\n            }\n        }\n    };\n});\n","Magento_Ui/js/lib/knockout/bindings/collapsible.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'ko',\n    'jquery',\n    'underscore',\n    '../template/renderer'\n], function (ko, $, _, renderer) {\n    'use strict';\n\n    var collapsible,\n        defaults;\n\n    defaults = {\n        closeOnOuter: true,\n        onTarget: false,\n        openClass: '_active',\n        as: '$collapsible'\n    };\n\n    collapsible = {\n\n        /**\n         * Sets 'opened' property to true.\n         */\n        open: function () {\n            this.opened(true);\n        },\n\n        /**\n         * Sets 'opened' property to false.\n         */\n        close: function () {\n            this.opened(false);\n        },\n\n        /**\n         * Toggles value of the 'opened' property.\n         */\n        toggle: function () {\n            this.opened(!this.opened());\n        }\n    };\n\n    /**\n     * Document click handler which in case if event target is not\n     * a descendant of provided container element, closes collapsible model.\n     *\n     * @param {HTMLElement} container\n     * @param {Object} model\n     * @param {EventObject} e\n     */\n    function onOuterClick(container, model, e) {\n        var target = e.target;\n\n        if (target !== container && !container.contains(target)) {\n            model.close();\n        }\n    }\n\n    /**\n     * Creates 'css' binding which toggles\n     * class specified in 'name' parameter.\n     *\n     * @param {Object} model\n     * @param {String} name\n     * @returns {Object}\n     */\n    function getClassBinding(model, name) {\n        var binding = {};\n\n        binding[name] = model.opened;\n\n        return {\n            css: binding\n        };\n    }\n\n    /**\n     * Prepares configuration for the binding based\n     * on a default properties and provided options.\n     *\n     * @param {Object} [options={}]\n     * @returns {Object} Complete instance configuration.\n     */\n    function buildConfig(options) {\n        if (typeof options !== 'object') {\n            options = {};\n        }\n\n        return _.extend({}, defaults, options);\n    }\n\n    ko.bindingHandlers.collapsible = {\n\n        /**\n         * Initializes 'collapsible' binding.\n         */\n        init: function (element, valueAccessor, allBindings, viewModel, bindingCtx) {\n            var $collapsible = Object.create(collapsible),\n                config = buildConfig(valueAccessor()),\n                outerClick,\n                bindings;\n\n            _.bindAll($collapsible, 'open', 'close', 'toggle');\n\n            $collapsible.opened = ko.observable(!!config.opened);\n\n            bindingCtx[config.as] = $collapsible;\n\n            if (config.closeOnOuter) {\n                outerClick = onOuterClick.bind(null, element, $collapsible);\n\n                $(document).on('click', outerClick);\n\n                ko.utils.domNodeDisposal.addDisposeCallback(element, function () {\n                    $(document).off('click', outerClick);\n                });\n            }\n\n            if (config.openClass) {\n                bindings = getClassBinding($collapsible, config.openClass);\n\n                ko.applyBindingsToNode(element, bindings, bindingCtx);\n            }\n\n            if (config.onTarget) {\n                $(element).on('click', $collapsible.toggle);\n            }\n\n            if (viewModel && _.isFunction(viewModel.on)) {\n                viewModel.on({\n                    close:          $collapsible.close,\n                    open:           $collapsible.open,\n                    toggleOpened:   $collapsible.toggle\n                });\n            }\n        }\n    };\n\n    ko.bindingHandlers.closeCollapsible = {\n\n        /**\n         * Creates listener for the click event on provided DOM element,\n         * which closes associated with it collapsible model.\n         */\n        init: function (element, valueAccessor, allBindings, viewModel, bindingCtx) {\n            var name = valueAccessor() || defaults.as,\n                $collapsible = bindingCtx[name];\n\n            if ($collapsible) {\n                $(element).on('click', $collapsible.close);\n            }\n        }\n    };\n\n    ko.bindingHandlers.openCollapsible = {\n\n        /**\n         * Creates listener for the click event on provided DOM element,\n         * which opens associated with it collapsible model.\n         */\n        init: function (element, valueAccessor, allBindings, viewModel, bindingCtx) {\n            var name = valueAccessor() || defaults.as,\n                $collapsible = bindingCtx[name];\n\n            if ($collapsible) {\n                $(element).on('click', $collapsible.open);\n            }\n        }\n    };\n\n    ko.bindingHandlers.toggleCollapsible = {\n\n        /**\n         * Creates listener for the click event on provided DOM element,\n         * which toggles associated with it collapsible model.\n         */\n        init: function (element, valueAccessor, allBindings, viewModel, bindingCtx) {\n            var name = valueAccessor() || defaults.as,\n                $collapsible = bindingCtx[name];\n\n            if ($collapsible) {\n                $(element).on('click', $collapsible.toggle);\n            }\n        }\n    };\n\n    renderer\n        .addAttribute('collapsible')\n        .addAttribute('openCollapsible')\n        .addAttribute('closeCollapsible')\n        .addAttribute('toggleCollapsible');\n});\n","Magento_Ui/js/lib/knockout/bindings/scope.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/** Creates scope binding and registers in to ko.bindingHandlers object */\ndefine([\n    'ko',\n    'uiRegistry',\n    'mage/translate',\n    '../template/renderer',\n    'jquery',\n    '../../logger/console-logger'\n], function (ko, registry, $t, renderer, $, consoleLogger) {\n    'use strict';\n\n    /**\n     * Creates child context with passed component param as $data. Extends context with $t helper.\n     * Applies bindings to descendant nodes.\n     * @param {HTMLElement} el - element to apply bindings to.\n     * @param {ko.bindingContext} bindingContext - instance of ko.bindingContext, passed to binding initially.\n     * @param {Promise} promise - instance of jQuery promise\n     * @param {Object} component - component instance to attach to new context\n     */\n    function applyComponents(el, bindingContext, promise, component) {\n        promise.resolve();\n        component = bindingContext.createChildContext(component);\n\n        ko.utils.extend(component, {\n            $t: $t\n        });\n\n        ko.utils.arrayForEach(ko.virtualElements.childNodes(el), ko.cleanNode);\n\n        ko.applyBindingsToDescendants(component, el);\n    }\n\n    ko.bindingHandlers.scope = {\n\n        /**\n         * Scope binding's init method.\n         * @returns {Object} - Knockout declaration for it to let binding control descendants.\n         */\n        init: function () {\n            return {\n                controlsDescendantBindings: true\n            };\n        },\n\n        /**\n         * Reads params passed to binding, parses component declarations.\n         * Fetches for those found and attaches them to the new context.\n         * @param {HTMLElement} el - Element to apply bindings to.\n         * @param {Function} valueAccessor - Function that returns value, passed to binding.\n         * @param {Object} allBindings - Object, which represents all bindings applied to element.\n         * @param {Object} viewModel - Object, which represents view model binded to el.\n         * @param {ko.bindingContext} bindingContext - Instance of ko.bindingContext, passed to binding initially.\n         */\n        update: function (el, valueAccessor, allBindings, viewModel, bindingContext) {\n            var component = valueAccessor(),\n                promise = $.Deferred(),\n                apply = applyComponents.bind(this, el, bindingContext, promise),\n                loggerUtils = consoleLogger.utils;\n\n            if (typeof component === 'string') {\n                loggerUtils.asyncLog(\n                    promise,\n                    {\n                        data: {\n                            component: component\n                        },\n                        messages: loggerUtils.createMessages(\n                            'requestingComponent',\n                            'requestingComponentIsLoaded',\n                            'requestingComponentIsFailed'\n                        )\n                    }\n                );\n\n                registry.get(component, apply);\n            } else if (typeof component === 'function') {\n                component(apply);\n            }\n        }\n    };\n\n    ko.virtualElements.allowedBindings.scope = true;\n\n    renderer\n        .addNode('scope')\n        .addAttribute('scope', {\n            name: 'ko-scope'\n        });\n});\n","Magento_Ui/js/lib/knockout/bindings/range.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'ko',\n    'jquery',\n    'underscore',\n    '../template/renderer'\n], function (ko, $, _, renderer) {\n    'use strict';\n\n    var isTouchDevice = !_.isUndefined(document.ontouchstart),\n        sliderFn = 'slider',\n        sliderModule = 'jquery-ui-modules/slider';\n\n    if (isTouchDevice) {\n        sliderFn = 'touchSlider';\n        sliderModule = 'mage/touch-slider';\n    }\n\n    ko.bindingHandlers.range = {\n\n        /**\n         * Initializes binding and a slider update.\n         *\n         * @param {HTMLElement} element\n         * @param {Function} valueAccessor\n         */\n        init: function (element, valueAccessor) {\n            var config  = valueAccessor(),\n                value   = config.value;\n\n            _.extend(config, {\n                value: value(),\n\n                /**\n                 * Callback which is being called when sliders' value changes.\n                 *\n                 * @param {Event} event\n                 * @param {Object} ui\n                 */\n                slide: function (event, ui) {\n                    value(ui.value);\n                }\n            });\n\n            require([sliderModule], function () {\n                $(element)[sliderFn](config);\n            });\n        },\n\n        /**\n         * Updates sliders' plugin configuration.\n         *\n         * @param {HTMLElement} element\n         * @param {Function} valueAccessor\n         */\n        update: function (element, valueAccessor) {\n            var config = valueAccessor();\n\n            config.value = ko.unwrap(config.value);\n\n            require([sliderModule], function () {\n                $(element)[sliderFn]('option', config);\n            });\n        }\n    };\n\n    renderer.addAttribute('range');\n});\n","Magento_Ui/js/lib/knockout/bindings/simple-checked.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'ko',\n    '../template/renderer'\n], function (ko, renderer) {\n    'use strict';\n\n    ko.bindingHandlers.simpleChecked = {\n        'after': ['attr'],\n\n        /**\n         * Implements same functionality as a standard 'simpleChecked' binding,\n         * but with a difference that it wont' change values array if\n         * value of DOM element changes.\n         */\n        init: function (element, valueAccessor) {\n            var isCheckbox = element.type === 'checkbox',\n                isRadio = element.type === 'radio',\n                updateView,\n                updateModel;\n\n            if (!isCheckbox && !isRadio) {\n                return;\n            }\n\n            /**\n             * Updates checked observable\n             */\n            updateModel = function () {\n                var  modelValue = ko.dependencyDetection.ignore(valueAccessor),\n                    isChecked = element.checked;\n\n                if (ko.computedContext.isInitial()) {\n                    return;\n                }\n\n                if (modelValue.peek() === isChecked) {\n                    return;\n                }\n\n                if (isRadio && !isChecked) {\n                    return;\n                }\n\n                modelValue(isChecked);\n            };\n\n            /**\n             * Updates checkbox state\n             */\n            updateView = function () {\n                var modelValue = ko.utils.unwrapObservable(valueAccessor());\n\n                element.checked = !!modelValue;\n            };\n\n            ko.utils.registerEventHandler(element, 'change', updateModel);\n\n            ko.computed(updateModel, null, {\n                disposeWhenNodeIsRemoved: element\n            });\n            ko.computed(updateView, null, {\n                disposeWhenNodeIsRemoved: element\n            });\n        }\n    };\n\n    ko.expressionRewriting._twoWayBindings.simpleChecked = true;\n\n    renderer.addAttribute('simpleChecked');\n    renderer.addAttribute('simple-checked', {\n        binding: 'simpleChecked'\n    });\n});\n","Magento_Ui/js/lib/knockout/bindings/staticChecked.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'ko',\n    '../template/renderer'\n], function (ko, renderer) {\n    'use strict';\n\n    ko.bindingHandlers.staticChecked = {\n        'after': ['value', 'attr'],\n\n        /**\n         * Implements same functionality as a standard 'checked' binding,\n         * but with a difference that it wont' change values array if\n         * value of DOM element changes.\n         */\n        init: function (element, valueAccessor, allBindings) {\n            var isCheckbox = element.type === 'checkbox',\n                isRadio = element.type === 'radio',\n                isValueArray,\n                oldElemValue,\n                useCheckedValue,\n                checkedValue,\n                updateModel,\n                updateView;\n\n            if (!isCheckbox && !isRadio) {\n                return;\n            }\n\n            checkedValue = ko.pureComputed(function () {\n                if (allBindings.has('checkedValue')) {\n                    return ko.utils.unwrapObservable(allBindings.get('checkedValue'));\n                } else if (allBindings.has('value')) {\n                    return ko.utils.unwrapObservable(allBindings.get('value'));\n                }\n\n                return element.value;\n            });\n\n            isValueArray = isCheckbox && ko.utils.unwrapObservable(valueAccessor()) instanceof Array;\n            oldElemValue = isValueArray ? checkedValue() : undefined;\n            useCheckedValue = isRadio || isValueArray;\n\n            /**\n             * Updates values array if it's necessary.\n             */\n            updateModel = function () {\n                var isChecked = element.checked,\n                    elemValue = useCheckedValue ? checkedValue() : isChecked,\n                    modelValue;\n\n                if (ko.computedContext.isInitial()) {\n                    return;\n                }\n\n                if (isRadio && !isChecked) {\n                    return;\n                }\n\n                modelValue = ko.dependencyDetection.ignore(valueAccessor);\n\n                if (isValueArray) {\n                    if (oldElemValue !== elemValue) {\n                        oldElemValue = elemValue;\n                    } else {\n                        ko.utils.addOrRemoveItem(modelValue, elemValue, isChecked);\n                    }\n                } else {\n                    ko.expressionRewriting.writeValueToProperty(modelValue, allBindings, 'checked', elemValue, true);\n                }\n            };\n\n            /**\n             * Updates checkbox state.\n             */\n            updateView = function () {\n                var modelValue = ko.utils.unwrapObservable(valueAccessor());\n\n                if (isValueArray) {\n                    element.checked = ko.utils.arrayIndexOf(modelValue, checkedValue()) >= 0;\n                } else if (isCheckbox) {\n                    element.checked = modelValue;\n                } else {\n                    element.checked = checkedValue() === modelValue;\n                }\n            };\n\n            ko.computed(updateModel, null, {\n                disposeWhenNodeIsRemoved: element\n            });\n\n            ko.utils.registerEventHandler(element, 'click', updateModel);\n\n            ko.computed(updateView, null, {\n                disposeWhenNodeIsRemoved: element\n            });\n        }\n    };\n\n    ko.expressionRewriting._twoWayBindings.staticChecked = true;\n\n    renderer.addAttribute('staticChecked');\n});\n","Magento_Ui/js/lib/knockout/bindings/autoselect.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'ko',\n    'jquery',\n    '../template/renderer'\n], function (ko, $, renderer) {\n    'use strict';\n\n    /**\n     * 'Focus' event handler.\n     *\n     * @param {EventObject} e\n     */\n    function onFocus(e) {\n        e.target.select();\n    }\n\n    ko.bindingHandlers.autoselect = {\n\n        /**\n         * Adds event handler which automatically\n         * selects inputs' element text when field gets focused.\n         */\n        init: function (element, valueAccessor) {\n            var enabled = ko.unwrap(valueAccessor());\n\n            if (enabled !== false) {\n                $(element).on('focus', onFocus);\n            }\n        }\n    };\n\n    renderer.addAttribute('autoselect');\n});\n","Magento_Ui/js/lib/knockout/bindings/outer_click.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/** Creates outerClick binding and registers in to ko.bindingHandlers object */\ndefine([\n    'ko',\n    'jquery',\n    'underscore',\n    '../template/renderer'\n], function (ko, $, _, renderer) {\n    'use strict';\n\n    var defaults = {\n        onlyIfVisible: true\n    };\n\n    /**\n     * Checks if element sis visible.\n     *\n     * @param {Element} el\n     * @returns {Boolean}\n     */\n    function isVisible(el) {\n        var style = window.getComputedStyle(el),\n            visibility = {\n                display: 'none',\n                visibility: 'hidden',\n                opacity: '0'\n            },\n            visible = true;\n\n        _.each(visibility, function (val, key) {\n            if (style[key] === val) {\n                visible = false;\n            }\n        });\n\n        return visible;\n    }\n\n    /**\n     * Document click handler which in case if event target is not\n     * a descendant of provided container element,\n     * invokes specified in configuration callback.\n     *\n     * @param {HTMLElement} container\n     * @param {Object} config\n     * @param {EventObject} e\n     */\n    function onOuterClick(container, config, e) {\n        var target = e.target,\n            callback = config.callback;\n\n        if (container === target || container.contains(target)) {\n            return;\n        }\n\n        if (config.onlyIfVisible) {\n            if (!_.isNull(container.offsetParent) && isVisible(container)) {\n                callback();\n            }\n        } else {\n            callback();\n        }\n    }\n\n    /**\n     * Prepares configuration for the binding based\n     * on a default properties and provided options.\n     *\n     * @param {(Object|Function)} [options={}]\n     * @returns {Object}\n     */\n    function buildConfig(options) {\n        var config = {};\n\n        if (_.isFunction(options)) {\n            options = {\n                callback: options\n            };\n        } else if (!_.isObject(options)) {\n            options = {};\n        }\n\n        return _.extend(config, defaults, options);\n    }\n\n    ko.bindingHandlers.outerClick = {\n\n        /**\n         * Initializes outer click binding.\n         */\n        init: function (element, valueAccessor) {\n            var config = buildConfig(valueAccessor()),\n                outerClick = onOuterClick.bind(null, element, config),\n                isTouchDevice = typeof document.ontouchstart !== 'undefined';\n\n            if (isTouchDevice) {\n                $(document).on('touchstart', outerClick);\n\n                ko.utils.domNodeDisposal.addDisposeCallback(element, function () {\n                    $(document).off('touchstart', outerClick);\n                });\n            } else {\n                $(document).on('click', outerClick);\n\n                ko.utils.domNodeDisposal.addDisposeCallback(element, function () {\n                    $(document).off('click', outerClick);\n                });\n            }\n        }\n    };\n\n    renderer.addAttribute('outerClick');\n});\n","Magento_Ui/js/lib/knockout/bindings/keyboard.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'ko',\n    '../template/renderer'\n], function (ko, renderer) {\n    'use strict';\n\n    ko.bindingHandlers.keyboard = {\n\n        /**\n         * Attaches keypress handlers to element\n         * @param {HTMLElement} el - Element, that binding is applied to\n         * @param {Function} valueAccessor - Function that returns value, passed to binding\n         * @param  {Object} allBindings - all bindings object\n         * @param  {Object} viewModel - reference to viewmodel\n         */\n        init: function (el, valueAccessor, allBindings, viewModel) {\n            var map = valueAccessor();\n\n            ko.utils.registerEventHandler(el, 'keyup', function (e) {\n                var callback = map[e.keyCode];\n\n                if (callback) {\n                    return callback.call(viewModel, e);\n                }\n            });\n        }\n    };\n\n    renderer.addAttribute('keyboard');\n});\n","Magento_Ui/js/lib/knockout/bindings/after-render.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'ko',\n    '../template/renderer'\n], function (ko, renderer) {\n    'use strict';\n\n    ko.bindingHandlers.afterRender = {\n\n        /**\n         * Binding init callback.\n         */\n        init: function (element, valueAccessor, allBindings, viewModel) {\n            var callback = valueAccessor();\n\n            if (typeof callback === 'function') {\n                callback.call(viewModel, element, viewModel);\n            }\n        }\n    };\n\n    renderer.addAttribute('afterRender');\n});\n","Magento_Ui/js/lib/knockout/bindings/tooltip.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'ko',\n    'underscore',\n    'mage/template',\n    'text!ui/template/tooltip/tooltip.html',\n    '../template/renderer'\n], function ($, ko, _, template, tooltipTmpl, renderer) {\n    'use strict';\n\n    var tooltip,\n        defaults,\n        positions,\n        transformProp,\n        checkedPositions = {},\n        iterator = 0,\n        previousTooltip,\n        tooltipData,\n        positionData = {},\n        tooltipsCollection = {},\n        isTouchDevice = (function () {\n            return 'ontouchstart' in document.documentElement;\n        })(),\n        CLICK_EVENT = (function () {\n            return isTouchDevice ? 'touchstart' : 'click';\n        })();\n\n    defaults = {\n        tooltipWrapper: '[data-tooltip=tooltip-wrapper]',\n        tooltipContentBlock: 'data-tooltip-content',\n        closeButtonClass: 'action-close',\n        tailClass: 'data-tooltip-tail',\n        action: 'hover',\n        delay: 300,\n        track: false,\n        step: 20,\n        position: 'top',\n        closeButton: false,\n        showed: false,\n        strict: true,\n        center: false,\n        closeOnScroll: true\n    };\n\n    tooltipData = {\n        tooltipClasses: '',\n        trigger: false,\n        timeout: 0,\n        element: false,\n        event: false,\n        targetElement: {},\n        showed: false,\n        currentID: 0\n    };\n\n    /**\n     * Polyfill for css transform\n     */\n    transformProp = (function () {\n        var style = document.createElement('div').style,\n            base = 'Transform',\n            vendors = ['webkit', 'moz', 'ms', 'o'],\n            vi = vendors.length,\n            property;\n\n        if (typeof style.transform !== 'undefined') {\n            return 'transform';\n        }\n\n        while (vi--) {\n            property = vendors[vi] + base;\n\n            if (typeof style[property] !== 'undefined') {\n                return property;\n            }\n        }\n    })();\n\n    positions = {\n\n        /*eslint max-depth: [0, 0]*/\n\n        map: {\n            horizontal: {\n                s: 'w',\n                p: 'left'\n            },\n            vertical: {\n                s: 'h',\n                p: 'top'\n            }\n        },\n\n        /**\n         * Wrapper function to get tooltip data (position, className, etc)\n         *\n         * @param {Object} s - object with sizes and positions elements\n         * @returns {Object} tooltip data (position, className, etc)\n         */\n        top: function (s) {\n            return positions._topLeftChecker(s, positions.map, 'vertical', '_bottom', 'top', 'right');\n        },\n\n        /**\n         * Wrapper function to get tooltip data (position, className, etc)\n         *\n         * @param {Object} s - object with sizes and positions elements\n         * @returns {Object} tooltip data (position, className, etc)\n         */\n        left: function (s) {\n            return positions._topLeftChecker(s, positions.map, 'horizontal', '_right', 'left', 'top');\n        },\n\n        /**\n         * Wrapper function to get tooltip data (position, className, etc)\n         *\n         * @param {Object} s - object with sizes and positions elements\n         * @returns {Object} tooltip data (position, className, etc)\n         */\n        bottom: function (s) {\n            return positions._bottomRightChecker(s, positions.map, 'vertical', '_top', 'bottom', 'left');\n        },\n\n        /**\n         * Wrapper function to get tooltip data (position, className, etc)\n         *\n         * @param {Object} s - object with sizes and positions elements\n         * @returns {Object} tooltip data (position, className, etc)\n         */\n        right: function (s) {\n            return positions._bottomRightChecker(s, positions.map, 'horizontal', '_left', 'right', 'bottom');\n        },\n\n        /**\n         * Check can tooltip setted on current position or not. If can't setted - delegate call.\n         *\n         * @param {Object} s - object with sizes and positions elements\n         * @param {Object} map - mapping for get direction positions\n         * @param {String} direction - vertical or horizontal\n         * @param {String} className - class whats should be setted to tooltip\n         * @param {String} side - parent method name\n         * @param {String} delegate - method name if tooltip can't be setted in current position\n         * @returns {Object} tooltip data (position, className, etc)\n         */\n        _topLeftChecker: function (s, map, direction, className, side, delegate) {\n            var result = {\n                    position: {}\n                },\n                config = tooltip.getTooltip(tooltipData.currentID),\n                startPosition = !config.strict ? s.eventPosition : s.elementPosition,\n                changedDirection;\n\n            checkedPositions[side] = true;\n\n            if (\n                startPosition[map[direction].p] - s.tooltipSize[map[direction].s] - config.step >\n                s.scrollPosition[map[direction].p]\n            ) {\n                result.position[map[direction].p] = startPosition[map[direction].p] - s.tooltipSize[map[direction].s] -\n                    config.step;\n                result.className = className;\n                result.side = side;\n                changedDirection = direction === 'vertical' ? 'horizontal' : 'vertical';\n                result = positions._normalize(s, result, config, delegate, map, changedDirection);\n            } else if (!checkedPositions[delegate]) {\n                result = positions[delegate].apply(null, arguments);\n            } else {\n                result = positions.positionCenter(s, result);\n            }\n\n            return result;\n        },\n\n        /**\n         * Check can tooltip setted on current position or not. If can't setted - delegate call.\n         *\n         * @param {Object} s - object with sizes and positions elements\n         * @param {Object} map - mapping for get direction positions\n         * @param {String} direction - vertical or horizontal\n         * @param {String} className - class whats should be setted to tooltip\n         * @param {String} side - parent method name\n         * @param {String} delegate - method name if tooltip can't be setted in current position\n         * @returns {Object} tooltip data (position, className, etc)\n         */\n        _bottomRightChecker: function (s, map, direction, className, side, delegate) {\n            var result = {\n                    position: {}\n                },\n                config = tooltip.getTooltip(tooltipData.currentID),\n                startPosition = !config.strict ? s.eventPosition : {\n                    top: s.elementPosition.top + s.elementSize.h,\n                    left: s.elementPosition.left + s.elementSize.w\n                },\n                changedDirection;\n\n            checkedPositions[side] = true;\n\n            if (\n                startPosition[map[direction].p] + s.tooltipSize[map[direction].s] + config.step <\n                s.scrollPosition[map[direction].p] + s.windowSize[map[direction].s]\n            ) {\n                result.position[map[direction].p] = startPosition[map[direction].p] + config.step;\n                result.className = className;\n                result.side = side;\n                changedDirection = direction === 'vertical' ? 'horizontal' : 'vertical';\n                result = positions._normalize(s, result, config, delegate, map, changedDirection);\n            } else if (!checkedPositions[delegate]) {\n                result = positions[delegate].apply(null, arguments);\n            } else {\n                result = positions.positionCenter(s, result);\n            }\n\n            return result;\n        },\n\n        /**\n         * Centered tooltip if tooltip does not fit in window\n         *\n         * @param {Object} s - object with sizes and positions elements\n         * @param {Object} data - current data (position, className, etc)\n         * @returns {Object} tooltip data (position, className, etc)\n         */\n        positionCenter: function (s, data) {\n            data = positions._positionCenter(s, data, 'horizontal', positions.map);\n            data = positions._positionCenter(s, data, 'vertical', positions.map);\n\n            return data;\n        },\n\n        /**\n         * Centered tooltip side\n         *\n         * @param {Object} s - object with sizes and positions elements\n         * @param {Object} data - current data (position, className, etc)\n         * @param {String} direction - vertical or horizontal\n         * @param {Object} map - mapping for get direction positions\n         * @returns {Object} tooltip data (position, className, etc)\n         */\n        _positionCenter: function (s, data, direction, map) {\n            if (s.tooltipSize[map[direction].s] < s.windowSize[map[direction].s]) {\n                data.position[map[direction].p] = (s.windowSize[map[direction].s] -\n                    s.tooltipSize[map[direction].s]) / 2 + s.scrollPosition[map[direction].p];\n            } else {\n                data.position[map[direction].p] = s.scrollPosition[map[direction].p];\n                data.tooltipSize = {};\n                data.tooltipSize[map[direction].s] = s.windowSize[map[direction].s];\n            }\n\n            return data;\n        },\n\n        /**\n         * Normalize horizontal or vertical position.\n         *\n         * @param {Object} s - object with sizes and positions elements\n         * @param {Object} data - current data (position, className, etc)\n         * @param {Object} config - tooltip config\n         * @param {String} delegate - method name if tooltip can't be setted in current position\n         * @param {Object} map - mapping for get direction positions\n         * @param {String} direction - vertical or horizontal\n         * @returns {Object} tooltip data (position, className, etc)\n         */\n        _normalize: function (s, data, config, delegate, map, direction) {\n            var startPosition = !config.center ? s.eventPosition : {\n                    left: s.elementPosition.left + s.elementSize.w / 2,\n                    top: s.elementPosition.top + s.elementSize.h / 2\n                },\n                depResult;\n\n            if (startPosition[map[direction].p] - s.tooltipSize[map[direction].s] / 2 >\n                s.scrollPosition[map[direction].p] && startPosition[map[direction].p] +\n                s.tooltipSize[map[direction].s] / 2 <\n                s.scrollPosition[map[direction].p] + s.windowSize[map[direction].s]\n            ) {\n                data.position[map[direction].p] = startPosition[map[direction].p] - s.tooltipSize[map[direction].s] / 2;\n            } else {\n\n                /*eslint-disable no-lonely-if*/\n                if (!checkedPositions[delegate]) {\n                    depResult = positions[delegate].apply(null, arguments);\n\n                    if (depResult.hasOwnProperty('className')) {\n                        data = depResult;\n                    } else {\n                        data = positions._normalizeTail(s, data, config, delegate, map, direction, startPosition);\n                    }\n                } else {\n                    data = positions._normalizeTail(s, data, config, delegate, map, direction, startPosition);\n                }\n            }\n\n            return data;\n        },\n\n        /**\n         * Calc tail position.\n         *\n         * @param {Object} s - object with sizes and positions elements\n         * @param {Object} data - current data (position, className, etc)\n         * @param {Object} config - tooltip config\n         * @param {String} delegate - method name if tooltip can't be setted in current position\n         * @param {Object} map - mapping for get direction positions\n         * @param {String} direction - vertical or horizontal\n         * @param {Object} startPosition - start position\n         * @returns {Object} tooltip data (position, className, etc)\n         */\n        _normalizeTail: function (s, data, config, delegate, map, direction, startPosition) {\n            data.tail = {};\n\n            if (s.tooltipSize[map[direction].s] < s.windowSize[map[direction].s]) {\n\n                if (\n                    startPosition[map[direction].p] >\n                    s.windowSize[map[direction].s] / 2 + s.scrollPosition[map[direction].p]\n                ) {\n                    data.position[map[direction].p] = s.windowSize[map[direction].s] +\n                        s.scrollPosition[map[direction].p] - s.tooltipSize[map[direction].s];\n                    data.tail[map[direction].p] = startPosition[map[direction].p] -\n                        s.tooltipSize[map[direction].s] / 2 - data.position[map[direction].p];\n                } else {\n                    data.position[map[direction].p] = s.scrollPosition[map[direction].p];\n                    data.tail[map[direction].p] = startPosition[map[direction].p] -\n                        s.tooltipSize[map[direction].s] / 2 - data.position[map[direction].p];\n                }\n            } else {\n                data.position[map[direction].p] = s.scrollPosition[map[direction].p];\n                data.tail[map[direction].p] = s.eventPosition[map[direction].p] - s.windowSize[map[direction].s] / 2;\n                data.tooltipSize = {};\n                data.tooltipSize[map[direction].s] = s.windowSize[map[direction].s];\n            }\n\n            return data;\n        }\n    };\n\n    tooltip = {\n\n        /**\n         * Set new tooltip to tooltipCollection, save config, and add unic id\n         *\n         * @param {Object} config - tooltip config\n         * @returns {String} tooltip id\n         */\n        setTooltip: function (config) {\n            var property = 'id-' + iterator;\n\n            tooltipsCollection[property] = config;\n            iterator++;\n\n            return property;\n        },\n\n        /**\n         * Get tooltip config by id\n         *\n         * @param {String} id - tooltip id\n         * @returns {Object} tooltip config\n         */\n        getTooltip: function (id) {\n            return tooltipsCollection[id];\n        },\n\n        /**\n         * Set content to current tooltip\n         *\n         * @param {Object} tooltipElement - tooltip element\n         * @param {Object} viewModel - tooltip view model\n         * @param {String} id - tooltip id\n         * @param {Object} bindingCtx - tooltip context\n         * @param {Object} event - action event\n         */\n        setContent: function (tooltipElement, viewModel, id, bindingCtx, event) {\n            var html = $(tooltipElement).html(),\n                config = tooltip.getTooltip(id),\n                body = $('body');\n\n            tooltipData.currentID = id;\n            tooltipData.trigger = $(event.currentTarget);\n            tooltip.setTargetData(event);\n            body.on('mousemove.setTargetData', tooltip.setTargetData);\n            tooltip.clearTimeout(id);\n\n            tooltipData.timeout = _.delay(function () {\n                body.off('mousemove.setTargetData', tooltip.setTargetData);\n\n                if (tooltipData.trigger[0] === tooltipData.targetElement) {\n                    tooltip.destroy(id);\n                    event.stopPropagation();\n                    tooltipElement = tooltip.createTooltip(id);\n                    tooltipElement.find('.' + defaults.tooltipContentBlock).append(html);\n                    tooltipElement.applyBindings(bindingCtx);\n                    tooltip.setHandlers(id);\n                    tooltip.setPosition(tooltipElement, id);\n                    previousTooltip = id;\n                }\n\n            }, config.delay);\n        },\n\n        /**\n         * Set position to current tooltip\n         *\n         * @param {Object} tooltipElement - tooltip element\n         * @param {String} id - tooltip id\n         */\n        setPosition: function (tooltipElement, id) {\n            var config = tooltip.getTooltip(id);\n\n            tooltip.sizeData = {\n                windowSize: {\n                    h: $(window).outerHeight(),\n                    w: $(window).outerWidth()\n                },\n                scrollPosition: {\n                    top: $(window).scrollTop(),\n                    left: $(window).scrollLeft()\n                },\n                tooltipSize: {\n                    h: tooltipElement.outerHeight(),\n                    w: tooltipElement.outerWidth()\n                },\n                elementSize: {\n                    h: tooltipData.trigger.outerHeight(),\n                    w: tooltipData.trigger.outerWidth()\n                },\n                elementPosition: tooltipData.trigger.offset(),\n                eventPosition: this.getEventPosition(tooltipData.event)\n            };\n\n            _.extend(positionData, positions[config.position](tooltip.sizeData));\n            tooltipElement.css(positionData.position);\n            tooltipElement.addClass(positionData.className);\n            tooltip._setTooltipSize(positionData, tooltipElement);\n            tooltip._setTailPosition(positionData, tooltipElement);\n            checkedPositions = {};\n        },\n\n        /**\n         * Check position data and change tooltip size if needs\n         *\n         * @param {Object} data - position data\n         * @param {Object} tooltipElement - tooltip element\n         */\n        _setTooltipSize: function (data, tooltipElement) {\n            if (data.tooltipSize) {\n                data.tooltipSize.w ?\n                    tooltipElement.css('width', data.tooltipSize.w) :\n                    tooltipElement.css('height', data.tooltipSize.h);\n            }\n        },\n\n        /**\n         * Check position data and set position to tail\n         *\n         * @param {Object} data - position data\n         * @param {Object} tooltipElement - tooltip element\n         */\n        _setTailPosition: function (data, tooltipElement) {\n            var tail,\n                tailMargin;\n\n            if (data.tail) {\n                tail = tooltipElement.find('.' + defaults.tailClass);\n\n                if (data.tail.left) {\n                    tailMargin = parseInt(tail.css('margin-left'), 10);\n                    tail.css('margin-left', tailMargin + data.tail.left);\n                } else {\n                    tailMargin = parseInt(tail.css('margin-top'), 10);\n                    tail.css('margin-top', tailMargin + data.tail.top);\n                }\n            }\n        },\n\n        /**\n         * Resolves position for tooltip\n         *\n         * @param {Object} event\n         * @returns {Object}\n         */\n        getEventPosition: function (event) {\n            var position = {\n                left: event.originalEvent && event.originalEvent.pageX || 0,\n                top: event.originalEvent && event.originalEvent.pageY || 0\n            };\n\n            if (position.left === 0 && position.top === 0) {\n                _.extend(position, event.target.getBoundingClientRect());\n            }\n\n            return position;\n        },\n\n        /**\n         * Close tooltip if action happened outside handler and tooltip element\n         *\n         * @param {String} id - tooltip id\n         * @param {Object} event - action event\n         */\n        outerClick: function (id, event) {\n            var tooltipElement = $(event.target).parents(defaults.tooltipWrapper)[0],\n                isTrigger = event.target === tooltipData.trigger[0] || $.contains(tooltipData.trigger[0], event.target);\n\n            if (tooltipData.showed && tooltipElement !== tooltipData.element[0] && !isTrigger) {\n                tooltip.destroy(id);\n            }\n        },\n\n        /**\n         * Parse keydown event and if event trigger is escape key - close tooltip\n         *\n         * @param {Object} event - action event\n         */\n        keydownHandler: function (event) {\n            if (tooltipData.showed && event.keyCode === 27) {\n                tooltip.destroy(tooltipData.currentID);\n            }\n        },\n\n        /**\n         * Change tooltip position when track is enabled\n         *\n         * @param {Object} event - current event\n         */\n        track: function (event) {\n            var inequality = {},\n                map = positions.map,\n                translate = {\n                    left: 'translateX',\n                    top: 'translateY'\n                },\n                eventPosition = {\n                    left: event.pageX,\n                    top: event.pageY\n                },\n                tooltipSize = {\n                    w: tooltipData.element.outerWidth(),\n                    h: tooltipData.element.outerHeight()\n                },\n                direction = positionData.side === 'bottom' || positionData.side === 'top' ? 'horizontal' : 'vertical';\n\n            inequality[map[direction].p] = eventPosition[map[direction].p] - (positionData.position[map[direction].p] +\n                tooltipSize[map[direction].s] / 2);\n\n            if (positionData.position[map[direction].p] + inequality[map[direction].p] +\n                tooltip.sizeData.tooltipSize[map[direction].s] >\n                tooltip.sizeData.windowSize[map[direction].s] + tooltip.sizeData.scrollPosition[map[direction].p] ||\n                inequality[map[direction].p] + positionData.position[map[direction].p] <\n                tooltip.sizeData.scrollPosition[map[direction].p]) {\n\n                return false;\n            }\n\n            tooltipData.element[0].style[transformProp] = translate[map[direction].p] +\n                '(' + inequality[map[direction].p] + 'px)';\n        },\n\n        /**\n         * Set handlers to tooltip\n         *\n         * @param {String} id - tooltip id\n         */\n        setHandlers: function (id) {\n            var config = tooltip.getTooltip(id);\n\n            if (config.track) {\n                tooltipData.trigger.on('mousemove.track', tooltip.track);\n            }\n\n            if (config.action === 'click') {\n                $(window).on(CLICK_EVENT + '.outerClick', tooltip.outerClick.bind(null, id));\n            }\n\n            if (config.closeButton) {\n                $('.' + config.closeButtonClass).on('click.closeButton', tooltip.destroy.bind(null, id));\n            }\n\n            if (config.closeOnScroll) {\n                document.addEventListener('scroll', tooltip.destroy, true);\n                $(window).on('scroll.tooltip', tooltip.outerClick.bind(null, id));\n            }\n\n            $(window).on('keydown.tooltip', tooltip.keydownHandler);\n            $(window).on('resize.outerClick', tooltip.outerClick.bind(null, id));\n        },\n\n        /**\n         * Toggle tooltip\n         *\n         * @param {Object} tooltipElement - tooltip element\n         * @param {Object} viewModel - tooltip view model\n         * @param {String} id - tooltip id\n         */\n        toggleTooltip: function (tooltipElement, viewModel, id) {\n            if (previousTooltip === id && tooltipData.showed) {\n                tooltip.destroy(id);\n\n                return false;\n            }\n\n            tooltip.setContent.apply(null, arguments);\n\n            return false;\n        },\n\n        /**\n         * Create tooltip and append to DOM\n         *\n         * @param {String} id - tooltip id\n         * @returns {Object} tooltip element\n         */\n        createTooltip: function (id) {\n            var body = $('body'),\n                config = tooltip.getTooltip(id);\n\n            $(template(tooltipTmpl, {\n                data: config\n            })).appendTo(body);\n\n            tooltipData.showed = true;\n            tooltipData.element = $(config.tooltipWrapper);\n\n            return tooltipData.element;\n        },\n\n        /**\n         * Check action and clean timeout\n         *\n         * @param {String} id - tooltip id\n         */\n        clearTimeout: function (id) {\n            var config = tooltip.getTooltip(id);\n\n            if (config.action === 'hover') {\n                clearTimeout(tooltipData.timeout);\n            }\n        },\n\n        /**\n         * Check previous tooltip\n         */\n        checkPreviousTooltip: function () {\n            if (!tooltipData.timeout) {\n                tooltip.destroy();\n            }\n        },\n\n        /**\n         * Destroy tooltip instance\n         */\n        destroy: function () {\n            if (tooltipData.element) {\n                tooltipData.element.remove();\n                tooltipData.showed = false;\n            }\n\n            positionData = {};\n            tooltipData.timeout = false;\n            tooltip.removeHandlers();\n        },\n\n        /**\n         * Remove tooltip handlers\n         */\n        removeHandlers: function () {\n            $('.' + defaults.closeButtonClass).off('click.closeButton');\n            tooltipData.trigger.off('mousemove.track');\n            document.removeEventListener('scroll', tooltip.destroy, true);\n            $(window).off('scroll.tooltip');\n            $(window).off(CLICK_EVENT + '.outerClick');\n            $(window).off('keydown.tooltip');\n            $(window).off('resize.outerClick');\n        },\n\n        /**\n         * Set target element\n         *\n         * @param {Object} event - current event\n         */\n        setTargetData: function (event) {\n            tooltipData.event = event;\n\n            //TODO: bug chrome v.49; Link to issue https://bugs.chromium.org/p/chromium/issues/detail?id=161464\n            if (event.timeStamp - (tooltipData.timestamp || 0) < 1) {\n                return;\n            }\n\n            if (event.type === 'mousemove') {\n                tooltipData.targetElement = event.target;\n            } else {\n                tooltipData.targetElement = event.currentTarget;\n                tooltipData.timestamp = event.timeStamp;\n            }\n        },\n\n        /**\n         * Merged user config with defaults configuration\n         *\n         * @param {Object} config - user config\n         * @returns {Object} merged config\n         */\n        processingConfig: function (config) {\n            return _.extend({}, defaults, config);\n        }\n    };\n\n    ko.bindingHandlers.tooltip = {\n\n        /**\n         * Initialize tooltip\n         *\n         * @param {Object} elem - tooltip DOM element\n         * @param {Function} valueAccessor - ko observable property, tooltip data\n         * @param {Object} allBindings - all bindings on current element\n         * @param {Object} viewModel - current element viewModel\n         * @param {Object} bindingCtx - current element binding context\n         */\n        init: function (elem, valueAccessor, allBindings, viewModel, bindingCtx) {\n            var config = tooltip.processingConfig(valueAccessor()),\n                $parentScope = config.parentScope ? $(config.parentScope) : $(elem).parent(),\n                tooltipId;\n\n            $(elem).addClass('hidden');\n\n            if (isTouchDevice) {\n                config.action = 'click';\n            }\n            tooltipId = tooltip.setTooltip(config);\n\n            if (config.action === 'hover') {\n                $parentScope.on(\n                    'mouseenter',\n                    config.trigger,\n                    tooltip.setContent.bind(null, elem, viewModel, tooltipId, bindingCtx)\n                );\n                $parentScope.on(\n                    'mouseleave',\n                    config.trigger,\n                    tooltip.checkPreviousTooltip.bind(null, tooltipId)\n                );\n            } else if (config.action === 'click') {\n                $parentScope.on(\n                    'click',\n                    config.trigger,\n                    tooltip.toggleTooltip.bind(null, elem, viewModel, tooltipId, bindingCtx)\n                );\n            }\n\n            return {\n                controlsDescendantBindings: true\n            };\n        }\n    };\n\n    renderer.addAttribute('tooltip');\n});\n","Magento_Ui/js/lib/knockout/bindings/datepicker.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/** Creates datepicker binding and registers in to ko.bindingHandlers object */\ndefine([\n    'ko',\n    'underscore',\n    'jquery',\n    'mage/translate'\n], function (ko, _, $, $t) {\n    'use strict';\n\n    var defaults = {\n        dateFormat: 'mm\\/dd\\/yyyy',\n        showsTime: false,\n        timeFormat: null,\n        buttonImage: null,\n        buttonImageOnly: null,\n        buttonText: $t('Select Date')\n    };\n\n    ko.bindingHandlers.datepicker = {\n        /**\n         * Initializes calendar widget on element and stores it's value to observable property.\n         * Datepicker binding takes either observable property or object\n         *  { storage: {ko.observable}, options: {Object} }.\n         * For more info about options take a look at \"mage/calendar\" and jquery.ui.datepicker widget.\n         * @param {HTMLElement} el - Element, that binding is applied to\n         * @param {Function} valueAccessor - Function that returns value, passed to binding\n         * @param {object} allBindings\n         * @param {object} viewModel\n         * @param {object} bindingContext\n         */\n        init: function (el, valueAccessor, allBindings, viewModel, bindingContext) {\n            var config = valueAccessor(),\n                observable,\n                options = {};\n\n            _.extend(options, defaults);\n\n            if (typeof config === 'object') {\n                observable = config.storage;\n                _.extend(options, config.options);\n            } else {\n                observable = config;\n            }\n\n            require(['mage/calendar'], function () {\n                $(el).calendar(options);\n\n                ko.utils.registerEventHandler(el, 'change', function () {\n                    observable(this.value);\n                });\n            });\n\n            if (bindingContext.$data) {\n                bindingContext.$data.value.subscribe(function (newVal) {\n                    if (!newVal) {\n                        $(el).val('');\n                    }\n                }, this);\n            }\n\n\n        },\n\n        /**\n         * Update calendar widget on element and stores it's value to observable property.\n         * Datepicker binding takes either observable property or object\n         *  { storage: {ko.observable}, options: {Object} }.\n         * @param {HTMLElement} element - Element, that binding is applied to\n         * @param {Function} valueAccessor - Function that returns value, passed to binding\n         */\n        update: function (element, valueAccessor) {\n            var config = valueAccessor(),\n                $element = $(element),\n                observable,\n                options = {},\n                newVal;\n\n            _.extend(options, defaults);\n\n            if (typeof config === 'object') {\n                observable = config.storage;\n                _.extend(options, config.options);\n            } else {\n                observable = config;\n            }\n\n            require(['moment', 'mage/utils/misc', 'mage/calendar'], function (moment, utils) {\n                if (_.isEmpty(observable())) {\n                    newVal = null;\n                } else {\n                    newVal = moment(\n                        observable(),\n                        utils.convertToMomentFormat(\n                            options.dateFormat + (options.showsTime ? ' ' + options.timeFormat : '')\n                        )\n                    ).toDate();\n                }\n\n                if (!options.timeOnly) {\n                    $element.datepicker('setDate', newVal);\n                    $element.trigger('blur');\n                }\n            });\n        }\n    };\n});\n","Magento_Ui/js/lib/knockout/bindings/resizable.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'ko',\n    'jquery',\n    'Magento_Ui/js/lib/view/utils/async',\n    'uiRegistry',\n    'underscore',\n    '../template/renderer'\n], function (ko, $, async, registry, _, renderer) {\n    'use strict';\n\n    var sizeOptions = [\n            'minHeight',\n            'maxHeight',\n            'minWidth',\n            'maxWidth'\n        ],\n\n        handles = {\n            height: '.ui-resizable-s, .ui-resizable-n',\n            width: '.ui-resizable-w, .ui-resizable-e'\n        };\n\n    /**\n     * Recalcs visibility of handles, width and height of resizable based on content\n     * @param {HTMLElement} element\n     */\n    function adjustSize(element) {\n        var maxHeight,\n            maxWidth;\n\n        element = $(element);\n        maxHeight = element.resizable('option').maxHeight;\n        maxWidth = element.resizable('option').maxWidth;\n\n        if (maxHeight && element.height() > maxHeight) {\n            element.height(maxHeight + 1);\n            $(handles.height).hide();\n        } else {\n            $(handles.height).show();\n        }\n\n        if (maxWidth && element.width() > maxWidth) {\n            element.width(maxWidth + 1);\n            $(handles.width).hide();\n        } else {\n            $(handles.width).show();\n        }\n    }\n\n    /**\n     * Recalcs allowed min, max width and height based on configured selectors\n     * @param {Object} sizeConstraints\n     * @param {String} componentName\n     * @param {HTMLElement} element\n     * @param {Boolean} hasWidthUpdate\n     */\n    function recalcAllowedSize(sizeConstraints, componentName, element, hasWidthUpdate) {\n        var size;\n\n        element = $(element);\n\n        if (!element.data('resizable')) {\n            return;\n        }\n\n        if (!hasWidthUpdate) {\n            element.css('width', 'auto');\n        }\n\n        _.each(sizeConstraints, function (selector, key) {\n            async.async({\n                component: componentName,\n                selector: selector\n            }, function (elem) {\n                size = key.indexOf('Height') !== -1 ? $(elem).outerHeight(true) : $(elem).outerWidth(true);\n\n                if (element.data('resizable')) {\n                    element.resizable('option', key, size + 1);\n                }\n            });\n        }, this);\n\n        adjustSize(element);\n    }\n\n    /**\n     * Preprocess config to separate options,\n     * which must be processed further before applying\n     *\n     * @param {Object} config\n     * @param {Object} viewModel\n     * @param {*} element\n     * @return {Object} config\n     */\n    function processConfig(config, viewModel, element) {\n        var sizeConstraint,\n            sizeConstraints = {},\n            recalc,\n            hasWidthUpdate;\n\n        if (_.isEmpty(config)) {\n            return {};\n        }\n        _.each(sizeOptions, function (key) {\n            sizeConstraint = config[key];\n\n            if (sizeConstraint && !_.isNumber(sizeConstraint)) {\n                sizeConstraints[key] = sizeConstraint;\n                delete config[key];\n            }\n        });\n        hasWidthUpdate =  _.some(sizeConstraints, function (value, key) {\n            return key.indexOf('Width') !== -1;\n        });\n\n        recalc = recalcAllowedSize.bind(null, sizeConstraints, viewModel.name, element, hasWidthUpdate);\n        config.start = recalc;\n        $(window).on('resize.resizable', recalc);\n        registry.get(viewModel.provider).on('reloaded', recalc);\n\n        return config;\n    }\n\n    ko.bindingHandlers.resizable = {\n\n        /**\n         * Binding init callback.\n         *\n         * @param {*} element\n         * @param {Function} valueAccessor\n         * @param {Function} allBindings\n         * @param {Object} viewModel\n         */\n        init: function (element, valueAccessor, allBindings, viewModel) {\n            var config = processConfig(valueAccessor(), viewModel, element);\n\n            require(['jquery-ui-modules/resizable'], function () {\n                if ($.fn.resizable) {\n                    $(element).resizable(config);\n                }\n            });\n        }\n    };\n\n    renderer.addAttribute('resizable');\n});\n","Magento_Ui/js/lib/knockout/bindings/bind-html.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'ko',\n    'underscore',\n    'mage/apply/main',\n    '../template/renderer'\n], function (ko, _, mage, renderer) {\n    'use strict';\n\n    /**\n     * Set html to node element.\n     *\n     * @param {HTMLElement} el - Element to apply bindings to.\n     * @param {Function} html - Observable html content.\n     */\n    function setHtml(el, html) {\n        ko.utils.emptyDomNode(el);\n        html = ko.utils.unwrapObservable(html);\n\n        if (!_.isNull(html) && !_.isUndefined(html)) {\n            if (!_.isString(html)) {\n                html = html.toString();\n            }\n\n            el.innerHTML = html;\n        }\n    }\n\n    /**\n     * Apply bindings and call magento attributes parser.\n     *\n     * @param {HTMLElement} el - Element to apply bindings to.\n     * @param {ko.bindingContext} ctx - Instance of ko.bindingContext, passed to binding initially.\n     */\n    function applyComponents(el, ctx) {\n        ko.utils.arrayForEach(el.childNodes, ko.cleanNode);\n        ko.applyBindingsToDescendants(ctx, el);\n        mage.apply();\n    }\n\n    ko.bindingHandlers.bindHtml = {\n        /**\n         * Scope binding's init method.\n         *\n         * @returns {Object} - Knockout declaration for it to let binding control descendants.\n         */\n        init: function () {\n            return {\n                controlsDescendantBindings: true\n            };\n        },\n\n        /**\n         * Reads params passed to binding.\n         * Set html to node element, apply bindings and call magento attributes parser.\n         *\n         * @param {HTMLElement} el - Element to apply bindings to.\n         * @param {Function} valueAccessor - Function that returns value, passed to binding.\n         * @param {Object} allBindings - Object, which represents all bindings applied to element.\n         * @param {Object} viewModel - Object, which represents view model binded to el.\n         * @param {ko.bindingContext} bindingContext - Instance of ko.bindingContext, passed to binding initially.\n         */\n        update: function (el, valueAccessor, allBindings, viewModel, bindingContext) {\n            setHtml(el, valueAccessor());\n            applyComponents(el, bindingContext);\n        }\n    };\n\n    renderer.addAttribute('bindHtml');\n});\n","Magento_Ui/js/lib/knockout/extender/observable_array.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'ko',\n    'underscore'\n], function (ko, _) {\n    'use strict';\n\n    /**\n     * Iterator function.\n     *\n     * @param {String} callback\n     * @param {Array} args\n     * @param {Object} elem\n     * @returns {*}\n     */\n    function iterator(callback, args, elem) {\n        callback = elem[callback];\n\n        if (_.isFunction(callback)) {\n            return callback.apply(elem, args);\n        }\n\n        return callback;\n    }\n\n    /**\n     * Wrapper function.\n     *\n     * @param {String} method\n     * @returns {Function}\n     */\n    function wrapper(method) {\n        return function (iteratee) {\n            var callback = iteratee,\n                elems = this(),\n                args = _.toArray(arguments);\n\n            if (_.isString(iteratee)) {\n                callback = iterator.bind(null, iteratee, args.slice(1));\n\n                args.unshift(callback);\n            }\n\n            args.unshift(elems);\n\n            return _[method].apply(_, args);\n        };\n    }\n\n    _.extend(ko.observableArray.fn, {\n        each: wrapper('each'),\n\n        map: wrapper('map'),\n\n        filter: wrapper('filter'),\n\n        some: wrapper('some'),\n\n        every: wrapper('every'),\n\n        groupBy: wrapper('groupBy'),\n\n        sortBy: wrapper('sortBy'),\n\n        /**\n         * Wrapper for underscore findWhere function.\n         *\n         * @param {Object} properties\n         * @return {Object}\n         */\n        findWhere: function (properties) {\n            return _.findWhere(this(), properties);\n        },\n\n        /**\n         * Wrapper for underscore contains function.\n         *\n         * @param {*} value\n         * @return {Boolean}\n         */\n        contains: function (value) {\n            return _.contains(this(), value);\n        },\n\n        /**\n         * Inverse contains call.\n         *\n         * @return {Boolean}\n         */\n        hasNo: function () {\n            return !this.contains.apply(this, arguments);\n        },\n\n        /**\n         * Getter for length property.\n         *\n         * @return {Number}\n         */\n        getLength: function () {\n            return this().length;\n        },\n\n        /**\n         * Create object with keys that gets from each object property.\n         *\n         * @return {Object}\n         */\n        indexBy: function (key) {\n            return _.indexBy(this(), key);\n        },\n\n        /**\n         * Returns a copy of the array with all instances of the values removed.\n         *\n         * @return {Array}\n         */\n        without: function () {\n            var args = Array.prototype.slice.call(arguments);\n\n            args.unshift(this());\n\n            return _.without.apply(_, args);\n        },\n\n        /**\n         * Returns the first element of an array.\n         *\n         * @return {*}\n         */\n        first: function () {\n            return _.first(this());\n        },\n\n        /**\n         * Returns the last element of an array\n         *\n         * @return {*}\n         */\n        last: function () {\n            return _.last(this());\n        },\n\n        /**\n         * Iterate and pick provided properties.\n         *\n         * @return {Array}\n         */\n        pluck: function () {\n            var args = Array.prototype.slice.call(arguments);\n\n            args.unshift(this());\n\n            return _.pluck.apply(_, args);\n        }\n    });\n});\n","Magento_Ui/js/lib/knockout/extender/bound-nodes.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'ko',\n    'underscore',\n    'mage/utils/wrapper',\n    'uiEvents'\n], function (ko, _, wrapper, Events) {\n    'use strict';\n\n    var nodesMap = new WeakMap();\n\n    /**\n     * Returns a array of nodes associated with a specified model.\n     *\n     * @param {Object} model\n     * @returns {Undefined|Array}\n     */\n    function getBounded(model) {\n        return nodesMap.get(model);\n    }\n\n    /**\n     * Removes specified node to models' associations list, if it's\n     * a root node (node is not a descendant of any previously added nodes).\n     * Triggers 'addNode' event.\n     *\n     * @param {Object} model\n     * @param {HTMLElement} node\n     */\n    function addBounded(model, node) {\n        var nodes = getBounded(model),\n            isRoot;\n\n        if (!nodes) {\n            nodesMap.set(model, [node]);\n\n            Events.trigger.call(model, 'addNode', node);\n\n            return;\n        }\n\n        isRoot = nodes.every(function (bounded) {\n            return !bounded.contains(node);\n        });\n\n        if (isRoot) {\n            nodes.push(node);\n\n            Events.trigger.call(model, 'addNode', node);\n        }\n    }\n\n    /**\n     * Removes specified node from models' associations list.\n     * Triggers 'removeNode' event.\n     *\n     * @param {Object} model\n     * @param {HTMLElement} node\n     */\n    function removeBounded(model, node) {\n        var nodes = getBounded(model),\n            index;\n\n        if (!nodes) {\n            return;\n        }\n\n        index = nodes.indexOf(node);\n\n        if (~index) {\n            nodes.splice(index, 0);\n\n            Events.trigger.call(model, 'removeNode', node);\n        }\n\n        if (!nodes.length) {\n            nodesMap.delete(model);\n        }\n    }\n\n    /**\n     * Returns node's first sibling of 'element' type within the common component scope\n     *\n     * @param {HTMLElement} node\n     * @param {*} data\n     * @returns {HTMLElement}\n     */\n    function getElement(node, data) {\n        var elem;\n\n        while (node.nextElementSibling) {\n            node = node.nextElementSibling;\n\n            if (node.nodeType === 1 && ko.dataFor(node) === data) {\n                elem = node;\n                break;\n            }\n        }\n\n        return elem;\n    }\n\n    wrapper.extend(ko, {\n\n        /**\n         * Extends knockouts' 'applyBindings'\n         * to track nodes associated with model.\n         *\n         * @param {Function} orig - Original 'applyBindings' method.\n         * @param {Object} ctx\n         * @param {HTMLElement} node - Original 'applyBindings' method.\n         */\n        applyBindings: function (orig, ctx, node) {\n            var result = orig(),\n                data = ctx && (ctx.$data || ctx);\n\n            if (node && node.nodeType === 8) {\n                node = getElement(node, data);\n            }\n\n            if (!node || node.nodeType !== 1) {\n                return result;\n            }\n\n            if (data && data.registerNodes) {\n                addBounded(data, node);\n            }\n\n            return result;\n        },\n\n        /**\n         * Extends knockouts' cleanNode\n         * to track nodes associated with model.\n         *\n         * @param {Function} orig - Original 'cleanNode' method.\n         * @param {HTMLElement} node - Original 'cleanNode' method.\n         */\n        cleanNode: function (orig, node) {\n            var result = orig(),\n                data;\n\n            if (node.nodeType !== 1) {\n                return result;\n            }\n\n            data = ko.dataFor(node);\n\n            if (data && data.registerNodes) {\n                removeBounded(data, node);\n            }\n\n            return result;\n        }\n    });\n\n    return {\n\n        /**\n         * Returns root nodes associated with a model. If callback is provided,\n         * will iterate through all of the present nodes triggering callback\n         * for each of it. Also it will subscribe to the 'addNode' event.\n         *\n         * @param {Object} model\n         * @param {Function} [callback]\n         * @returns {Array|Undefined}\n         */\n        get: function (model, callback) {\n            var nodes = getBounded(model) || [];\n\n            if (!_.isFunction(callback)) {\n                return nodes;\n            }\n\n            nodes.forEach(function (node) {\n                callback(node);\n            });\n\n            this.add.apply(this, arguments);\n        },\n\n        /**\n         * Subscribes to adding of nodes associated with a model.\n         *\n         * @param {Object} model\n         */\n        add: function (model) {\n            var args = _.toArray(arguments).slice(1);\n\n            args.unshift('addNode');\n\n            Events.on.apply(model, args);\n        },\n\n        /**\n         * Subscribes to removal of nodes associated with a model.\n         *\n         * @param {Object} model\n         */\n        remove: function (model) {\n            var args = _.toArray(arguments).slice(1);\n\n            args.unshift('removeNode');\n\n            Events.on.apply(model, args);\n        },\n\n        /**\n         * Removes subscriptions from the model.\n         *\n         * @param {Object} model\n         */\n        off: function (model) {\n            var args = _.toArray(arguments).slice(1);\n\n            Events.off.apply(model, args);\n        }\n    };\n});\n","Magento_Ui/js/lib/core/events.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'ko',\n    'underscore'\n], function (ko, _) {\n    'use strict';\n\n    var eventsMap = new WeakMap();\n\n    /**\n     * Returns events map or a specific event\n     * data associated with a provided object.\n     *\n     * @param {Object} obj - Key in the events weakmap.\n     * @param {String} [name] - Name of the event.\n     * @returns {Map|Array|Boolean}\n     */\n    function getEvents(obj, name) {\n        var events = eventsMap.get(obj);\n\n        if (!events) {\n            return false;\n        }\n\n        return name ? events.get(name) : events;\n    }\n\n    /**\n     * Adds new event handler.\n     *\n     * @param {Object} obj - Key in the events weakmap.\n     * @param {String} ns - Callback namespace.\n     * @param {Function} callback - Event callback.\n     * @param {String} name - Name of the event.\n     */\n    function addHandler(obj, ns, callback, name) {\n        var events      = getEvents(obj),\n            observable,\n            data;\n\n        observable = !ko.isObservable(obj[name]) ?\n            ko.getObservable(obj, name) :\n            obj[name];\n\n        if (observable) {\n            observable.subscribe(callback);\n\n            return;\n        }\n\n        if (!events) {\n            events = new Map();\n\n            eventsMap.set(obj, events);\n        }\n\n        data = {\n            callback: callback,\n            ns: ns\n        };\n\n        events.has(name) ?\n            events.get(name).push(data) :\n            events.set(name, [data]);\n    }\n\n    /**\n     * Invokes provided callbacks with a specified arguments.\n     *\n     * @param {Array} handlers\n     * @param {Array} args\n     * @returns {Boolean}\n     */\n    function trigger(handlers, args) {\n        var bubble = true,\n            callback;\n\n        handlers.forEach(function (handler) {\n            callback = handler.callback;\n\n            if (callback.apply(null, args) === false) {\n                bubble = false;\n            }\n        });\n\n        return bubble;\n    }\n\n    return {\n\n        /**\n         * Calls callback when name event is triggered.\n         * @param  {String}   events\n         * @param  {Function} callback\n         * @param  {Function} ns\n         * @return {Object} reference to this\n         */\n        on: function (events, callback, ns) {\n            var iterator;\n\n            if (arguments.length < 2) {\n                ns = callback;\n            }\n\n            iterator = addHandler.bind(null, this, ns);\n\n            _.isObject(events) ?\n                _.each(events, iterator) :\n                iterator(callback, events);\n\n            return this;\n        },\n\n        /**\n         * Removed callback from listening to target event\n         * @param  {String} ns\n         * @return {Object} reference to this\n         */\n        off: function (ns) {\n            var storage = getEvents(this);\n\n            if (!storage) {\n                return this;\n            }\n\n            storage.forEach(function (handlers, name) {\n                handlers = handlers.filter(function (handler) {\n                    return !ns ? false : handler.ns !== ns;\n                });\n\n                handlers.length ?\n                    storage.set(name, handlers) :\n                    storage.delete(name);\n            });\n\n            return this;\n        },\n\n        /**\n         * Triggers event and executes all attached callbacks.\n         *\n         * @param {String} name - Name of the event to be triggered.\n         * @returns {Boolean}\n         */\n        trigger: function (name) {\n            var handlers,\n                args;\n\n            handlers = getEvents(this, name),\n            args = _.toArray(arguments).slice(1);\n\n            if (!handlers || !name) {\n                return true;\n            }\n\n            return trigger(handlers, args);\n        }\n    };\n});\n","Magento_Ui/js/lib/core/collection.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'underscore',\n    'mageUtils',\n    'uiRegistry',\n    'uiElement'\n], function (_, utils, registry, Element) {\n    'use strict';\n\n    /**\n     * Removes non plain object items from the specified array.\n     *\n     * @param {Array} container - Array whose value should be filtered.\n     * @returns {Array}\n     */\n    function compact(container) {\n        return _.values(container).filter(utils.isObject);\n    }\n\n    /**\n     * Defines index of an item in a specified container.\n     *\n     * @param {*} item - Item whose index should be defined.\n     * @param {Array} container - Container upon which to perform search.\n     * @returns {Number}\n     */\n    function _findIndex(item, container) {\n        var index = _.findKey(container, function (value) {\n            return value === item;\n        });\n\n        if (typeof index === 'undefined') {\n            index = _.findKey(container, function (value) {\n                return value && value.name === item;\n            });\n        }\n\n        return typeof index === 'undefined' ? -1 : index;\n    }\n\n    /**\n     * Inserts specified item into container at a specified position.\n     *\n     * @param {*} item - Item to be inserted into container.\n     * @param {Array} container - Container of items.\n     * @param {*} [position=-1] - Position at which item should be inserted.\n     *      Position can represent:\n     *          - specific index in container\n     *          - item which might already be present in container\n     *          - structure with one of these properties: after, before\n     * @returns {Boolean|*}\n     *      - true if element has changed its' position\n     *      - false if nothing has changed\n     *      - inserted value if it wasn't present in container\n     */\n    function _insertAt(item, container, position) {\n        var currentIndex = _findIndex(item, container),\n            newIndex,\n            target;\n\n        if (typeof position === 'undefined') {\n            position = -1;\n        } else if (typeof position === 'string') {\n            position = isNaN(+position) ? position : +position;\n        }\n\n        newIndex = position;\n\n        if (~currentIndex) {\n            target = container.splice(currentIndex, 1)[0];\n\n            if (typeof item === 'string') {\n                item = target;\n            }\n        }\n\n        if (typeof position !== 'number') {\n            target = position.after || position.before || position;\n\n            newIndex = _findIndex(target, container);\n\n            if (~newIndex && (position.after || newIndex >= currentIndex)) {\n                newIndex++;\n            }\n        }\n\n        if (newIndex < 0) {\n            newIndex += container.length + 1;\n        }\n\n        container[newIndex] ?\n            container.splice(newIndex, 0, item) :\n            container[newIndex] = item;\n\n        return !~currentIndex ? item : currentIndex !== newIndex;\n    }\n\n    return Element.extend({\n        defaults: {\n            template: 'ui/collection',\n            _elems: [],\n            ignoreTmpls: {\n                childDefaults: true\n            }\n        },\n\n        /**\n         * Initializes observable properties.\n         *\n         * @returns {Model} Chainable.\n         */\n        initObservable: function () {\n            this._super()\n                .observe({\n                    elems: []\n                });\n\n            return this;\n        },\n\n        /**\n         * Called when another element was added to current component.\n         *\n         * @param {Object} elem - Instance of an element that was added.\n         * @returns {Collection} Chainable.\n         */\n        initElement: function (elem) {\n            elem.initContainer(this);\n\n            return this;\n        },\n\n        /**\n         * Returns instance of a child found by provided index.\n         *\n         * @param {String} index - Index of a child.\n         * @returns {Object}\n         */\n        getChild: function (index) {\n            return _.findWhere(this.elems(), {\n                index: index\n            });\n        },\n\n        /**\n         * Requests specified components to insert\n         * them into 'elems' array starting from provided position.\n         *\n         * @param {(String|Array)} elems - Name of the component to insert.\n         * @param {Number} [position=-1] - Position at which to insert elements.\n         * @returns {Collection} Chainable.\n         */\n        insertChild: function (elems, position) {\n            var container   = this._elems,\n                insert      = this._insert.bind(this),\n                update;\n\n            if (!Array.isArray(elems)) {\n                elems = [elems];\n            }\n\n            elems.map(function (item) {\n                return item.elem ?\n                    _insertAt(item.elem, container, item.position) :\n                    _insertAt(item, container, position);\n            }).forEach(function (item) {\n                if (item === true) {\n                    update = true;\n                } else if (_.isString(item)) {\n                    registry.get(item, insert);\n                } else if (utils.isObject(item)) {\n                    insert(item);\n                }\n            });\n\n            if (update) {\n                this._updateCollection();\n            }\n\n            return this;\n        },\n\n        /**\n         * Removes specified child from collection.\n         *\n         * @param {(Object|String)} elem - Child or index of a child to be removed.\n         * @param {Boolean} skipUpdate - skip collection update when element to be destroyed.\n         *\n         * @returns {Collection} Chainable.\n         */\n        removeChild: function (elem, skipUpdate) {\n            if (_.isString(elem)) {\n                elem = this.getChild(elem);\n            }\n\n            if (elem) {\n                utils.remove(this._elems, elem);\n\n                if (!skipUpdate) {\n                    this._updateCollection();\n                }\n            }\n\n            return this;\n        },\n\n        /**\n         * Destroys collection children with its' elements.\n         */\n        destroyChildren: function () {\n            this.elems.each(function (elem) {\n                elem.destroy(true);\n            });\n\n            this._updateCollection();\n        },\n\n        /**\n         * Clear data. Call method \"clear\"\n         * in child components\n         *\n         * @returns {Object} Chainable.\n         */\n        clear: function () {\n            var elems = this.elems();\n\n            _.each(elems, function (elem) {\n                if (_.isFunction(elem.clear)) {\n                    elem.clear();\n                }\n            }, this);\n\n            return this;\n        },\n\n        /**\n         * Checks if specified child exists in collection.\n         *\n         * @param {String} index - Index of a child.\n         * @returns {Boolean}\n         */\n        hasChild: function (index) {\n            return !!this.getChild(index);\n        },\n\n        /**\n         * Creates 'async' wrapper for the specified child\n         * using uiRegistry 'async' method and caches it\n         * in a '_requested' components  object.\n         *\n         * @param {String} index - Index of a child.\n         * @returns {Function} Async module wrapper.\n         */\n        requestChild: function (index) {\n            var name = this.formChildName(index);\n\n            return this.requestModule(name);\n        },\n\n        /**\n         * Creates complete child name based on a provided index.\n         *\n         * @param {String} index - Index of a child.\n         * @returns {String}\n         */\n        formChildName: function (index) {\n            return this.name + '.' + index;\n        },\n\n        /**\n         * Retrieves requested region.\n         * Creates region if it was not created yet\n         *\n         * @returns {ObservableArray}\n         */\n        getRegion: function (name) {\n            var regions = this.regions = this.regions || {};\n\n            if (!regions[name]) {\n                regions[name] = [];\n\n                this.observe.call(regions, name);\n            }\n\n            return regions[name];\n        },\n\n        /**\n         * Checks if the specified region has any elements\n         * associated with it.\n         *\n         * @param {String} name\n         * @returns {Boolean}\n         */\n        regionHasElements: function (name) {\n            var region = this.getRegion(name);\n\n            return region().length > 0;\n        },\n\n        /**\n         * Replaces specified regions' data with a provided one.\n         * Creates region if it was not created yet.\n         *\n         * @param {Array} items - New regions' data.\n         * @param {String} name - Name of the region.\n         * @returns {Collection} Chainable.\n         */\n        updateRegion: function (items, name) {\n            this.getRegion(name)(items);\n\n            return this;\n        },\n\n        /**\n         * Destroys collection along with its' elements.\n         */\n        destroy: function () {\n            this._super();\n\n            this.elems.each('destroy');\n        },\n\n        /**\n         * Inserts provided component into 'elems' array at a specified position.\n         * @private\n         *\n         * @param {Object} elem - Element to insert.\n         */\n        _insert: function (elem) {\n            var index = _.findKey(this._elems, function (value) {\n                return value === elem.name;\n            });\n\n            if (typeof index !== 'undefined') {\n                this._elems[index] = elem;\n            }\n\n            this._updateCollection()\n                .initElement(elem);\n        },\n\n        /**\n         * Synchronizes multiple elements arrays with a core '_elems' container.\n         * Performs elemets grouping by theirs 'displayArea' property.\n         * @private\n         *\n         * @returns {Collection} Chainable.\n         */\n        _updateCollection: function () {\n            var _elems = compact(this._elems),\n                grouped;\n\n            grouped = _elems.filter(function (elem) {\n                return elem.displayArea && _.isString(elem.displayArea);\n            });\n            grouped = _.groupBy(grouped, 'displayArea');\n\n            _.each(grouped, this.updateRegion, this);\n\n            _.each(this.regions, function (items) {\n                var hasObsoleteComponents = items().length && !_.intersection(_elems, items()).length;\n\n                if (hasObsoleteComponents) {\n                    items.removeAll();\n                }\n            });\n\n            this.elems(_elems);\n\n            return this;\n        },\n\n        /**\n         * Tries to call specified method of a current component,\n         * otherwise delegates attempt to its' children.\n         *\n         * @param {String} target - Name of the method.\n         * @param {...*} parameters - Arguments that will be passed to method.\n         * @returns {*} Result of the method calls.\n         */\n        delegate: function (target) {\n            var args = _.toArray(arguments);\n\n            target = this[target];\n\n            if (_.isFunction(target)) {\n                return target.apply(this, args.slice(1));\n            }\n\n            return this._delegate(args);\n        },\n\n        /**\n         * Calls 'delegate' method of all of it's children components.\n         * @private\n         *\n         * @param {Array} args - An array of arguments to pass to the next delegation call.\n         * @returns {Array} An array of delegation results.\n         */\n        _delegate: function (args) {\n            var result;\n\n            result = this.elems.map(function (elem) {\n                var target;\n\n                if (!_.isFunction(elem.delegate)) {\n                    target = elem[args[0]];\n\n                    if (_.isFunction(target)) {\n                        return target.apply(elem, args.slice(1));\n                    }\n                } else {\n                    return elem.delegate.apply(elem, args);\n                }\n            });\n\n            return _.flatten(result);\n        }\n    });\n});\n","Magento_Ui/js/lib/core/class.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore',\n    'mageUtils',\n    'mage/utils/wrapper'\n], function (_, utils, wrapper) {\n    'use strict';\n\n    var Class;\n\n    /**\n     * Returns property of an object if\n     * it's his own property.\n     *\n     * @param {Object} obj - Object whose property should be retrieved.\n     * @param {String} prop - Name of the property.\n     * @returns {*} Value of the property or false.\n     */\n    function getOwn(obj, prop) {\n        return _.isObject(obj) && obj.hasOwnProperty(prop) && obj[prop];\n    }\n\n    /**\n     * Creates constructor function which allows\n     * initialization without usage of a 'new' operator.\n     *\n     * @param {Object} protoProps - Prototypal properties of a new constructor.\n     * @param {Function} constructor\n     * @returns {Function} Created constructor.\n     */\n    function createConstructor(protoProps, constructor) {\n        var UiClass = constructor;\n\n        if (!UiClass) {\n\n            /**\n             * Default constructor function.\n             */\n            UiClass = function () {\n                var obj = this;\n\n                if (!_.isObject(obj) || Object.getPrototypeOf(obj) !== UiClass.prototype) {\n                    obj = Object.create(UiClass.prototype);\n                }\n\n                obj.initialize.apply(obj, arguments);\n\n                return obj;\n            };\n        }\n\n        UiClass.prototype = protoProps;\n        UiClass.prototype.constructor = UiClass;\n\n        return UiClass;\n    }\n\n    Class = createConstructor({\n\n        /**\n         * Entry point to the initialization of constructor's instance.\n         *\n         * @param {Object} [options={}]\n         * @returns {Class} Chainable.\n         */\n        initialize: function (options) {\n            this.initConfig(options);\n\n            return this;\n        },\n\n        /**\n         * Recursively extends data specified in constructors' 'defaults'\n         * property with provided options object. Evaluates resulting\n         * object using string templates (see: mage/utils/template.js).\n         *\n         * @param {Object} [options={}]\n         * @returns {Class} Chainable.\n         */\n        initConfig: function (options) {\n            var defaults    = this.constructor.defaults,\n                config      = utils.extend({}, defaults, options || {}),\n                ignored     = config.ignoreTmpls || {},\n                cached      = utils.omit(config, ignored);\n\n            config = utils.template(config, this, false, true);\n\n            _.each(cached, function (value, key) {\n                utils.nested(config, key, value);\n            });\n\n            return _.extend(this, config);\n        }\n    });\n\n    _.extend(Class, {\n        defaults: {\n            ignoreTmpls: {\n                templates: true\n            }\n        },\n\n        /**\n         * Creates new constructor based on a current prototype properties,\n         * extending them with properties specified in 'exender' object.\n         *\n         * @param {Object} [extender={}]\n         * @returns {Function} New constructor.\n         */\n        extend: function (extender) {\n            var parent      = this,\n                parentProto = parent.prototype,\n                childProto  = Object.create(parentProto),\n                child       = createConstructor(childProto, getOwn(extender, 'constructor')),\n                defaults;\n\n            extender = extender || {};\n            defaults = extender.defaults;\n\n            delete extender.defaults;\n\n            _.each(extender, function (method, name) {\n                childProto[name] = wrapper.wrapSuper(parentProto[name], method);\n            });\n\n            child.defaults = utils.extend({}, parent.defaults || {});\n\n            if (defaults) {\n                utils.extend(child.defaults, defaults);\n                extender.defaults = defaults;\n            }\n\n            return _.extend(child, {\n                __super__:  parentProto,\n                extend:     parent.extend\n            });\n        }\n    });\n\n    return Class;\n});\n","Magento_Ui/js/lib/core/element/element.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'ko',\n    'underscore',\n    'mageUtils',\n    'uiRegistry',\n    'uiEvents',\n    'uiClass',\n    './links',\n    '../storage/local'\n], function (ko, _, utils, registry, Events, Class, links) {\n    'use strict';\n\n    var Element;\n\n    /**\n     * Creates observable property using knockouts'\n     * 'observableArray' or 'observable' methods,\n     * depending on a type of 'value' parameter.\n     *\n     * @param {Object} obj - Object to whom property belongs.\n     * @param {String} key - Key of the property.\n     * @param {*} value - Initial value.\n     */\n    function observable(obj, key, value) {\n        var method = Array.isArray(value) ? 'observableArray' : 'observable';\n\n        if (_.isFunction(obj[key]) && !ko.isObservable(obj[key])) {\n            return;\n        }\n\n        if (ko.isObservable(value)) {\n            value = value();\n        }\n\n        ko.isObservable(obj[key]) ?\n            obj[key](value) :\n            obj[key] = ko[method](value);\n    }\n\n    /**\n     * Creates observable property using 'track' method.\n     *\n     * @param {Object} obj - Object to whom property belongs.\n     * @param {String} key - Key of the property.\n     * @param {*} value - Initial value.\n     */\n    function accessor(obj, key, value) {\n        if (_.isFunction(obj[key]) || ko.isObservable(obj[key])) {\n            return;\n        }\n\n        obj[key] = value;\n\n        if (!ko.es5.isTracked(obj, key)) {\n            ko.track(obj, [key]);\n        }\n    }\n\n    Element = _.extend({\n        defaults: {\n            _requested: {},\n            containers: [],\n            exports: {},\n            imports: {},\n            links: {},\n            listens: {},\n            name: '',\n            ns: '${ $.name.split(\".\")[0] }',\n            provider: '',\n            registerNodes: true,\n            source: null,\n            statefull: {},\n            template: '',\n            tracks: {},\n            storageConfig: {\n                provider: 'localStorage',\n                namespace: '${ $.name }',\n                path: '${ $.storageConfig.provider }:${ $.storageConfig.namespace }'\n            },\n            maps: {\n                imports: {},\n                exports: {}\n            },\n            modules: {\n                storage: '${ $.storageConfig.provider }'\n            }\n        },\n\n        /**\n         * Initializes model instance.\n         *\n         * @returns {Element} Chainable.\n         */\n        initialize: function () {\n            this._super()\n                .initObservable()\n                .initModules()\n                .initStatefull()\n                .initLinks()\n                .initUnique();\n\n            return this;\n        },\n\n        /**\n         * Initializes observable properties.\n         *\n         * @returns {Element} Chainable.\n         */\n        initObservable: function () {\n            _.each(this.tracks, function (enabled, key) {\n                if (enabled) {\n                    this.track(key);\n                }\n            }, this);\n\n            return this;\n        },\n\n        /**\n         * Parses 'modules' object and creates\n         * async wrappers for specified components.\n         *\n         * @returns {Element} Chainable.\n         */\n        initModules: function () {\n            _.each(this.modules, function (name, property) {\n                if (name) {\n                    this[property] = this.requestModule(name);\n                }\n            }, this);\n\n            if (!_.isFunction(this.source)) {\n                this.source = registry.get(this.provider);\n            }\n\n            return this;\n        },\n\n        /**\n         * Called when current element was injected to another component.\n         *\n         * @param {Object} parent - Instance of a 'parent' component.\n         * @returns {Collection} Chainable.\n         */\n        initContainer: function (parent) {\n            this.containers.push(parent);\n\n            return this;\n        },\n\n        /**\n         * Initializes statefull properties\n         * based on the keys of 'statefull' object.\n         *\n         * @returns {Element} Chainable.\n         */\n        initStatefull: function () {\n            _.each(this.statefull, function (path, key) {\n                if (path) {\n                    this.setStatefull(key, path);\n                }\n            }, this);\n\n            return this;\n        },\n\n        /**\n         * Initializes links between properties.\n         *\n         * @returns {Element} Chainbale.\n         */\n        initLinks: function () {\n            return this.setListeners(this.listens)\n                       .setLinks(this.links, 'imports')\n                       .setLinks(this.links, 'exports')\n                       .setLinks(this.exports, 'exports')\n                       .setLinks(this.imports, 'imports');\n        },\n\n        /**\n         * Initializes listeners of the unique property.\n         *\n         * @returns {Element} Chainable.\n         */\n        initUnique: function () {\n            var update = this.onUniqueUpdate.bind(this),\n                uniqueNs = this.uniqueNs;\n\n            this.hasUnique = this.uniqueProp && uniqueNs;\n\n            if (this.hasUnique) {\n                this.source.on(uniqueNs, update, this.name);\n            }\n\n            return this;\n        },\n\n        /**\n         * Makes specified property to be stored automatically.\n         *\n         * @param {String} key - Name of the property\n         *      that will be stored.\n         * @param {String} [path=key] - Path to the property in storage.\n         * @returns {Element} Chainable.\n         */\n        setStatefull: function (key, path) {\n            var link = {};\n\n            path        = !_.isString(path) || !path ? key : path;\n            link[key]   = this.storageConfig.path + '.' + path;\n\n            this.setLinks(link, 'imports')\n                .setLinks(link, 'exports');\n\n            return this;\n        },\n\n        /**\n         * Updates property specified in uniqueNs\n         * if elements' unique property is set to 'true'.\n         *\n         * @returns {Element} Chainable.\n         */\n        setUnique: function () {\n            var property = this.uniqueProp;\n\n            if (this[property]()) {\n                this.source.set(this.uniqueNs, this.name);\n            }\n\n            return this;\n        },\n\n        /**\n         * Creates 'async' wrapper for the specified component\n         * using uiRegistry 'async' method and caches it\n         * in a '_requested' components  object.\n         *\n         * @param {String} name - Name of requested component.\n         * @returns {Function} Async module wrapper.\n         */\n        requestModule: function (name) {\n            var requested = this._requested;\n\n            if (!requested[name]) {\n                requested[name] = registry.async(name);\n            }\n\n            return requested[name];\n        },\n\n        /**\n         * Returns path to elements' template.\n         *\n         * @returns {String}\n         */\n        getTemplate: function () {\n            return this.template;\n        },\n\n        /**\n         * Checks if template was specified for an element.\n         *\n         * @returns {Boolean}\n         */\n        hasTemplate: function () {\n            return !!this.template;\n        },\n\n        /**\n         * Returns value of the nested property.\n         *\n         * @param {String} path - Path to the property.\n         * @returns {*} Value of the property.\n         */\n        get: function (path) {\n            return utils.nested(this, path);\n        },\n\n        /**\n         * Sets provided value as a value of the specified nested property.\n         * Triggers changes notifications, if value has mutated.\n         *\n         * @param {String} path - Path to property.\n         * @param {*} value - New value of the property.\n         * @returns {Element} Chainable.\n         */\n        set: function (path, value) {\n            var data = this.get(path),\n                diffs;\n\n            diffs = !_.isFunction(data) && !this.isTracked(path) ?\n                utils.compare(data, value, path) :\n                false;\n\n            utils.nested(this, path, value);\n\n            if (diffs) {\n                this._notifyChanges(diffs);\n            }\n\n            return this;\n        },\n\n        /**\n         * Removes nested property from the object.\n         *\n         * @param {String} path - Path to the property.\n         * @returns {Element} Chainable.\n         */\n        remove: function (path) {\n            var data = utils.nested(this, path),\n                diffs;\n\n            if (_.isUndefined(data) || _.isFunction(data)) {\n                return this;\n            }\n\n            diffs = utils.compare(data, undefined, path);\n\n            utils.nestedRemove(this, path);\n\n            this._notifyChanges(diffs);\n\n            return this;\n        },\n\n        /**\n         * Creates observable properties for the current object.\n         *\n         * If 'useTrack' flag is set to 'true' then each property will be\n         * created with a ES5 get/set accessor descriptors, instead of\n         * making them an observable functions.\n         * See 'knockout-es5' library for more information.\n         *\n         * @param {Boolean} [useAccessors=false] - Whether to create an\n         *      observable function or to use property accesessors.\n         * @param {(Object|String|Array)} properties - List of observable properties.\n         * @returns {Element} Chainable.\n         *\n         * @example Sample declaration and equivalent knockout methods.\n         *      this.key = 'value';\n         *      this.array = ['value'];\n         *\n         *      this.observe(['key', 'array']);\n         *      =>\n         *          this.key = ko.observable('value');\n         *          this.array = ko.observableArray(['value']);\n         *\n         * @example Another syntaxes of the previous example.\n         *      this.observe({\n         *          key: 'value',\n         *          array: ['value']\n         *      });\n         */\n        observe: function (useAccessors, properties) {\n            var model = this,\n                trackMethod;\n\n            if (typeof useAccessors !== 'boolean') {\n                properties   = useAccessors;\n                useAccessors = false;\n            }\n\n            trackMethod = useAccessors ? accessor : observable;\n\n            if (_.isString(properties)) {\n                properties = properties.split(' ');\n            }\n\n            if (Array.isArray(properties)) {\n                properties.forEach(function (key) {\n                    trackMethod(model, key, model[key]);\n                });\n            } else if (typeof properties === 'object') {\n                _.each(properties, function (value, key) {\n                    trackMethod(model, key, value);\n                });\n            }\n\n            return this;\n        },\n\n        /**\n         * Delegates call to 'observe' method but\n         * with a predefined 'useAccessors' flag.\n         *\n         * @param {(String|Array|Object)} properties - List of observable properties.\n         * @returns {Element} Chainable.\n         */\n        track: function (properties) {\n            this.observe(true, properties);\n\n            return this;\n        },\n\n        /**\n         * Checks if specified property is tracked.\n         *\n         * @param {String} property - Property to be checked.\n         * @returns {Boolean}\n         */\n        isTracked: function (property) {\n            return ko.es5.isTracked(this, property);\n        },\n\n        /**\n         * Invokes subscribers for the provided changes.\n         *\n         * @param {Object} diffs - Object with changes descriptions.\n         * @returns {Element} Chainable.\n         */\n        _notifyChanges: function (diffs) {\n            diffs.changes.forEach(function (change) {\n                this.trigger(change.path, change.value, change);\n            }, this);\n\n            _.each(diffs.containers, function (changes, name) {\n                var value = utils.nested(this, name);\n\n                this.trigger(name, value, changes);\n            }, this);\n\n            return this;\n        },\n\n        /**\n         * Extracts all stored data and sets it to element.\n         *\n         * @returns {Element} Chainable.\n         */\n        restore: function () {\n            var ns = this.storageConfig.namespace,\n                storage = this.storage();\n\n            if (storage) {\n                utils.extend(this, storage.get(ns));\n            }\n\n            return this;\n        },\n\n        /**\n         * Stores value of the specified property in components' storage module.\n         *\n         * @param {String} property\n         * @param {*} [data=this[property]]\n         * @returns {Element} Chainable.\n         */\n        store: function (property, data) {\n            var ns = this.storageConfig.namespace,\n                path = utils.fullPath(ns, property);\n\n            if (arguments.length < 2) {\n                data = this.get(property);\n            }\n\n            this.storage('set', path, data);\n\n            return this;\n        },\n\n        /**\n         * Extracts specified property from storage.\n         *\n         * @param {String} [property] - Name of the property\n         *      to be extracted. If not specified then all of the\n         *      stored will be returned.\n         * @returns {*}\n         */\n        getStored: function (property) {\n            var ns = this.storageConfig.namespace,\n                path = utils.fullPath(ns, property),\n                storage = this.storage(),\n                data;\n\n            if (storage) {\n                data = storage.get(path);\n            }\n\n            return data;\n        },\n\n        /**\n         * Removes stored property.\n         *\n         * @param {String} property - Property to be removed from storage.\n         * @returns {Element} Chainable.\n         */\n        removeStored: function (property) {\n            var ns = this.storageConfig.namespace,\n                path = utils.fullPath(ns, property);\n\n            this.storage('remove', path);\n\n            return this;\n        },\n\n        /**\n         * Destroys current instance along with all of its' children.\n         * @param {Boolean} skipUpdate - skip collection update when element to be destroyed.\n         */\n        destroy: function (skipUpdate) {\n            this._dropHandlers()\n                ._clearRefs(skipUpdate);\n        },\n\n        /**\n         * Removes events listeners.\n         * @private\n         *\n         * @returns {Element} Chainable.\n         */\n        _dropHandlers: function () {\n            this.off();\n\n            if (_.isFunction(this.source)) {\n                this.source().off(this.name);\n            } else if (this.source) {\n                this.source.off(this.name);\n            }\n\n            return this;\n        },\n\n        /**\n         * Removes all references to current instance and\n         * calls 'destroy' method on all of its' children.\n         * @private\n         * @param {Boolean} skipUpdate - skip collection update when element to be destroyed.\n         *\n         * @returns {Element} Chainable.\n         */\n        _clearRefs: function (skipUpdate) {\n            registry.remove(this.name);\n\n            this.containers.forEach(function (parent) {\n                parent.removeChild(this, skipUpdate);\n            }, this);\n\n            return this;\n        },\n\n        /**\n         * Overrides 'EventsBus.trigger' method to implement events bubbling.\n         *\n         * @param {...*} arguments - Any number of arguments that should be passed to the events' handler.\n         * @returns {Boolean} False if event bubbling was canceled.\n         */\n        bubble: function () {\n            var args = _.toArray(arguments),\n                bubble = this.trigger.apply(this, args),\n                result;\n\n            if (!bubble) {\n                return false;\n            }\n\n            this.containers.forEach(function (parent) {\n                result = parent.bubble.apply(parent, args);\n\n                if (result === false) {\n                    bubble = false;\n                }\n            });\n\n            return !!bubble;\n        },\n\n        /**\n         * Callback which fires when property under uniqueNs has changed.\n         */\n        onUniqueUpdate: function (name) {\n            var active = name === this.name,\n                property = this.uniqueProp;\n\n            this[property](active);\n        },\n\n        /**\n         * Clean data form data source.\n         *\n         * @returns {Element}\n         */\n        cleanData: function () {\n            if (this.source && this.source.componentType === 'dataSource') {\n                if (this.elems) {\n                    _.each(this.elems(), function (val) {\n                        val.cleanData();\n                    });\n                } else {\n                    this.source.remove(this.dataScope);\n                }\n            }\n\n            return this;\n        },\n\n        /**\n         * Fallback data.\n         */\n        cacheData: function () {\n            this.cachedComponent = utils.copy(this);\n        },\n\n        /**\n         * Update configuration in component.\n         *\n         * @param {*} oldValue\n         * @param {*} newValue\n         * @param {String} path - path to value.\n         * @returns {Element}\n         */\n        updateConfig: function (oldValue, newValue, path) {\n            var names = path.split('.'),\n                index = _.lastIndexOf(names, 'config') + 1;\n\n            names = names.splice(index, names.length - index).join('.');\n            this.set(names, newValue);\n\n            return this;\n        }\n    }, Events, links);\n\n    return Class.extend(Element);\n});\n","Magento_Ui/js/lib/core/element/links.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'ko',\n    'underscore',\n    'mageUtils',\n    'uiRegistry'\n], function (ko, _, utils, registry) {\n    'use strict';\n\n    /**\n     * Parse provided data.\n     *\n     * @param {String} placeholder\n     * @param {String} data\n     * @param {String} direction\n     * @returns {Boolean|Object}\n     */\n    function parseData(placeholder, data, direction) {\n        if (typeof data !== 'string') {\n            return false;\n        }\n\n        data = data.split(':');\n\n        if (!data[0]) {\n            return false;\n        }\n\n        if (!data[1]) {\n            data[1] = data[0];\n            data[0] = placeholder;\n        }\n\n        return {\n            target: data[0],\n            property: data[1],\n            direction: direction\n        };\n    }\n\n    /**\n     * Check if value not empty.\n     *\n     * @param {*} value\n     * @returns {Boolean}\n     */\n    function notEmpty(value) {\n        return typeof value !== 'undefined' && value != null;\n    }\n\n    /**\n     * Update value for linked component.\n     *\n     * @param {Object} data\n     * @param {Object} owner\n     * @param {Object} target\n     * @param {*} value\n     */\n    function updateValue(data, owner, target, value) {\n        var component = target.component,\n            property = target.property,\n            linked = data.linked;\n\n        if (data.mute) {\n            return;\n        }\n\n        if (linked) {\n            linked.mute = true;\n        }\n\n        if (owner.component !== target.component) {\n            value = data.inversionValue ? !utils.copy(value) : utils.copy(value);\n        }\n\n        component.set(property, value, owner);\n\n        if (property === 'disabled' && value) {\n            component.set('validate', value, owner);\n        }\n\n        if (linked) {\n            linked.mute = false;\n        }\n    }\n\n    /**\n     * Get value form owner component property.\n     *\n     * @param {Object} owner\n     * @returns {*}\n     */\n    function getValue(owner) {\n        var component = owner.component,\n            property = owner.property;\n\n        return component.get(property);\n    }\n\n    /**\n     * Format provided params to object.\n     *\n     * @param {String} ownerComponent\n     * @param {String} targetComponent\n     * @param {String} ownerProp\n     * @param {String} targetProp\n     * @param {String} direction\n     * @returns {Object}\n     */\n    function form(ownerComponent, targetComponent, ownerProp, targetProp, direction) {\n        var result,\n            tmp;\n\n        result = {\n            owner: {\n                component: ownerComponent,\n                property: ownerProp\n            },\n            target: {\n                component: targetComponent,\n                property: targetProp\n            }\n        };\n\n        if (direction === 'exports') {\n            tmp = result.owner;\n            result.owner = result.target;\n            result.target = tmp;\n        }\n\n        return result;\n    }\n\n    /**\n     * Set data to linked property.\n     *\n     * @param {Object} map\n     * @param {Object} data\n     */\n    function setLinked(map, data) {\n        var match;\n\n        if (!map) {\n            return;\n        }\n\n        match = _.findWhere(map, {\n            linked: false,\n            target: data.target,\n            property: data.property\n        });\n\n        if (match) {\n            match.linked = data;\n            data.linked = match;\n        }\n    }\n\n    /**\n     * Set data by direction.\n     *\n     * @param {Object} maps\n     * @param {String} property\n     * @param {Object} data\n     */\n    function setData(maps, property, data) {\n        var direction   = data.direction,\n            map         = maps[direction];\n\n        data.linked = false;\n\n        (map[property] = map[property] || []).push(data);\n\n        direction = direction === 'imports' ? 'exports' : 'imports';\n\n        setLinked(maps[direction][property], data);\n    }\n\n    /**\n     * Set links for components.\n     *\n     * @param {String} target\n     * @param {String} owner\n     * @param {Object} data\n     * @param {String} property\n     * @param {Boolean} immediate\n     */\n    function setLink(target, owner, data, property, immediate) {\n        var direction = data.direction,\n            formated = form(target, owner, data.property, property, direction),\n            callback,\n            value;\n\n        owner = formated.owner;\n        target = formated.target;\n\n        callback = updateValue.bind(null, data, owner, target);\n\n        owner.component.on(owner.property, callback, target.component.name);\n\n        if (immediate) {\n            value = getValue(owner);\n\n            if (notEmpty(value)) {\n                updateValue(data, owner, target, value);\n            }\n        }\n    }\n\n    /**\n     * Transfer data between components.\n     *\n     * @param {Object} owner\n     * @param {Object} data\n     */\n    function transfer(owner, data) {\n        var args = _.toArray(arguments);\n\n        if (data.target.substr(0, 1) === '!') {\n            data.target = data.target.substr(1);\n            data.inversionValue = true;\n        }\n\n        if (owner.name === data.target) {\n            args.unshift(owner);\n\n            setLink.apply(null, args);\n        } else {\n            registry.get(data.target, function (target) {\n                args.unshift(target);\n\n                setLink.apply(null, args);\n            });\n        }\n    }\n\n    return {\n        /**\n         * Assign listeners.\n         *\n         * @param {Object} listeners\n         * @returns {Object} Chainable\n         */\n        setListeners: function (listeners) {\n            var owner = this,\n                data;\n\n            _.each(listeners, function (callbacks, sources) {\n                sources = sources.split(' ');\n                callbacks = callbacks.split(' ');\n\n                sources.forEach(function (target) {\n                    callbacks.forEach(function (callback) {//eslint-disable-line max-nested-callbacks\n                        data = parseData(owner.name, target, 'imports');\n\n                        if (data) {\n                            setData(owner.maps, callback, data);\n                            transfer(owner, data, callback);\n                        }\n                    });\n                });\n            });\n\n            return this;\n        },\n\n        /**\n         * Set links in provided direction.\n         *\n         * @param {Object} links\n         * @param {String} direction\n         * @returns {Object} Chainable\n         */\n        setLinks: function (links, direction) {\n            var owner = this,\n                property,\n                data;\n\n            for (property in links) {\n                if (links.hasOwnProperty(property)) {\n                    data = parseData(owner.name, links[property], direction);\n\n                    if (data) {//eslint-disable-line max-depth\n                        setData(owner.maps, property, data);\n                        transfer(owner, data, property, true);\n                    }\n                }\n            }\n\n            return this;\n        }\n    };\n});\n","Magento_Ui/js/lib/core/storage/local.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore',\n    'uiRegistry',\n    'mageUtils',\n    'uiEvents'\n], function (_, registry, utils, EventsBus) {\n    'use strict';\n\n    var root = 'appData',\n        localStorage,\n        hasSupport,\n        storage;\n\n    /**\n     * Flag which indicates whether localStorage is supported.\n     */\n    hasSupport = (function () {\n        var key = '_storageSupported';\n\n        try {\n            localStorage = window.localStorage;\n            localStorage.setItem(key, 'true');\n\n            if (localStorage.getItem(key) === 'true') {\n                localStorage.removeItem(key);\n\n                return true;\n            }\n\n            return false;\n        } catch (e) {\n            return false;\n        }\n    })();\n\n    if (!hasSupport) {\n        localStorage = {\n            _data: {},\n\n            /**\n             * Sets value of the specified item.\n             *\n             * @param {String} key - Key of the property.\n             * @param {*} value - Properties' value.\n             */\n            setItem: function (key, value) {\n                this._data[key] = value + '';\n            },\n\n            /**\n             * Retrieves specified item.\n             *\n             * @param {String} key - Key of the property to be retrieved.\n             */\n            getItem: function (key) {\n                return this._data[key];\n            },\n\n            /**\n             * Removes specified item.\n             *\n             * @param {String} key - Key of the property to be removed.\n             */\n            removeItem: function (key) {\n                delete this._data[key];\n            },\n\n            /**\n             * Removes all items.\n             */\n            clear: function () {\n                this._data = {};\n            }\n        };\n    }\n\n    /**\n     * Extracts and parses data stored in localStorage by the\n     * key specified in 'root' variable.\n     *\n     * @returns {Object}\n     */\n    function getRoot() {\n        var data = localStorage.getItem(root),\n            result = {};\n\n        if (!_.isNull(data) && typeof data != 'undefined') {\n            result = JSON.parse(data);\n        }\n\n        return result;\n    }\n\n    /**\n     * Writes provided data to the localStorage.\n     *\n     * @param {*} data - Data to be stored.\n     */\n    function setRoot(data) {\n        localStorage.setItem(root, JSON.stringify(data));\n    }\n\n    /**\n     * Provides methods to work with a localStorage\n     * as a single nested structure.\n     */\n    storage = _.extend({\n\n        /**\n         * Retrieves value of the specified property.\n         *\n         * @param {String} path - Path to the property.\n         *\n         * @example Retrieving data.\n         *      localStorage =>\n         *          'appData' => '\n         *              \"one\": {\"two\": \"three\"}\n         *          '\n         *      storage.get('one.two')\n         *      => \"three\"\n         *\n         *      storage.get('one')\n         *      => {\"two\": \"three\"}\n         */\n        get: function (path) {\n            var data = getRoot();\n\n            return utils.nested(data, path);\n        },\n\n        /**\n         * Sets specified data to the localStorage.\n         *\n         * @param {String} path - Path of the property.\n         * @param {*} value - Value of the property.\n         *\n         * @example Setting data.\n         *      storage.set('one.two', 'four');\n         *      => localStorage =>\n         *          'appData' => '\n         *              \"one\": {\"two\": \"four\"}\n         *          '\n         */\n        set: function (path, value) {\n            var data = getRoot();\n\n            utils.nested(data, path, value);\n\n            setRoot(data);\n        },\n\n        /**\n         * Removes specified data from the localStorage.\n         *\n         * @param {String} path - Path to the property that should be removed.\n         *\n         * @example Removing data.\n         *      storage.remove('one.two', 'four');\n         *      => localStorage =>\n         *          'appData' => '\n         *              \"one\": {}\n         *          '\n         */\n        remove: function (path) {\n            var data = getRoot();\n\n            utils.nestedRemove(data, path);\n\n            setRoot(data);\n        }\n    }, EventsBus);\n\n    registry.set('localStorage', storage);\n\n    return storage;\n});\n","Magento_AdminAnalytics/js/release-notification/modal/component-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['jquery', 'analyticsPopupConfig'], function ($, analyticsPopupConfig) {\n    'use strict';\n\n    var deferred = $.Deferred(),\n\n        mixin = {\n        /**\n         * Initializes content only if its visible\n         */\n        initializeContent: function () {\n            var initializeContent = this._super.bind(this);\n\n            if (!analyticsPopupConfig.analyticsVisible) {\n                initializeContent();\n            } else {\n                deferred.then(function () {\n                    initializeContent();\n                });\n            }\n        },\n\n        /**\n         * Initializes release notification content after admin analytics\n         */\n        initializeContentAfterAnalytics: function () {\n            deferred.resolve();\n        }\n    };\n\n    return function (target) {\n        return target.extend(mixin);\n    };\n});\n\n","Magento_AdminAnalytics/js/modal/component.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore',\n    'jquery',\n    'Magento_Ui/js/modal/modal-component',\n    'uiRegistry',\n    'analyticsPopupConfig'\n],\n    function (_, $, Modal, registry, analyticsPopupConfig) {\n        'use strict';\n\n        return Modal.extend(\n            {\n                defaults: {\n                    imports: {\n                        enableLogAction: '${ $.provider }:data.enableLogAction',\n                        disableLogAction: '${ $.provider }:data.disableLogAction'\n                    },\n                    options: {},\n                    notificationWindow: null\n                },\n\n                /**\n                 * Initializes modal on opened function\n                 */\n                initModal: function () {\n                    this.options.opened = this.onOpened.bind(this);\n                    this._super();\n                },\n\n                /**\n                 * Configure ESC and TAB so user can't leave modal\n                 * without selecting an option\n                 *\n                 * @returns {Object} Chainable.\n                 */\n                initModalEvents: function () {\n                    this._super();\n                    //Don't allow ESC key to close modal\n                    this.options.keyEventHandlers.escapeKey = this.handleEscKey.bind(this);\n                    //Restrict tab action to the modal\n                    this.options.keyEventHandlers.tabKey = this.handleTabKey.bind(this);\n\n                    return this;\n                },\n\n                /**\n                 * Once the modal is opened it hides the X\n                 */\n                onOpened: function () {\n                    $('.modal-header button.action-close').attr('disabled', true).hide();\n\n                    this.focusableElements = $(this.rootSelector).find('a[href], button:enabled');\n                    this.firstFocusableElement = this.focusableElements[0];\n                    this.lastFocusableElement = this.focusableElements[this.focusableElements.length - 1];\n                    this.firstFocusableElement.focus();\n                },\n\n                /**\n                 * Changes admin usage setting to yes\n                 */\n                enableAdminUsage: function () {\n                    var data = {\n                        'form_key': window.FORM_KEY\n                    };\n\n                    $.ajax(\n                        {\n                            type: 'POST',\n                            url: this.enableLogAction,\n                            data: data,\n                            showLoader: true\n                        }\n                    ).done(\n                        function (xhr) {\n                            if (xhr.error) {\n                                self.onError(xhr);\n                            }\n                        }\n                    ).fail(this.onError);\n                    this.openReleasePopup();\n                    this.closeModal();\n                },\n\n                /**\n                 * Changes admin usage setting to no\n                 */\n                disableAdminUsage: function () {\n                    var data = {\n                        'form_key': window.FORM_KEY\n                    };\n\n                    $.ajax(\n                        {\n                            type: 'POST',\n                            url: this.disableLogAction,\n                            data: data,\n                            showLoader: true\n                        }\n                    ).done(\n                        function (xhr) {\n                            if (xhr.error) {\n                                self.onError(xhr);\n                            }\n                        }\n                    ).fail(this.onError);\n                    this.openReleasePopup();\n                    this.closeModal();\n                },\n\n                /**\n                 * Allows admin usage popup to be shown first and then new release notification\n                 */\n                openReleasePopup: function () {\n                    var notificationModalSelector = 'release_notification.release_notification.notification_modal_1';\n\n                    if (analyticsPopupConfig.releaseVisible) {\n                        registry.get(notificationModalSelector).initializeContentAfterAnalytics();\n                    }\n                },\n\n                /**\n                 * Handle Tab and Shift+Tab key event\n                 *\n                 * Keep the tab actions restricted to the popup modal\n                 * so the user must select an option to dismiss the modal\n                 */\n                handleTabKey: function (event) {\n                    var modal = this,\n                        KEY_TAB = 9;\n\n                    /**\n                     * Handle Shift+Tab to tab backwards\n                     */\n                    function handleBackwardTab() {\n                        if (document.activeElement === modal.firstFocusableElement ||\n                            document.activeElement === $(modal.rootSelector)[0]\n                        ) {\n                            event.preventDefault();\n                            modal.lastFocusableElement.focus();\n                        }\n                    }\n\n                    /**\n                     * Handle Tab forward\n                     */\n                    function handleForwardTab() {\n                        if (document.activeElement === modal.lastFocusableElement) {\n                            event.preventDefault();\n                            modal.firstFocusableElement.focus();\n                        }\n                    }\n\n                    switch (event.keyCode) {\n                        case KEY_TAB:\n                            if (modal.focusableElements.length === 1) {\n                                event.preventDefault();\n                                break;\n                            }\n\n                            if (event.shiftKey) {\n                                handleBackwardTab();\n                                break;\n                            }\n                            handleForwardTab();\n                            break;\n                        default:\n                            break;\n                    }\n                },\n\n                /**\n                 * Handle Esc key\n                 *\n                 * Esc key should not close modal\n                 */\n                handleEscKey: function (event) {\n                    event.preventDefault();\n                }\n            }\n        );\n    }\n);\n","Magento_Email/js/variables.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global Variables, updateElementAtCursor */\ndefine([\n    'jquery',\n    'mage/translate',\n    'Magento_Ui/js/modal/modal',\n    'jquery/ui',\n    'prototype'\n], function (jQuery, $t) {\n    'use strict';\n\n    window.Variables = {\n        textareaElementId: null,\n        variablesContent: null,\n        dialogWindow: null,\n        dialogWindowId: 'variables-chooser',\n        overlayShowEffectOptions: null,\n        overlayHideEffectOptions: null,\n        insertFunction: 'Variables.insertVariable',\n        variablesValue: [],\n\n        /**\n         * @param {*} textareaElementId\n         * @param {Function} insertFunction\n         */\n        init: function (textareaElementId, insertFunction) {\n            if ($(textareaElementId)) {\n                this.textareaElementId = textareaElementId;\n            }\n\n            if (insertFunction) {\n                this.insertFunction = insertFunction;\n            }\n        },\n\n        /**\n         * reset data.\n         */\n        resetData: function () {\n            this.variablesContent = null;\n            this.dialogWindow = null;\n        },\n\n        /**\n         * @param {Object} variables\n         */\n        openVariableChooser: function (variables) {\n            if (this.variablesContent == null && variables) {\n                this.variablesContent = '<ul class=\"insert-variable\">';\n                variables.each(function (variableGroup) {\n                    if (variableGroup.label && variableGroup.value) {\n                        this.variablesContent += '<li><b>' + variableGroup.label.escapeHTML() + '</b></li>';\n                        variableGroup.value.each(function (variable) {\n                            if (variable.value && variable.label) {\n                                this.variablesValue.push(variable.value);\n                                this.variablesContent += '<li>' +\n                                    this.prepareVariableRow(this.variablesValue.length, variable.label) + '</li>';\n                            }\n                        }.bind(this));\n                    }\n                }.bind(this));\n                this.variablesContent += '</ul>';\n            }\n\n            if (this.variablesContent) {\n                this.openDialogWindow(this.variablesContent);\n            }\n        },\n\n        /**\n         * @param {*} variablesContent\n         */\n        openDialogWindow: function (variablesContent) {\n            var windowId = this.dialogWindowId;\n\n            jQuery('<div id=\"' + windowId + '\">' + variablesContent + '</div>').modal({\n                title: $t('Insert Variable...'),\n                type: 'slide',\n                buttons: [],\n\n                /** @inheritdoc */\n                closed: function (e, modal) {\n                    modal.modal.remove();\n                }\n            });\n\n            jQuery('#' + windowId).modal('openModal');\n        },\n\n        /**\n         * Close dialog window.\n         */\n        closeDialogWindow: function () {\n            jQuery('#' + this.dialogWindowId).modal('closeModal');\n        },\n\n        /**\n         * @param {Number} index\n         * @param {*} varLabel\n         * @return {String}\n         */\n        prepareVariableRow: function (index, varLabel) {\n            return '<a href=\"#\" onclick=\"' +\n                this.insertFunction +\n                '(' +\n                index +\n                ');return false;\">' +\n                varLabel.escapeHTML() +\n                '</a>';\n        },\n\n        /**\n         * @param {*} variable\n         */\n        insertVariable: function (variable) {\n            var windowId = this.dialogWindowId,\n                textareaElm, scrollPos;\n\n            jQuery('#' + windowId).modal('closeModal');\n            textareaElm = $(this.textareaElementId);\n\n            if (textareaElm) {\n                scrollPos = textareaElm.scrollTop;\n\n                if (!isNaN(variable)) {\n                    updateElementAtCursor(textareaElm, Variables.variablesValue[variable - 1]);\n                } else {\n                    updateElementAtCursor(textareaElm, variable);\n                }\n                textareaElm.focus();\n                textareaElm.scrollTop = scrollPos;\n                jQuery(textareaElm).trigger('change');\n                textareaElm = null;\n            }\n        }\n    };\n\n    window.MagentovariablePlugin = {\n        editor: null,\n        variables: null,\n        textareaId: null,\n\n        /**\n         * @param {*} editor\n         */\n        setEditor: function (editor) {\n            this.editor = editor;\n        },\n\n        /**\n         * @param {String} url\n         * @param {*} textareaId\n         */\n        loadChooser: function (url, textareaId) {\n            this.textareaId = textareaId;\n\n            if (this.variables == null) {\n                new Ajax.Request(url, {\n                    parameters: {},\n                    onComplete: function (transport) {\n                        if (transport.responseText.isJSON()) {\n                            Variables.init(null, 'MagentovariablePlugin.insertVariable');\n                            this.variables = transport.responseText.evalJSON();\n                            this.openChooser(this.variables);\n                        }\n                    }.bind(this)\n                });\n            } else {\n                this.openChooser(this.variables);\n            }\n        },\n\n        /**\n         * @param {*} variables\n         */\n        openChooser: function (variables) {\n            Variables.openVariableChooser(variables);\n        },\n\n        /**\n         * @param {*} value\n         */\n        insertVariable: function (value) {\n            if (this.textareaId) {\n                Variables.init(this.textareaId);\n                Variables.insertVariable(value);\n            } else {\n                Variables.closeDialogWindow();\n                this.editor.execCommand('mceInsertContent', false, value);\n            }\n        }\n    };\n});\n","Magento_InventoryBundleProductAdminUi/js/form/element/grid-column-quantity-per-source.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'mage/translate',\n    'Magento_Ui/js/grid/columns/column'\n], function ($t, Column) {\n    'use strict';\n\n    return Column.extend({\n        defaults: {\n            bodyTmpl: 'Magento_InventoryBundleProductAdminUi/grid/column/quantity-per-source',\n            itemsToDisplay: 3,\n            showFullListDescription: $t('Show more...')\n        },\n\n        /**\n         * Get source items from product data.\n         *\n         * @param {Object} rowData\n         * @returns {Array}\n         */\n        getSourceItemsData: function (rowData) {\n            return rowData['quantity_per_source'];\n        }\n    });\n});\n","Magento_InventoryBundleProductAdminUi/js/form/element/quantity-per-source.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'mage/translate',\n    'Magento_Ui/js/form/element/abstract'\n], function ($t, Abstract) {\n    'use strict';\n\n    return Abstract.extend({\n        defaults: {\n            elementTmpl: 'Magento_InventoryBundleProductAdminUi/dynamic-rows/cells/cell-source',\n            itemsToDisplay: 3,\n            isFullList: true,\n            showFullListDescription: $t('Show more...'),\n            listens: {\n                value: 'updateItems'\n            }\n        },\n\n        /**\n         * Observe elements.\n         *\n         * @returns {exports}\n         */\n        initObservable: function () {\n            this._super()\n                .observe(['items', 'isFullList']);\n\n            return this;\n        },\n\n        /**\n         * Prepare data to use.\n         *\n         * @param {Object} data\n         * @private\n         */\n        updateItems: function (data) {\n            this.isFullList(data.length > this.itemsToDisplay);\n            this.isFullList() ? this.items(data.slice(0, this.itemsToDisplay)) : this.items(data);\n        }\n    });\n});\n","Magento_ConfigurableProduct/js/configurable-type-handler.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'jquery',\n    'Magento_Catalog/catalog/type-events',\n    'collapsible',\n    'Magento_Ui/js/modal/modal',\n    'mage/translate',\n    'domReady!'\n], function ($, productType) {\n    'use strict';\n\n    return {\n        $block: null,\n        hasVariations: null,\n        configurationSectionMessageHandler: (function () {\n            var title = $('[data-role=\"product-create-configuration-info\"]'),\n                buttons = $('[data-action=\"product-create-configuration-buttons\"]'),\n                newText = 'Configurations cannot be created for a standard product with downloadable files.' +\n                ' To create configurations, first remove all downloadable files.',\n                oldText = title.text();\n\n            return function (change) {\n                if (change) {\n                    title.text(newText);\n                    buttons.hide();\n                } else {\n                    title.text(oldText);\n                    buttons.show();\n                }\n            };\n        }()),\n\n        /**\n         * Set element disabled\n         * @param {Object} $element - jquery instance element\n         * @param {Bool} state\n         * @param {Bool} triggerEvent\n         * @private\n         */\n        _setElementDisabled: function ($element, state, triggerEvent) {\n            if (!$element.is('[data-locked]')) {\n                $element.prop('disabled', state);\n\n                if (triggerEvent) {\n                    $element.trigger('change');\n                }\n            }\n        },\n\n        /**\n         * Show\n         */\n        show: function () {\n            this.configurationSectionMessageHandler(false);\n        },\n\n        /**\n         * Hide\n         */\n        hide: function () {\n            this.configurationSectionMessageHandler(true);\n        },\n\n        /**\n         * Bind all\n         */\n        bindAll: function () {\n            $(document).on('changeConfigurableTypeProduct', function (event, isConfigurable) {\n                $(document).trigger('setTypeProduct', isConfigurable ?\n                    'configurable' :\n                    productType.type.init === 'configurable' ? 'simple' : productType.type.init\n                );\n            });\n            $(document).on('changeTypeProduct', this._initType.bind(this));\n        },\n\n        /**\n         * Init type\n         * @private\n         */\n        _initType: function () {\n\n            /*var suggestContainer = $('#product-template-suggest-container .action-dropdown > .action-toggle');\n\n\n            if (productType.type.current === 'configurable') {\n                this._setElementDisabled(suggestContainer.addClass('disabled'), true);\n                this._setElementDisabled($('#inventory_qty'), true);\n                this._setElementDisabled($('#inventory_stock_availability'), false);\n                this._setElementDisabled($('#qty'), true, true);\n                this._setElementDisabled($('#quantity_and_stock_status'), false, false);\n            } else {\n                this._setElementDisabled(suggestContainer.removeClass('disabled'), false);\n                this._setElementDisabled($('#inventory_qty'), false);\n                this._setElementDisabled($('#inventory_stock_availability'), true);\n                this._setElementDisabled($('#qty'), false, true);\n            }\n            */\n\n            /*if (['simple', 'virtual', 'configurable'].indexOf(productType.type.current) < 0) {\n                this.hide();\n            } else {\n                this.show();\n            }*/\n\n            this.show();\n        },\n\n        /**\n         * Constructor component\n         * @param {Object} data - this backend data\n         */\n        'Magento_ConfigurableProduct/js/configurable-type-handler': function (data) {\n            this.$block = $(data.blockId + ' input[name=\"attributes[]\"]');\n            this.hasVariations = data.hasVariations;\n\n            //advancedPricingHandler.init();\n            //priceTypeHandler.init();\n\n            /*if (productType.type.init === 'configurable' && !this.hasVariations) {\n                $(document).trigger('setTypeProduct', 'simple');\n            }*/\n            $(document).trigger('setTypeProduct', 'simple');\n\n            this.bindAll();\n            this._initType();\n        }\n    };\n});\n","Magento_ConfigurableProduct/js/configurable.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**************************** CONFIGURABLE PRODUCT **************************/\n/* global Product, optionsPrice */\ndefine([\n    'jquery',\n    'mage/template',\n    'mage/translate',\n    'prototype'\n], function (jQuery, mageTemplate) {\n    'use strict';\n\n    if (typeof Product == 'undefined') {\n        window.Product = {};\n    }\n\n    Product.Config = Class.create();\n    Product.Config.prototype = {\n        /**\n         * Initialize function.\n         *\n         * @param {Object} config\n         */\n        initialize: function (config) {\n            var separatorIndex, paramsStr, urlValues, i, childSettings, prevSetting, nextSetting;\n\n            // Magic preprocessing\n            // TODO MAGETWO-31539\n            config.taxConfig = {\n                showBothPrices: false,\n                inclTaxTitle: jQuery.mage.__('Incl. Tax')\n            };\n\n            this.config     = config;\n            this.taxConfig  = this.config.taxConfig;\n\n            if (config.containerId) {\n                this.settings   = $$('#' + config.containerId + ' ' + '.super-attribute-select');\n            } else {\n                this.settings   = $$('.super-attribute-select');\n            }\n            this.state      = new Hash();\n            this.priceTemplate = mageTemplate(this.config.template);\n            this.prices     = config.prices;\n            this.values     = {};\n\n            // Set default values from config\n            if (config.defaultValues) {\n                this.values = config.defaultValues;\n            }\n\n            // Overwrite defaults by url\n            separatorIndex = window.location.href.indexOf('#');\n\n            if (separatorIndex != -1) { //eslint-disable-line eqeqeq\n                paramsStr = window.location.href.substr(separatorIndex + 1);\n                urlValues = paramsStr.toQueryParams();\n\n                for (i in urlValues) { //eslint-disable-line guard-for-in\n                    this.values[i] = urlValues[i];\n                }\n            }\n\n            // Overwrite defaults by inputs values if needed\n            if (config.inputsInitialized) {\n                this.values = {};\n                this.settings.each(function (element) {\n                    var attributeId;\n\n                    if (element.value) {\n                        attributeId = element.id.replace(/[a-z]*/, '');\n                        this.values[attributeId] = element.value;\n                    }\n                }.bind(this));\n            }\n\n            // Put events to check select reloads\n            this.settings.each(function (element) {\n                Event.observe(element, 'change', this.configure.bind(this));\n            }.bind(this));\n\n            // fill state\n            this.settings.each(function (element) {\n                var attributeId = element.id.replace(/[a-z]*/, '');\n\n                if (attributeId && this.config.attributes[attributeId]) {\n                    element.config = this.config.attributes[attributeId];\n                    element.attributeId = attributeId;\n                    this.state[attributeId] = false;\n                }\n            }.bind(this));\n\n            // Init settings dropdown\n            childSettings = [];\n\n            for (i = this.settings.length - 1; i >= 0; i--) {\n                prevSetting = this.settings[i - 1] ? this.settings[i - 1] : false;\n                nextSetting = this.settings[i + 1] ? this.settings[i + 1] : false;\n\n                if (i === 0) {\n                    this.fillSelect(this.settings[i]);\n                } else {\n                    this.settings[i].disabled = true;\n                }\n                $(this.settings[i]).childSettings = childSettings.clone();\n                $(this.settings[i]).prevSetting   = prevSetting;\n                $(this.settings[i]).nextSetting   = nextSetting;\n                childSettings.push(this.settings[i]);\n            }\n\n            // Set values to inputs\n            this.configureForValues();\n            document.observe('dom:loaded', this.configureForValues.bind(this));\n        },\n\n        /**\n         * Configure for values.\n         */\n        configureForValues: function () {\n            if (this.values) {\n                this.settings.each(function (element) {\n                    var attributeId = element.attributeId;\n\n                    element.value = typeof this.values[attributeId] === 'undefined' ? '' : this.values[attributeId];\n                    this.configureElement(element);\n                }.bind(this));\n            }\n        },\n\n        /**\n         * @param {Object} event\n         */\n        configure: function (event) {\n            var element = Event.element(event);\n\n            this.configureElement(element);\n        },\n\n        /**\n         * @param {Object} element\n         */\n        configureElement: function (element) {\n            this.reloadOptionLabels(element);\n\n            if (element.value) {\n                this.state[element.config.id] = element.value;\n\n                if (element.nextSetting) {\n                    element.nextSetting.disabled = false;\n                    this.fillSelect(element.nextSetting);\n                    this.resetChildren(element.nextSetting);\n                }\n            } else {\n                this.resetChildren(element);\n            }\n            this.reloadPrice();\n        },\n\n        /**\n         * @param {Object} element\n         */\n        reloadOptionLabels: function (element) {\n            var selectedPrice = 0,\n                option, i;\n\n            if (element.options[element.selectedIndex] && element.options[element.selectedIndex].config) {\n                option = element.options[element.selectedIndex].config;\n                selectedPrice = parseFloat(this.config.optionPrices[option.allowedProducts[0]].finalPrice.amount);\n            }\n            element.setAttribute('price', selectedPrice);\n\n            for (i = 0; i < element.options.length; i++) {\n                if (element.options[i].config) {\n                    element.options[i].setAttribute('price', selectedPrice);\n                    element.options[i].setAttribute('summarizePrice', 0);\n                    element.options[i].text = this.getOptionLabel(element.options[i].config, selectedPrice);\n                }\n            }\n        },\n\n        /* eslint-disable max-depth */\n        /**\n         * @param {Object} element\n         */\n        resetChildren: function (element) {\n            var i;\n\n            if (element.childSettings) {\n                for (i = 0; i < element.childSettings.length; i++) {\n                    element.childSettings[i].selectedIndex = 0;\n                    element.childSettings[i].disabled = true;\n\n                    if (element.config) {\n                        this.state[element.config.id] = false;\n                    }\n                }\n            }\n        },\n\n        /**\n         * @param {Object} element\n         */\n        fillSelect: function (element) {\n            var attributeId = element.id.replace(/[a-z]*/, ''),\n                options = this.getAttributeOptions(attributeId),\n                prevConfig = false,\n                index = 1,\n                i, j, allowedProducts;\n\n            this.clearSelect(element);\n            element.options[0] = new Option('', '');\n            element.options[0].innerHTML = this.config.chooseText;\n\n            if (element.prevSetting) {\n                prevConfig = element.prevSetting.options[element.prevSetting.selectedIndex];\n            }\n\n            if (options) {\n                for (i = 0; i < options.length; i++) {\n                    allowedProducts = [];\n\n                    if (prevConfig) {\n                        for (j = 0; j < options[i].products.length; j++) {\n                            if (prevConfig.config.allowedProducts &&\n                                prevConfig.config.allowedProducts.indexOf(options[i].products[j]) > -1\n                            ) {\n                                allowedProducts.push(options[i].products[j]);\n                            }\n                        }\n                    } else {\n                        allowedProducts = options[i].products.clone();\n                    }\n\n                    if (allowedProducts.size() > 0) {\n                        options[i].allowedProducts = allowedProducts;\n                        element.options[index] = new Option(this.getOptionLabel(options[i]), options[i].id);\n\n                        if (typeof options[i].price != 'undefined') {\n                            element.options[index].setAttribute('price', options[i].price);\n                        }\n                        element.options[index].config = options[i];\n                        index++;\n                    }\n                }\n            }\n        },\n\n        //eslint-enable max-depth\n        /**\n         * @param {Object} option\n         */\n        getOptionLabel: function (option) {\n            return option.label;\n        },\n\n        /**\n         * @param {*} price\n         * @param {Boolean} showSign\n         * @return {String}\n         */\n        formatPrice: function (price, showSign) {\n            var str = '',\n                roundedPrice;\n\n            price = parseFloat(price);\n\n            if (showSign) {\n                if (price < 0) {\n                    str += '-';\n                    price = -price;\n                } else {\n                    str += '+';\n                }\n            }\n\n            roundedPrice = Number(Math.round(price + 'e+2') + 'e-2').toString();\n\n            if (this.prices && this.prices[roundedPrice]) {\n                str += this.prices[roundedPrice];\n            } else {\n                str += this.priceTemplate({\n                    data: {\n                        price: price.toFixed(2)\n                    }\n                });\n            }\n\n            return str;\n        },\n\n        /**\n         * @param {Object} element\n         */\n        clearSelect: function (element) {\n            var i;\n\n            for (i = element.options.length - 1; i >= 0; i--) {\n                element.remove(i);\n            }\n        },\n\n        /**\n         * @param {*} attributeId\n         * @return {*|undefined}\n         */\n        getAttributeOptions: function (attributeId) {\n            if (this.config.attributes[attributeId]) {\n                return this.config.attributes[attributeId].options;\n            }\n        },\n\n        /**\n         * Reload price.\n         *\n         * @return {undefined|Number}\n         */\n        reloadPrice: function () {\n            var price = 0,\n                oldPrice = 0,\n                inclTaxPrice = 0,\n                exclTaxPrice = 0,\n                i, selected;\n\n            if (this.config.disablePriceReload) {\n                return undefined;\n            }\n\n            for (i = this.settings.length - 1; i >= 0; i--) {\n                selected = this.settings[i].options[this.settings[i].selectedIndex];\n\n                if (selected.config) {\n                    price += parseFloat(selected.config.price);\n                    oldPrice += parseFloat(selected.config.oldPrice);\n                    inclTaxPrice += parseFloat(selected.config.inclTaxPrice);\n                    exclTaxPrice += parseFloat(selected.config.exclTaxPrice);\n                }\n            }\n\n            optionsPrice.changePrice(\n                'config', {\n                    'price': price,\n                    'oldPrice': oldPrice,\n                    'inclTaxPrice': inclTaxPrice,\n                    'exclTaxPrice': exclTaxPrice\n                }\n            );\n            optionsPrice.reload();\n\n            return price;\n        },\n\n        /**\n         * Reload old price.\n         */\n        reloadOldPrice: function () {\n            var price, i, selected;\n\n            if (this.config.disablePriceReload) {\n                return;\n            }\n\n            if ($('old-price-' + this.config.productId)) {\n\n                price = parseFloat(this.config.oldPrice);\n\n                for (i = this.settings.length - 1; i >= 0; i--) {\n                    selected = this.settings[i].options[this.settings[i].selectedIndex];\n\n                    if (selected.config) {\n                        price += parseFloat(selected.config.price);\n                    }\n                }\n\n                if (price < 0) {\n                    price = 0;\n                }\n                price = this.formatPrice(price);\n\n                if ($('old-price-' + this.config.productId)) {\n                    $('old-price-' + this.config.productId).innerHTML = price;\n                }\n\n            }\n        }\n    };\n});\n","Magento_ConfigurableProduct/js/variations/variations.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent',\n    'jquery',\n    'ko',\n    'underscore',\n    'Magento_Ui/js/modal/alert',\n    'uiRegistry',\n    'mage/translate'\n], function (Component, $, ko, _, alert, registry, $t) {\n    'use strict';\n\n    /**\n     * @param {*} message\n     * @constructor\n     */\n    function UserException(message) {\n        this.message = message;\n        this.name = 'UserException';\n    }\n    UserException.prototype = Object.create(Error.prototype);\n\n    return Component.extend({\n        defaults: {\n            opened: false,\n            attributes: [],\n            usedAttributes: [],\n            attributeCodes: [],\n            attributesData: {},\n            productMatrix: [],\n            variations: [],\n            formSaveParams: [],\n            productAttributes: [],\n            disabledAttributes: [],\n            fullAttributes: [],\n            rowIndexToEdit: false,\n            productAttributesMap: null,\n            value: [],\n            modules: {\n                associatedProductGrid: '${ $.configurableProductGrid }',\n                wizardButtonElement: '${ $.wizardModalButtonName }',\n                formElement: '${ $.formName }',\n                attributeSetHandlerModal: '${ $.attributeSetHandler }'\n            },\n            imports: {\n                attributeSetName: '${ $.provider }:configurableNewAttributeSetName',\n                attributeSetId: '${ $.provider }:configurableExistingAttributeSetId',\n                attributeSetSelection: '${ $.provider }:configurableAffectedAttributeSet',\n                productPrice: '${ $.provider }:data.product.price'\n            },\n            links: {\n                value: '${ $.provider }:${ $.dataScopeVariations }',\n                usedAttributes: '${ $.provider }:${ $.dataScopeAttributes }',\n                attributesData: '${ $.provider }:${ $.dataScopeAttributesData }',\n                attributeCodes: '${ $.provider }:${ $.dataScopeAttributeCodes }',\n                skeletonAttributeSet: '${ $.provider }:data.new-variations-attribute-set-id'\n            }\n        },\n\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n\n            this.changeButtonWizard();\n            this.initProductAttributesMap();\n            this.disableConfigurableAttributes(this.productAttributes);\n        },\n\n        /** @inheritdoc */\n        initObservable: function () {\n            this._super().observe(\n                'actions opened attributes productMatrix value usedAttributes attributesData attributeCodes'\n            );\n\n            return this;\n        },\n\n        /**\n         * @param {Object} product\n         * @return {Object}\n         * @private\n         */\n        _makeProduct: function (product) {\n            var productId = product['entity_id'] || product.productId || null,\n                attributes = _.pick(product, this.attributes.pluck('code')),\n                options = _.map(attributes, function (option, attribute) {\n                    var oldOptions = _.findWhere(this.attributes(), {\n                            code: attribute\n                        }).options,\n                        result;\n\n                    if (_.isFunction(oldOptions)) {\n                        result = oldOptions.findWhere({\n                            value: option\n                        });\n                    } else {\n                        result = _.findWhere(oldOptions, {\n                            value: option\n                        });\n                    }\n\n                    return result;\n                }.bind(this));\n\n            return {\n                attribute: JSON.stringify(attributes),\n                editable: false,\n                images: {\n                    preview: product['thumbnail_src']\n                },\n                name: product.name || product.sku,\n                options: options,\n                price: parseFloat(Math.round(product.price.replace(/[^\\d.]+/g, '') + 'e+4') + 'e-4').toFixed(4),\n                productId: productId,\n                productUrl: this.buildProductUrl(productId),\n                quantity: product.quantity || null,\n                sku: product.sku,\n                status: product.status === undefined ? 1 : parseInt(product.status, 10),\n                variationKey: this.getVariationKey(options),\n                weight: product.weight || null\n            };\n        },\n\n        /**\n         * @param {String} name\n         * @return {String|Number|Array}\n         */\n        getProductValue: function (name) {\n            var value;\n\n            name = name.split('/').join('][');\n            value = $('[name=\"product[' + name + ']\"]:enabled:not(.ignore-validate)', this.productForm).val();\n            if (value === undefined) {\n                value = this.source.get('data.product.' + name);\n            }\n            return value;\n        },\n\n        /**\n         * @param {Object} data\n         * @param {String} field\n         * @return {String}\n         */\n        getRowId: function (data, field) {\n            var key = data.variationKey;\n\n            return 'variations-matrix-' + key + '-' + field;\n        },\n\n        /**\n         * @param {Object} variation\n         * @param {String} field\n         * @return {String}\n         */\n        getVariationRowName: function (variation, field) {\n            var result;\n\n            if (variation.productId) {\n                result = 'configurations[' + variation.productId + '][' + field.split('/').join('][') + ']';\n            } else {\n                result = 'variations-matrix[' + variation.variationKey + '][' + field.split('/').join('][') + ']';\n            }\n\n            return result;\n        },\n\n        /**\n         * @param {*} variations\n         * @param {*} attributes\n         */\n        render: function (variations, attributes) {\n            this.changeButtonWizard();\n            this.populateVariationMatrix(variations);\n            this.attributes(attributes);\n            this.disableConfigurableAttributes(attributes);\n            this.handleValue(variations);\n            this.handleAttributes();\n        },\n\n        /**\n         * Change button wizard.\n         */\n        changeButtonWizard: function () {\n            if (this.variations.length) {\n                this.wizardButtonElement().title(this.wizardModalButtonTitle);\n            }\n        },\n\n        /**\n         * @param {Array} variations\n         */\n        handleValue: function (variations) {\n            var tmpArray = [];\n\n            _.each(variations, function (variation) {\n                var attributes = _.reduce(variation.options, function (memo, option) {\n                    var attribute = {};\n\n                    attribute[option['attribute_code']] = option.value;\n\n                    return _.extend(memo, attribute);\n                }, {}),\n                    gallery = {\n                        images: {}\n                    },\n                    types = {};\n\n                _.each(variation.images.images, function (image) {\n                    gallery.images[image['file_id']] = {\n                        position: image.position,\n                        file: image.file,\n                        disabled: image.disabled,\n                        label: image.label || ''\n                    };\n                    _.each(image.galleryTypes, function (type) {\n                        types[type] = image.file;\n                    });\n                }, this);\n\n                tmpArray.push(_.extend(variation, types, {\n                    productId: variation.productId || null,\n                    name: variation.name || variation.sku,\n                    priceCurrency: this.currencySymbol,\n                    weight: variation.weight,\n                    attribute: JSON.stringify(attributes),\n                    variationKey: this.getVariationKey(variation.options),\n                    editable: variation.editable === undefined ? 0 : 1,\n                    productUrl: this.buildProductUrl(variation.productId),\n                    status: variation.status === undefined ? 1 : parseInt(variation.status, 10),\n                    newProduct: variation.productId ? 0 : 1,\n                    'media_gallery': gallery\n                }));\n            }, this);\n\n            this.value(tmpArray);\n        },\n\n        /**\n         * Handle attributes.\n         */\n        handleAttributes: function () {\n            var tmpArray = [],\n                codesArray = [],\n                tmpOptions = {},\n                option = {},\n                position = 0,\n                values = {};\n\n            _.each(this.attributes(), function (attribute) {\n                tmpArray.push(attribute.id);\n                codesArray.push(attribute.code);\n                values = {};\n                _.each(attribute.chosen, function (row) {\n                    values[row.value] = {\n                        'include': '1',\n                        'value_index': row.value\n                    };\n                }, this);\n                option = {\n                    'attribute_id': attribute.id,\n                    'code': attribute.code,\n                    'label': attribute.label,\n                    'position': position,\n                    'values': values\n                };\n                tmpOptions[attribute.id] = option;\n                position++;\n            }, this);\n\n            this.attributesData(tmpOptions);\n            this.usedAttributes(tmpArray);\n            this.attributeCodes(codesArray);\n        },\n\n        /**\n         * Get attributes options\n         * @see use in matrix.phtml\n         *\n         * @returns {Array}\n         */\n        getAttributesOptions: function () {\n            return this.showVariations() ? this.productMatrix()[0].options : [];\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        showVariations: function () {\n            return this.productMatrix().length > 0;\n        },\n\n        /**\n         * @param {Array} variations\n         */\n        populateVariationMatrix: function (variations) {\n            this.productMatrix([]);\n            _.each(variations, function (variation) {\n                var attributes = _.reduce(variation.options, function (memo, option) {\n                    var attribute = {};\n\n                    attribute[option['attribute_code']] = option.value;\n\n                    return _.extend(memo, attribute);\n                }, {});\n\n                this.productMatrix.push(_.extend(variation, {\n                    productId: variation.productId || null,\n                    name: variation.name || variation.sku,\n                    weight: variation.weight,\n                    attribute: JSON.stringify(attributes),\n                    variationKey: this.getVariationKey(variation.options),\n                    editable: variation.editable === undefined ? !variation.productId : variation.editable,\n                    productUrl: this.buildProductUrl(variation.productId),\n                    status: variation.status === undefined ? 1 : parseInt(variation.status, 10)\n                }));\n            }, this);\n        },\n\n        /**\n         * @param {*} productId\n         */\n        buildProductUrl: function (productId) {\n            return this.productUrl.replace('%id%', productId);\n        },\n\n        /**\n         * @param {Object} options\n         * @return {String}\n         */\n        getVariationKey: function (options) {\n            return _.pluck(options, 'value').sort().join('-');\n        },\n\n        /**\n         * @param {*} options\n         * @return {*|null}\n         */\n        getProductIdByOptions: function (options) {\n            return this.productAttributesMap[this.getVariationKey(options)] || null;\n        },\n\n        /**\n         * Init product attributes map\n         */\n        initProductAttributesMap: function () {\n            if (this.productAttributesMap === null) {\n                this.productAttributesMap = {};\n                _.each(this.variations, function (product) {\n                    this.productAttributesMap[this.getVariationKey(product.options)] = product.productId;\n                }.bind(this));\n            }\n        },\n\n        /**\n         * @param {Array} attributes\n         */\n        disableConfigurableAttributes: function (attributes) {\n            var element;\n\n            _.each(this.disabledAttributes, function (attribute) {\n                registry.get('inputName = ' + 'product[' + attribute + ']').disabled(false);\n            });\n            this.disabledAttributes = [];\n\n            _.each(attributes, function (attribute) {\n                element = registry.get('inputName = ' + 'product[' + attribute.code + ']');\n\n                if (!_.isUndefined(element)) {\n                    element.disabled(true);\n                    this.disabledAttributes.push(attribute.code);\n                }\n            }, this);\n        },\n\n        /**\n         * Get currency symbol\n         * @returns {String}\n         */\n        getCurrencySymbol: function () {\n            return this.currencySymbol;\n        },\n\n        /**\n         * Chose action for the form save button\n         */\n        saveFormHandler: function () {\n            this.formElement().validate();\n\n            if (this.formElement().source.get('params.invalid') === false) {\n                this.serializeData();\n            }\n\n            if (this.checkForNewAttributes()) {\n                this.formSaveParams = arguments;\n                this.attributeSetHandlerModal().openModal();\n            } else {\n                if (this.validateForm(this.formElement())) {\n                    this.clearOutdatedData();\n                }\n                this.formElement().save(arguments[0], arguments[1]);\n\n                if (this.formElement().source.get('params.invalid')) {\n                    this.unserializeData();\n                }\n            }\n        },\n\n        /**\n         * @param {Object} formElement\n         *\n         * Validates each form element and returns true, if all elements are valid.\n         */\n        validateForm: function (formElement) {\n            formElement.validate();\n\n            return !formElement.additionalInvalid && !formElement.source.get('params.invalid');\n        },\n\n        /**\n         * Serialize data for specific form fields\n         *\n         * Serializes some complex data fields\n         *\n         * Original fields:\n         *   - configurable-matrix;\n         *   - associated_product_ids.\n         *\n         * Serialized fields in request:\n         *   - configurable-matrix-serialized;\n         *   - associated_product_ids_serialized.\n         */\n        serializeData: function () {\n            if (this.source.data['configurable-matrix']) {\n                this.source.data['configurable-matrix-serialized'] =\n                    JSON.stringify(this.source.data['configurable-matrix']);\n            }\n\n            if (this.source.data['associated_product_ids']) {\n                this.source.data['associated_product_ids_serialized'] =\n                    JSON.stringify(this.source.data['associated_product_ids']);\n            }\n        },\n\n        /**\n         * Clear outdated data for specific form fields\n         *\n         * Outdated fields:\n         *   - configurable-matrix;\n         *   - associated_product_ids.\n         */\n        clearOutdatedData: function () {\n            if (this.source.data['configurable-matrix']) {\n                delete this.source.data['configurable-matrix'];\n            }\n\n            if (this.source.data['associated_product_ids']) {\n                delete this.source.data['associated_product_ids'];\n            }\n        },\n\n        /**\n         * Unserialize data for specific form fields\n         *\n         * Unserializes some fields that were serialized this.serializeData\n         */\n        unserializeData: function () {\n            if (this.source.data['configurable-matrix-serialized']) {\n                this.source.data['configurable-matrix'] =\n                    JSON.parse(this.source.data['configurable-matrix-serialized']);\n                delete this.source.data['configurable-matrix-serialized'];\n            }\n\n            if (this.source.data['associated_product_ids_serialized']) {\n                this.source.data['associated_product_ids'] =\n                    JSON.parse(this.source.data['associated_product_ids_serialized']);\n                delete this.source.data['associated_product_ids_serialized'];\n            }\n        },\n\n        /**\n         * Check for newly added attributes\n         * @returns {Boolean}\n         */\n        checkForNewAttributes: function () {\n            var element, newAttributes = false;\n\n            _.each(this.source.get('data.attribute_codes'), function (attribute) {\n                element = registry.get('index = ' + attribute);\n\n                if (_.isUndefined(element)) {\n                    newAttributes = true;\n                }\n            }, this);\n\n            return newAttributes;\n        },\n\n        /**\n         * New attributes handler\n         * @returns {Boolean}\n         */\n        addNewAttributeSetHandler: function () {\n            var chosenAttributeSetOption;\n\n            this.formElement().validate();\n\n            if (this.formElement().source.get('params.invalid') === false) {\n                chosenAttributeSetOption = this.attributeSetSelection;\n\n                if (chosenAttributeSetOption === 'new') {\n                    this.createNewAttributeSet();\n\n                    return false;\n                }\n\n                if (chosenAttributeSetOption === 'existing') {\n                    this.set(\n                        'skeletonAttributeSet',\n                        this.attributeSetId\n                    );\n                }\n\n                this.closeDialogAndProcessForm();\n\n                return true;\n            }\n\n            this.unserializeData();\n\n            return false;\n        },\n\n        /**\n         * Handles new attribute set creation\n         * @returns {Boolean}\n         */\n        createNewAttributeSet: function () {\n            var messageBoxElement = registry.get('index = affectedAttributeSetError');\n\n            messageBoxElement.visible(false);\n\n            $.ajax({\n                type: 'POST',\n                url: this.attributeSetCreationUrl,\n                data: {\n                    gotoEdit: 1,\n                    'attribute_set_name': this.attributeSetName,\n                    'skeleton_set': this.skeletonAttributeSet,\n                    'return_session_messages_only': 1\n                },\n                dataType: 'json',\n                showLoader: true,\n                context: this\n            }).done(function (data) {\n                if (!data.error) {\n                    this.set(\n                        'skeletonAttributeSet',\n                        data.id\n                    );\n                    messageBoxElement.content(data.messages);\n                    messageBoxElement.visible(true);\n                    this.closeDialogAndProcessForm();\n                } else {\n                    messageBoxElement.content(data.messages);\n                    messageBoxElement.visible(true);\n                }\n\n                return false;\n            }).fail(function (xhr) {\n                if (xhr.statusText === 'abort') {\n                    return;\n                }\n\n                alert({\n                    content: $t('Something went wrong.')\n                });\n            });\n\n            return false;\n        },\n\n        /**\n         * Closes attribute set handler modal and process product form\n         */\n        closeDialogAndProcessForm: function () {\n            this.attributeSetHandlerModal().closeModal();\n            this.formElement().save(this.formSaveParams[0], this.formSaveParams[1]);\n        },\n\n        /**\n         * Retrieves product price\n         * @returns {*}\n         */\n        getProductPrice: function () {\n            return this.productPrice;\n        }\n    });\n});\n","Magento_ConfigurableProduct/js/variations/product-grid.js":"// jscs:disable requireDotNotation\n/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent',\n    'jquery',\n    'Magento_Ui/js/core/app',\n    'underscore',\n    'notification',\n    'mage/translate'\n], function (Component, $, bootstrap, _) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            productsGridUrl: null,\n            productAttributes: [],\n            productsModal: null,\n            button: '',\n            gridSelector: '[data-grid-id=associated-products-container]',\n            modules: {\n                productsFilter: '${ $.productsFilter }',\n                productsProvider: '${ $.productsProvider }',\n                productsMassAction: '${ $.productsMassAction }',\n                productsColumns: '${ $.productsColumns }',\n                variationsComponent: '${ $.configurableVariations }'\n            },\n            listens: {\n                '${ $.productsProvider }:data': '_showMessageAssociatedGrid _handleManualGridOpening',\n                '${ $.productsMassAction }:selected': '_handleManualGridSelect',\n                '${ $.configurableVariations }:productMatrix': '_showButtonAddManual _switchProductType'\n            }\n        },\n\n        /**\n         * Initialize\n         *\n         * @param {Array} options\n         */\n        initialize: function (options) {\n            this._super(options);\n            this.productsModal = $(this.gridSelector).modal({\n                title: $.mage.__('Select Associated Product'),\n                type: 'slide',\n                buttons: [\n                    {\n                        text: $.mage.__('Cancel'),\n\n                        /** Close modal */\n                        click: function () {\n                            this.closeModal();\n                        }\n                    }, {\n                        text: $.mage.__('Done'),\n                        click: this.close.bind(this, null)\n                    }\n                ]\n            });\n\n            this.productsProvider(function () {\n                this.productsModal.notification();\n            }.bind(this));\n            this.variationsComponent(function (variation) {\n                this._showButtonAddManual(variation.productMatrix());\n            }.bind(this));\n\n            this._initGrid = _.once(this._initGrid);\n            this._switchProductType = _.wrap(this._switchProductType.bind(this), function (func, params) {\n                if (!!params.length !== !!this.init) {\n                    this.init = !!params.length;\n                    func(params);\n                }\n            }.bind(this._switchProductType));\n        },\n\n        /**\n         * Initial observerable\n         * @returns {*}\n         */\n        initObservable: function () {\n            this._super().observe('button');\n\n            return this;\n        },\n\n        /**\n         * init Grid\n         * @private\n         */\n        _initGrid: function (filterData) {\n            $.ajax({\n                type: 'GET',\n                url: this._buildGridUrl(filterData),\n                context: $('body')\n            }).done(function (data) {\n                bootstrap(JSON.parse(data));\n            });\n        },\n\n        /**\n         * Select different product in configurations section\n         * @see configurable_associated_product_listing.xml\n         * @param {Integer} rowIndex\n         */\n        selectProduct: function (rowIndex) {\n            this.close(rowIndex);\n        },\n\n        /**\n         * Open\n         * @param {Object} filterData - filter data\n         * @param {Object|*} filterData.filters - attribute name\n         * @param {Object|*} filterData.filters_modifier - modifier value\n         * @param {String} callbackName\n         * @param {Boolean} showMassActionColumn\n         */\n        open: function (filterData, callbackName, showMassActionColumn) {\n            this.callbackName = callbackName;\n            this.productsMassAction(function (massActionComponent) {\n                this.productsColumns().elems().each(function (rowElement) {\n                    rowElement.disableAction = showMassActionColumn;\n                });\n                massActionComponent.visible = showMassActionColumn;\n            }.bind(this));\n            this._setFilter(filterData);\n            this._initGrid(filterData);\n            this.productsModal.trigger('openModal');\n        },\n\n        /**\n         * Close\n         */\n        close: function (rowIndex) {\n            try {\n                if (this.productsMassAction().selected.getLength()) {\n                    this.variationsComponent()[this.callbackName](this.productsMassAction()\n                        .selected.map(this.getProductById.bind(this)));\n                    this.productsMassAction().deselectAll();\n                } else if (!_.isNull(rowIndex)) {\n                    this.variationsComponent()[this.callbackName]([this.getProductByIndex(rowIndex)]);\n                }\n                this.productsModal.trigger('closeModal');\n            } catch (e) {\n                if (e.name === 'UserException') {\n                    this.productsModal.notification('clear');\n                    this.productsModal.notification('add', {\n                        message: e.message,\n                        messageContainer: this.gridSelector\n                    });\n                } else {\n                    throw e;\n                }\n            }\n        },\n\n        /**\n         * Get product by id\n         * @param {Integer} productId\n         * @returns {*}\n         */\n        getProductById: function (productId) {\n            return _.findWhere(this.productsProvider().data.items, {\n                'entity_id': productId\n            });\n        },\n\n        /**\n         * Get product\n         * @param {Integer} rowIndex\n         * @returns {*}\n         */\n        getProductByIndex: function (rowIndex) {\n            return this.productsProvider().data.items[rowIndex];\n        },\n\n        /**\n         * Build grid url\n         * @private\n         */\n        _buildGridUrl: function (filterData) {\n            var params = '?' + $.param({\n                'filters': filterData.filters,\n                'attributes_codes': this._getAttributesCodes(),\n                'filters_modifier': filterData['filters_modifier']\n            });\n\n            return this.productsGridUrl + params;\n        },\n\n        /**\n         * Show button add manual\n         * @param {Array} variations\n         * @returns {*}\n         * @private\n         */\n        _showButtonAddManual: function (variations) {\n            return this.button(variations.length);\n        },\n\n        /**\n         * @param {Array} variations\n         * @private\n         */\n        _switchProductType: function (variations) {\n            $(document).trigger('changeConfigurableTypeProduct', variations.length);\n        },\n\n        /**\n         * Get attributes codes used for configurable\n         * @private\n         */\n        _getAttributesCodes: function () {\n            return this.variationsComponent().attributes.pluck('code');\n        },\n\n        /**\n         * Show data associated grid\n         * @private\n         */\n        _showMessageAssociatedGrid: function (data) {\n            this.productsModal.notification('clear');\n\n            if (data.items.length) {\n                this.productsModal.notification('add', {\n                    message: $.mage.__('Choose a new product to delete and replace the current product configuration.'),\n                    messageContainer: this.gridSelector\n                });\n            } else {\n                this.productsModal.notification('add', {\n                    message: $.mage.__('For better results, add attributes and attribute values to your products.'),\n                    messageContainer: this.gridSelector\n                });\n            }\n        },\n\n        /**\n         * Show manually grid\n         */\n        showManuallyGrid: function () {\n            var filterModifier = _.mapObject(_.object(this._getAttributesCodes(), []), function () {\n                    return {\n                        'condition_type': 'notnull'\n                    };\n                }),\n                usedProductIds = _.values(this.variationsComponent().productAttributesMap);\n\n            if (usedProductIds && usedProductIds.length > 0) {\n                filterModifier['entity_id'] = {\n                    'condition_type': 'nin', value: usedProductIds\n                };\n            }\n\n            this.open(\n                {\n                    'filters_modifier': filterModifier\n                },\n                'appendProducts',\n                true\n            );\n        },\n\n        /**\n         * Handle manual grid after opening\n         * @private\n         */\n        _handleManualGridOpening: function (data) {\n            if (data.items.length && this.callbackName == 'appendProducts') { //eslint-disable-line eqeqeq\n                this.productsColumns().elems().each(function (rowElement) {\n                    rowElement.disableAction = true;\n                });\n\n                this._disableRows(data.items);\n            }\n        },\n\n        /**\n         * Disable rows in grid for products with the same variation key\n         *\n         * @param {Array} items\n         * @param {Array} selectedVariationKeys\n         * @param {Array} selected\n         * @private\n         */\n        _disableRows: function (items, selectedVariationKeys, selected) {\n            selectedVariationKeys = selectedVariationKeys === undefined ? [] : selectedVariationKeys;\n            selected = selected === undefined ? [] : selected;\n            this.productsMassAction(function (massaction) {\n                var configurableVariationKeys = _.union(\n                        selectedVariationKeys,\n                        _.pluck(this.variationsComponent().productMatrix(), 'variationKey')\n                    ),\n                    variationKeyMap = this._getVariationKeyMap(items),\n                    rowsForDisable = _.keys(_.pick(\n                        variationKeyMap,\n                        function (variationKey) {\n                            return configurableVariationKeys.indexOf(variationKey) !== -1;\n                        }\n                    ));\n\n                massaction.disabled(_.difference(rowsForDisable, selected));\n            }.bind(this));\n        },\n\n        /**\n         * @private\n         */\n        _handleManualGridSelect: function (selected) {\n            var selectedRows, selectedVariationKeys;\n\n            if (this.callbackName == 'appendProducts') { //eslint-disable-line eqeqeq\n                selectedRows = _.filter(this.productsProvider().data.items, function (row) {\n                    return selected.indexOf(row['entity_id']) !== -1;\n                });\n                selectedVariationKeys = _.values(this._getVariationKeyMap(selectedRows));\n                this._disableRows(this.productsProvider().data.items, selectedVariationKeys, selected);\n            }\n        },\n\n        /**\n         * Get variation key map used in manual grid.\n         *\n         * @param {Object} items\n         * @returns {Array} [{entity_id: variation-key}, ...]\n         * @private\n         */\n        _getVariationKeyMap: function (items) {\n            this._variationKeyMap = {};\n\n            _.each(items, function (row) {\n                this._variationKeyMap[row['entity_id']] = _.values(\n                    _.pick(row, this._getAttributesCodes())\n                ).sort().join('-');\n\n            }, this);\n\n            return this._variationKeyMap;\n        },\n\n        /**\n         * Set filter\n         * @private\n         */\n        _setFilter: function (filterData) {\n            this.productsProvider(function (provider) {\n                provider.params['filters_modifier'] = filterData['filters_modifier'];\n                provider.params['attributes_codes'] = this._getAttributesCodes();\n            }.bind(this));\n\n            this.productsFilter(function (filter) {\n                filter.set('filters', _.extend({\n                    'filters_modifier': filterData['filters_modifier']\n                }, filterData.filters))\n                    .apply();\n            });\n        }\n    });\n});\n","Magento_ConfigurableProduct/js/variations/paging/sizes.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'Magento_Ui/js/grid/paging/sizes'\n], function (Sizes) {\n    'use strict';\n\n    return Sizes.extend({\n        defaults: {\n            options: {\n                '20': {\n                    value: 20,\n                    label: 20\n                },\n                '30': {\n                    value: 30,\n                    label: 30\n                },\n                '50': {\n                    value: 50,\n                    label: 50\n                }\n            },\n            value: 20\n        }\n    });\n});\n","Magento_ConfigurableProduct/js/variations/steps/attributes_values.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent',\n    'jquery',\n    'ko',\n    'underscore',\n    'mageUtils',\n    'Magento_Ui/js/lib/collapsible',\n    'mage/translate'\n], function (Component, $, ko, _, utils, Collapsible) {\n    'use strict';\n\n    //connect items with observableArrays\n    ko.bindingHandlers.sortableList = {\n        /** @inheritdoc */\n        init: function (element, valueAccessor) {\n            var list = valueAccessor();\n\n            $(element).sortable({\n                axis: 'y',\n                handle: '[data-role=\"draggable\"]',\n                tolerance: 'pointer',\n\n                /** @inheritdoc */\n                update: function (event, ui) {\n                    var item = ko.contextFor(ui.item[0]).$data,\n                        position = ko.utils.arrayIndexOf(ui.item.parent().children(), ui.item[0]);\n\n                    if (ko.contextFor(ui.item[0]).$index() != position) { //eslint-disable-line eqeqeq\n                        if (position >= 0) {\n                            list.remove(item);\n                            list.splice(position, 0, item);\n                        }\n                        ui.item.remove();\n                    }\n                }\n            });\n        }\n    };\n\n    return Collapsible.extend({\n        defaults: {\n            notificationMessage: {\n                text: null,\n                error: null\n            },\n            createOptionsUrl: null,\n            attributes: [],\n            stepInitialized: false\n        },\n\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n            this.createAttribute = _.wrap(this.createAttribute, function () {\n                var args = _.toArray(arguments),\n                    createAttribute = args.shift();\n\n                return this.doInitSavedOptions(createAttribute.apply(this, args));\n            });\n            this.createAttribute = _.memoize(this.createAttribute.bind(this), _.property('id'));\n        },\n\n        /** @inheritdoc */\n        initObservable: function () {\n            this._super().observe(['attributes']);\n\n            return this;\n        },\n\n        /**\n         * Create option.\n         */\n        createOption: function () {\n            // this - current attribute\n            this.options.push({\n                value: 0,\n                label: '',\n                id: utils.uniqueid(),\n                'attribute_id': this.id,\n                'is_new': true\n            });\n        },\n\n        /**\n         * @param {Object} option\n         */\n        saveOption: function (option) {\n            if (this.isValidOption(option)) {\n                this.options.remove(option);\n                this.options.push(option);\n                this.chosenOptions.push(option.id);\n            }\n        },\n\n        /**\n         * @param {Object} newOption\n         * @return boolean\n         */\n        isValidOption: function (newOption) {\n            var duplicatedOptions = [],\n                errorOption,\n                allOptions = [];\n\n            newOption.label = newOption.label.trim();\n\n            if (_.isEmpty(newOption.label)) {\n                return false;\n            }\n\n            _.each(this.options(), function (option) {\n                if (!_.isUndefined(allOptions[option.label]) && newOption.label === option.label) {\n                    duplicatedOptions.push(option);\n                }\n\n                allOptions[option.label] = option.label;\n            });\n\n            if (duplicatedOptions.length) {\n                _.each(duplicatedOptions, function (duplicatedOption) {\n                    errorOption = $('[data-role=\"' + duplicatedOption.id + '\"]');\n                    errorOption.addClass('_error');\n                });\n\n                return false;\n            }\n\n            return true;\n        },\n\n        /**\n         * @param {Object} option\n         */\n        removeOption: function (option) {\n            this.options.remove(option);\n        },\n\n        /**\n         * @param {String} attribute\n         */\n        removeAttribute: function (attribute) {\n            this.attributes.remove(attribute);\n            this.wizard.setNotificationMessage(\n                $.mage.__('An attribute has been removed. This attribute will no longer appear in your configurations.')\n            );\n        },\n\n        /**\n         * @param {Object} attribute\n         * @param {*} index\n         * @return {Object}\n         */\n        createAttribute: function (attribute, index) {\n            attribute.chosenOptions = ko.observableArray([]);\n            attribute.options = ko.observableArray(_.map(attribute.options, function (option) {\n                option.id = utils.uniqueid();\n\n                return option;\n            }));\n            attribute.opened = ko.observable(this.initialOpened(index));\n            attribute.collapsible = ko.observable(true);\n            attribute.isValidOption = this.isValidOption;\n\n            return attribute;\n        },\n\n        /**\n         * First 3 attribute panels must be open.\n         *\n         * @param {Number} index\n         * @return {Boolean}\n         */\n        initialOpened: function (index) {\n            return index < 3;\n        },\n\n        /**\n         * Save attribute.\n         */\n        saveAttribute: function () {\n            var errorMessage = $.mage.__('Select options for all attributes or remove unused attributes.');\n\n            if (!this.attributes().length) {\n                throw new Error(errorMessage);\n            }\n\n            _.each(this.attributes(), function (attribute) {\n                attribute.chosen = [];\n\n                if (!attribute.chosenOptions.getLength()) {\n                    throw new Error(errorMessage);\n                }\n                _.each(attribute.chosenOptions(), function (id) {\n                    attribute.chosen.push(attribute.options.findWhere({\n                        id: id\n                    }));\n                });\n            });\n        },\n\n        /**\n         * @param {Object} attribute\n         */\n        selectAllAttributes: function (attribute) {\n            this.chosenOptions(_.pluck(attribute.options(), 'id'));\n        },\n\n        /**\n         * @param {Object} attribute\n         */\n        deSelectAllAttributes: function (attribute) {\n            attribute.chosenOptions.removeAll();\n        },\n\n        /**\n         * @return {Boolean}\n         */\n        saveOptions: function () {\n            var newOptions = [];\n\n            _.each(this.attributes(), function (attribute) {\n                _.each(attribute.options(), function (element) {\n                    var option = attribute.options.findWhere({\n                        id: element.id\n                    });\n\n                    if (option['is_new'] === true) {\n                        if (!attribute.isValidOption(option)) {\n                            throw new Error(\n                                $.mage.__('The value of attribute \"\"%1\"\" must be unique')\n                                    .replace('\"%1\"', attribute.label)\n                            );\n                        }\n\n                        newOptions.push(option);\n                    }\n                });\n            });\n\n            if (!newOptions.length) {\n                return false;\n            }\n\n            $.ajax({\n                type: 'POST',\n                url: this.createOptionsUrl,\n                data: {\n                    options: newOptions\n                },\n                showLoader: true\n            }).done(function (savedOptions) {\n                if (savedOptions.error) {\n                    this.notificationMessage.error = savedOptions.error;\n                    this.notificationMessage.text = savedOptions.message;\n\n                    return;\n                }\n\n                _.each(this.attributes(), function (attribute) {\n                    _.each(savedOptions, function (newOptionId, oldOptionId) {\n                        var option = attribute.options.findWhere({\n                            id: oldOptionId\n                        });\n\n                        if (option) {\n                            attribute.options.remove(option);\n                            option['is_new'] = false;\n                            option.value = newOptionId;\n                            attribute.options.push(option);\n                        }\n                    });\n                });\n\n            }.bind(this));\n        },\n\n        /**\n         * @param {*} attributeIds\n         */\n        requestAttributes: function (attributeIds) {\n            $.ajax({\n                type: 'GET',\n                url: this.optionsUrl,\n                data: {\n                    attributes: attributeIds\n                },\n                showLoader: true\n            }).done(function (attributes) {\n                attributes = _.sortBy(attributes, function (attribute) {\n                    return this.wizard.data.attributesIds.indexOf(attribute.id);\n                }.bind(this));\n                this.attributes(_.map(attributes, this.createAttribute));\n            }.bind(this));\n        },\n\n        /**\n         * @param {*} attribute\n         * @return {*}\n         */\n        doInitSavedOptions: function (attribute) {\n            var selectedOptions, selectedOptionsIds, selectedAttribute = _.findWhere(this.initData.attributes, {\n                id: attribute.id\n            });\n\n            if (selectedAttribute) {\n                selectedOptions = _.pluck(selectedAttribute.chosen, 'value');\n                selectedOptionsIds = _.pluck(_.filter(attribute.options(), function (option) {\n                    return _.contains(selectedOptions, option.value);\n                }), 'id');\n                attribute.chosenOptions(selectedOptionsIds);\n                this.initData.attributes = _.without(this.initData.attributes, selectedAttribute);\n            }\n\n            return attribute;\n        },\n\n        /**\n         * @param {Object} wizard\n         */\n        render: function (wizard) {\n            this.wizard = wizard;\n            this.requestAttributes(wizard.data.attributesIds());\n        },\n\n        /**\n         * @param {Object} wizard\n         */\n        force: function (wizard) {\n            this.saveOptions();\n            this.saveAttribute(wizard);\n\n            wizard.data.attributes = this.attributes;\n        },\n\n        /**\n         * @param {Object} wizard\n         */\n        back: function (wizard) {\n            wizard.data.attributesIds(this.attributes().pluck('id'));\n        }\n    });\n});\n","Magento_ConfigurableProduct/js/variations/steps/bulk.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global FORM_KEY, byteConvert */\ndefine([\n    'uiComponent',\n    'jquery',\n    'ko',\n    'underscore',\n    'Magento_Ui/js/lib/collapsible',\n    'mage/template',\n    'Magento_Ui/js/modal/alert',\n    'Magento_Catalog/js/product-gallery',\n    'jquery/file-uploader',\n    'mage/translate',\n    'Magento_ConfigurableProduct/js/variations/variations'\n], function (Component, $, ko, _, Collapsible, mageTemplate, alert) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            modules: {\n                variationsComponent: '${ $.variationsComponent }'\n            },\n            countVariations: 0,\n            attributes: [],\n            sections: {},\n            images: null,\n            price: '',\n            quantity: '',\n            notificationMessage: {\n                text: null,\n                error: null\n            }\n        },\n\n        /** @inheritdoc */\n        initObservable: function () {\n            this._super().observe('countVariations attributes sections');\n\n            return this;\n        },\n\n        /** @inheritdoc */\n        initialize: function () {\n            var self = this;\n\n            this._super();\n            this.sections({\n                images: {\n                    label: 'images',\n                    type: ko.observable('none'),\n                    value: ko.observable(),\n                    attribute: ko.observable()\n                },\n                price: {\n                    label: 'price',\n                    type: ko.observable('none'),\n                    value: ko.observable(),\n                    attribute: ko.observable(),\n                    currencySymbol: ''\n                },\n                quantity: {\n                    label: 'quantity',\n                    type: ko.observable('none'),\n                    value: ko.observable(),\n                    attribute: ko.observable()\n                }\n            });\n\n            this.variationsComponent(function (variationsComponent) {\n                this.sections().price.currencySymbol = variationsComponent.getCurrencySymbol();\n            }.bind(this));\n\n            /**\n             * Make options sections.\n             */\n            this.makeOptionSections = function () {\n                return {\n                    images: new this.makeImages(null),\n                    price: this.price,\n                    quantity: this.quantity\n                };\n            }.bind(this);\n\n            /**\n             * @param {Object} images\n             * @param {*} typePreview\n             */\n            this.makeImages = function (images, typePreview) {\n                var preview;\n\n                if (!images) {\n                    this.images = [];\n                    this.preview = self.noImage;\n                    this.file = null;\n                } else {\n                    this.images = images;\n                    preview = _.find(this.images, function (image) {\n                        return _.contains(image.galleryTypes, typePreview);\n                    });\n\n                    if (preview) {\n                        this.file = preview.file;\n                        this.preview = preview.url;\n                    } else {\n                        this.file = null;\n                        this.preview = self.noImage;\n                    }\n                }\n            };\n            this.images = new this.makeImages();\n            _.each(this.sections(), function (section) {\n                section.type.subscribe(function () {\n                    this.setWizardNotifyMessageDependOnSectionType();\n                }.bind(this));\n            }, this);\n        },\n        types: ['each', 'single', 'none'],\n\n        /**\n         * Set Wizard notify message depend on section type\n         */\n        setWizardNotifyMessageDependOnSectionType: function () {\n            var flag = false;\n\n            _.each(this.sections(), function (section) {\n                if (section.type() !== 'none') {\n                    flag = true;\n                }\n            }, this);\n\n            if (flag) {\n                this.wizard.setNotificationMessage(\n                    $.mage.__('Choose this option to delete and replace extension data for all past configurations.')\n                );\n            } else {\n                this.wizard.cleanNotificationMessage();\n            }\n        },\n\n        /**\n         * @param {Object} wizard\n         */\n        render: function (wizard) {\n            this.wizard = wizard;\n            this.attributes(wizard.data.attributes());\n\n            if (this.mode === 'edit') {\n                this.setWizardNotifyMessageDependOnSectionType();\n            }\n            //fill option section data\n            this.attributes.each(function (attribute) {\n                attribute.chosen.each(function (option) {\n                    option.sections = ko.observable(this.makeOptionSections());\n                }, this);\n            }, this);\n            //reset section.attribute\n            _.each(this.sections(), function (section) {\n                section.attribute(null);\n            });\n\n            this.initCountVariations();\n            this.bindGalleries();\n        },\n\n        /**\n         * Init count variations.\n         */\n        initCountVariations: function () {\n            var variations = this.generateVariation(this.attributes()),\n                newVariations = _.map(variations, function (options) {\n                    return this.variationsComponent().getVariationKey(options);\n                }.bind(this)),\n                existingVariations = _.keys(this.variationsComponent().productAttributesMap);\n\n            this.countVariations(_.difference(newVariations, existingVariations).length);\n        },\n\n        /**\n         * @param {Object} attributes - example [['b1', 'b2'],['a1', 'a2', 'a3'],['c1', 'c2', 'c3'],['d1']]\n         * @returns {*} example [['b1','a1','c1','d1'],['b1','a1','c2','d1']...]\n         */\n        generateVariation: function (attributes) {\n            return _.reduce(attributes, function (matrix, attribute) {\n                var tmp = [];\n\n                _.each(matrix, function (variations) {\n                    _.each(attribute.chosen, function (option) {\n                        option['attribute_code'] = attribute.code;\n                        option['attribute_label'] = attribute.label;\n                        tmp.push(_.union(variations, [option]));\n                    });\n                });\n\n                if (!tmp.length) {\n                    return _.map(attribute.chosen, function (option) {\n                        option['attribute_code'] = attribute.code;\n                        option['attribute_label'] = attribute.label;\n\n                        return [option];\n                    });\n                }\n\n                return tmp;\n            }, []);\n        },\n\n        /**\n         * @param {*} section\n         * @param {Object} options\n         * @return {*}\n         */\n        getSectionValue: function (section, options) {\n            switch (this.sections()[section].type()) {\n                case 'each':\n                    return _.find(this.sections()[section].attribute().chosen, function (chosen) {\n                        return _.find(options, function (option) {\n                            return chosen.id == option.id; //eslint-disable-line eqeqeq\n                        });\n                    }).sections()[section];\n\n                case 'single':\n                    return this.sections()[section].value();\n\n                case 'none':\n                    return this[section];\n            }\n        },\n\n        /**\n         * @param {*} node\n         * @return {Promise|*}\n         */\n        getImageProperty: function (node) {\n            var types = node.find('[data-role=gallery]').productGallery('option').types,\n                images = _.map(node.find('[data-role=image]'), function (image) {\n                    var imageData = $(image).data('imageData'),\n                        positionElement;\n\n                    imageData.galleryTypes = _.pluck(_.filter(types, function (type) {\n                        return type.value === imageData.file;\n                    }), 'code');\n\n                    //jscs:disable requireCamelCaseOrUpperCaseIdentifiers\n                    positionElement =\n                        $(image).find('[name=\"product[media_gallery][images][' + imageData.file_id + '][position]\"]');\n                    //jscs:enable requireCamelCaseOrUpperCaseIdentifiers\n                    if (!_.isEmpty(positionElement.val())) {\n                        imageData.position = positionElement.val();\n                    }\n\n                    return imageData;\n                });\n\n            return _.reject(images, function (image) {\n                return !!image.isRemoved;\n            });\n        },\n\n        /**\n         * Fill images section.\n         */\n        fillImagesSection: function () {\n            switch (this.sections().images.type()) {\n                case 'each':\n                    if (this.sections().images.attribute()) {\n                        this.sections().images.attribute().chosen.each(function (option) {\n                            option.sections().images = new this.makeImages(\n                                this.getImageProperty($('[data-role=step-gallery-option-' + option.id + ']')),\n                                'thumbnail'\n                            );\n                        }, this);\n                    }\n                    break;\n\n                case 'single':\n                    this.sections().images.value(new this.makeImages(\n                        this.getImageProperty($('[data-role=step-gallery-single]')),\n                        'thumbnail'\n                    ));\n                    break;\n\n                default:\n                    this.sections().images.value(new this.makeImages());\n                    break;\n            }\n        },\n\n        /**\n         * @param {Object} wizard\n         */\n        force: function (wizard) {\n            this.fillImagesSection();\n            this.validate();\n            this.validateImage();\n            wizard.data.sections = this.sections;\n            wizard.data.sectionHelper = this.getSectionValue.bind(this);\n            wizard.data.variations = this.generateVariation(this.attributes());\n        },\n\n        /**\n         * Validate.\n         */\n        validate: function () {\n            var formValid;\n\n            _.each(this.sections(), function (section) {\n                switch (section.type()) {\n                    case 'each':\n                        if (!section.attribute()) {\n                            throw new Error($.mage.__('Please select attribute for {section} section.')\n                                .replace('{section}', section.label));\n                        }\n                        break;\n\n                    case 'single':\n                        if (!section.value()) {\n                            throw new Error($.mage.__('Please fill in the values for {section} section.')\n                                .replace('{section}', section.label));\n                        }\n                        break;\n                }\n            }, this);\n            formValid = true;\n            _.each($('[data-role=attributes-values-form]'), function (form) {\n                formValid = $(form).valid() && formValid;\n            });\n\n            if (!formValid) {\n                throw new Error($.mage.__('Please fill-in correct values.'));\n            }\n        },\n\n        /**\n         * Validate image.\n         */\n        validateImage: function () {\n            switch (this.sections().images.type()) {\n                case 'each':\n                    _.each(this.sections().images.attribute().chosen, function (option) {\n                        if (!option.sections().images.images.length) {\n                            throw new Error($.mage.__('Please select image(s) for your attribute.'));\n                        }\n                    });\n                    break;\n\n                case 'single':\n                    if (this.sections().images.value().file == null) {\n                        throw new Error($.mage.__('Please choose image(s).'));\n                    }\n                    break;\n            }\n        },\n\n        /**\n         * Back.\n         */\n        back: function () {\n            this.setWizardNotifyMessageDependOnSectionType();\n        },\n\n        /**\n         * Bind galleries.\n         */\n        bindGalleries: function () {\n            $('[data-role=bulk-step] [data-role=gallery]').each(function (index, element) {\n                var gallery = $(element),\n                    uploadInput = $(gallery.find('[name=image]')),\n                    dropZone = $(gallery).find('.image-placeholder');\n\n                if (!gallery.data('gallery-initialized')) {\n                    gallery.mage('productGallery', {\n                        template: '[data-template=gallery-content]',\n                        dialogTemplate: '.dialog-template',\n                        dialogContainerTmpl: '[data-role=img-dialog-container-tmpl]'\n                    });\n\n                    uploadInput.fileupload({\n                        dataType: 'json',\n                        dropZone: dropZone,\n                        process: [{\n                            action: 'load',\n                            fileTypes: /^image\\/(gif|jpeg|png)$/\n                        }, {\n                            action: 'resize',\n                            maxWidth: 1920,\n                            maxHeight: 1200\n                        }, {\n                            action: 'save'\n                        }],\n                        formData: {\n                            'form_key': FORM_KEY\n                        },\n                        sequentialUploads: true,\n                        acceptFileTypes: /(\\.|\\/)(gif|jpe?g|png)$/i,\n\n                        /**\n                         * @param {jQuery.Event} e\n                         * @param {Object} data\n                         */\n                        add: function (e, data) {\n                            var progressTmpl = mageTemplate('[data-template=uploader]'),\n                                fileSize,\n                                tmpl;\n\n                            $.each(data.files, function (i, file) {\n                                fileSize = typeof file.size == 'undefined' ?\n                                    $.mage.__('We could not detect a size.') :\n                                    byteConvert(file.size);\n\n                                data.fileId = Math.random().toString(33).substr(2, 18);\n\n                                tmpl = progressTmpl({\n                                    data: {\n                                        name: file.name,\n                                        size: fileSize,\n                                        id: data.fileId\n                                    }\n                                });\n\n                                $(tmpl).appendTo(gallery.find('[data-role=uploader]'));\n                            });\n\n                            $(this).fileupload('process', data).done(function () {\n                                data.submit();\n                            });\n                        },\n\n                        /**\n                         * @param {jQuery.Event} e\n                         * @param {Object} data\n                         */\n                        done: function (e, data) {\n                            if (data.result && !data.result.error) {\n                                gallery.trigger('addItem', data.result);\n                            } else {\n                                $('#' + data.fileId)\n                                    .delay(2000)\n                                    .hide('highlight');\n                                alert({\n                                    content: $.mage.__('We don\\'t recognize or support this file extension type.')\n                                });\n                            }\n                            $('#' + data.fileId).remove();\n                        },\n\n                        /**\n                         * @param {jQuery.Event} e\n                         * @param {Object} data\n                         */\n                        progress: function (e, data) {\n                            var progress = parseInt(data.loaded / data.total * 100, 10),\n                                progressSelector = '#' + data.fileId + ' .progressbar-container .progressbar';\n\n                            $(progressSelector).css('width', progress + '%');\n                        },\n\n                        /**\n                         * @param {jQuery.Event} e\n                         * @param {Object} data\n                         */\n                        fail: function (e, data) {\n                            var progressSelector = '#' + data.fileId;\n\n                            $(progressSelector).removeClass('upload-progress').addClass('upload-failure')\n                                .delay(2000)\n                                .hide('highlight')\n                                .remove();\n                        }\n                    });\n                    gallery.data('gallery-initialized', 1);\n                }\n            });\n        }\n    });\n});\n","Magento_ConfigurableProduct/js/variations/steps/summary.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent',\n    'jquery',\n    'ko',\n    'underscore',\n    'Magento_Ui/js/grid/paging/paging',\n    'mage/translate'\n], function (Component, $, ko, _, paging) {\n    'use strict';\n\n    return Component.extend({\n        defaults: {\n            modules: {\n                variationsComponent: '${ $.variationsComponent }',\n                modalComponent: '${ $.modalComponent }',\n                matrixGridComponent: '${ $.matrixGridComponent }'\n            },\n            notificationMessage: {\n                text: null,\n                error: null\n            },\n            gridExisting: [],\n            gridNew: [],\n            gridDeleted: [],\n            variationsExisting: [],\n            variationsNew: [],\n            variationsDeleted: [],\n            pagingExisting: paging({\n                name: 'configurableWizard.pagingExisting',\n                sizesConfig: {\n                    component: 'Magento_ConfigurableProduct/js/variations/paging/sizes',\n                    name: 'configurableWizard.pagingExisting_sizes'\n                }\n            }),\n            pagingNew: paging({\n                name: 'configurableWizard.pagingNew',\n                sizesConfig: {\n                    component: 'Magento_ConfigurableProduct/js/variations/paging/sizes',\n                    name: 'configurableWizard.pagingNew_sizes'\n                }\n            }),\n            pagingDeleted: paging({\n                name: 'configurableWizard.pagingDeleted',\n                sizesConfig: {\n                    component: 'Magento_ConfigurableProduct/js/variations/paging/sizes',\n                    name: 'configurableWizard.pagingDeleted_sizes'\n                }\n            }),\n            attributes: [],\n            attributesName: [$.mage.__('Images'), $.mage.__('SKU'), $.mage.__('Quantity'), $.mage.__('Price')],\n            sections: [],\n            gridTemplate: 'Magento_ConfigurableProduct/variations/steps/summary-grid',\n            quantityFieldName: 'quantity'\n        },\n\n        /** @inheritdoc */\n        initObservable: function () {\n            var pagingObservables = {\n                currentNew: ko.getObservable(this.pagingNew, 'current'),\n                currentExisting: ko.getObservable(this.pagingExisting, 'current'),\n                currentDeleted: ko.getObservable(this.pagingDeleted, 'current'),\n                pageSizeNew: ko.getObservable(this.pagingNew, 'pageSize'),\n                pageSizeExisting: ko.getObservable(this.pagingExisting, 'pageSize'),\n                pageSizeDeleted: ko.getObservable(this.pagingDeleted, 'pageSize')\n            };\n\n            this._super().observe('gridExisting gridNew gridDeleted attributes sections');\n            this.gridExisting.columns = ko.observableArray();\n            this.gridNew.columns = ko.observableArray();\n            this.gridDeleted.columns = ko.observableArray();\n\n            _.each(pagingObservables, function (observable) {\n                observable.subscribe(function () {\n                    this.generateGrid();\n                }, this);\n            }, this);\n\n            return this;\n        },\n        nextLabelText: $.mage.__('Generate Products'),\n        variations: [],\n\n        /**\n         * @param {*} variations\n         * @param {Function} getSectionValue\n         */\n        calculate: function (variations, getSectionValue) {\n            var productSku = this.variationsComponent().getProductValue('sku'),\n                productPrice = this.variationsComponent().getProductPrice(),\n                productWeight = this.variationsComponent().getProductValue('weight'),\n                productName = this.variationsComponent().getProductValue('name'),\n                variationsKeys = [],\n                gridExisting = [],\n                gridNew = [],\n                gridDeleted = [],\n                matrixGridData = this.matrixGridComponent() ?\n                    _.indexBy(this.matrixGridComponent().getUnionInsertData(), 'variationKey') : {};\n\n            this.variations = [];\n            _.each(variations, function (options) {\n                var product, images, sku, name, quantity, price, variation,\n                    variationsKey = this.variationsComponent().getVariationKey(options),\n                    productDataFromGrid = matrixGridData[variationsKey] || {},\n                    productDataFromWizard = {},\n                    productId = this.variationsComponent().getProductIdByOptions(options);\n\n                if (productId) {\n                    product = _.findWhere(this.variationsComponent().variations, {\n                        productId: productId\n                    });\n                }\n                images = getSectionValue('images', options);\n                sku = productSku + _.reduce(options, function (memo, option) {\n                    return memo + '-' + option.label;\n                }, '');\n                name = productName + _.reduce(options, function (memo, option) {\n                    return memo + '-' + option.label;\n                }, '');\n                quantity = getSectionValue(this.quantityFieldName, options);\n\n                if (quantity) {\n                    productDataFromWizard[this.quantityFieldName] = quantity;\n                }\n                price = getSectionValue('price', options);\n\n                if (price) {\n                    productDataFromWizard.price = price;\n                }\n\n                if (productId && !images.file) {\n                    images = product.images;\n                }\n                productDataFromGrid = _.pick(\n                    productDataFromGrid,\n                    'sku',\n                    'name',\n                    'weight',\n                    'status',\n                    'price',\n                    'qty'\n                );\n\n                if (productDataFromGrid.hasOwnProperty('qty')) {\n                    productDataFromGrid[this.quantityFieldName] = productDataFromGrid.qty;\n                }\n                delete productDataFromGrid.qty;\n                product = _.pick(\n                    product || {},\n                    'sku',\n                    'name',\n                    'weight',\n                    'status',\n                    'price',\n                    this.quantityFieldName\n                );\n                variation = {\n                    options: options,\n                    images: images,\n                    sku: sku,\n                    name: name,\n                    price: productPrice,\n                    productId: productId,\n                    weight: productWeight,\n                    editable: true\n                };\n                variation[this.quantityFieldName] = quantity;\n                variation = _.extend(variation, product, productDataFromGrid, productDataFromWizard);\n\n                if (productId) {\n                    gridExisting.push(this.prepareRowForGrid(variation));\n                } else {\n                    gridNew.push(this.prepareRowForGrid(variation));\n                }\n                this.variations.push(variation);\n                variationsKeys.push(variationsKey);\n            }, this);\n\n            _.each(_.omit(this.variationsComponent().productAttributesMap, variationsKeys), function (productId) {\n                gridDeleted.push(this.prepareRowForGrid(\n                    _.findWhere(this.variationsComponent().variations, {\n                        productId: productId\n                    })\n                ));\n            }.bind(this));\n\n            this.variationsExisting = gridExisting;\n            this.variationsNew = gridNew;\n            this.variationsDeleted = gridDeleted;\n        },\n\n        /**\n         * Generate grid.\n         */\n        generateGrid: function () {\n            var pageExisting = this.pagingExisting.pageSize * this.pagingExisting.current,\n                pageNew = this.pagingNew.pageSize * this.pagingNew.current,\n                pageDeleted = this.pagingDeleted.pageSize * this.pagingDeleted.current;\n\n            this.pagingExisting.totalRecords = this.variationsExisting.length;\n            this.gridExisting(this.variationsExisting.slice(pageExisting - this.pagingExisting.pageSize, pageExisting));\n\n            this.pagingNew.totalRecords = this.variationsNew.length;\n            this.gridNew(this.variationsNew.slice(pageNew - this.pagingNew.pageSize, pageNew));\n\n            this.pagingDeleted.totalRecords = this.variationsDeleted.length;\n            this.gridDeleted(this.variationsDeleted.slice(pageDeleted - this.pagingDeleted.pageSize, pageDeleted));\n        },\n\n        /**\n         * @param {Object} variation\n         * @return {Array}\n         */\n        prepareRowForGrid: function (variation) {\n            var row = [];\n\n            row.push(_.extend({\n                images: []\n            }, variation.images));\n            row.push(variation.sku);\n            row.push(variation[this.quantityFieldName]);\n            _.each(variation.options, function (option) {\n                row.push(option.label);\n            });\n            row.push(this.variationsComponent().getCurrencySymbol() +  ' ' + variation.price);\n\n            return row;\n        },\n\n        /**\n         * @return {String|*}\n         */\n        getGridTemplate: function () {\n            return this.gridTemplate;\n        },\n\n        /**\n         * @return {*|String}\n         */\n        getGridId: function () {\n            return _.uniqueId('grid_');\n        },\n\n        /**\n         * @param {*} attributes\n         * @return {Array}\n         */\n        getColumnsName: function (attributes) {\n            var columns = this.attributesName.slice(0);\n\n            attributes.each(function (attribute, index) {\n                columns.splice(3 + index, 0, attribute.label);\n            }, this);\n\n            return columns;\n        },\n\n        /**\n         * @param {Object} wizard\n         */\n        render: function (wizard) {\n            this.wizard = wizard;\n            this.sections(wizard.data.sections());\n            this.attributes(wizard.data.attributes());\n            this.gridNew([]);\n            this.gridExisting([]);\n            this.gridDeleted([]);\n            this.gridExisting.columns(this.getColumnsName(this.wizard.data.attributes));\n            this.gridNew.columns(this.getColumnsName(this.wizard.data.attributes));\n            this.gridDeleted.columns(this.getColumnsName(this.variationsComponent().productAttributes));\n            this.calculate(wizard.data.variations, wizard.data.sectionHelper);\n            this.generateGrid();\n        },\n\n        /**\n         * Force.\n         */\n        force: function () {\n            this.variationsComponent().render(this.variations, this.attributes());\n            this.modalComponent().closeModal();\n        },\n\n        /**\n         * Back.\n         */\n        back: function () {\n        }\n    });\n});\n","Magento_ConfigurableProduct/js/variations/steps/select_attributes.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent',\n    'jquery',\n    'underscore',\n    'mage/translate'\n], function (Component, $, _) {\n    'use strict';\n\n    /**\n     * @param {Function} provider\n     */\n    var initNewAttributeListener = function (provider) {\n        $('[data-role=product-variations-matrix]').on('add', function () {\n            provider().reload();\n        });\n    };\n\n    return Component.extend({\n        attributesLabels: {},\n        stepInitialized: false,\n        defaults: {\n            modules: {\n                multiselect: '${ $.multiselectName }',\n                attributeProvider: '${ $.providerName }'\n            },\n            listens: {\n                '${ $.multiselectName }:selected': 'doSelectedAttributesLabels',\n                '${ $.multiselectName }:rows': 'doSelectSavedAttributes'\n            },\n            notificationMessage: {\n                text: null,\n                error: null\n            },\n            selectedAttributes: []\n        },\n\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n            this.selected = [];\n\n            initNewAttributeListener(this.attributeProvider);\n        },\n\n        /** @inheritdoc */\n        initObservable: function () {\n            this._super().observe(['selectedAttributes']);\n\n            return this;\n        },\n\n        /**\n         * @param {Object} wizard\n         */\n        render: function (wizard) {\n            this.wizard = wizard;\n            this.setNotificationMessage();\n        },\n\n        /**\n         * Set notification message.\n         */\n        setNotificationMessage: function () {\n            /*eslint-disable max-len*/\n            var msg = $.mage.__('When you remove or add an attribute, we automatically update all configurations and you will need to recreate current configurations manually.');\n\n            /*eslint-enable max-len*/\n\n            if (this.mode === 'edit') {\n                this.wizard.setNotificationMessage(msg);\n            }\n        },\n\n        /**\n         * Do select saved attributes.\n         */\n        doSelectSavedAttributes: function () {\n            if (this.stepInitialized === false) {\n                this.stepInitialized = true;\n                //cache attributes labels, which can be present on the 2nd page\n                _.each(this.initData.attributes, function (attribute) {\n                    this.attributesLabels[attribute.id] = attribute.label;\n                }.bind(this));\n                this.multiselect().selected(_.pluck(this.initData.attributes, 'id'));\n            }\n        },\n\n        /**\n         * @param {*} selected\n         */\n        doSelectedAttributesLabels: function (selected) {\n            var labels = [];\n\n            this.selected = selected;\n            _.each(selected, function (attributeId) {\n                var attribute;\n\n                if (!this.attributesLabels[attributeId]) {\n                    attribute = _.findWhere(this.multiselect().rows(), {\n                        'attribute_id': attributeId\n                    });\n\n                    if (attribute) {\n                        this.attributesLabels[attribute['attribute_id']] = attribute['frontend_label'];\n                    }\n                }\n                labels.push(this.attributesLabels[attributeId]);\n            }.bind(this));\n            this.selectedAttributes(labels.join(', '));\n        },\n\n        /**\n         * @param {Object} wizard\n         */\n        force: function (wizard) {\n            wizard.data.attributesIds = this.multiselect().selected;\n\n            if (!wizard.data.attributesIds() || wizard.data.attributesIds().length === 0) {\n                throw new Error($.mage.__('Please select attribute(s).'));\n            }\n            this.setNotificationMessage();\n        },\n\n        /**\n         * Back.\n         */\n        back: function () {\n        }\n    });\n});\n","Magento_ConfigurableProduct/js/options/price-type-handler.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/*\ndefine([\n    'jquery',\n    'Magento_Catalog/catalog/type-events',\n    'notification',\n    'mage/translate'\n], function ($, productType) {\n    'use strict';\n\n    return {\n        isConfigurable: false,\n        messageInited: false,\n        messageSelector: '[data-role=product-custom-options-content]',\n        isPercentPriceTypeExist: function () {\n            var productOptionsContainer = $('#product_options_container_top');\n\n            return !!productOptionsContainer.length;\n        },\n        showWarning: function () {\n            if (!this.messageInited) {\n                $(this.messageSelector).notification();\n                this.messageInited = true;\n            }\n            this.hideWarning();\n            $(this.messageSelector).notification('add', {\n                message: $.mage.__('Custom options with price type \"percent\" is not available for ' +\n                    'configurable product.'),\n                error: false,\n                messageContainer: this.messageSelector\n            });\n        },\n        hideWarning: function () {\n            $(this.messageSelector).notification('clear');\n        },\n        init: function () {\n            $(document).on('changeTypeProduct', this._initType.bind(this));\n\n            $('#product-edit-form-tabs').on('change', '.opt-type > select', function () {\n                var selected = $('.opt-type > select :selected'),\n                    optGroup = selected.parent().attr('label');\n\n                if (optGroup === 'Select') {\n                    $('#product-edit-form-tabs').on(\n                        'click',\n                        '[data-ui-id=\"admin-product-options-options-box-select-option-type-add-select-row-button\"]',\n                        function () {\n                            this.percentPriceTypeHandler();\n                        }.bind(this)\n                    );\n                } else {\n                    this.percentPriceTypeHandler();\n                }\n            }.bind(this));\n\n            this._initType();\n        },\n        _initType: function () {\n            this.isConfigurable = productType.type.current === 'configurable';\n            if (this.isPercentPriceTypeExist()) {\n                this.percentPriceTypeHandler();\n            }\n        },\n        percentPriceTypeHandler: function () {\n            var priceType = $('[data-attr=\"price-type\"]'),\n                optionPercentPriceType = priceType.find('option[value=\"percent\"]');\n\n            if (this.isConfigurable) {\n                this.showWarning();\n                optionPercentPriceType.hide();\n                optionPercentPriceType.parent().val() === 'percent' ? optionPercentPriceType.parent().val('fixed') : '';\n            } else {\n                $(this.messageSelector).notification();\n                optionPercentPriceType.show();\n                this.hideWarning();\n            }\n        }\n    };\n});\n*/\n","Magento_ConfigurableProduct/js/components/custom-options-warning.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'Magento_Ui/js/form/components/html'\n], function (Html) {\n    'use strict';\n\n    return Html.extend({\n        defaults: {\n            isConfigurable: false\n        },\n\n        /**\n         * Updates component visibility state.\n         *\n         * @param {Boolean} variationsEmpty\n         * @returns {Boolean}\n         */\n        updateVisibility: function (variationsEmpty) {\n            var isVisible = this.isConfigurable || !variationsEmpty;\n\n            this.visible(isVisible);\n\n            return isVisible;\n        }\n    });\n});\n","Magento_ConfigurableProduct/js/components/file-uploader.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'Magento_Ui/js/form/element/file-uploader',\n    'underscore'\n], function (Element, _) {\n    'use strict';\n\n    return Element.extend({\n        processedFile: {},\n        actionsListOpened: false,\n        thumbnailUrl: '',\n        thumbnail: null,\n        smallImage: null,\n        defaults: {\n            fileInputName: ''\n        },\n\n        /**\n         * Initialize observables.\n         *\n         * @returns {Object} Chainable.\n         */\n        initObservable: function () {\n            this._super().observe(['processedFile', 'actionsListOpened', 'thumbnailUrl', 'thumbnail', 'smallImage']);\n\n            return this;\n        },\n\n        /** @inheritdoc */\n        setInitialValue: function () {\n            var value = this.getInitialValue();\n\n            if (!_.isString(value)) {\n                this._super();\n            }\n\n            return this;\n        },\n\n        /**\n         * Adds provided file to the files list.\n         *\n         * @param {Object} file\n         * @returns {Object} Chainable.\n         */\n        addFile: function (file) {\n            this.processedFile(this.processFile(file));\n\n            this.value(this.processedFile().file);\n\n            return this;\n        },\n\n        /**\n         * Toggle actions list.\n         *\n         * @returns {Object} Chainable.\n         */\n        toggleActionsList: function () {\n            if (this.actionsListOpened()) {\n                this.actionsListOpened(false);\n            } else {\n                this.actionsListOpened(true);\n            }\n\n            return this;\n        },\n\n        /**\n         * Close action list.\n         *\n         * @returns {Object} Chainable\n         */\n        closeList: function () {\n            if (this.actionsListOpened()) {\n                this.actionsListOpened(false);\n            }\n\n            return this;\n        },\n\n        /**\n         * Delete Image\n         *\n         * @returns {Object} Chainable\n         */\n        deleteImage: function () {\n            this.processedFile({});\n            this.value(null);\n            this.thumbnail(null);\n            this.thumbnailUrl(null);\n            this.smallImage(null);\n\n            return this;\n        }\n    });\n});\n","Magento_ConfigurableProduct/js/components/associated-product-insert-listing.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore',\n    'Magento_Ui/js/form/components/insert-listing'\n], function (_, insertListing) {\n    'use strict';\n\n    return insertListing.extend({\n        defaults: {\n            gridInitialized: false,\n            paramsUpdated: false,\n            showMassActionColumn: true,\n            currentProductId: 0,\n            dataScopeAssociatedProduct: 'data.associated_product_ids',\n            typeGrid: '',\n            product: {},\n            rowIndexForChange: undefined,\n            changeProductData: [],\n            modules: {\n                productsProvider: '${ $.productsProvider }',\n                productsColumns: '${ $.productsColumns }',\n                productsMassAction: '${ $.productsMassAction }',\n                modalWithGrid: '${ $.modalWithGrid }',\n                productsFilters: '${ $.productsFilters }'\n            },\n            exports: {\n                externalProviderParams: '${ $.externalProvider }:params'\n            },\n            links: {\n                changeProductData: '${ $.provider }:${ $.changeProductProvider }'\n            },\n            listens: {\n                '${ $.externalProvider }:params': '_setFilters _setVisibilityMassActionColumn',\n                '${ $.productsProvider }:data': '_handleManualGridOpening',\n                '${ $.productsMassAction }:selected': '_handleManualGridSelect'\n            }\n        },\n\n        /**\n         * Initialize observables.\n         *\n         * @returns {Object} Chainable.\n         */\n        initObservable: function () {\n            this._super().observe(\n                'changeProductData'\n            );\n\n            return this;\n        },\n\n        /**\n         * Get ids of used products.\n         *\n         * @returns {Array}\n         */\n        getUsedProductIds: function () {\n            var usedProductsIds = this.source.get(this.dataScopeAssociatedProduct);\n\n            return usedProductsIds.slice();\n        },\n\n        /**\n         * Request for render content.\n         *\n         * @returns {Object}\n         */\n        doRender: function (showMassActionColumn, typeGrid) {\n            this.typeGrid = typeGrid;\n            this.showMassActionColumn = showMassActionColumn;\n\n            if (this.gridInitialized) {\n                this.paramsUpdated = false;\n                this.productsFilters().clear();\n                this._setFilters(this.externalProviderParams);\n                this._setVisibilityMassActionColumn();\n            }\n\n            return this.render();\n        },\n\n        /**\n         * Show grid with assigned product.\n         *\n         * @returns {Object}\n         */\n        showGridAssignProduct: function () {\n            this.product = {};\n            this.rowIndexForChange = undefined;\n\n            return this.doRender(true, 'assignProduct');\n        },\n\n        /**\n         * Show grid with changed product.\n         *\n         * @param {String} rowIndex\n         * @param {String} product\n         */\n        showGridChangeProduct: function (rowIndex, product) {\n            this.rowIndexForChange = rowIndex;\n            this.product = product;\n            this.doRender(false, 'changeProduct');\n        },\n\n        /**\n         * Select product.\n         *\n         * @param {String} rowIndex\n         */\n        selectProduct: function (rowIndex) {\n            this.changeProductData({\n                rowIndex: this.rowIndexForChange,\n                product: this.productsProvider().data.items[rowIndex]\n            });\n            this.modalWithGrid().closeModal();\n        },\n\n        /**\n         * Set visibility state for mass action column\n         *\n         * @private\n         */\n        _setVisibilityMassActionColumn: function () {\n            this.productsMassAction(function (massActionComponent) {\n                this.productsColumns().elems().each(function (rowElement) {\n                    rowElement.disableAction = this.showMassActionColumn;\n                }, this);\n                massActionComponent.visible = this.showMassActionColumn;\n            }.bind(this));\n        },\n\n        /**\n         * Set filters.\n         *\n         * @param {Object} params\n         * @private\n         */\n        _setFilters: function (params) {\n            var filterModifier = {},\n                attrCodes,\n                usedProductIds,\n                attributes;\n\n            params = _.omit(params);\n\n            if (!this.paramsUpdated) {\n                this.gridInitialized = true;\n                this.paramsUpdated = true;\n\n                attrCodes = this._getAttributesCodes();\n                usedProductIds = this.getUsedProductIds();\n\n                if (this.currentProductId) {\n                    usedProductIds.push(this.currentProductId);\n                }\n\n                filterModifier['entity_id'] = {\n                    'condition_type': 'nin', value: usedProductIds\n                };\n                attrCodes.each(function (code) {\n                    filterModifier[code] = {\n                        'condition_type': 'notnull'\n                    };\n                });\n\n                if (this.typeGrid === 'changeProduct') {\n                    attributes = JSON.parse(this.product.attributes);\n\n                    filterModifier = _.extend(filterModifier, _.mapObject(attributes, function (value) {\n                        return {\n                            'condition_type': 'eq',\n                            'value': value\n                        };\n                    }));\n\n                    params.filters = attributes;\n                } else {\n                    params.filters = {};\n                }\n\n                params['attributes_codes'] = attrCodes;\n\n                this.set('externalProviderParams', params);\n                this.set('externalFiltersModifier', filterModifier);\n            }\n        },\n\n        /**\n         * Get attribute codes.\n         *\n         * @returns {Array}\n         * @private\n         */\n        _getAttributesCodes: function () {\n            var attrCodes = this.source.get('data.attribute_codes');\n\n            return attrCodes ? attrCodes : [];\n        },\n\n        /**\n         * Get product variations.\n         *\n         * @returns {Array}\n         * @private\n         */\n        _getProductVariations: function () {\n            var matrix = this.source.get('data.configurable-matrix');\n\n            return matrix ? matrix : [];\n        },\n\n        /**\n         * Handle manual grid after opening\n         * @private\n         */\n        _handleManualGridOpening: function (data) {\n            if (data.items.length && this.typeGrid === 'assignProduct') {\n                this.productsColumns().elems().each(function (rowElement) {\n                    rowElement.disableAction = true;\n                });\n\n                this._disableRows(data.items);\n            }\n        },\n\n        /**\n         * Handle manual selection.\n         *\n         * @param {Array} selected\n         * @private\n         */\n        _handleManualGridSelect: function (selected) {\n            var selectedRows,\n                selectedVariationKeys;\n\n            if (this.typeGrid === 'assignProduct') {\n                selectedRows = _.filter(this.productsProvider().data.items, function (row) {\n                    return selected.indexOf(row['entity_id']) !== -1;\n                });\n                selectedVariationKeys = _.values(this._getVariationKeyMap(selectedRows));\n                this._disableRows(this.productsProvider().data.items, selectedVariationKeys, selected);\n            }\n        },\n\n        /**\n         * Disable rows in grid for products with the same variation key\n         *\n         * @param {Array} items\n         * @param {Array} selectedVariationKeys\n         * @param {Array} selected\n         * @private\n         */\n        _disableRows: function (items, selectedVariationKeys, selected) {\n            selectedVariationKeys = selectedVariationKeys === undefined ? [] : selectedVariationKeys;\n            selected = selected === undefined ? [] : selected;\n            this.productsMassAction(function (massaction) {\n                var configurableVariationKeys = _.union(\n                    selectedVariationKeys,\n                    _.pluck(this._getProductVariations(), 'variationKey')\n                    ),\n                    variationKeyMap = this._getVariationKeyMap(items),\n                    rowsForDisable = _.keys(_.pick(\n                        variationKeyMap,\n                        function (variationKey) {\n                            return configurableVariationKeys.indexOf(variationKey) !== -1;\n                        }\n                    ));\n\n                massaction.disabled(_.difference(rowsForDisable, selected));\n            }.bind(this));\n        },\n\n        /**\n         * Get variation key map used in manual grid.\n         *\n         * @param {Array} items\n         * @returns {Array} [{entity_id: variation-key}, ...]\n         * @private\n         */\n        _getVariationKeyMap: function (items) {\n            var variationKeyMap = {};\n\n            _.each(items, function (row) {\n                variationKeyMap[row['entity_id']] = _.values(\n                    _.pick(row, this._getAttributesCodes())\n                ).sort().join('-');\n\n            }, this);\n\n            return variationKeyMap;\n        }\n    });\n});\n","Magento_ConfigurableProduct/js/components/modal-configurable.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'Magento_Ui/js/modal/modal-component',\n    'uiRegistry',\n    'underscore'\n], function (Modal, registry, _) {\n    'use strict';\n\n    return Modal.extend({\n        defaults: {\n            stepWizard: '',\n            modules: {\n                form: '${ $.formName }'\n            }\n        },\n\n        /**\n         * Open modal\n         */\n        openModal: function () {\n            var stepWizard = {};\n\n            this.form().validate();\n\n            if (this.form().source.get('params.invalid') === false) {\n                stepWizard = registry.get('index = ' + this.stepWizard);\n\n                if (!_.isUndefined(stepWizard)) {\n                    stepWizard.open();\n                }\n\n                this._super();\n            } else {\n                this.form().focusInvalid();\n            }\n        }\n    });\n});\n","Magento_ConfigurableProduct/js/components/dynamic-rows-configurable.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore',\n    'uiRegistry',\n    'Magento_Ui/js/dynamic-rows/dynamic-rows',\n    'jquery'\n], function (_, registry, dynamicRows, $) {\n    'use strict';\n\n    return dynamicRows.extend({\n        defaults: {\n            actionsListOpened: false,\n            canEditField: 'canEdit',\n            newProductField: 'newProduct',\n            dataScopeAssociatedProduct: 'data.associated_product_ids',\n            dataProviderFromGrid: '',\n            dataProviderChangeFromGrid: '',\n            insertDataFromGrid: [],\n            changeDataFromGrid: [],\n            dataProviderFromWizard: '',\n            insertDataFromWizard: [],\n            map: null,\n            isEmpty: true,\n            isShowAddProductButton: false,\n            cacheGridData: [],\n            unionInsertData: [],\n            deleteProperty: false,\n            dataLength: 0,\n            identificationProperty: 'id',\n            'attribute_set_id': '',\n            attributesTmp: [],\n            changedFlag: 'was_changed',\n            listens: {\n                'insertDataFromGrid': 'processingInsertDataFromGrid',\n                'insertDataFromWizard': 'processingInsertDataFromWizard',\n                'unionInsertData': 'processingUnionInsertData',\n                'changeDataFromGrid': 'processingChangeDataFromGrid',\n                'isEmpty': 'changeVisibility'\n            },\n            imports: {\n                'attribute_set_id': '${$.provider}:data.product.attribute_set_id'\n            },\n            'exports': {\n                'attribute_set_id': '${$.provider}:data.new-variations-attribute-set-id'\n            },\n            modules: {\n                modalWithGrid: '${ $.modalWithGrid }',\n                gridWithProducts: '${ $.gridWithProducts}'\n            }\n        },\n\n        /**\n         * Invokes initialize method of parent class,\n         * contains initialization logic\n         */\n        initialize: function () {\n            this._super()\n                .changeVisibility(this.isEmpty());\n\n            return this;\n        },\n\n        /**\n         * Change visibility\n         *\n         * When isEmpty = true, then visbible = false\n         *\n         * @param {Boolean} isEmpty\n         */\n        changeVisibility: function (isEmpty) {\n            this.visible(!isEmpty);\n        },\n\n        /**\n         * Open modal with grid.\n         *\n         * @param {String} rowIndex\n         */\n        openModalWithGrid: function (rowIndex) {\n            var productSource = this.source.get(this.dataScope + '.' + this.index + '.' + rowIndex),\n                product = {\n                    'id': productSource.id,\n                    'attributes': productSource['configurable_attribute']\n                };\n\n            this.modalWithGrid().openModal();\n            this.gridWithProducts().showGridChangeProduct(rowIndex, product);\n        },\n\n        /**\n         * Initialize children\n         *\n         * @returns {Object} Chainable.\n         */\n        initChildren: function () {\n            var tmpArray = [];\n\n            this.recordData.each(function (recordData) {\n                tmpArray.push(recordData);\n            }, this);\n\n            this.unionInsertData(tmpArray);\n\n            return this;\n        },\n\n        /**\n         * Delete record\n         *\n         * @param {Number} index - row index\n         */\n        deleteRecord: function (index) {\n            var tmpArray,\n                lastRecord;\n\n            this.reRender = false;\n            tmpArray = this.getUnionInsertData();\n            tmpArray.splice(index, 1);\n\n            if (!tmpArray.length) {\n                this.attributesTmp = this.source.get('data.attributes');\n                this.source.set('data.attributes', []);\n                this.cacheGridData = [];\n            }\n\n            if (parseInt(this.currentPage(), 10) === this.pages()) {\n                lastRecord =\n                    _.findWhere(this.elems(), {\n                        index: this.startIndex + this.getChildItems().length - 1\n                    }) ||\n                    _.findWhere(this.elems(), {\n                        index: (this.startIndex + this.getChildItems().length - 1).toString()\n                    });\n\n                lastRecord.destroy();\n            }\n\n            this.unionInsertData(tmpArray);\n\n            if (this.pages() < parseInt(this.currentPage(), 10)) {\n                this.currentPage(this.pages());\n            }\n\n            this.reRender = true;\n            this.showSpinner(false);\n        },\n\n        /**\n         * Generate associated products\n         */\n        generateAssociatedProducts: function () {\n            var productsIds = [];\n\n            this.getUnionInsertData().forEach(function (data) {\n                if (data.id !== null) {\n                    productsIds.push(data.id);\n                }\n            });\n\n            this.source.set(this.dataScopeAssociatedProduct, productsIds);\n        },\n\n        /**\n         * Calls 'initObservable' of parent\n         *\n         * @returns {Object} Chainable.\n         */\n        initObservable: function () {\n            this._super()\n                .observe([\n                    'insertDataFromGrid', 'unionInsertData', 'isEmpty', 'isShowAddProductButton', 'actionsListOpened'\n                ]);\n\n            return this;\n        },\n\n        /**\n         * Get union insert data from source\n         *\n         * @returns {Array}\n         */\n        getUnionInsertData: function () {\n            var source = this.source.get(this.dataScope + '.' + this.index),\n                result = [];\n\n            _.each(source, function (data) {\n                result.push(data);\n            });\n\n            return result;\n        },\n\n        /**\n         * Process union insert data.\n         *\n         * @param {Array} data\n         */\n        processingUnionInsertData: function (data) {\n            var dataCount,\n                elemsCount,\n                tmpData,\n                path,\n                attributeCodes = this.source.get('data.attribute_codes');\n\n            this.isEmpty(data.length === 0);\n            this.isShowAddProductButton(\n                (!attributeCodes || data.length > 0 ? data.length : attributeCodes.length) > 0\n            );\n\n            tmpData = data.slice(this.pageSize * (this.currentPage() - 1),\n                                 this.pageSize * (this.currentPage() - 1) + parseInt(this.pageSize, 10));\n\n            this.source.set(this.dataScope + '.' + this.index, []);\n\n            _.each(tmpData, function (row, index) {\n                path = this.dataScope + '.' + this.index + '.' + (this.startIndex + index);\n                row.attributes = $('<i></i>').text(row.attributes).html();\n                this.source.set(path, row);\n            }, this);\n\n            this.source.set(this.dataScope + '.' + this.index, data);\n            this.parsePagesData(data);\n\n            // Render\n            dataCount = tmpData.length;\n            elemsCount = this.elems().length;\n\n            if (dataCount > elemsCount) {\n                tmpData.each(function (elemData, index) {\n                    this.addChild(elemData, this.startIndex + index);\n                }, this);\n            } else {\n                for (elemsCount; elemsCount > dataCount; elemsCount--) {\n                    this.elems()[elemsCount - 1].destroy();\n                }\n            }\n\n            this.generateAssociatedProducts();\n        },\n\n        /**\n         * Set initial property to records data\n         *\n         * @returns {Object} Chainable.\n         */\n        setInitialProperty: function () {\n            return this;\n        },\n\n        /**\n         * Parsed data\n         *\n         * @param {Array} data - array with data\n         * about selected records\n         */\n        processingInsertDataFromGrid: function (data) {\n            var changes,\n                tmpArray;\n\n            if (!data.length) {\n                return;\n            }\n\n            tmpArray = this.getUnionInsertData();\n\n            changes = this._checkGridData(data);\n            this.cacheGridData = data;\n\n            changes.each(function (changedObject) {\n                var mappedData = this.mappingValue(changedObject);\n\n                mappedData[this.canEditField] = 0;\n                mappedData[this.newProductField] = 0;\n                mappedData.variationKey = this._getVariationKey(changedObject);\n                mappedData['configurable_attribute'] = this._getConfigurableAttribute(changedObject);\n                tmpArray.push(mappedData);\n            }, this);\n\n            // Attributes cannot be changed before regeneration thought wizard\n            if (!this.source.get('data.attributes').length) {\n                this.source.set('data.attributes', this.attributesTmp);\n            }\n            this.unionInsertData(tmpArray);\n        },\n\n        /**\n         * Process changes from grid.\n         *\n         * @param {Object} data\n         */\n        processingChangeDataFromGrid: function (data) {\n            var tmpArray = this.getUnionInsertData(),\n                mappedData = this.mappingValue(data.product);\n\n            mappedData[this.canEditField] = 0;\n            mappedData[this.newProductField] = 0;\n            mappedData.variationKey = this._getVariationKey(data.product);\n            mappedData['configurable_attribute'] = this._getConfigurableAttribute(data.product);\n            tmpArray[data.rowIndex] = mappedData;\n\n            this.unionInsertData(tmpArray);\n        },\n\n        /**\n         * Get variation key.\n         *\n         * @param {Object} data\n         * @returns {String}\n         * @private\n         */\n        _getVariationKey: function (data) {\n            var attrCodes = this.source.get('data.attribute_codes'),\n                key = [];\n\n            attrCodes.each(function (code) {\n                key.push(data[code]);\n            });\n\n            return key.sort().join('-');\n        },\n\n        /**\n         * Get configurable attribute.\n         *\n         * @param {Object} data\n         * @returns {String}\n         * @private\n         */\n        _getConfigurableAttribute: function (data) {\n            var attrCodes = this.source.get('data.attribute_codes'),\n                confAttrs = {};\n\n            attrCodes.each(function (code) {\n                confAttrs[code] = data[code];\n            });\n\n            return JSON.stringify(confAttrs);\n        },\n\n        /**\n         * Process data insertion from wizard\n         *\n         * @param {Object} data\n         */\n        processingInsertDataFromWizard: function (data) {\n            var tmpArray = this.getUnionInsertData(),\n                productIdsToDelete = this.source.get(this.dataScopeAssociatedProduct),\n                index,\n                product = {};\n\n            tmpArray = this.unsetArrayItem(\n                tmpArray,\n                {\n                    id: null\n                }\n            );\n\n            _.each(data, function (row) {\n                if (row.productId) {\n                    index = _.indexOf(productIdsToDelete, row.productId);\n\n                    if (index > -1) {\n                        productIdsToDelete.splice(index, 1);\n                        tmpArray = this.unsetArrayItem(\n                            tmpArray,\n                            {\n                                id: row.productId\n                            }\n                        );\n                    }\n                }\n                product = this.getProductData(row);\n\n                product[this.changedFlag] = true;\n                product[this.canEditField] = row.editable;\n                product[this.newProductField] = row.newProduct;\n                tmpArray.push(product);\n            }, this);\n\n            _.each(productIdsToDelete, function (id) {\n                tmpArray = this.unsetArrayItem(\n                    tmpArray,\n                    {\n                        id: id\n                    }\n                );\n            }, this);\n\n            this.unionInsertData(tmpArray);\n        },\n\n        /**\n         *\n         * @param {Object} row\n         * @returns {Object}\n         */\n        getProductData: function (row) {\n            var product,\n                attributesText = '';\n\n            _.each(row.options, function (attribute) {\n                if (attributesText) {\n                    attributesText += ', ';\n                }\n                attributesText += attribute['attribute_label'] + ': ' + attribute.label;\n            }, this);\n\n            product = {\n                'id': row.productId,\n                'product_link': row.productUrl,\n                'name': row.name,\n                'sku': row.sku,\n                'status': row.status,\n                'price': row.price,\n                'price_currency': row.priceCurrency,\n                'price_string': row.priceCurrency + row.price,\n                'weight': row.weight,\n                'qty': row.quantity,\n                'variationKey': row.variationKey,\n                'configurable_attribute': row.attribute,\n                'thumbnail_image': row.images.preview,\n                'media_gallery': row['media_gallery'],\n                'swatch_image': row['swatch_image'],\n                'small_image': row['small_image'],\n                image: row.image,\n                'thumbnail': row.thumbnail,\n                'attributes': attributesText\n            };\n\n            return product;\n        },\n\n        /**\n         * Remove array items matching condition.\n         *\n         * @param {Array} data\n         * @param {Object} condition\n         * @returns {Array}\n         */\n        unsetArrayItem: function (data, condition) {\n            var objs = _.where(data, condition);\n\n            _.each(objs, function (obj) {\n                var index = _.indexOf(data, obj);\n\n                if (index > -1) {\n                    data.splice(index, 1);\n                }\n            });\n\n            return data;\n        },\n\n        /**\n         * Check changed records\n         *\n         * @param {Array} data - array with records data\n         * @returns {Array} Changed records\n         */\n        _checkGridData: function (data) {\n            var cacheLength = this.cacheGridData.length,\n                curData = data.length,\n                max = cacheLength > curData ? this.cacheGridData : data,\n                changes = [],\n                obj = {};\n\n            max.each(function (record, index) {\n                obj[this.map.id] = record[this.map.id];\n\n                if (!_.where(this.cacheGridData, obj).length) {\n                    changes.push(data[index]);\n                }\n            }, this);\n\n            return changes;\n        },\n\n        /**\n         * Mapped value\n         */\n        mappingValue: function (data) {\n            var result = {};\n\n            _.each(this.map, function (prop, index) {\n                result[index] = data[prop];\n            });\n\n            return result;\n        },\n\n        /**\n         * Toggle actions list.\n         *\n         * @param {Number} rowIndex\n         * @returns {Object} Chainable.\n         */\n        toggleActionsList: function (rowIndex) {\n            var state = false;\n\n            if (rowIndex !== this.actionsListOpened()) {\n                state = rowIndex;\n            }\n            this.actionsListOpened(state);\n\n            return this;\n        },\n\n        /**\n         * Close action list.\n         *\n         * @param {Number} rowIndex\n         * @returns {Object} Chainable\n         */\n        closeList: function (rowIndex) {\n            if (this.actionsListOpened() === rowIndex) {\n                this.actionsListOpened(false);\n            }\n\n            return this;\n        },\n\n        /**\n         * Toggle product status.\n         *\n         * @param {Number} rowIndex\n         */\n        toggleStatusProduct: function (rowIndex) {\n            var tmpArray = this.getUnionInsertData(),\n                status = parseInt(tmpArray[rowIndex].status, 10);\n\n            if (status === 1) {\n                tmpArray[rowIndex].status = 2;\n            } else {\n                tmpArray[rowIndex].status = 1;\n            }\n\n            tmpArray[rowIndex][this.changedFlag] = true;\n            this.unionInsertData(tmpArray);\n        }\n    });\n});\n","Magento_ConfigurableProduct/js/components/custom-options-price-type.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore',\n    'Magento_Catalog/js/components/custom-options-price-type'\n], function (_, PriceType) {\n    'use strict';\n\n    return PriceType.extend({\n        defaults: {\n            isConfigurable: false,\n            isFiltered: null,\n            defaultOptions: null,\n            filteredOptions: null,\n            bannedOptions: []\n        },\n\n        /**\n         * Updates options.\n         *\n         * @param {Boolean} variationsEmpty\n         * @returns {Boolean}\n         */\n        updateOptions: function (variationsEmpty) {\n            var isFiltered = this.isConfigurable || !variationsEmpty,\n                value;\n\n            if (this.isFiltered !== isFiltered) {\n                value = this.value();\n\n                this.options(isFiltered ? this.getFilteredOptions() : this.getDefaultOptions());\n                this.value(value);\n            }\n\n            return isFiltered;\n        },\n\n        /**\n         * Get default list of options.\n         *\n         * @returns {Array}\n         */\n        getDefaultOptions: function () {\n            if (this.defaultOptions === null) {\n                this.defaultOptions = this.options();\n            }\n\n            return this.defaultOptions;\n        },\n\n        /**\n         * Get filtered list of options.\n         *\n         * @returns {Array}\n         */\n        getFilteredOptions: function () {\n            var defaultOptions;\n\n            if (this.filteredOptions === null) {\n                defaultOptions = this.getDefaultOptions();\n                this.filteredOptions = [];\n\n                _.each(defaultOptions, function (option) {\n                    if (this.bannedOptions.indexOf(option.value) === -1) {\n                        this.filteredOptions.push(option);\n                    }\n                }, this);\n            }\n\n            return this.filteredOptions;\n        }\n    });\n});\n","Magento_ConfigurableProduct/js/components/qty-configurable.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'Magento_Ui/js/form/element/abstract'\n], function (Abstract) {\n    'use strict';\n\n    return Abstract.extend({\n        defaults: {\n            imports: {\n                isConfigurable: '!ns = ${ $.ns }, index = configurable-matrix:isEmpty'\n            }\n        },\n\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n            // resolve initial disable state\n            this.handleQtyValue(this.isConfigurable);\n\n            /** important to set this listener in initialize because of a different order of processing.\n             * Do not move to defaults->listens section */\n            this.setListeners({\n                isConfigurable: 'handleQtyValue'\n            });\n\n            return this;\n        },\n\n        /**\n         * Disable and clear Qty if product type changed to configurable\n         *\n         * @param {String} isConfigurable\n         */\n        handleQtyValue: function (isConfigurable) {\n            this.disabled(!!this.isUseDefault() || isConfigurable);\n\n            if (isConfigurable) {\n                this.clear();\n            }\n        }\n    });\n});\n","Magento_ConfigurableProduct/js/components/container-configurable-handler.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'uiComponent'\n], function (Element) {\n    'use strict';\n\n    return Element.extend({\n        defaults: {\n            listens: {\n                '${ $.provider }:data.is_downloadable': 'handleProductType'\n            },\n            links: {\n                isDownloadable: '${ $.provider }:data.is_downloadable'\n            },\n            modules: {\n                createConfigurableButton: '${$.createConfigurableButton}'\n            }\n        },\n\n        /**\n         * Invokes initialize method of parent class,\n         * contains initialization logic\n         */\n        initialize: function () {\n            this._super();\n            this.handleProductType(this.isDownloadable);\n\n            return this;\n        },\n\n        /**\n         * Calls 'initObservable' of parent\n         *\n         * @returns {Object} Chainable.\n         */\n        initObservable: function () {\n            this._super()\n                .observe(['content']);\n\n            return this;\n        },\n\n        /**\n         * Change content for container and visibility for button\n         *\n         * @param {String} isDownloadable\n         */\n        handleProductType: function (isDownloadable) {\n            if (isDownloadable === '1') {\n                this.content(this.content2);\n\n                if (this.createConfigurableButton()) {\n                    this.createConfigurableButton().visible(false);\n                }\n            } else {\n                this.content(this.content1);\n\n                if (this.createConfigurableButton()) {\n                    this.createConfigurableButton().visible(true);\n                }\n            }\n        }\n    });\n});\n","Magento_ConfigurableProduct/js/components/price-configurable.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore',\n    'uiRegistry',\n    'Magento_Ui/js/form/element/abstract'\n], function (_, registry, Abstract) {\n    'use strict';\n\n    return Abstract.extend({\n        defaults: {\n            imports: {\n                isConfigurable: '!ns = ${ $.ns }, index = configurable-matrix:isEmpty'\n            },\n            modules: {\n                createConfigurableButton: '${$.createConfigurableButton}'\n            }\n        },\n\n        /** @inheritdoc */\n        initialize: function () {\n            this._super();\n            // resolve initial disable state\n            this.handlePriceValue(this.isConfigurable);\n            // add listener to track \"configurable\" type\n            this.setListeners({\n                isConfigurable: 'handlePriceValue'\n            });\n\n            return this;\n        },\n\n        /**\n         * Calls 'initObservable' of parent\n         *\n         * @returns {Object} Chainable.\n         */\n        initObservable: function () {\n            this._super()\n                .observe(['content']);\n\n            return this;\n        },\n\n        /**\n         * Disable and clear price if product type changed to configurable\n         *\n         * @param {String} isConfigurable\n         */\n        handlePriceValue: function (isConfigurable) {\n            this.disabled(!!this.isUseDefault() || isConfigurable);\n            this.required(!!this.isUseDefault() || !isConfigurable);\n\n            if (isConfigurable) {\n                this.clear();\n            }\n        }\n    });\n});\n","Magento_PageBuilderAdminAnalytics/js/page-builder/events-mixin.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['underscore', 'Magento_PageBuilderAdminAnalytics/js/page-builder/event-builder'],\n    function (_, EventBuilder) {\n        'use strict';\n\n        return function (target) {\n            var originalTarget = target.trigger,\n                isAdminAnalyticsEnabled,\n                event,\n                hasPageBuilderBeenUsed = false,\n                delayedPush;\n\n            /**\n             * Invokes custom code to track information regarding Page Builder usage\n             *\n             * @param {String} name\n             * @param {Array} args\n             */\n\n            target.trigger = function (name, args) {\n                originalTarget.apply(originalTarget, [name, args]);\n                isAdminAnalyticsEnabled =\n                    !_.isUndefined(window.digitalData) &&\n                    !_.isUndefined(window._satellite);\n\n                if (!hasPageBuilderBeenUsed && name.indexOf('stage:fullScreenModeChangeAfter') !== -1 &&\n                    args.fullScreen && isAdminAnalyticsEnabled\n                ) {\n                    hasPageBuilderBeenUsed = true;\n                    window.digitalData.page.url = window.location.href;\n                    window.digitalData.page.attributes = {\n                        editedWithPageBuilder: 'true'\n                    };\n                    window._satellite.track('page');\n                }\n\n                event = EventBuilder.build(name, args);\n\n                if (isAdminAnalyticsEnabled && !_.isUndefined(window.digitalData.event) && !_.isUndefined(event)) {\n                    delayedPush = setInterval(function (object) {\n                        if (_.isArray(window.digitalData.event)) {\n                            window.digitalData.event.push(object);\n                            window._satellite.track('event');\n                            clearInterval(delayedPush);\n                        }\n                    }, 500, event);\n                }\n            };\n\n            return target;\n        };\n    });\n","Magento_PageBuilderAdminAnalytics/js/page-builder/event-builder.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine(['underscore'], function (_) {\n    'use strict';\n\n    return {\n\n        /**\n         * Sets up event attributes and action depending on name and args\n         *\n         * @param {String} name\n         * @param {Array} args\n         */\n\n        build: function (name, args) {\n            var action = '',\n                eventAttributes = {},\n                event;\n\n            if (_.isUndefined(args)) {\n                return;\n            }\n\n            switch (name) {\n                case 'contentType:duplicateAfter':\n                    action = 'duplicate';\n                    break;\n\n                case 'contentType:removeAfter':\n                    action = 'remove';\n                    break;\n\n                case 'contentType:createAfter':\n                    action = 'create';\n                    break;\n\n                case 'contentType:editBefore':\n                    action = 'edit';\n                    break;\n\n                case 'contentType:visibilityAfter':\n                    action = args.visibility ? 'show' : 'hide';\n                    break;\n\n                default:\n                    break;\n            }\n\n            if (!_.isUndefined(args.contentType)) {\n                eventAttributes = args.contentType.config;\n            } else if (!_.isUndefined(args.originalContentType)) {\n                eventAttributes = args.originalContentType.config;\n            }\n\n            if (action !== '' && !_.isEmpty(eventAttributes)) {\n                event = {\n                    element: eventAttributes.label,\n                    type: eventAttributes.name,\n                    action: action,\n                    widget: {\n                        name: eventAttributes.form,\n                        type: eventAttributes['menu_section']\n                    },\n                    feature: 'page-builder-tracker'\n                };\n            }\n\n            return event;\n        }\n    };\n});\n","chartjs/es6-shim.min.js":"/*!\n  * https://github.com/paulmillr/es6-shim\n  * @license es6-shim Copyright 2013-2014 by Paul Miller (http://paulmillr.com)\n  *   and contributors,  MIT License\n  * es6-shim: v0.25.0\n  * see https://github.com/paulmillr/es6-shim/blob/0.25.0/LICENSE\n  * Details and documentation:\n  * https://github.com/paulmillr/es6-shim/\n  */\n(function(e,t){if(typeof define===\"function\"&&define.amd){define(t)}else if(typeof exports===\"object\"){module.exports=t()}else{e.returnExports=t()}})(this,function(){\"use strict\";var e=function(e){try{e()}catch(t){return false}return true};var t=function(e,t){try{var r=function(){e.apply(this,arguments)};if(!r.__proto__){return false}Object.setPrototypeOf(r,e);r.prototype=Object.create(e.prototype,{constructor:{value:e}});return t(r)}catch(n){return false}};var r=function(){try{Object.defineProperty({},\"x\",{});return true}catch(e){return false}};var n=function(){var e=false;if(String.prototype.startsWith){try{\"/a/\".startsWith(/a/)}catch(t){e=true}}return e};var i=new Function(\"return this;\");var o=i();var a=o.isFinite;var u=!!Object.defineProperty&&r();var s=n();var f=Function.call.bind(String.prototype.indexOf);var c=Function.call.bind(Object.prototype.toString);var l=Function.call.bind(Object.prototype.hasOwnProperty);var p;var h=function(){};var v=o.Symbol||{};var y=v.species||\"@@species\";var b={string:function(e){return c(e)===\"[object String]\"},regex:function(e){return c(e)===\"[object RegExp]\"},symbol:function(e){return typeof o.Symbol===\"function\"&&typeof e===\"symbol\"}};var g=function(e,t,r,n){if(!n&&t in e){return}if(u){Object.defineProperty(e,t,{configurable:true,enumerable:false,writable:true,value:r})}else{e[t]=r}};var d={getter:function(e,t,r){if(!u){throw new TypeError(\"getters require true ES5 support\")}Object.defineProperty(e,t,{configurable:true,enumerable:false,get:r})},proxy:function(e,t,r){if(!u){throw new TypeError(\"getters require true ES5 support\")}var n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,{configurable:n.configurable,enumerable:n.enumerable,get:function i(){return e[t]},set:function o(r){e[t]=r}})},redefine:function(e,t,r){if(u){var n=Object.getOwnPropertyDescriptor(e,t);n.value=r;Object.defineProperty(e,t,n)}else{e[t]=r}}};var m=function(e,t){Object.keys(t).forEach(function(r){var n=t[r];g(e,r,n,false)})};var w=Object.create||function(e,t){function r(){}r.prototype=e;var n=new r;if(typeof t!==\"undefined\"){m(n,t)}return n};var O=b.symbol(v.iterator)?v.iterator:\"_es6-shim iterator_\";if(o.Set&&typeof(new o.Set)[\"@@iterator\"]===\"function\"){O=\"@@iterator\"}var j=function(e,t){if(!t){t=function n(){return this}}var r={};r[O]=t;m(e,r);if(!e[O]&&b.symbol(O)){e[O]=t}};var I=function dt(e){var t=c(e);var r=t===\"[object Arguments]\";if(!r){r=t!==\"[object Array]\"&&e!==null&&typeof e===\"object\"&&typeof e.length===\"number\"&&e.length>=0&&c(e.callee)===\"[object Function]\"}return r};var T=Function.call.bind(Function.apply);var M={Call:function mt(e,t){var r=arguments.length>2?arguments[2]:[];if(!M.IsCallable(e)){throw new TypeError(e+\" is not a function\")}return T(e,t,r)},RequireObjectCoercible:function(e,t){if(e==null){throw new TypeError(t||\"Cannot call method on \"+e)}},TypeIsObject:function(e){return e!=null&&Object(e)===e},ToObject:function(e,t){M.RequireObjectCoercible(e,t);return Object(e)},IsCallable:function(e){return typeof e===\"function\"&&c(e)===\"[object Function]\"},ToInt32:function(e){return M.ToNumber(e)>>0},ToUint32:function(e){return M.ToNumber(e)>>>0},ToNumber:function(e){if(c(e)===\"[object Symbol]\"){throw new TypeError(\"Cannot convert a Symbol value to a number\")}return+e},ToInteger:function(e){var t=M.ToNumber(e);if(Number.isNaN(t)){return 0}if(t===0||!Number.isFinite(t)){return t}return(t>0?1:-1)*Math.floor(Math.abs(t))},ToLength:function(e){var t=M.ToInteger(e);if(t<=0){return 0}if(t>Number.MAX_SAFE_INTEGER){return Number.MAX_SAFE_INTEGER}return t},SameValue:function(e,t){if(e===t){if(e===0){return 1/e===1/t}return true}return Number.isNaN(e)&&Number.isNaN(t)},SameValueZero:function(e,t){return e===t||Number.isNaN(e)&&Number.isNaN(t)},IsIterable:function(e){return M.TypeIsObject(e)&&(typeof e[O]!==\"undefined\"||I(e))},GetIterator:function(e){if(I(e)){return new p(e,\"value\")}var t=e[O];if(!M.IsCallable(t)){throw new TypeError(\"value is not an iterable\")}var r=t.call(e);if(!M.TypeIsObject(r)){throw new TypeError(\"bad iterator\")}return r},IteratorNext:function(e){var t=arguments.length>1?e.next(arguments[1]):e.next();if(!M.TypeIsObject(t)){throw new TypeError(\"bad iterator\")}return t},Construct:function(e,t){var r;if(M.IsCallable(e[y])){r=e[y]()}else{r=w(e.prototype||null)}m(r,{_es6construct:true});var n=M.Call(e,r,t);return M.TypeIsObject(n)?n:r}};var N=function(e){if(!M.TypeIsObject(e)){throw new TypeError(\"bad object\")}if(!e._es6construct){if(e.constructor&&M.IsCallable(e.constructor[y])){e=e.constructor[y](e)}m(e,{_es6construct:true})}return e};var _=function(){function e(e){var t=Math.floor(e),r=e-t;if(r<.5){return t}if(r>.5){return t+1}return t%2?t+1:t}function t(t,r,n){var i=(1<<r-1)-1,o,a,u,s,f,c,l;if(t!==t){a=(1<<r)-1;u=Math.pow(2,n-1);o=0}else if(t===Infinity||t===-Infinity){a=(1<<r)-1;u=0;o=t<0?1:0}else if(t===0){a=0;u=0;o=1/t===-Infinity?1:0}else{o=t<0;t=Math.abs(t);if(t>=Math.pow(2,1-i)){a=Math.min(Math.floor(Math.log(t)/Math.LN2),1023);u=e(t/Math.pow(2,a)*Math.pow(2,n));if(u/Math.pow(2,n)>=2){a=a+1;u=1}if(a>i){a=(1<<r)-1;u=0}else{a=a+i;u=u-Math.pow(2,n)}}else{a=0;u=e(t/Math.pow(2,1-i-n))}}f=[];for(s=n;s;s-=1){f.push(u%2?1:0);u=Math.floor(u/2)}for(s=r;s;s-=1){f.push(a%2?1:0);a=Math.floor(a/2)}f.push(o?1:0);f.reverse();c=f.join(\"\");l=[];while(c.length){l.push(parseInt(c.slice(0,8),2));c=c.slice(8)}return l}function r(e,t,r){var n=[],i,o,a,u,s,f,c,l;for(i=e.length;i;i-=1){a=e[i-1];for(o=8;o;o-=1){n.push(a%2?1:0);a=a>>1}}n.reverse();u=n.join(\"\");s=(1<<t-1)-1;f=parseInt(u.slice(0,1),2)?-1:1;c=parseInt(u.slice(1,1+t),2);l=parseInt(u.slice(1+t),2);if(c===(1<<t)-1){return l!==0?NaN:f*Infinity}else if(c>0){return f*Math.pow(2,c-s)*(1+l/Math.pow(2,r))}else if(l!==0){return f*Math.pow(2,-(s-1))*(l/Math.pow(2,r))}else{return f<0?-0:0}}function n(e){return r(e,11,52)}function i(e){return t(e,11,52)}function o(e){return r(e,8,23)}function a(e){return t(e,8,23)}var u={toFloat32:function(e){return o(a(e))}};if(typeof Float32Array!==\"undefined\"){var s=new Float32Array(1);u.toFloat32=function(e){s[0]=e;return s[0]}}return u}();m(String,{fromCodePoint:function wt(e){var t=[];var r;for(var n=0,i=arguments.length;n<i;n++){r=Number(arguments[n]);if(!M.SameValue(r,M.ToInteger(r))||r<0||r>1114111){throw new RangeError(\"Invalid code point \"+r)}if(r<65536){t.push(String.fromCharCode(r))}else{r-=65536;t.push(String.fromCharCode((r>>10)+55296));t.push(String.fromCharCode(r%1024+56320))}}return t.join(\"\")},raw:function Ot(e){var t=M.ToObject(e,\"bad callSite\");var r=t.raw;var n=M.ToObject(r,\"bad raw value\");var i=n.length;var o=M.ToLength(i);if(o<=0){return\"\"}var a=[];var u=0;var s,f,c,l;while(u<o){s=String(u);f=n[s];c=String(f);a.push(c);if(u+1>=o){break}f=u+1<arguments.length?arguments[u+1]:\"\";l=String(f);a.push(l);u++}return a.join(\"\")}});if(String.fromCodePoint.length!==1){var E=Function.apply.bind(String.fromCodePoint);g(String,\"fromCodePoint\",function jt(e){return E(this,arguments)},true)}var x=function It(e,t){if(t<1){return\"\"}if(t%2){return It(e,t-1)+e}var r=It(e,t/2);return r+r};var S=Infinity;var P={repeat:function Tt(e){M.RequireObjectCoercible(this);var t=String(this);e=M.ToInteger(e);if(e<0||e>=S){throw new RangeError(\"repeat count must be less than infinity and not overflow maximum string size\")}return x(t,e)},startsWith:function(e){M.RequireObjectCoercible(this);var t=String(this);if(b.regex(e)){throw new TypeError('Cannot call method \"startsWith\" with a regex')}e=String(e);var r=arguments.length>1?arguments[1]:void 0;var n=Math.max(M.ToInteger(r),0);return t.slice(n,n+e.length)===e},endsWith:function(e){M.RequireObjectCoercible(this);var t=String(this);if(b.regex(e)){throw new TypeError('Cannot call method \"endsWith\" with a regex')}e=String(e);var r=t.length;var n=arguments.length>1?arguments[1]:void 0;var i=typeof n===\"undefined\"?r:M.ToInteger(n);var o=Math.min(Math.max(i,0),r);return t.slice(o-e.length,o)===e},includes:function Mt(e){var t=arguments.length>1?arguments[1]:void 0;return f(this,e,t)!==-1},codePointAt:function(e){M.RequireObjectCoercible(this);var t=String(this);var r=M.ToInteger(e);var n=t.length;if(r>=0&&r<n){var i=t.charCodeAt(r);var o=r+1===n;if(i<55296||i>56319||o){return i}var a=t.charCodeAt(r+1);if(a<56320||a>57343){return i}return(i-55296)*1024+(a-56320)+65536}}};m(String.prototype,P);var C=\"\\x85\".trim().length!==1;if(C){delete String.prototype.trim;var k=[\"\t\\n\u000b\\f\\r \\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\",\"\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\",\"\\u2029\\ufeff\"].join(\"\");var A=new RegExp(\"(^[\"+k+\"]+)|([\"+k+\"]+$)\",\"g\");m(String.prototype,{trim:function(){if(typeof this===\"undefined\"||this===null){throw new TypeError(\"can't convert \"+this+\" to object\")}return String(this).replace(A,\"\")}})}var R=function(e){M.RequireObjectCoercible(e);this._s=String(e);this._i=0};R.prototype.next=function(){var e=this._s,t=this._i;if(typeof e===\"undefined\"||t>=e.length){this._s=void 0;return{value:void 0,done:true}}var r=e.charCodeAt(t),n,i;if(r<55296||r>56319||t+1===e.length){i=1}else{n=e.charCodeAt(t+1);i=n<56320||n>57343?1:2}this._i=t+i;return{value:e.substr(t,i),done:false}};j(R.prototype);j(String.prototype,function(){return new R(this)});if(!s){g(String.prototype,\"startsWith\",P.startsWith,true);g(String.prototype,\"endsWith\",P.endsWith,true)}var F={from:function(e){var t=arguments.length>1?arguments[1]:void 0;var r=M.ToObject(e,\"bad iterable\");if(typeof t!==\"undefined\"&&!M.IsCallable(t)){throw new TypeError(\"Array.from: when provided, the second argument must be a function\")}var n=arguments.length>2;var i=n?arguments[2]:void 0;var o=M.IsIterable(r);var a;var u,s,f;if(o){s=0;u=M.IsCallable(this)?Object(new this):[];var c=o?M.GetIterator(r):null;var l;do{l=M.IteratorNext(c);if(!l.done){f=l.value;if(t){u[s]=n?t.call(i,f,s):t(f,s)}else{u[s]=f}s+=1}}while(!l.done);a=s}else{a=M.ToLength(r.length);u=M.IsCallable(this)?Object(new this(a)):new Array(a);for(s=0;s<a;++s){f=r[s];if(t){u[s]=n?t.call(i,f,s):t(f,s)}else{u[s]=f}}}u.length=a;return u},of:function(){return Array.from(arguments)}};m(Array,F);var D=function(){try{return Array.from({length:-1}).length===0}catch(e){return false}};if(!D()){g(Array,\"from\",F.from,true)}var z=function(e){return{value:e,done:arguments.length===0}};p=function(e,t){this.i=0;this.array=e;this.kind=t};m(p.prototype,{next:function(){var e=this.i,t=this.array;if(!(this instanceof p)){throw new TypeError(\"Not an ArrayIterator\")}if(typeof t!==\"undefined\"){var r=M.ToLength(t.length);for(;e<r;e++){var n=this.kind;var i;if(n===\"key\"){i=e}else if(n===\"value\"){i=t[e]}else if(n===\"entry\"){i=[e,t[e]]}this.i=e+1;return{value:i,done:false}}}this.array=void 0;return{value:void 0,done:true}}});j(p.prototype);var L=function(e,t){this.object=e;this.array=null;this.kind=t};function q(e){var t=[];for(var r in e){t.push(r)}return t}m(L.prototype,{next:function(){var e,t=this.array;if(!(this instanceof L)){throw new TypeError(\"Not an ObjectIterator\")}if(t===null){t=this.array=q(this.object)}while(M.ToLength(t.length)>0){e=t.shift();if(!(e in this.object)){continue}if(this.kind===\"key\"){return z(e)}else if(this.kind===\"value\"){return z(this.object[e])}else{return z([e,this.object[e]])}}return z()}});j(L.prototype);var G={copyWithin:function(e,t){var r=arguments[2];var n=M.ToObject(this);var i=M.ToLength(n.length);e=M.ToInteger(e);t=M.ToInteger(t);var o=e<0?Math.max(i+e,0):Math.min(e,i);var a=t<0?Math.max(i+t,0):Math.min(t,i);r=typeof r===\"undefined\"?i:M.ToInteger(r);var u=r<0?Math.max(i+r,0):Math.min(r,i);var s=Math.min(u-a,i-o);var f=1;if(a<o&&o<a+s){f=-1;a+=s-1;o+=s-1}while(s>0){if(l(n,a)){n[o]=n[a]}else{delete n[a]}a+=f;o+=f;s-=1}return n},fill:function(e){var t=arguments.length>1?arguments[1]:void 0;var r=arguments.length>2?arguments[2]:void 0;var n=M.ToObject(this);var i=M.ToLength(n.length);t=M.ToInteger(typeof t===\"undefined\"?0:t);r=M.ToInteger(typeof r===\"undefined\"?i:r);var o=t<0?Math.max(i+t,0):Math.min(t,i);var a=r<0?i+r:r;for(var u=o;u<i&&u<a;++u){n[u]=e}return n},find:function Nt(e){var t=M.ToObject(this);var r=M.ToLength(t.length);if(!M.IsCallable(e)){throw new TypeError(\"Array#find: predicate must be a function\")}var n=arguments.length>1?arguments[1]:null;for(var i=0,o;i<r;i++){o=t[i];if(n){if(e.call(n,o,i,t)){return o}}else if(e(o,i,t)){return o}}},findIndex:function _t(e){var t=M.ToObject(this);var r=M.ToLength(t.length);if(!M.IsCallable(e)){throw new TypeError(\"Array#findIndex: predicate must be a function\")}var n=arguments.length>1?arguments[1]:null;for(var i=0;i<r;i++){if(n){if(e.call(n,t[i],i,t)){return i}}else if(e(t[i],i,t)){return i}}return-1},keys:function(){return new p(this,\"key\")},values:function(){return new p(this,\"value\")},entries:function(){return new p(this,\"entry\")}};if(Array.prototype.keys&&!M.IsCallable([1].keys().next)){delete Array.prototype.keys}if(Array.prototype.entries&&!M.IsCallable([1].entries().next)){delete Array.prototype.entries}if(Array.prototype.keys&&Array.prototype.entries&&!Array.prototype.values&&Array.prototype[O]){m(Array.prototype,{values:Array.prototype[O]});if(b.symbol(v.unscopables)){Array.prototype[v.unscopables].values=true}}m(Array.prototype,G);j(Array.prototype,function(){return this.values()});if(Object.getPrototypeOf){j(Object.getPrototypeOf([].values()))}var W=Math.pow(2,53)-1;m(Number,{MAX_SAFE_INTEGER:W,MIN_SAFE_INTEGER:-W,EPSILON:2.220446049250313e-16,parseInt:o.parseInt,parseFloat:o.parseFloat,isFinite:function(e){return typeof e===\"number\"&&a(e)},isInteger:function(e){return Number.isFinite(e)&&M.ToInteger(e)===e},isSafeInteger:function(e){return Number.isInteger(e)&&Math.abs(e)<=Number.MAX_SAFE_INTEGER},isNaN:function(e){return e!==e}});if(![,1].find(function(e,t){return t===0})){g(Array.prototype,\"find\",G.find,true)}if([,1].findIndex(function(e,t){return t===0})!==0){g(Array.prototype,\"findIndex\",G.findIndex,true)}if(u){m(Object,{assign:function(e,t){if(!M.TypeIsObject(e)){throw new TypeError(\"target must be an object\")}return Array.prototype.reduce.call(arguments,function(e,t){return Object.keys(Object(t)).reduce(function(e,r){e[r]=t[r];return e},e)})},is:function(e,t){return M.SameValue(e,t)},setPrototypeOf:function(e,t){var r;var n=function(e,t){if(!M.TypeIsObject(e)){throw new TypeError(\"cannot set prototype on a non-object\")}if(!(t===null||M.TypeIsObject(t))){throw new TypeError(\"can only set prototype to an object or null\"+t)}};var i=function(e,t){n(e,t);r.call(e,t);return e};try{r=e.getOwnPropertyDescriptor(e.prototype,t).set;r.call({},null)}catch(o){if(e.prototype!=={}[t]){return}r=function(e){this[t]=e};i.polyfill=i(i({},null),e.prototype)instanceof e}return i}(Object,\"__proto__\")})}if(Object.setPrototypeOf&&Object.getPrototypeOf&&Object.getPrototypeOf(Object.setPrototypeOf({},null))!==null&&Object.getPrototypeOf(Object.create(null))===null){(function(){var e=Object.create(null);var t=Object.getPrototypeOf,r=Object.setPrototypeOf;Object.getPrototypeOf=function(r){var n=t(r);return n===e?null:n};Object.setPrototypeOf=function(t,n){if(n===null){n=e}return r(t,n)};Object.setPrototypeOf.polyfill=false})()}var V=function(){try{Object.keys(\"foo\");return true}catch(e){return false}}();if(!V){var U=Object.keys;g(Object,\"keys\",function Et(e){return U(M.ToObject(e))},true)}if(Object.getOwnPropertyNames){var X=function(){try{Object.getOwnPropertyNames(\"foo\");return true}catch(e){return false}}();if(!X){var Z=Object.getOwnPropertyNames;g(Object,\"getOwnPropertyNames\",function xt(e){return Z(M.ToObject(e))},true)}}if(!RegExp.prototype.flags&&u){var $=function St(){if(!M.TypeIsObject(this)){throw new TypeError(\"Method called on incompatible type: must be an object.\")}var e=\"\";if(this.global){e+=\"g\"}if(this.ignoreCase){e+=\"i\"}if(this.multiline){e+=\"m\"}if(this.unicode){e+=\"u\"}if(this.sticky){e+=\"y\"}return e};d.getter(RegExp.prototype,\"flags\",$)}var K=function(){try{return String(new RegExp(/a/g,\"i\"))===\"/a/i\"}catch(e){return false}}();if(!K&&u){var B=RegExp;var H=function Pt(e,t){if(b.regex(e)&&b.string(t)){return new Pt(e.source,t)}return new B(e,t)};g(H,\"toString\",B.toString.bind(B),true);if(Object.setPrototypeOf){Object.setPrototypeOf(B,H)}Object.getOwnPropertyNames(B).forEach(function(e){if(e===\"$input\"){return}if(e in h){return}d.proxy(B,e,H)});H.prototype=B.prototype;d.redefine(B.prototype,\"constructor\",H);RegExp=H;d.redefine(o,\"RegExp\",H)}var J={acosh:function(e){var t=Number(e);if(Number.isNaN(t)||e<1){return NaN}if(t===1){return 0}if(t===Infinity){return t}return Math.log(t/Math.E+Math.sqrt(t+1)*Math.sqrt(t-1)/Math.E)+1},asinh:function(e){e=Number(e);if(e===0||!a(e)){return e}return e<0?-Math.asinh(-e):Math.log(e+Math.sqrt(e*e+1))},atanh:function(e){e=Number(e);if(Number.isNaN(e)||e<-1||e>1){return NaN}if(e===-1){return-Infinity}if(e===1){return Infinity}if(e===0){return e}return.5*Math.log((1+e)/(1-e))},cbrt:function(e){e=Number(e);if(e===0){return e}var t=e<0,r;if(t){e=-e}r=Math.pow(e,1/3);return t?-r:r},clz32:function(e){e=Number(e);var t=M.ToUint32(e);if(t===0){return 32}return 32-t.toString(2).length},cosh:function(e){e=Number(e);if(e===0){return 1}if(Number.isNaN(e)){return NaN}if(!a(e)){return Infinity}if(e<0){e=-e}if(e>21){return Math.exp(e)/2}return(Math.exp(e)+Math.exp(-e))/2},expm1:function(e){var t=Number(e);if(t===-Infinity){return-1}if(!a(t)||e===0){return t}if(Math.abs(t)>.5){return Math.exp(t)-1}var r=t;var n=0;var i=1;while(n+r!==n){n+=r;i+=1;r*=t/i}return n},hypot:function(e,t){var r=false;var n=true;var i=false;var o=[];Array.prototype.every.call(arguments,function(e){var t=Number(e);if(Number.isNaN(t)){r=true}else if(t===Infinity||t===-Infinity){i=true}else if(t!==0){n=false}if(i){return false}else if(!r){o.push(Math.abs(t))}return true});if(i){return Infinity}if(r){return NaN}if(n){return 0}o.sort(function(e,t){return t-e});var a=o[0];var u=o.map(function(e){return e/a});var s=u.reduce(function(e,t){return e+t*t},0);return a*Math.sqrt(s)},log2:function(e){return Math.log(e)*Math.LOG2E},log10:function(e){return Math.log(e)*Math.LOG10E},log1p:function(e){var t=Number(e);if(t<-1||Number.isNaN(t)){return NaN}if(t===0||t===Infinity){return t}if(t===-1){return-Infinity}return 1+t-1===0?t:t*(Math.log(1+t)/(1+t-1))},sign:function(e){var t=+e;if(t===0){return t}if(Number.isNaN(t)){return t}return t<0?-1:1},sinh:function(e){var t=Number(e);if(!a(e)||e===0){return e}if(Math.abs(t)<1){return(Math.expm1(t)-Math.expm1(-t))/2}return(Math.exp(t-1)-Math.exp(-t-1))*Math.E/2},tanh:function(e){var t=Number(e);if(Number.isNaN(e)||t===0){return t}if(t===Infinity){return 1}if(t===-Infinity){return-1}var r=Math.expm1(t);var n=Math.expm1(-t);if(r===Infinity){return 1}if(n===Infinity){return-1}return(r-n)/(Math.exp(t)+Math.exp(-t))},trunc:function(e){var t=Number(e);return t<0?-Math.floor(-t):Math.floor(t)},imul:function(e,t){e=M.ToUint32(e);t=M.ToUint32(t);var r=e>>>16&65535;var n=e&65535;var i=t>>>16&65535;var o=t&65535;return n*o+(r*o+n*i<<16>>>0)|0},fround:function(e){if(e===0||e===Infinity||e===-Infinity||Number.isNaN(e)){return e}var t=Number(e);return _.toFloat32(t)}};m(Math,J);g(Math,\"tanh\",J.tanh,Math.tanh(-2e-17)!==-2e-17);g(Math,\"acosh\",J.acosh,Math.acosh(Number.MAX_VALUE)===Infinity);g(Math,\"sinh\",J.sinh,Math.sinh(-2e-17)!==-2e-17);var Q=Math.expm1(10);g(Math,\"expm1\",J.expm1,Q>22025.465794806718||Q<22025.465794806718);var Y=Math.round(.5-Number.EPSILON/4)===0&&Math.round(-.5+Number.EPSILON/3.99)===1;var et=Math.round;g(Math,\"round\",function Ct(e){if(-.5<=e&&e<.5&&e!==0){return Math.sign(e*0)}return et(e)},!Y);if(Math.imul(4294967295,5)!==-5){Math.imul=J.imul}var tt=function(){var e,t;M.IsPromise=function(e){if(!M.TypeIsObject(e)){return false}if(!e._promiseConstructor){return false}if(typeof e._status===\"undefined\"){return false}return true};var r=function(e){if(!M.IsCallable(e)){throw new TypeError(\"bad promise constructor\")}var t=this;var r=function(e,r){t.resolve=e;t.reject=r};t.promise=M.Construct(e,[r]);if(!t.promise._es6construct){throw new TypeError(\"bad promise constructor\")}if(!(M.IsCallable(t.resolve)&&M.IsCallable(t.reject))){throw new TypeError(\"bad promise constructor\")}};var n=o.setTimeout;var i;if(typeof window!==\"undefined\"&&M.IsCallable(window.postMessage)){i=function(){var e=[];var t=\"zero-timeout-message\";var r=function(r){e.push(r);window.postMessage(t,\"*\")};var n=function(r){if(r.source===window&&r.data===t){r.stopPropagation();if(e.length===0){return}var n=e.shift();n()}};window.addEventListener(\"message\",n,true);return r}}var a=function(){var e=o.Promise;return e&&e.resolve&&function(t){return e.resolve().then(t)}};var u=M.IsCallable(o.setImmediate)?o.setImmediate.bind(o):typeof process===\"object\"&&process.nextTick?process.nextTick:a()||(M.IsCallable(i)?i():function(e){n(e,0)});var s=function(e,t){if(!M.TypeIsObject(e)){return false}var r=t.resolve;var n=t.reject;try{var i=e.then;if(!M.IsCallable(i)){return false}i.call(e,r,n)}catch(o){n(o)}return true};var f=function(e,t){e.forEach(function(e){u(function(){var r=e.handler;var n=e.capability;var i=n.resolve;var o=n.reject;try{var a=r(t);if(a===n.promise){throw new TypeError(\"self resolution\")}var u=s(a,n);if(!u){i(a)}}catch(f){o(f)}})})};var c=function(e,t,n){return function(i){if(i===e){return n(new TypeError(\"self resolution\"))}var o=e._promiseConstructor;var a=new r(o);var u=s(i,a);if(u){return a.promise.then(t,n)}else{return t(i)}}};e=function(e){var t=this;t=N(t);if(!t._promiseConstructor){throw new TypeError(\"bad promise\")}if(typeof t._status!==\"undefined\"){throw new TypeError(\"promise already initialized\")}if(!M.IsCallable(e)){throw new TypeError(\"not a valid resolver\")}t._status=\"unresolved\";t._resolveReactions=[];t._rejectReactions=[];var r=function(e){if(t._status!==\"unresolved\"){return}var r=t._resolveReactions;t._result=e;t._resolveReactions=void 0;t._rejectReactions=void 0;t._status=\"has-resolution\";f(r,e)};var n=function(e){if(t._status!==\"unresolved\"){return}var r=t._rejectReactions;t._result=e;t._resolveReactions=void 0;t._rejectReactions=void 0;t._status=\"has-rejection\";f(r,e)};try{e(r,n)}catch(i){n(i)}return t};t=e.prototype;var l=function(e,t,r,n){var i=false;return function(o){if(i){return}i=true;t[e]=o;if(--n.count===0){var a=r.resolve;a(t)}}};g(e,y,function(e){var r=this;var n=r.prototype||t;e=e||w(n);m(e,{_status:void 0,_result:void 0,_resolveReactions:void 0,_rejectReactions:void 0,_promiseConstructor:void 0});e._promiseConstructor=r;return e});m(e,{all:function p(e){var t=this;var n=new r(t);var i=n.resolve;var o=n.reject;try{if(!M.IsIterable(e)){throw new TypeError(\"bad iterable\")}var a=M.GetIterator(e);var u=[],s={count:1};for(var f=0;;f++){var c=M.IteratorNext(a);if(c.done){break}var p=t.resolve(c.value);var h=l(f,u,n,s);s.count++;p.then(h,n.reject)}if(--s.count===0){i(u)}}catch(v){o(v)}return n.promise},race:function h(e){var t=this;var n=new r(t);var i=n.resolve;var o=n.reject;try{if(!M.IsIterable(e)){throw new TypeError(\"bad iterable\")}var a=M.GetIterator(e);while(true){var u=M.IteratorNext(a);if(u.done){break}var s=t.resolve(u.value);s.then(i,o)}}catch(f){o(f)}return n.promise},reject:function v(e){var t=this;var n=new r(t);var i=n.reject;i(e);return n.promise},resolve:function b(e){var t=this;if(M.IsPromise(e)){var n=e._promiseConstructor;if(n===t){return e}}var i=new r(t);var o=i.resolve;o(e);return i.promise}});m(t,{\"catch\":function(e){return this.then(void 0,e)},then:function d(e,t){var n=this;if(!M.IsPromise(n)){throw new TypeError(\"not a promise\")}var i=this.constructor;var o=new r(i);if(!M.IsCallable(t)){t=function(e){throw e}}if(!M.IsCallable(e)){e=function(e){return e}}var a=c(n,e,t);var u={capability:o,handler:a};var s={capability:o,handler:t};switch(n._status){case\"unresolved\":n._resolveReactions.push(u);n._rejectReactions.push(s);break;case\"has-resolution\":f([u],n._result);break;case\"has-rejection\":f([s],n._result);break;default:throw new TypeError(\"unexpected\")}return o.promise}});return e}();if(o.Promise){delete o.Promise.accept;delete o.Promise.defer;delete o.Promise.prototype.chain}m(o,{Promise:tt});var rt=t(o.Promise,function(e){return e.resolve(42)instanceof e});var nt=function(){try{o.Promise.reject(42).then(null,5).then(null,h);return true}catch(e){return false}}();var it=function(){try{Promise.call(3,h)}catch(e){return true}return false}();if(!rt||!nt||!it){Promise=tt;g(o,\"Promise\",tt,true)}var ot=function(e){var t=Object.keys(e.reduce(function(e,t){e[t]=true;return e},{}));return e.join(\":\")===t.join(\":\")};var at=ot([\"z\",\"a\",\"bb\"]);var ut=ot([\"z\",1,\"a\",\"3\",2]);if(u){var st=function kt(e){if(!at){return null}var t=typeof e;if(t===\"string\"){return\"$\"+e}else if(t===\"number\"){if(!ut){return\"n\"+e}return e}return null};var ft=function At(){return Object.create?Object.create(null):{}};var ct={Map:function(){var e={};function t(e,t){this.key=e;this.value=t;this.next=null;this.prev=null}t.prototype.isRemoved=function(){return this.key===e};function r(e,t){this.head=e._head;this.i=this.head;this.kind=t}r.prototype={next:function(){var e=this.i,t=this.kind,r=this.head,n;if(typeof this.i===\"undefined\"){return{value:void 0,done:true}}while(e.isRemoved()&&e!==r){e=e.prev}while(e.next!==r){e=e.next;if(!e.isRemoved()){if(t===\"key\"){n=e.key}else if(t===\"value\"){n=e.value}else{n=[e.key,e.value]}this.i=e;return{value:n,done:false}}}this.i=void 0;return{value:void 0,done:true}}};j(r.prototype);function n(e){var r=this;if(!M.TypeIsObject(r)){throw new TypeError(\"Map does not accept arguments when called as a function\")}r=N(r);if(!r._es6map){throw new TypeError(\"bad map\")}var n=new t(null,null);n.next=n.prev=n;m(r,{_head:n,_storage:ft(),_size:0});if(typeof e!==\"undefined\"&&e!==null){var i=M.GetIterator(e);var o=r.set;if(!M.IsCallable(o)){throw new TypeError(\"bad map\")}while(true){var a=M.IteratorNext(i);if(a.done){break}var u=a.value;if(!M.TypeIsObject(u)){throw new TypeError(\"expected iterable of pairs\")}o.call(r,u[0],u[1])}}return r}var i=n.prototype;g(n,y,function(e){var t=this;var r=t.prototype||i;e=e||w(r);m(e,{_es6map:true});return e});d.getter(n.prototype,\"size\",function(){if(typeof this._size===\"undefined\"){throw new TypeError(\"size method called on incompatible Map\")}return this._size});m(n.prototype,{get:function(e){var t=st(e);if(t!==null){var r=this._storage[t];if(r){return r.value}else{return}}var n=this._head,i=n;while((i=i.next)!==n){if(M.SameValueZero(i.key,e)){return i.value}}},has:function(e){var t=st(e);if(t!==null){return typeof this._storage[t]!==\"undefined\"}var r=this._head,n=r;while((n=n.next)!==r){if(M.SameValueZero(n.key,e)){return true}}return false},set:function(e,r){var n=this._head,i=n,o;var a=st(e);if(a!==null){if(typeof this._storage[a]!==\"undefined\"){this._storage[a].value=r;return this}else{o=this._storage[a]=new t(e,r);i=n.prev}}while((i=i.next)!==n){if(M.SameValueZero(i.key,e)){i.value=r;return this}}o=o||new t(e,r);if(M.SameValue(-0,e)){o.key=+0}o.next=this._head;o.prev=this._head.prev;o.prev.next=o;o.next.prev=o;this._size+=1;return this},\"delete\":function(t){var r=this._head,n=r;var i=st(t);if(i!==null){if(typeof this._storage[i]===\"undefined\"){return false}n=this._storage[i].prev;delete this._storage[i]}while((n=n.next)!==r){if(M.SameValueZero(n.key,t)){n.key=n.value=e;n.prev.next=n.next;n.next.prev=n.prev;this._size-=1;return true}}return false},clear:function(){this._size=0;this._storage=ft();var t=this._head,r=t,n=r.next;while((r=n)!==t){r.key=r.value=e;n=r.next;r.next=r.prev=t}t.next=t.prev=t},keys:function(){return new r(this,\"key\")},values:function(){return new r(this,\"value\")},entries:function(){return new r(this,\"key+value\")},forEach:function(e){var t=arguments.length>1?arguments[1]:null;var r=this.entries();for(var n=r.next();!n.done;n=r.next()){if(t){e.call(t,n.value[1],n.value[0],this)}else{e(n.value[1],n.value[0],this)}}}});j(n.prototype,function(){return this.entries()});return n}(),Set:function(){var e=function n(e){var t=this;if(!M.TypeIsObject(t)){throw new TypeError(\"Set does not accept arguments when called as a function\")}t=N(t);if(!t._es6set){throw new TypeError(\"bad set\")}m(t,{\"[[SetData]]\":null,_storage:ft()});if(typeof e!==\"undefined\"&&e!==null){var r=M.GetIterator(e);var n=t.add;if(!M.IsCallable(n)){throw new TypeError(\"bad set\")}while(true){var i=M.IteratorNext(r);if(i.done){break}var o=i.value;n.call(t,o)}}return t};var t=e.prototype;g(e,y,function(e){var r=this;var n=r.prototype||t;e=e||w(n);m(e,{_es6set:true});return e});var r=function i(e){if(!e[\"[[SetData]]\"]){var t=e[\"[[SetData]]\"]=new ct.Map;Object.keys(e._storage).forEach(function(e){if(e.charCodeAt(0)===36){e=e.slice(1)}else if(e.charAt(0)===\"n\"){e=+e.slice(1)}else{e=+e}t.set(e,e)});e._storage=null}};d.getter(e.prototype,\"size\",function(){if(typeof this._storage===\"undefined\"){throw new TypeError(\"size method called on incompatible Set\")}r(this);return this[\"[[SetData]]\"].size});m(e.prototype,{has:function(e){var t;if(this._storage&&(t=st(e))!==null){return!!this._storage[t]}r(this);return this[\"[[SetData]]\"].has(e)},add:function(e){var t;if(this._storage&&(t=st(e))!==null){this._storage[t]=true;return this}r(this);this[\"[[SetData]]\"].set(e,e);return this},\"delete\":function(e){var t;if(this._storage&&(t=st(e))!==null){var n=l(this._storage,t);return delete this._storage[t]&&n}r(this);return this[\"[[SetData]]\"][\"delete\"](e)},clear:function(){if(this._storage){this._storage=ft()}else{this[\"[[SetData]]\"].clear()}},values:function(){r(this);return this[\"[[SetData]]\"].values()},entries:function(){r(this);return this[\"[[SetData]]\"].entries()},forEach:function(e){var t=arguments.length>1?arguments[1]:null;var n=this;r(n);this[\"[[SetData]]\"].forEach(function(r,i){if(t){e.call(t,i,i,n)}else{e(i,i,n)}})}});g(e,\"keys\",e.values,true);j(e.prototype,function(){return this.values()});return e}()};m(o,ct);if(o.Map||o.Set){if(typeof o.Map.prototype.clear!==\"function\"||(new o.Set).size!==0||(new o.Map).size!==0||typeof o.Map.prototype.keys!==\"function\"||typeof o.Set.prototype.keys!==\"function\"||typeof o.Map.prototype.forEach!==\"function\"||typeof o.Set.prototype.forEach!==\"function\"||e(o.Map)||e(o.Set)||!t(o.Map,function(e){var t=new e([]);t.set(42,42);return t instanceof e})){o.Map=ct.Map;o.Set=ct.Set}}if(o.Set.prototype.keys!==o.Set.prototype.values){g(o.Set.prototype,\"keys\",o.Set.prototype.values,true)}j(Object.getPrototypeOf((new o.Map).keys()));j(Object.getPrototypeOf((new o.Set).keys()))}if(!o.Reflect){g(o,\"Reflect\",{})}var lt=o.Reflect;var pt=function Rt(e){if(!M.TypeIsObject(e)){throw new TypeError(\"target must be an object\")}};m(o.Reflect,{apply:function Ft(){return M.Call.apply(null,arguments)},construct:function Dt(e,t){if(!M.IsCallable(e)){throw new TypeError(\"First argument must be callable.\")}return M.Construct(e,t)},deleteProperty:function zt(e,t){pt(e);if(u){var r=Object.getOwnPropertyDescriptor(e,t);if(r&&!r.configurable){return false}}return delete e[t]},enumerate:function Lt(e){pt(e);return new L(e,\"key\")},has:function qt(e,t){pt(e);return t in e}});if(Object.getOwnPropertyNames){m(o.Reflect,{ownKeys:function Gt(e){pt(e);var t=Object.getOwnPropertyNames(e);if(M.IsCallable(Object.getOwnPropertySymbols)){t.push.apply(t,Object.getOwnPropertySymbols(e))}return t}})}if(Object.preventExtensions){m(o.Reflect,{isExtensible:function Wt(e){pt(e);return Object.isExtensible(e)},preventExtensions:function Vt(e){pt(e);return yt(function(){Object.preventExtensions(e)})}})}if(u){var ht=function Ut(e,t,r){var n=Object.getOwnPropertyDescriptor(e,t);if(!n){var i=Object.getPrototypeOf(e);if(i===null){return undefined}return ht(i,t,r)}if(\"value\"in n){return n.value}if(n.get){return n.get.call(r)}return undefined};var vt=function Xt(e,t,r,n){var i=Object.getOwnPropertyDescriptor(e,t);if(!i){var o=Object.getPrototypeOf(e);if(o!==null){return vt(o,t,r,n)}i={value:void 0,writable:true,enumerable:true,configurable:true}}if(\"value\"in i){if(!i.writable){return false}if(!M.TypeIsObject(n)){return false}var a=Object.getOwnPropertyDescriptor(n,t);if(a){return lt.defineProperty(n,t,{value:r})}else{return lt.defineProperty(n,t,{value:r,writable:true,enumerable:true,configurable:true})}}if(i.set){i.set.call(n,r);return true}return false\n};var yt=function Zt(e){try{e()}catch(t){return false}return true};m(o.Reflect,{defineProperty:function $t(e,t,r){pt(e);return yt(function(){Object.defineProperty(e,t,r)})},getOwnPropertyDescriptor:function Kt(e,t){pt(e);return Object.getOwnPropertyDescriptor(e,t)},get:function Bt(e,t){pt(e);var r=arguments.length>2?arguments[2]:e;return ht(e,t,r)},set:function Ht(e,t,r){pt(e);var n=arguments.length>3?arguments[3]:e;return vt(e,t,r,n)}})}if(Object.getPrototypeOf){var bt=Object.getPrototypeOf;m(o.Reflect,{getPrototypeOf:function Jt(e){pt(e);return bt(e)}})}if(Object.setPrototypeOf){var gt=function(e,t){while(t){if(e===t){return true}t=lt.getPrototypeOf(t)}return false};m(o.Reflect,{setPrototypeOf:function Qt(e,t){pt(e);if(t!==null&&!M.TypeIsObject(t)){throw new TypeError(\"proto must be an object or null\")}if(t===lt.getPrototypeOf(e)){return true}if(lt.isExtensible&&!lt.isExtensible(e)){return false}if(gt(e,t)){return false}Object.setPrototypeOf(e,t);return true}})}return o});\n\n","chartjs/Chart.min.js":"/*!\n * Chart.js v3.9.1\n * https://www.chartjs.org\n * (c) 2022 Chart.js Contributors\n * Released under the MIT License\n */\n!function(t,e){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=e():\"function\"==typeof define&&define.amd?define(e):(t=\"undefined\"!=typeof globalThis?globalThis:t||self).Chart=e()}(this,(function(){\"use strict\";function t(){}const e=function(){let t=0;return function(){return t++}}();function i(t){return null==t}function s(t){if(Array.isArray&&Array.isArray(t))return!0;const e=Object.prototype.toString.call(t);return\"[object\"===e.slice(0,7)&&\"Array]\"===e.slice(-6)}function n(t){return null!==t&&\"[object Object]\"===Object.prototype.toString.call(t)}const o=t=>(\"number\"==typeof t||t instanceof Number)&&isFinite(+t);function a(t,e){return o(t)?t:e}function r(t,e){return void 0===t?e:t}const l=(t,e)=>\"string\"==typeof t&&t.endsWith(\"%\")?parseFloat(t)/100:t/e,h=(t,e)=>\"string\"==typeof t&&t.endsWith(\"%\")?parseFloat(t)/100*e:+t;function c(t,e,i){if(t&&\"function\"==typeof t.call)return t.apply(i,e)}function d(t,e,i,o){let a,r,l;if(s(t))if(r=t.length,o)for(a=r-1;a>=0;a--)e.call(i,t[a],a);else for(a=0;a<r;a++)e.call(i,t[a],a);else if(n(t))for(l=Object.keys(t),r=l.length,a=0;a<r;a++)e.call(i,t[l[a]],l[a])}function u(t,e){let i,s,n,o;if(!t||!e||t.length!==e.length)return!1;for(i=0,s=t.length;i<s;++i)if(n=t[i],o=e[i],n.datasetIndex!==o.datasetIndex||n.index!==o.index)return!1;return!0}function f(t){if(s(t))return t.map(f);if(n(t)){const e=Object.create(null),i=Object.keys(t),s=i.length;let n=0;for(;n<s;++n)e[i[n]]=f(t[i[n]]);return e}return t}function g(t){return-1===[\"__proto__\",\"prototype\",\"constructor\"].indexOf(t)}function p(t,e,i,s){if(!g(t))return;const o=e[t],a=i[t];n(o)&&n(a)?m(o,a,s):e[t]=f(a)}function m(t,e,i){const o=s(e)?e:[e],a=o.length;if(!n(t))return t;const r=(i=i||{}).merger||p;for(let s=0;s<a;++s){if(!n(e=o[s]))continue;const a=Object.keys(e);for(let s=0,n=a.length;s<n;++s)r(a[s],t,e,i)}return t}function b(t,e){return m(t,e,{merger:x})}function x(t,e,i){if(!g(t))return;const s=e[t],o=i[t];n(s)&&n(o)?b(s,o):Object.prototype.hasOwnProperty.call(e,t)||(e[t]=f(o))}const _={\"\":t=>t,x:t=>t.x,y:t=>t.y};function y(t,e){const i=_[e]||(_[e]=function(t){const e=v(t);return t=>{for(const i of e){if(\"\"===i)break;t=t&&t[i]}return t}}(e));return i(t)}function v(t){const e=t.split(\".\"),i=[];let s=\"\";for(const t of e)s+=t,s.endsWith(\"\\\\\")?s=s.slice(0,-1)+\".\":(i.push(s),s=\"\");return i}function w(t){return t.charAt(0).toUpperCase()+t.slice(1)}const M=t=>void 0!==t,k=t=>\"function\"==typeof t,S=(t,e)=>{if(t.size!==e.size)return!1;for(const i of t)if(!e.has(i))return!1;return!0};function P(t){return\"mouseup\"===t.type||\"click\"===t.type||\"contextmenu\"===t.type}const D=Math.PI,O=2*D,C=O+D,A=Number.POSITIVE_INFINITY,T=D/180,L=D/2,E=D/4,R=2*D/3,I=Math.log10,z=Math.sign;function F(t){const e=Math.round(t);t=N(t,e,t/1e3)?e:t;const i=Math.pow(10,Math.floor(I(t))),s=t/i;return(s<=1?1:s<=2?2:s<=5?5:10)*i}function V(t){const e=[],i=Math.sqrt(t);let s;for(s=1;s<i;s++)t%s==0&&(e.push(s),e.push(t/s));return i===(0|i)&&e.push(i),e.sort(((t,e)=>t-e)).pop(),e}function B(t){return!isNaN(parseFloat(t))&&isFinite(t)}function N(t,e,i){return Math.abs(t-e)<i}function W(t,e){const i=Math.round(t);return i-e<=t&&i+e>=t}function j(t,e,i){let s,n,o;for(s=0,n=t.length;s<n;s++)o=t[s][i],isNaN(o)||(e.min=Math.min(e.min,o),e.max=Math.max(e.max,o))}function H(t){return t*(D/180)}function $(t){return t*(180/D)}function Y(t){if(!o(t))return;let e=1,i=0;for(;Math.round(t*e)/e!==t;)e*=10,i++;return i}function U(t,e){const i=e.x-t.x,s=e.y-t.y,n=Math.sqrt(i*i+s*s);let o=Math.atan2(s,i);return o<-.5*D&&(o+=O),{angle:o,distance:n}}function X(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}function q(t,e){return(t-e+C)%O-D}function K(t){return(t%O+O)%O}function G(t,e,i,s){const n=K(t),o=K(e),a=K(i),r=K(o-n),l=K(a-n),h=K(n-o),c=K(n-a);return n===o||n===a||s&&o===a||r>l&&h<c}function Z(t,e,i){return Math.max(e,Math.min(i,t))}function J(t){return Z(t,-32768,32767)}function Q(t,e,i,s=1e-6){return t>=Math.min(e,i)-s&&t<=Math.max(e,i)+s}function tt(t,e,i){i=i||(i=>t[i]<e);let s,n=t.length-1,o=0;for(;n-o>1;)s=o+n>>1,i(s)?o=s:n=s;return{lo:o,hi:n}}const et=(t,e,i,s)=>tt(t,i,s?s=>t[s][e]<=i:s=>t[s][e]<i),it=(t,e,i)=>tt(t,i,(s=>t[s][e]>=i));function st(t,e,i){let s=0,n=t.length;for(;s<n&&t[s]<e;)s++;for(;n>s&&t[n-1]>i;)n--;return s>0||n<t.length?t.slice(s,n):t}const nt=[\"push\",\"pop\",\"shift\",\"splice\",\"unshift\"];function ot(t,e){t._chartjs?t._chartjs.listeners.push(e):(Object.defineProperty(t,\"_chartjs\",{configurable:!0,enumerable:!1,value:{listeners:[e]}}),nt.forEach((e=>{const i=\"_onData\"+w(e),s=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value(...e){const n=s.apply(this,e);return t._chartjs.listeners.forEach((t=>{\"function\"==typeof t[i]&&t[i](...e)})),n}})})))}function at(t,e){const i=t._chartjs;if(!i)return;const s=i.listeners,n=s.indexOf(e);-1!==n&&s.splice(n,1),s.length>0||(nt.forEach((e=>{delete t[e]})),delete t._chartjs)}function rt(t){const e=new Set;let i,s;for(i=0,s=t.length;i<s;++i)e.add(t[i]);return e.size===s?t:Array.from(e)}const lt=\"undefined\"==typeof window?function(t){return t()}:window.requestAnimationFrame;function ht(t,e,i){const s=i||(t=>Array.prototype.slice.call(t));let n=!1,o=[];return function(...i){o=s(i),n||(n=!0,lt.call(window,(()=>{n=!1,t.apply(e,o)})))}}function ct(t,e){let i;return function(...s){return e?(clearTimeout(i),i=setTimeout(t,e,s)):t.apply(this,s),e}}const dt=t=>\"start\"===t?\"left\":\"end\"===t?\"right\":\"center\",ut=(t,e,i)=>\"start\"===t?e:\"end\"===t?i:(e+i)/2,ft=(t,e,i,s)=>t===(s?\"left\":\"right\")?i:\"center\"===t?(e+i)/2:e;function gt(t,e,i){const s=e.length;let n=0,o=s;if(t._sorted){const{iScale:a,_parsed:r}=t,l=a.axis,{min:h,max:c,minDefined:d,maxDefined:u}=a.getUserBounds();d&&(n=Z(Math.min(et(r,a.axis,h).lo,i?s:et(e,l,a.getPixelForValue(h)).lo),0,s-1)),o=u?Z(Math.max(et(r,a.axis,c,!0).hi+1,i?0:et(e,l,a.getPixelForValue(c),!0).hi+1),n,s)-n:s-n}return{start:n,count:o}}function pt(t){const{xScale:e,yScale:i,_scaleRanges:s}=t,n={xmin:e.min,xmax:e.max,ymin:i.min,ymax:i.max};if(!s)return t._scaleRanges=n,!0;const o=s.xmin!==e.min||s.xmax!==e.max||s.ymin!==i.min||s.ymax!==i.max;return Object.assign(s,n),o}var mt=new class{constructor(){this._request=null,this._charts=new Map,this._running=!1,this._lastDate=void 0}_notify(t,e,i,s){const n=e.listeners[s],o=e.duration;n.forEach((s=>s({chart:t,initial:e.initial,numSteps:o,currentStep:Math.min(i-e.start,o)})))}_refresh(){this._request||(this._running=!0,this._request=lt.call(window,(()=>{this._update(),this._request=null,this._running&&this._refresh()})))}_update(t=Date.now()){let e=0;this._charts.forEach(((i,s)=>{if(!i.running||!i.items.length)return;const n=i.items;let o,a=n.length-1,r=!1;for(;a>=0;--a)o=n[a],o._active?(o._total>i.duration&&(i.duration=o._total),o.tick(t),r=!0):(n[a]=n[n.length-1],n.pop());r&&(s.draw(),this._notify(s,i,t,\"progress\")),n.length||(i.running=!1,this._notify(s,i,t,\"complete\"),i.initial=!1),e+=n.length})),this._lastDate=t,0===e&&(this._running=!1)}_getAnims(t){const e=this._charts;let i=e.get(t);return i||(i={running:!1,initial:!0,items:[],listeners:{complete:[],progress:[]}},e.set(t,i)),i}listen(t,e,i){this._getAnims(t).listeners[e].push(i)}add(t,e){e&&e.length&&this._getAnims(t).items.push(...e)}has(t){return this._getAnims(t).items.length>0}start(t){const e=this._charts.get(t);e&&(e.running=!0,e.start=Date.now(),e.duration=e.items.reduce(((t,e)=>Math.max(t,e._duration)),0),this._refresh())}running(t){if(!this._running)return!1;const e=this._charts.get(t);return!!(e&&e.running&&e.items.length)}stop(t){const e=this._charts.get(t);if(!e||!e.items.length)return;const i=e.items;let s=i.length-1;for(;s>=0;--s)i[s].cancel();e.items=[],this._notify(t,e,Date.now(),\"complete\")}remove(t){return this._charts.delete(t)}};\n    /*!\n     * @kurkle/color v0.2.1\n     * https://github.com/kurkle/color#readme\n     * (c) 2022 Jukka Kurkela\n     * Released under the MIT License\n     */function bt(t){return t+.5|0}const xt=(t,e,i)=>Math.max(Math.min(t,i),e);function _t(t){return xt(bt(2.55*t),0,255)}function yt(t){return xt(bt(255*t),0,255)}function vt(t){return xt(bt(t/2.55)/100,0,1)}function wt(t){return xt(bt(100*t),0,100)}const Mt={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,A:10,B:11,C:12,D:13,E:14,F:15,a:10,b:11,c:12,d:13,e:14,f:15},kt=[...\"0123456789ABCDEF\"],St=t=>kt[15&t],Pt=t=>kt[(240&t)>>4]+kt[15&t],Dt=t=>(240&t)>>4==(15&t);function Ot(t){var e=(t=>Dt(t.r)&&Dt(t.g)&&Dt(t.b)&&Dt(t.a))(t)?St:Pt;return t?\"#\"+e(t.r)+e(t.g)+e(t.b)+((t,e)=>t<255?e(t):\"\")(t.a,e):void 0}const Ct=/^(hsla?|hwb|hsv)\\(\\s*([-+.e\\d]+)(?:deg)?[\\s,]+([-+.e\\d]+)%[\\s,]+([-+.e\\d]+)%(?:[\\s,]+([-+.e\\d]+)(%)?)?\\s*\\)$/;function At(t,e,i){const s=e*Math.min(i,1-i),n=(e,n=(e+t/30)%12)=>i-s*Math.max(Math.min(n-3,9-n,1),-1);return[n(0),n(8),n(4)]}function Tt(t,e,i){const s=(s,n=(s+t/60)%6)=>i-i*e*Math.max(Math.min(n,4-n,1),0);return[s(5),s(3),s(1)]}function Lt(t,e,i){const s=At(t,1,.5);let n;for(e+i>1&&(n=1/(e+i),e*=n,i*=n),n=0;n<3;n++)s[n]*=1-e-i,s[n]+=e;return s}function Et(t){const e=t.r/255,i=t.g/255,s=t.b/255,n=Math.max(e,i,s),o=Math.min(e,i,s),a=(n+o)/2;let r,l,h;return n!==o&&(h=n-o,l=a>.5?h/(2-n-o):h/(n+o),r=function(t,e,i,s,n){return t===n?(e-i)/s+(e<i?6:0):e===n?(i-t)/s+2:(t-e)/s+4}(e,i,s,h,n),r=60*r+.5),[0|r,l||0,a]}function Rt(t,e,i,s){return(Array.isArray(e)?t(e[0],e[1],e[2]):t(e,i,s)).map(yt)}function It(t,e,i){return Rt(At,t,e,i)}function zt(t){return(t%360+360)%360}function Ft(t){const e=Ct.exec(t);let i,s=255;if(!e)return;e[5]!==i&&(s=e[6]?_t(+e[5]):yt(+e[5]));const n=zt(+e[2]),o=+e[3]/100,a=+e[4]/100;return i=\"hwb\"===e[1]?function(t,e,i){return Rt(Lt,t,e,i)}(n,o,a):\"hsv\"===e[1]?function(t,e,i){return Rt(Tt,t,e,i)}(n,o,a):It(n,o,a),{r:i[0],g:i[1],b:i[2],a:s}}const Vt={x:\"dark\",Z:\"light\",Y:\"re\",X:\"blu\",W:\"gr\",V:\"medium\",U:\"slate\",A:\"ee\",T:\"ol\",S:\"or\",B:\"ra\",C:\"lateg\",D:\"ights\",R:\"in\",Q:\"turquois\",E:\"hi\",P:\"ro\",O:\"al\",N:\"le\",M:\"de\",L:\"yello\",F:\"en\",K:\"ch\",G:\"arks\",H:\"ea\",I:\"ightg\",J:\"wh\"},Bt={OiceXe:\"f0f8ff\",antiquewEte:\"faebd7\",aqua:\"ffff\",aquamarRe:\"7fffd4\",azuY:\"f0ffff\",beige:\"f5f5dc\",bisque:\"ffe4c4\",black:\"0\",blanKedOmond:\"ffebcd\",Xe:\"ff\",XeviTet:\"8a2be2\",bPwn:\"a52a2a\",burlywood:\"deb887\",caMtXe:\"5f9ea0\",KartYuse:\"7fff00\",KocTate:\"d2691e\",cSO:\"ff7f50\",cSnflowerXe:\"6495ed\",cSnsilk:\"fff8dc\",crimson:\"dc143c\",cyan:\"ffff\",xXe:\"8b\",xcyan:\"8b8b\",xgTMnPd:\"b8860b\",xWay:\"a9a9a9\",xgYF:\"6400\",xgYy:\"a9a9a9\",xkhaki:\"bdb76b\",xmagFta:\"8b008b\",xTivegYF:\"556b2f\",xSange:\"ff8c00\",xScEd:\"9932cc\",xYd:\"8b0000\",xsOmon:\"e9967a\",xsHgYF:\"8fbc8f\",xUXe:\"483d8b\",xUWay:\"2f4f4f\",xUgYy:\"2f4f4f\",xQe:\"ced1\",xviTet:\"9400d3\",dAppRk:\"ff1493\",dApskyXe:\"bfff\",dimWay:\"696969\",dimgYy:\"696969\",dodgerXe:\"1e90ff\",fiYbrick:\"b22222\",flSOwEte:\"fffaf0\",foYstWAn:\"228b22\",fuKsia:\"ff00ff\",gaRsbSo:\"dcdcdc\",ghostwEte:\"f8f8ff\",gTd:\"ffd700\",gTMnPd:\"daa520\",Way:\"808080\",gYF:\"8000\",gYFLw:\"adff2f\",gYy:\"808080\",honeyMw:\"f0fff0\",hotpRk:\"ff69b4\",RdianYd:\"cd5c5c\",Rdigo:\"4b0082\",ivSy:\"fffff0\",khaki:\"f0e68c\",lavFMr:\"e6e6fa\",lavFMrXsh:\"fff0f5\",lawngYF:\"7cfc00\",NmoncEffon:\"fffacd\",ZXe:\"add8e6\",ZcSO:\"f08080\",Zcyan:\"e0ffff\",ZgTMnPdLw:\"fafad2\",ZWay:\"d3d3d3\",ZgYF:\"90ee90\",ZgYy:\"d3d3d3\",ZpRk:\"ffb6c1\",ZsOmon:\"ffa07a\",ZsHgYF:\"20b2aa\",ZskyXe:\"87cefa\",ZUWay:\"778899\",ZUgYy:\"778899\",ZstAlXe:\"b0c4de\",ZLw:\"ffffe0\",lime:\"ff00\",limegYF:\"32cd32\",lRF:\"faf0e6\",magFta:\"ff00ff\",maPon:\"800000\",VaquamarRe:\"66cdaa\",VXe:\"cd\",VScEd:\"ba55d3\",VpurpN:\"9370db\",VsHgYF:\"3cb371\",VUXe:\"7b68ee\",VsprRggYF:\"fa9a\",VQe:\"48d1cc\",VviTetYd:\"c71585\",midnightXe:\"191970\",mRtcYam:\"f5fffa\",mistyPse:\"ffe4e1\",moccasR:\"ffe4b5\",navajowEte:\"ffdead\",navy:\"80\",Tdlace:\"fdf5e6\",Tive:\"808000\",TivedBb:\"6b8e23\",Sange:\"ffa500\",SangeYd:\"ff4500\",ScEd:\"da70d6\",pOegTMnPd:\"eee8aa\",pOegYF:\"98fb98\",pOeQe:\"afeeee\",pOeviTetYd:\"db7093\",papayawEp:\"ffefd5\",pHKpuff:\"ffdab9\",peru:\"cd853f\",pRk:\"ffc0cb\",plum:\"dda0dd\",powMrXe:\"b0e0e6\",purpN:\"800080\",YbeccapurpN:\"663399\",Yd:\"ff0000\",Psybrown:\"bc8f8f\",PyOXe:\"4169e1\",saddNbPwn:\"8b4513\",sOmon:\"fa8072\",sandybPwn:\"f4a460\",sHgYF:\"2e8b57\",sHshell:\"fff5ee\",siFna:\"a0522d\",silver:\"c0c0c0\",skyXe:\"87ceeb\",UXe:\"6a5acd\",UWay:\"708090\",UgYy:\"708090\",snow:\"fffafa\",sprRggYF:\"ff7f\",stAlXe:\"4682b4\",tan:\"d2b48c\",teO:\"8080\",tEstN:\"d8bfd8\",tomato:\"ff6347\",Qe:\"40e0d0\",viTet:\"ee82ee\",JHt:\"f5deb3\",wEte:\"ffffff\",wEtesmoke:\"f5f5f5\",Lw:\"ffff00\",LwgYF:\"9acd32\"};let Nt;function Wt(t){Nt||(Nt=function(){const t={},e=Object.keys(Bt),i=Object.keys(Vt);let s,n,o,a,r;for(s=0;s<e.length;s++){for(a=r=e[s],n=0;n<i.length;n++)o=i[n],r=r.replace(o,Vt[o]);o=parseInt(Bt[a],16),t[r]=[o>>16&255,o>>8&255,255&o]}return t}(),Nt.transparent=[0,0,0,0]);const e=Nt[t.toLowerCase()];return e&&{r:e[0],g:e[1],b:e[2],a:4===e.length?e[3]:255}}const jt=/^rgba?\\(\\s*([-+.\\d]+)(%)?[\\s,]+([-+.e\\d]+)(%)?[\\s,]+([-+.e\\d]+)(%)?(?:[\\s,/]+([-+.e\\d]+)(%)?)?\\s*\\)$/;const Ht=t=>t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055,$t=t=>t<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4);function Yt(t,e,i){if(t){let s=Et(t);s[e]=Math.max(0,Math.min(s[e]+s[e]*i,0===e?360:1)),s=It(s),t.r=s[0],t.g=s[1],t.b=s[2]}}function Ut(t,e){return t?Object.assign(e||{},t):t}function Xt(t){var e={r:0,g:0,b:0,a:255};return Array.isArray(t)?t.length>=3&&(e={r:t[0],g:t[1],b:t[2],a:255},t.length>3&&(e.a=yt(t[3]))):(e=Ut(t,{r:0,g:0,b:0,a:1})).a=yt(e.a),e}function qt(t){return\"r\"===t.charAt(0)?function(t){const e=jt.exec(t);let i,s,n,o=255;if(e){if(e[7]!==i){const t=+e[7];o=e[8]?_t(t):xt(255*t,0,255)}return i=+e[1],s=+e[3],n=+e[5],i=255&(e[2]?_t(i):xt(i,0,255)),s=255&(e[4]?_t(s):xt(s,0,255)),n=255&(e[6]?_t(n):xt(n,0,255)),{r:i,g:s,b:n,a:o}}}(t):Ft(t)}class Kt{constructor(t){if(t instanceof Kt)return t;const e=typeof t;let i;var s,n,o;\"object\"===e?i=Xt(t):\"string\"===e&&(o=(s=t).length,\"#\"===s[0]&&(4===o||5===o?n={r:255&17*Mt[s[1]],g:255&17*Mt[s[2]],b:255&17*Mt[s[3]],a:5===o?17*Mt[s[4]]:255}:7!==o&&9!==o||(n={r:Mt[s[1]]<<4|Mt[s[2]],g:Mt[s[3]]<<4|Mt[s[4]],b:Mt[s[5]]<<4|Mt[s[6]],a:9===o?Mt[s[7]]<<4|Mt[s[8]]:255})),i=n||Wt(t)||qt(t)),this._rgb=i,this._valid=!!i}get valid(){return this._valid}get rgb(){var t=Ut(this._rgb);return t&&(t.a=vt(t.a)),t}set rgb(t){this._rgb=Xt(t)}rgbString(){return this._valid?(t=this._rgb)&&(t.a<255?`rgba(${t.r}, ${t.g}, ${t.b}, ${vt(t.a)})`:`rgb(${t.r}, ${t.g}, ${t.b})`):void 0;var t}hexString(){return this._valid?Ot(this._rgb):void 0}hslString(){return this._valid?function(t){if(!t)return;const e=Et(t),i=e[0],s=wt(e[1]),n=wt(e[2]);return t.a<255?`hsla(${i}, ${s}%, ${n}%, ${vt(t.a)})`:`hsl(${i}, ${s}%, ${n}%)`}(this._rgb):void 0}mix(t,e){if(t){const i=this.rgb,s=t.rgb;let n;const o=e===n?.5:e,a=2*o-1,r=i.a-s.a,l=((a*r==-1?a:(a+r)/(1+a*r))+1)/2;n=1-l,i.r=255&l*i.r+n*s.r+.5,i.g=255&l*i.g+n*s.g+.5,i.b=255&l*i.b+n*s.b+.5,i.a=o*i.a+(1-o)*s.a,this.rgb=i}return this}interpolate(t,e){return t&&(this._rgb=function(t,e,i){const s=$t(vt(t.r)),n=$t(vt(t.g)),o=$t(vt(t.b));return{r:yt(Ht(s+i*($t(vt(e.r))-s))),g:yt(Ht(n+i*($t(vt(e.g))-n))),b:yt(Ht(o+i*($t(vt(e.b))-o))),a:t.a+i*(e.a-t.a)}}(this._rgb,t._rgb,e)),this}clone(){return new Kt(this.rgb)}alpha(t){return this._rgb.a=yt(t),this}clearer(t){return this._rgb.a*=1-t,this}greyscale(){const t=this._rgb,e=bt(.3*t.r+.59*t.g+.11*t.b);return t.r=t.g=t.b=e,this}opaquer(t){return this._rgb.a*=1+t,this}negate(){const t=this._rgb;return t.r=255-t.r,t.g=255-t.g,t.b=255-t.b,this}lighten(t){return Yt(this._rgb,2,t),this}darken(t){return Yt(this._rgb,2,-t),this}saturate(t){return Yt(this._rgb,1,t),this}desaturate(t){return Yt(this._rgb,1,-t),this}rotate(t){return function(t,e){var i=Et(t);i[0]=zt(i[0]+e),i=It(i),t.r=i[0],t.g=i[1],t.b=i[2]}(this._rgb,t),this}}function Gt(t){return new Kt(t)}function Zt(t){if(t&&\"object\"==typeof t){const e=t.toString();return\"[object CanvasPattern]\"===e||\"[object CanvasGradient]\"===e}return!1}function Jt(t){return Zt(t)?t:Gt(t)}function Qt(t){return Zt(t)?t:Gt(t).saturate(.5).darken(.1).hexString()}const te=Object.create(null),ee=Object.create(null);function ie(t,e){if(!e)return t;const i=e.split(\".\");for(let e=0,s=i.length;e<s;++e){const s=i[e];t=t[s]||(t[s]=Object.create(null))}return t}function se(t,e,i){return\"string\"==typeof e?m(ie(t,e),i):m(ie(t,\"\"),e)}var ne=new class{constructor(t){this.animation=void 0,this.backgroundColor=\"rgba(0,0,0,0.1)\",this.borderColor=\"rgba(0,0,0,0.1)\",this.color=\"#666\",this.datasets={},this.devicePixelRatio=t=>t.chart.platform.getDevicePixelRatio(),this.elements={},this.events=[\"mousemove\",\"mouseout\",\"click\",\"touchstart\",\"touchmove\"],this.font={family:\"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\",size:12,style:\"normal\",lineHeight:1.2,weight:null},this.hover={},this.hoverBackgroundColor=(t,e)=>Qt(e.backgroundColor),this.hoverBorderColor=(t,e)=>Qt(e.borderColor),this.hoverColor=(t,e)=>Qt(e.color),this.indexAxis=\"x\",this.interaction={mode:\"nearest\",intersect:!0,includeInvisible:!1},this.maintainAspectRatio=!0,this.onHover=null,this.onClick=null,this.parsing=!0,this.plugins={},this.responsive=!0,this.scale=void 0,this.scales={},this.showLine=!0,this.drawActiveElementsOnTop=!0,this.describe(t)}set(t,e){return se(this,t,e)}get(t){return ie(this,t)}describe(t,e){return se(ee,t,e)}override(t,e){return se(te,t,e)}route(t,e,i,s){const o=ie(this,t),a=ie(this,i),l=\"_\"+e;Object.defineProperties(o,{[l]:{value:o[e],writable:!0},[e]:{enumerable:!0,get(){const t=this[l],e=a[s];return n(t)?Object.assign({},e,t):r(t,e)},set(t){this[l]=t}}})}}({_scriptable:t=>!t.startsWith(\"on\"),_indexable:t=>\"events\"!==t,hover:{_fallback:\"interaction\"},interaction:{_scriptable:!1,_indexable:!1}});function oe(){return\"undefined\"!=typeof window&&\"undefined\"!=typeof document}function ae(t){let e=t.parentNode;return e&&\"[object ShadowRoot]\"===e.toString()&&(e=e.host),e}function re(t,e,i){let s;return\"string\"==typeof t?(s=parseInt(t,10),-1!==t.indexOf(\"%\")&&(s=s/100*e.parentNode[i])):s=t,s}const le=t=>window.getComputedStyle(t,null);function he(t,e){return le(t).getPropertyValue(e)}const ce=[\"top\",\"right\",\"bottom\",\"left\"];function de(t,e,i){const s={};i=i?\"-\"+i:\"\";for(let n=0;n<4;n++){const o=ce[n];s[o]=parseFloat(t[e+\"-\"+o+i])||0}return s.width=s.left+s.right,s.height=s.top+s.bottom,s}function ue(t,e){if(\"native\"in t)return t;const{canvas:i,currentDevicePixelRatio:s}=e,n=le(i),o=\"border-box\"===n.boxSizing,a=de(n,\"padding\"),r=de(n,\"border\",\"width\"),{x:l,y:h,box:c}=function(t,e){const i=t.touches,s=i&&i.length?i[0]:t,{offsetX:n,offsetY:o}=s;let a,r,l=!1;if(((t,e,i)=>(t>0||e>0)&&(!i||!i.shadowRoot))(n,o,t.target))a=n,r=o;else{const t=e.getBoundingClientRect();a=s.clientX-t.left,r=s.clientY-t.top,l=!0}return{x:a,y:r,box:l}}(t,i),d=a.left+(c&&r.left),u=a.top+(c&&r.top);let{width:f,height:g}=e;return o&&(f-=a.width+r.width,g-=a.height+r.height),{x:Math.round((l-d)/f*i.width/s),y:Math.round((h-u)/g*i.height/s)}}const fe=t=>Math.round(10*t)/10;function ge(t,e,i,s){const n=le(t),o=de(n,\"margin\"),a=re(n.maxWidth,t,\"clientWidth\")||A,r=re(n.maxHeight,t,\"clientHeight\")||A,l=function(t,e,i){let s,n;if(void 0===e||void 0===i){const o=ae(t);if(o){const t=o.getBoundingClientRect(),a=le(o),r=de(a,\"border\",\"width\"),l=de(a,\"padding\");e=t.width-l.width-r.width,i=t.height-l.height-r.height,s=re(a.maxWidth,o,\"clientWidth\"),n=re(a.maxHeight,o,\"clientHeight\")}else e=t.clientWidth,i=t.clientHeight}return{width:e,height:i,maxWidth:s||A,maxHeight:n||A}}(t,e,i);let{width:h,height:c}=l;if(\"content-box\"===n.boxSizing){const t=de(n,\"border\",\"width\"),e=de(n,\"padding\");h-=e.width+t.width,c-=e.height+t.height}return h=Math.max(0,h-o.width),c=Math.max(0,s?Math.floor(h/s):c-o.height),h=fe(Math.min(h,a,l.maxWidth)),c=fe(Math.min(c,r,l.maxHeight)),h&&!c&&(c=fe(h/2)),{width:h,height:c}}function pe(t,e,i){const s=e||1,n=Math.floor(t.height*s),o=Math.floor(t.width*s);t.height=n/s,t.width=o/s;const a=t.canvas;return a.style&&(i||!a.style.height&&!a.style.width)&&(a.style.height=`${t.height}px`,a.style.width=`${t.width}px`),(t.currentDevicePixelRatio!==s||a.height!==n||a.width!==o)&&(t.currentDevicePixelRatio=s,a.height=n,a.width=o,t.ctx.setTransform(s,0,0,s,0,0),!0)}const me=function(){let t=!1;try{const e={get passive(){return t=!0,!1}};window.addEventListener(\"test\",null,e),window.removeEventListener(\"test\",null,e)}catch(t){}return t}();function be(t,e){const i=he(t,e),s=i&&i.match(/^(\\d+)(\\.\\d+)?px$/);return s?+s[1]:void 0}function xe(t){return!t||i(t.size)||i(t.family)?null:(t.style?t.style+\" \":\"\")+(t.weight?t.weight+\" \":\"\")+t.size+\"px \"+t.family}function _e(t,e,i,s,n){let o=e[n];return o||(o=e[n]=t.measureText(n).width,i.push(n)),o>s&&(s=o),s}function ye(t,e,i,n){let o=(n=n||{}).data=n.data||{},a=n.garbageCollect=n.garbageCollect||[];n.font!==e&&(o=n.data={},a=n.garbageCollect=[],n.font=e),t.save(),t.font=e;let r=0;const l=i.length;let h,c,d,u,f;for(h=0;h<l;h++)if(u=i[h],null!=u&&!0!==s(u))r=_e(t,o,a,r,u);else if(s(u))for(c=0,d=u.length;c<d;c++)f=u[c],null==f||s(f)||(r=_e(t,o,a,r,f));t.restore();const g=a.length/2;if(g>i.length){for(h=0;h<g;h++)delete o[a[h]];a.splice(0,g)}return r}function ve(t,e,i){const s=t.currentDevicePixelRatio,n=0!==i?Math.max(i/2,.5):0;return Math.round((e-n)*s)/s+n}function we(t,e){(e=e||t.getContext(\"2d\")).save(),e.resetTransform(),e.clearRect(0,0,t.width,t.height),e.restore()}function Me(t,e,i,s){ke(t,e,i,s,null)}function ke(t,e,i,s,n){let o,a,r,l,h,c;const d=e.pointStyle,u=e.rotation,f=e.radius;let g=(u||0)*T;if(d&&\"object\"==typeof d&&(o=d.toString(),\"[object HTMLImageElement]\"===o||\"[object HTMLCanvasElement]\"===o))return t.save(),t.translate(i,s),t.rotate(g),t.drawImage(d,-d.width/2,-d.height/2,d.width,d.height),void t.restore();if(!(isNaN(f)||f<=0)){switch(t.beginPath(),d){default:n?t.ellipse(i,s,n/2,f,0,0,O):t.arc(i,s,f,0,O),t.closePath();break;case\"triangle\":t.moveTo(i+Math.sin(g)*f,s-Math.cos(g)*f),g+=R,t.lineTo(i+Math.sin(g)*f,s-Math.cos(g)*f),g+=R,t.lineTo(i+Math.sin(g)*f,s-Math.cos(g)*f),t.closePath();break;case\"rectRounded\":h=.516*f,l=f-h,a=Math.cos(g+E)*l,r=Math.sin(g+E)*l,t.arc(i-a,s-r,h,g-D,g-L),t.arc(i+r,s-a,h,g-L,g),t.arc(i+a,s+r,h,g,g+L),t.arc(i-r,s+a,h,g+L,g+D),t.closePath();break;case\"rect\":if(!u){l=Math.SQRT1_2*f,c=n?n/2:l,t.rect(i-c,s-l,2*c,2*l);break}g+=E;case\"rectRot\":a=Math.cos(g)*f,r=Math.sin(g)*f,t.moveTo(i-a,s-r),t.lineTo(i+r,s-a),t.lineTo(i+a,s+r),t.lineTo(i-r,s+a),t.closePath();break;case\"crossRot\":g+=E;case\"cross\":a=Math.cos(g)*f,r=Math.sin(g)*f,t.moveTo(i-a,s-r),t.lineTo(i+a,s+r),t.moveTo(i+r,s-a),t.lineTo(i-r,s+a);break;case\"star\":a=Math.cos(g)*f,r=Math.sin(g)*f,t.moveTo(i-a,s-r),t.lineTo(i+a,s+r),t.moveTo(i+r,s-a),t.lineTo(i-r,s+a),g+=E,a=Math.cos(g)*f,r=Math.sin(g)*f,t.moveTo(i-a,s-r),t.lineTo(i+a,s+r),t.moveTo(i+r,s-a),t.lineTo(i-r,s+a);break;case\"line\":a=n?n/2:Math.cos(g)*f,r=Math.sin(g)*f,t.moveTo(i-a,s-r),t.lineTo(i+a,s+r);break;case\"dash\":t.moveTo(i,s),t.lineTo(i+Math.cos(g)*f,s+Math.sin(g)*f)}t.fill(),e.borderWidth>0&&t.stroke()}}function Se(t,e,i){return i=i||.5,!e||t&&t.x>e.left-i&&t.x<e.right+i&&t.y>e.top-i&&t.y<e.bottom+i}function Pe(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()}function De(t){t.restore()}function Oe(t,e,i,s,n){if(!e)return t.lineTo(i.x,i.y);if(\"middle\"===n){const s=(e.x+i.x)/2;t.lineTo(s,e.y),t.lineTo(s,i.y)}else\"after\"===n!=!!s?t.lineTo(e.x,i.y):t.lineTo(i.x,e.y);t.lineTo(i.x,i.y)}function Ce(t,e,i,s){if(!e)return t.lineTo(i.x,i.y);t.bezierCurveTo(s?e.cp1x:e.cp2x,s?e.cp1y:e.cp2y,s?i.cp2x:i.cp1x,s?i.cp2y:i.cp1y,i.x,i.y)}function Ae(t,e,n,o,a,r={}){const l=s(e)?e:[e],h=r.strokeWidth>0&&\"\"!==r.strokeColor;let c,d;for(t.save(),t.font=a.string,function(t,e){e.translation&&t.translate(e.translation[0],e.translation[1]);i(e.rotation)||t.rotate(e.rotation);e.color&&(t.fillStyle=e.color);e.textAlign&&(t.textAlign=e.textAlign);e.textBaseline&&(t.textBaseline=e.textBaseline)}(t,r),c=0;c<l.length;++c)d=l[c],h&&(r.strokeColor&&(t.strokeStyle=r.strokeColor),i(r.strokeWidth)||(t.lineWidth=r.strokeWidth),t.strokeText(d,n,o,r.maxWidth)),t.fillText(d,n,o,r.maxWidth),Te(t,n,o,d,r),o+=a.lineHeight;t.restore()}function Te(t,e,i,s,n){if(n.strikethrough||n.underline){const o=t.measureText(s),a=e-o.actualBoundingBoxLeft,r=e+o.actualBoundingBoxRight,l=i-o.actualBoundingBoxAscent,h=i+o.actualBoundingBoxDescent,c=n.strikethrough?(l+h)/2:h;t.strokeStyle=t.fillStyle,t.beginPath(),t.lineWidth=n.decorationWidth||2,t.moveTo(a,c),t.lineTo(r,c),t.stroke()}}function Le(t,e){const{x:i,y:s,w:n,h:o,radius:a}=e;t.arc(i+a.topLeft,s+a.topLeft,a.topLeft,-L,D,!0),t.lineTo(i,s+o-a.bottomLeft),t.arc(i+a.bottomLeft,s+o-a.bottomLeft,a.bottomLeft,D,L,!0),t.lineTo(i+n-a.bottomRight,s+o),t.arc(i+n-a.bottomRight,s+o-a.bottomRight,a.bottomRight,L,0,!0),t.lineTo(i+n,s+a.topRight),t.arc(i+n-a.topRight,s+a.topRight,a.topRight,0,-L,!0),t.lineTo(i+a.topLeft,s)}function Ee(t,e=[\"\"],i=t,s,n=(()=>t[0])){M(s)||(s=$e(\"_fallback\",t));const o={[Symbol.toStringTag]:\"Object\",_cacheable:!0,_scopes:t,_rootScopes:i,_fallback:s,_getTarget:n,override:n=>Ee([n,...t],e,i,s)};return new Proxy(o,{deleteProperty:(e,i)=>(delete e[i],delete e._keys,delete t[0][i],!0),get:(i,s)=>Ve(i,s,(()=>function(t,e,i,s){let n;for(const o of e)if(n=$e(ze(o,t),i),M(n))return Fe(t,n)?je(i,s,t,n):n}(s,e,t,i))),getOwnPropertyDescriptor:(t,e)=>Reflect.getOwnPropertyDescriptor(t._scopes[0],e),getPrototypeOf:()=>Reflect.getPrototypeOf(t[0]),has:(t,e)=>Ye(t).includes(e),ownKeys:t=>Ye(t),set(t,e,i){const s=t._storage||(t._storage=n());return t[e]=s[e]=i,delete t._keys,!0}})}function Re(t,e,i,o){const a={_cacheable:!1,_proxy:t,_context:e,_subProxy:i,_stack:new Set,_descriptors:Ie(t,o),setContext:e=>Re(t,e,i,o),override:s=>Re(t.override(s),e,i,o)};return new Proxy(a,{deleteProperty:(e,i)=>(delete e[i],delete t[i],!0),get:(t,e,i)=>Ve(t,e,(()=>function(t,e,i){const{_proxy:o,_context:a,_subProxy:r,_descriptors:l}=t;let h=o[e];k(h)&&l.isScriptable(e)&&(h=function(t,e,i,s){const{_proxy:n,_context:o,_subProxy:a,_stack:r}=i;if(r.has(t))throw new Error(\"Recursion detected: \"+Array.from(r).join(\"->\")+\"->\"+t);r.add(t),e=e(o,a||s),r.delete(t),Fe(t,e)&&(e=je(n._scopes,n,t,e));return e}(e,h,t,i));s(h)&&h.length&&(h=function(t,e,i,s){const{_proxy:o,_context:a,_subProxy:r,_descriptors:l}=i;if(M(a.index)&&s(t))e=e[a.index%e.length];else if(n(e[0])){const i=e,s=o._scopes.filter((t=>t!==i));e=[];for(const n of i){const i=je(s,o,t,n);e.push(Re(i,a,r&&r[t],l))}}return e}(e,h,t,l.isIndexable));Fe(e,h)&&(h=Re(h,a,r&&r[e],l));return h}(t,e,i))),getOwnPropertyDescriptor:(e,i)=>e._descriptors.allKeys?Reflect.has(t,i)?{enumerable:!0,configurable:!0}:void 0:Reflect.getOwnPropertyDescriptor(t,i),getPrototypeOf:()=>Reflect.getPrototypeOf(t),has:(e,i)=>Reflect.has(t,i),ownKeys:()=>Reflect.ownKeys(t),set:(e,i,s)=>(t[i]=s,delete e[i],!0)})}function Ie(t,e={scriptable:!0,indexable:!0}){const{_scriptable:i=e.scriptable,_indexable:s=e.indexable,_allKeys:n=e.allKeys}=t;return{allKeys:n,scriptable:i,indexable:s,isScriptable:k(i)?i:()=>i,isIndexable:k(s)?s:()=>s}}const ze=(t,e)=>t?t+w(e):e,Fe=(t,e)=>n(e)&&\"adapters\"!==t&&(null===Object.getPrototypeOf(e)||e.constructor===Object);function Ve(t,e,i){if(Object.prototype.hasOwnProperty.call(t,e))return t[e];const s=i();return t[e]=s,s}function Be(t,e,i){return k(t)?t(e,i):t}const Ne=(t,e)=>!0===t?e:\"string\"==typeof t?y(e,t):void 0;function We(t,e,i,s,n){for(const o of e){const e=Ne(i,o);if(e){t.add(e);const o=Be(e._fallback,i,n);if(M(o)&&o!==i&&o!==s)return o}else if(!1===e&&M(s)&&i!==s)return null}return!1}function je(t,e,i,o){const a=e._rootScopes,r=Be(e._fallback,i,o),l=[...t,...a],h=new Set;h.add(o);let c=He(h,l,i,r||i,o);return null!==c&&((!M(r)||r===i||(c=He(h,l,r,c,o),null!==c))&&Ee(Array.from(h),[\"\"],a,r,(()=>function(t,e,i){const o=t._getTarget();e in o||(o[e]={});const a=o[e];if(s(a)&&n(i))return i;return a}(e,i,o))))}function He(t,e,i,s,n){for(;i;)i=We(t,e,i,s,n);return i}function $e(t,e){for(const i of e){if(!i)continue;const e=i[t];if(M(e))return e}}function Ye(t){let e=t._keys;return e||(e=t._keys=function(t){const e=new Set;for(const i of t)for(const t of Object.keys(i).filter((t=>!t.startsWith(\"_\"))))e.add(t);return Array.from(e)}(t._scopes)),e}function Ue(t,e,i,s){const{iScale:n}=t,{key:o=\"r\"}=this._parsing,a=new Array(s);let r,l,h,c;for(r=0,l=s;r<l;++r)h=r+i,c=e[h],a[r]={r:n.parse(y(c,o),h)};return a}const Xe=Number.EPSILON||1e-14,qe=(t,e)=>e<t.length&&!t[e].skip&&t[e],Ke=t=>\"x\"===t?\"y\":\"x\";function Ge(t,e,i,s){const n=t.skip?e:t,o=e,a=i.skip?e:i,r=X(o,n),l=X(a,o);let h=r/(r+l),c=l/(r+l);h=isNaN(h)?0:h,c=isNaN(c)?0:c;const d=s*h,u=s*c;return{previous:{x:o.x-d*(a.x-n.x),y:o.y-d*(a.y-n.y)},next:{x:o.x+u*(a.x-n.x),y:o.y+u*(a.y-n.y)}}}function Ze(t,e=\"x\"){const i=Ke(e),s=t.length,n=Array(s).fill(0),o=Array(s);let a,r,l,h=qe(t,0);for(a=0;a<s;++a)if(r=l,l=h,h=qe(t,a+1),l){if(h){const t=h[e]-l[e];n[a]=0!==t?(h[i]-l[i])/t:0}o[a]=r?h?z(n[a-1])!==z(n[a])?0:(n[a-1]+n[a])/2:n[a-1]:n[a]}!function(t,e,i){const s=t.length;let n,o,a,r,l,h=qe(t,0);for(let c=0;c<s-1;++c)l=h,h=qe(t,c+1),l&&h&&(N(e[c],0,Xe)?i[c]=i[c+1]=0:(n=i[c]/e[c],o=i[c+1]/e[c],r=Math.pow(n,2)+Math.pow(o,2),r<=9||(a=3/Math.sqrt(r),i[c]=n*a*e[c],i[c+1]=o*a*e[c])))}(t,n,o),function(t,e,i=\"x\"){const s=Ke(i),n=t.length;let o,a,r,l=qe(t,0);for(let h=0;h<n;++h){if(a=r,r=l,l=qe(t,h+1),!r)continue;const n=r[i],c=r[s];a&&(o=(n-a[i])/3,r[`cp1${i}`]=n-o,r[`cp1${s}`]=c-o*e[h]),l&&(o=(l[i]-n)/3,r[`cp2${i}`]=n+o,r[`cp2${s}`]=c+o*e[h])}}(t,o,e)}function Je(t,e,i){return Math.max(Math.min(t,i),e)}function Qe(t,e,i,s,n){let o,a,r,l;if(e.spanGaps&&(t=t.filter((t=>!t.skip))),\"monotone\"===e.cubicInterpolationMode)Ze(t,n);else{let i=s?t[t.length-1]:t[0];for(o=0,a=t.length;o<a;++o)r=t[o],l=Ge(i,r,t[Math.min(o+1,a-(s?0:1))%a],e.tension),r.cp1x=l.previous.x,r.cp1y=l.previous.y,r.cp2x=l.next.x,r.cp2y=l.next.y,i=r}e.capBezierPoints&&function(t,e){let i,s,n,o,a,r=Se(t[0],e);for(i=0,s=t.length;i<s;++i)a=o,o=r,r=i<s-1&&Se(t[i+1],e),o&&(n=t[i],a&&(n.cp1x=Je(n.cp1x,e.left,e.right),n.cp1y=Je(n.cp1y,e.top,e.bottom)),r&&(n.cp2x=Je(n.cp2x,e.left,e.right),n.cp2y=Je(n.cp2y,e.top,e.bottom)))}(t,i)}const ti=t=>0===t||1===t,ei=(t,e,i)=>-Math.pow(2,10*(t-=1))*Math.sin((t-e)*O/i),ii=(t,e,i)=>Math.pow(2,-10*t)*Math.sin((t-e)*O/i)+1,si={linear:t=>t,easeInQuad:t=>t*t,easeOutQuad:t=>-t*(t-2),easeInOutQuad:t=>(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1),easeInCubic:t=>t*t*t,easeOutCubic:t=>(t-=1)*t*t+1,easeInOutCubic:t=>(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2),easeInQuart:t=>t*t*t*t,easeOutQuart:t=>-((t-=1)*t*t*t-1),easeInOutQuart:t=>(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2),easeInQuint:t=>t*t*t*t*t,easeOutQuint:t=>(t-=1)*t*t*t*t+1,easeInOutQuint:t=>(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2),easeInSine:t=>1-Math.cos(t*L),easeOutSine:t=>Math.sin(t*L),easeInOutSine:t=>-.5*(Math.cos(D*t)-1),easeInExpo:t=>0===t?0:Math.pow(2,10*(t-1)),easeOutExpo:t=>1===t?1:1-Math.pow(2,-10*t),easeInOutExpo:t=>ti(t)?t:t<.5?.5*Math.pow(2,10*(2*t-1)):.5*(2-Math.pow(2,-10*(2*t-1))),easeInCirc:t=>t>=1?t:-(Math.sqrt(1-t*t)-1),easeOutCirc:t=>Math.sqrt(1-(t-=1)*t),easeInOutCirc:t=>(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1),easeInElastic:t=>ti(t)?t:ei(t,.075,.3),easeOutElastic:t=>ti(t)?t:ii(t,.075,.3),easeInOutElastic(t){const e=.1125;return ti(t)?t:t<.5?.5*ei(2*t,e,.45):.5+.5*ii(2*t-1,e,.45)},easeInBack(t){const e=1.70158;return t*t*((e+1)*t-e)},easeOutBack(t){const e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack(t){let e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:t=>1-si.easeOutBounce(1-t),easeOutBounce(t){const e=7.5625,i=2.75;return t<1/i?e*t*t:t<2/i?e*(t-=1.5/i)*t+.75:t<2.5/i?e*(t-=2.25/i)*t+.9375:e*(t-=2.625/i)*t+.984375},easeInOutBounce:t=>t<.5?.5*si.easeInBounce(2*t):.5*si.easeOutBounce(2*t-1)+.5};function ni(t,e,i,s){return{x:t.x+i*(e.x-t.x),y:t.y+i*(e.y-t.y)}}function oi(t,e,i,s){return{x:t.x+i*(e.x-t.x),y:\"middle\"===s?i<.5?t.y:e.y:\"after\"===s?i<1?t.y:e.y:i>0?e.y:t.y}}function ai(t,e,i,s){const n={x:t.cp2x,y:t.cp2y},o={x:e.cp1x,y:e.cp1y},a=ni(t,n,i),r=ni(n,o,i),l=ni(o,e,i),h=ni(a,r,i),c=ni(r,l,i);return ni(h,c,i)}const ri=new Map;function li(t,e,i){return function(t,e){e=e||{};const i=t+JSON.stringify(e);let s=ri.get(i);return s||(s=new Intl.NumberFormat(t,e),ri.set(i,s)),s}(e,i).format(t)}const hi=new RegExp(/^(normal|(\\d+(?:\\.\\d+)?)(px|em|%)?)$/),ci=new RegExp(/^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/);function di(t,e){const i=(\"\"+t).match(hi);if(!i||\"normal\"===i[1])return 1.2*e;switch(t=+i[2],i[3]){case\"px\":return t;case\"%\":t/=100}return e*t}function ui(t,e){const i={},s=n(e),o=s?Object.keys(e):e,a=n(t)?s?i=>r(t[i],t[e[i]]):e=>t[e]:()=>t;for(const t of o)i[t]=+a(t)||0;return i}function fi(t){return ui(t,{top:\"y\",right:\"x\",bottom:\"y\",left:\"x\"})}function gi(t){return ui(t,[\"topLeft\",\"topRight\",\"bottomLeft\",\"bottomRight\"])}function pi(t){const e=fi(t);return e.width=e.left+e.right,e.height=e.top+e.bottom,e}function mi(t,e){t=t||{},e=e||ne.font;let i=r(t.size,e.size);\"string\"==typeof i&&(i=parseInt(i,10));let s=r(t.style,e.style);s&&!(\"\"+s).match(ci)&&(console.warn('Invalid font style specified: \"'+s+'\"'),s=\"\");const n={family:r(t.family,e.family),lineHeight:di(r(t.lineHeight,e.lineHeight),i),size:i,style:s,weight:r(t.weight,e.weight),string:\"\"};return n.string=xe(n),n}function bi(t,e,i,n){let o,a,r,l=!0;for(o=0,a=t.length;o<a;++o)if(r=t[o],void 0!==r&&(void 0!==e&&\"function\"==typeof r&&(r=r(e),l=!1),void 0!==i&&s(r)&&(r=r[i%r.length],l=!1),void 0!==r))return n&&!l&&(n.cacheable=!1),r}function xi(t,e,i){const{min:s,max:n}=t,o=h(e,(n-s)/2),a=(t,e)=>i&&0===t?0:t+e;return{min:a(s,-Math.abs(o)),max:a(n,o)}}function _i(t,e){return Object.assign(Object.create(t),e)}function yi(t,e,i){return t?function(t,e){return{x:i=>t+t+e-i,setWidth(t){e=t},textAlign:t=>\"center\"===t?t:\"right\"===t?\"left\":\"right\",xPlus:(t,e)=>t-e,leftForLtr:(t,e)=>t-e}}(e,i):{x:t=>t,setWidth(t){},textAlign:t=>t,xPlus:(t,e)=>t+e,leftForLtr:(t,e)=>t}}function vi(t,e){let i,s;\"ltr\"!==e&&\"rtl\"!==e||(i=t.canvas.style,s=[i.getPropertyValue(\"direction\"),i.getPropertyPriority(\"direction\")],i.setProperty(\"direction\",e,\"important\"),t.prevTextDirection=s)}function wi(t,e){void 0!==e&&(delete t.prevTextDirection,t.canvas.style.setProperty(\"direction\",e[0],e[1]))}function Mi(t){return\"angle\"===t?{between:G,compare:q,normalize:K}:{between:Q,compare:(t,e)=>t-e,normalize:t=>t}}function ki({start:t,end:e,count:i,loop:s,style:n}){return{start:t%i,end:e%i,loop:s&&(e-t+1)%i==0,style:n}}function Si(t,e,i){if(!i)return[t];const{property:s,start:n,end:o}=i,a=e.length,{compare:r,between:l,normalize:h}=Mi(s),{start:c,end:d,loop:u,style:f}=function(t,e,i){const{property:s,start:n,end:o}=i,{between:a,normalize:r}=Mi(s),l=e.length;let h,c,{start:d,end:u,loop:f}=t;if(f){for(d+=l,u+=l,h=0,c=l;h<c&&a(r(e[d%l][s]),n,o);++h)d--,u--;d%=l,u%=l}return u<d&&(u+=l),{start:d,end:u,loop:f,style:t.style}}(t,e,i),g=[];let p,m,b,x=!1,_=null;const y=()=>x||l(n,b,p)&&0!==r(n,b),v=()=>!x||0===r(o,p)||l(o,b,p);for(let t=c,i=c;t<=d;++t)m=e[t%a],m.skip||(p=h(m[s]),p!==b&&(x=l(p,n,o),null===_&&y()&&(_=0===r(p,n)?t:i),null!==_&&v()&&(g.push(ki({start:_,end:t,loop:u,count:a,style:f})),_=null),i=t,b=p));return null!==_&&g.push(ki({start:_,end:d,loop:u,count:a,style:f})),g}function Pi(t,e){const i=[],s=t.segments;for(let n=0;n<s.length;n++){const o=Si(s[n],t.points,e);o.length&&i.push(...o)}return i}function Di(t,e){const i=t.points,s=t.options.spanGaps,n=i.length;if(!n)return[];const o=!!t._loop,{start:a,end:r}=function(t,e,i,s){let n=0,o=e-1;if(i&&!s)for(;n<e&&!t[n].skip;)n++;for(;n<e&&t[n].skip;)n++;for(n%=e,i&&(o+=n);o>n&&t[o%e].skip;)o--;return o%=e,{start:n,end:o}}(i,n,o,s);if(!0===s)return Oi(t,[{start:a,end:r,loop:o}],i,e);return Oi(t,function(t,e,i,s){const n=t.length,o=[];let a,r=e,l=t[e];for(a=e+1;a<=i;++a){const i=t[a%n];i.skip||i.stop?l.skip||(s=!1,o.push({start:e%n,end:(a-1)%n,loop:s}),e=r=i.stop?a:null):(r=a,l.skip&&(e=a)),l=i}return null!==r&&o.push({start:e%n,end:r%n,loop:s}),o}(i,a,r<a?r+n:r,!!t._fullLoop&&0===a&&r===n-1),i,e)}function Oi(t,e,i,s){return s&&s.setContext&&i?function(t,e,i,s){const n=t._chart.getContext(),o=Ci(t.options),{_datasetIndex:a,options:{spanGaps:r}}=t,l=i.length,h=[];let c=o,d=e[0].start,u=d;function f(t,e,s,n){const o=r?-1:1;if(t!==e){for(t+=l;i[t%l].skip;)t-=o;for(;i[e%l].skip;)e+=o;t%l!=e%l&&(h.push({start:t%l,end:e%l,loop:s,style:n}),c=n,d=e%l)}}for(const t of e){d=r?d:t.start;let e,o=i[d%l];for(u=d+1;u<=t.end;u++){const r=i[u%l];e=Ci(s.setContext(_i(n,{type:\"segment\",p0:o,p1:r,p0DataIndex:(u-1)%l,p1DataIndex:u%l,datasetIndex:a}))),Ai(e,c)&&f(d,u-1,t.loop,c),o=r,c=e}d<u-1&&f(d,u-1,t.loop,c)}return h}(t,e,i,s):e}function Ci(t){return{backgroundColor:t.backgroundColor,borderCapStyle:t.borderCapStyle,borderDash:t.borderDash,borderDashOffset:t.borderDashOffset,borderJoinStyle:t.borderJoinStyle,borderWidth:t.borderWidth,borderColor:t.borderColor}}function Ai(t,e){return e&&JSON.stringify(t)!==JSON.stringify(e)}var Ti=Object.freeze({__proto__:null,easingEffects:si,isPatternOrGradient:Zt,color:Jt,getHoverColor:Qt,noop:t,uid:e,isNullOrUndef:i,isArray:s,isObject:n,isFinite:o,finiteOrDefault:a,valueOrDefault:r,toPercentage:l,toDimension:h,callback:c,each:d,_elementsEqual:u,clone:f,_merger:p,merge:m,mergeIf:b,_mergerIf:x,_deprecated:function(t,e,i,s){void 0!==e&&console.warn(t+': \"'+i+'\" is deprecated. Please use \"'+s+'\" instead')},resolveObjectKey:y,_splitKey:v,_capitalize:w,defined:M,isFunction:k,setsEqual:S,_isClickEvent:P,toFontString:xe,_measureText:_e,_longestText:ye,_alignPixel:ve,clearCanvas:we,drawPoint:Me,drawPointLegend:ke,_isPointInArea:Se,clipArea:Pe,unclipArea:De,_steppedLineTo:Oe,_bezierCurveTo:Ce,renderText:Ae,addRoundedRectPath:Le,_lookup:tt,_lookupByKey:et,_rlookupByKey:it,_filterBetween:st,listenArrayEvents:ot,unlistenArrayEvents:at,_arrayUnique:rt,_createResolver:Ee,_attachContext:Re,_descriptors:Ie,_parseObjectDataRadialScale:Ue,splineCurve:Ge,splineCurveMonotone:Ze,_updateBezierControlPoints:Qe,_isDomSupported:oe,_getParentNode:ae,getStyle:he,getRelativePosition:ue,getMaximumSize:ge,retinaScale:pe,supportsEventListenerOptions:me,readUsedSize:be,fontString:function(t,e,i){return e+\" \"+t+\"px \"+i},requestAnimFrame:lt,throttled:ht,debounce:ct,_toLeftRightCenter:dt,_alignStartEnd:ut,_textX:ft,_getStartAndCountOfVisiblePoints:gt,_scaleRangesChanged:pt,_pointInLine:ni,_steppedInterpolation:oi,_bezierInterpolation:ai,formatNumber:li,toLineHeight:di,_readValueToProps:ui,toTRBL:fi,toTRBLCorners:gi,toPadding:pi,toFont:mi,resolve:bi,_addGrace:xi,createContext:_i,PI:D,TAU:O,PITAU:C,INFINITY:A,RAD_PER_DEG:T,HALF_PI:L,QUARTER_PI:E,TWO_THIRDS_PI:R,log10:I,sign:z,niceNum:F,_factorize:V,isNumber:B,almostEquals:N,almostWhole:W,_setMinAndMaxByKey:j,toRadians:H,toDegrees:$,_decimalPlaces:Y,getAngleFromPoint:U,distanceBetweenPoints:X,_angleDiff:q,_normalizeAngle:K,_angleBetween:G,_limitValue:Z,_int16Range:J,_isBetween:Q,getRtlAdapter:yi,overrideTextDirection:vi,restoreTextDirection:wi,_boundSegment:Si,_boundSegments:Pi,_computeSegments:Di});function Li(t,e,i,s){const{controller:n,data:o,_sorted:a}=t,r=n._cachedMeta.iScale;if(r&&e===r.axis&&\"r\"!==e&&a&&o.length){const t=r._reversePixels?it:et;if(!s)return t(o,e,i);if(n._sharedOptions){const s=o[0],n=\"function\"==typeof s.getRange&&s.getRange(e);if(n){const s=t(o,e,i-n),a=t(o,e,i+n);return{lo:s.lo,hi:a.hi}}}}return{lo:0,hi:o.length-1}}function Ei(t,e,i,s,n){const o=t.getSortedVisibleDatasetMetas(),a=i[e];for(let t=0,i=o.length;t<i;++t){const{index:i,data:r}=o[t],{lo:l,hi:h}=Li(o[t],e,a,n);for(let t=l;t<=h;++t){const e=r[t];e.skip||s(e,i,t)}}}function Ri(t,e,i,s,n){const o=[];if(!n&&!t.isPointInArea(e))return o;return Ei(t,i,e,(function(i,a,r){(n||Se(i,t.chartArea,0))&&i.inRange(e.x,e.y,s)&&o.push({element:i,datasetIndex:a,index:r})}),!0),o}function Ii(t,e,i,s,n,o){let a=[];const r=function(t){const e=-1!==t.indexOf(\"x\"),i=-1!==t.indexOf(\"y\");return function(t,s){const n=e?Math.abs(t.x-s.x):0,o=i?Math.abs(t.y-s.y):0;return Math.sqrt(Math.pow(n,2)+Math.pow(o,2))}}(i);let l=Number.POSITIVE_INFINITY;return Ei(t,i,e,(function(i,h,c){const d=i.inRange(e.x,e.y,n);if(s&&!d)return;const u=i.getCenterPoint(n);if(!(!!o||t.isPointInArea(u))&&!d)return;const f=r(e,u);f<l?(a=[{element:i,datasetIndex:h,index:c}],l=f):f===l&&a.push({element:i,datasetIndex:h,index:c})})),a}function zi(t,e,i,s,n,o){return o||t.isPointInArea(e)?\"r\"!==i||s?Ii(t,e,i,s,n,o):function(t,e,i,s){let n=[];return Ei(t,i,e,(function(t,i,o){const{startAngle:a,endAngle:r}=t.getProps([\"startAngle\",\"endAngle\"],s),{angle:l}=U(t,{x:e.x,y:e.y});G(l,a,r)&&n.push({element:t,datasetIndex:i,index:o})})),n}(t,e,i,n):[]}function Fi(t,e,i,s,n){const o=[],a=\"x\"===i?\"inXRange\":\"inYRange\";let r=!1;return Ei(t,i,e,((t,s,l)=>{t[a](e[i],n)&&(o.push({element:t,datasetIndex:s,index:l}),r=r||t.inRange(e.x,e.y,n))})),s&&!r?[]:o}var Vi={evaluateInteractionItems:Ei,modes:{index(t,e,i,s){const n=ue(e,t),o=i.axis||\"x\",a=i.includeInvisible||!1,r=i.intersect?Ri(t,n,o,s,a):zi(t,n,o,!1,s,a),l=[];return r.length?(t.getSortedVisibleDatasetMetas().forEach((t=>{const e=r[0].index,i=t.data[e];i&&!i.skip&&l.push({element:i,datasetIndex:t.index,index:e})})),l):[]},dataset(t,e,i,s){const n=ue(e,t),o=i.axis||\"xy\",a=i.includeInvisible||!1;let r=i.intersect?Ri(t,n,o,s,a):zi(t,n,o,!1,s,a);if(r.length>0){const e=r[0].datasetIndex,i=t.getDatasetMeta(e).data;r=[];for(let t=0;t<i.length;++t)r.push({element:i[t],datasetIndex:e,index:t})}return r},point:(t,e,i,s)=>Ri(t,ue(e,t),i.axis||\"xy\",s,i.includeInvisible||!1),nearest(t,e,i,s){const n=ue(e,t),o=i.axis||\"xy\",a=i.includeInvisible||!1;return zi(t,n,o,i.intersect,s,a)},x:(t,e,i,s)=>Fi(t,ue(e,t),\"x\",i.intersect,s),y:(t,e,i,s)=>Fi(t,ue(e,t),\"y\",i.intersect,s)}};const Bi=[\"left\",\"top\",\"right\",\"bottom\"];function Ni(t,e){return t.filter((t=>t.pos===e))}function Wi(t,e){return t.filter((t=>-1===Bi.indexOf(t.pos)&&t.box.axis===e))}function ji(t,e){return t.sort(((t,i)=>{const s=e?i:t,n=e?t:i;return s.weight===n.weight?s.index-n.index:s.weight-n.weight}))}function Hi(t,e){const i=function(t){const e={};for(const i of t){const{stack:t,pos:s,stackWeight:n}=i;if(!t||!Bi.includes(s))continue;const o=e[t]||(e[t]={count:0,placed:0,weight:0,size:0});o.count++,o.weight+=n}return e}(t),{vBoxMaxWidth:s,hBoxMaxHeight:n}=e;let o,a,r;for(o=0,a=t.length;o<a;++o){r=t[o];const{fullSize:a}=r.box,l=i[r.stack],h=l&&r.stackWeight/l.weight;r.horizontal?(r.width=h?h*s:a&&e.availableWidth,r.height=n):(r.width=s,r.height=h?h*n:a&&e.availableHeight)}return i}function $i(t,e,i,s){return Math.max(t[i],e[i])+Math.max(t[s],e[s])}function Yi(t,e){t.top=Math.max(t.top,e.top),t.left=Math.max(t.left,e.left),t.bottom=Math.max(t.bottom,e.bottom),t.right=Math.max(t.right,e.right)}function Ui(t,e,i,s){const{pos:o,box:a}=i,r=t.maxPadding;if(!n(o)){i.size&&(t[o]-=i.size);const e=s[i.stack]||{size:0,count:1};e.size=Math.max(e.size,i.horizontal?a.height:a.width),i.size=e.size/e.count,t[o]+=i.size}a.getPadding&&Yi(r,a.getPadding());const l=Math.max(0,e.outerWidth-$i(r,t,\"left\",\"right\")),h=Math.max(0,e.outerHeight-$i(r,t,\"top\",\"bottom\")),c=l!==t.w,d=h!==t.h;return t.w=l,t.h=h,i.horizontal?{same:c,other:d}:{same:d,other:c}}function Xi(t,e){const i=e.maxPadding;function s(t){const s={left:0,top:0,right:0,bottom:0};return t.forEach((t=>{s[t]=Math.max(e[t],i[t])})),s}return s(t?[\"left\",\"right\"]:[\"top\",\"bottom\"])}function qi(t,e,i,s){const n=[];let o,a,r,l,h,c;for(o=0,a=t.length,h=0;o<a;++o){r=t[o],l=r.box,l.update(r.width||e.w,r.height||e.h,Xi(r.horizontal,e));const{same:a,other:d}=Ui(e,i,r,s);h|=a&&n.length,c=c||d,l.fullSize||n.push(r)}return h&&qi(n,e,i,s)||c}function Ki(t,e,i,s,n){t.top=i,t.left=e,t.right=e+s,t.bottom=i+n,t.width=s,t.height=n}function Gi(t,e,i,s){const n=i.padding;let{x:o,y:a}=e;for(const r of t){const t=r.box,l=s[r.stack]||{count:1,placed:0,weight:1},h=r.stackWeight/l.weight||1;if(r.horizontal){const s=e.w*h,o=l.size||t.height;M(l.start)&&(a=l.start),t.fullSize?Ki(t,n.left,a,i.outerWidth-n.right-n.left,o):Ki(t,e.left+l.placed,a,s,o),l.start=a,l.placed+=s,a=t.bottom}else{const s=e.h*h,a=l.size||t.width;M(l.start)&&(o=l.start),t.fullSize?Ki(t,o,n.top,a,i.outerHeight-n.bottom-n.top):Ki(t,o,e.top+l.placed,a,s),l.start=o,l.placed+=s,o=t.right}}e.x=o,e.y=a}ne.set(\"layout\",{autoPadding:!0,padding:{top:0,right:0,bottom:0,left:0}});var Zi={addBox(t,e){t.boxes||(t.boxes=[]),e.fullSize=e.fullSize||!1,e.position=e.position||\"top\",e.weight=e.weight||0,e._layers=e._layers||function(){return[{z:0,draw(t){e.draw(t)}}]},t.boxes.push(e)},removeBox(t,e){const i=t.boxes?t.boxes.indexOf(e):-1;-1!==i&&t.boxes.splice(i,1)},configure(t,e,i){e.fullSize=i.fullSize,e.position=i.position,e.weight=i.weight},update(t,e,i,s){if(!t)return;const n=pi(t.options.layout.padding),o=Math.max(e-n.width,0),a=Math.max(i-n.height,0),r=function(t){const e=function(t){const e=[];let i,s,n,o,a,r;for(i=0,s=(t||[]).length;i<s;++i)n=t[i],({position:o,options:{stack:a,stackWeight:r=1}}=n),e.push({index:i,box:n,pos:o,horizontal:n.isHorizontal(),weight:n.weight,stack:a&&o+a,stackWeight:r});return e}(t),i=ji(e.filter((t=>t.box.fullSize)),!0),s=ji(Ni(e,\"left\"),!0),n=ji(Ni(e,\"right\")),o=ji(Ni(e,\"top\"),!0),a=ji(Ni(e,\"bottom\")),r=Wi(e,\"x\"),l=Wi(e,\"y\");return{fullSize:i,leftAndTop:s.concat(o),rightAndBottom:n.concat(l).concat(a).concat(r),chartArea:Ni(e,\"chartArea\"),vertical:s.concat(n).concat(l),horizontal:o.concat(a).concat(r)}}(t.boxes),l=r.vertical,h=r.horizontal;d(t.boxes,(t=>{\"function\"==typeof t.beforeLayout&&t.beforeLayout()}));const c=l.reduce(((t,e)=>e.box.options&&!1===e.box.options.display?t:t+1),0)||1,u=Object.freeze({outerWidth:e,outerHeight:i,padding:n,availableWidth:o,availableHeight:a,vBoxMaxWidth:o/2/c,hBoxMaxHeight:a/2}),f=Object.assign({},n);Yi(f,pi(s));const g=Object.assign({maxPadding:f,w:o,h:a,x:n.left,y:n.top},n),p=Hi(l.concat(h),u);qi(r.fullSize,g,u,p),qi(l,g,u,p),qi(h,g,u,p)&&qi(l,g,u,p),function(t){const e=t.maxPadding;function i(i){const s=Math.max(e[i]-t[i],0);return t[i]+=s,s}t.y+=i(\"top\"),t.x+=i(\"left\"),i(\"right\"),i(\"bottom\")}(g),Gi(r.leftAndTop,g,u,p),g.x+=g.w,g.y+=g.h,Gi(r.rightAndBottom,g,u,p),t.chartArea={left:g.left,top:g.top,right:g.left+g.w,bottom:g.top+g.h,height:g.h,width:g.w},d(r.chartArea,(e=>{const i=e.box;Object.assign(i,t.chartArea),i.update(g.w,g.h,{left:0,top:0,right:0,bottom:0})}))}};class Ji{acquireContext(t,e){}releaseContext(t){return!1}addEventListener(t,e,i){}removeEventListener(t,e,i){}getDevicePixelRatio(){return 1}getMaximumSize(t,e,i,s){return e=Math.max(0,e||t.width),i=i||t.height,{width:e,height:Math.max(0,s?Math.floor(e/s):i)}}isAttached(t){return!0}updateConfig(t){}}class Qi extends Ji{acquireContext(t){return t&&t.getContext&&t.getContext(\"2d\")||null}updateConfig(t){t.options.animation=!1}}const ts={touchstart:\"mousedown\",touchmove:\"mousemove\",touchend:\"mouseup\",pointerenter:\"mouseenter\",pointerdown:\"mousedown\",pointermove:\"mousemove\",pointerup:\"mouseup\",pointerleave:\"mouseout\",pointerout:\"mouseout\"},es=t=>null===t||\"\"===t;const is=!!me&&{passive:!0};function ss(t,e,i){t.canvas.removeEventListener(e,i,is)}function ns(t,e){for(const i of t)if(i===e||i.contains(e))return!0}function os(t,e,i){const s=t.canvas,n=new MutationObserver((t=>{let e=!1;for(const i of t)e=e||ns(i.addedNodes,s),e=e&&!ns(i.removedNodes,s);e&&i()}));return n.observe(document,{childList:!0,subtree:!0}),n}function as(t,e,i){const s=t.canvas,n=new MutationObserver((t=>{let e=!1;for(const i of t)e=e||ns(i.removedNodes,s),e=e&&!ns(i.addedNodes,s);e&&i()}));return n.observe(document,{childList:!0,subtree:!0}),n}const rs=new Map;let ls=0;function hs(){const t=window.devicePixelRatio;t!==ls&&(ls=t,rs.forEach(((e,i)=>{i.currentDevicePixelRatio!==t&&e()})))}function cs(t,e,i){const s=t.canvas,n=s&&ae(s);if(!n)return;const o=ht(((t,e)=>{const s=n.clientWidth;i(t,e),s<n.clientWidth&&i()}),window),a=new ResizeObserver((t=>{const e=t[0],i=e.contentRect.width,s=e.contentRect.height;0===i&&0===s||o(i,s)}));return a.observe(n),function(t,e){rs.size||window.addEventListener(\"resize\",hs),rs.set(t,e)}(t,o),a}function ds(t,e,i){i&&i.disconnect(),\"resize\"===e&&function(t){rs.delete(t),rs.size||window.removeEventListener(\"resize\",hs)}(t)}function us(t,e,i){const s=t.canvas,n=ht((e=>{null!==t.ctx&&i(function(t,e){const i=ts[t.type]||t.type,{x:s,y:n}=ue(t,e);return{type:i,chart:e,native:t,x:void 0!==s?s:null,y:void 0!==n?n:null}}(e,t))}),t,(t=>{const e=t[0];return[e,e.offsetX,e.offsetY]}));return function(t,e,i){t.addEventListener(e,i,is)}(s,e,n),n}class fs extends Ji{acquireContext(t,e){const i=t&&t.getContext&&t.getContext(\"2d\");return i&&i.canvas===t?(function(t,e){const i=t.style,s=t.getAttribute(\"height\"),n=t.getAttribute(\"width\");if(t.$chartjs={initial:{height:s,width:n,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||\"block\",i.boxSizing=i.boxSizing||\"border-box\",es(n)){const e=be(t,\"width\");void 0!==e&&(t.width=e)}if(es(s))if(\"\"===t.style.height)t.height=t.width/(e||2);else{const e=be(t,\"height\");void 0!==e&&(t.height=e)}}(t,e),i):null}releaseContext(t){const e=t.canvas;if(!e.$chartjs)return!1;const s=e.$chartjs.initial;[\"height\",\"width\"].forEach((t=>{const n=s[t];i(n)?e.removeAttribute(t):e.setAttribute(t,n)}));const n=s.style||{};return Object.keys(n).forEach((t=>{e.style[t]=n[t]})),e.width=e.width,delete e.$chartjs,!0}addEventListener(t,e,i){this.removeEventListener(t,e);const s=t.$proxies||(t.$proxies={}),n={attach:os,detach:as,resize:cs}[e]||us;s[e]=n(t,e,i)}removeEventListener(t,e){const i=t.$proxies||(t.$proxies={}),s=i[e];if(!s)return;({attach:ds,detach:ds,resize:ds}[e]||ss)(t,e,s),i[e]=void 0}getDevicePixelRatio(){return window.devicePixelRatio}getMaximumSize(t,e,i,s){return ge(t,e,i,s)}isAttached(t){const e=ae(t);return!(!e||!e.isConnected)}}function gs(t){return!oe()||\"undefined\"!=typeof OffscreenCanvas&&t instanceof OffscreenCanvas?Qi:fs}var ps=Object.freeze({__proto__:null,_detectPlatform:gs,BasePlatform:Ji,BasicPlatform:Qi,DomPlatform:fs});const ms=\"transparent\",bs={boolean:(t,e,i)=>i>.5?e:t,color(t,e,i){const s=Jt(t||ms),n=s.valid&&Jt(e||ms);return n&&n.valid?n.mix(s,i).hexString():e},number:(t,e,i)=>t+(e-t)*i};class xs{constructor(t,e,i,s){const n=e[i];s=bi([t.to,s,n,t.from]);const o=bi([t.from,n,s]);this._active=!0,this._fn=t.fn||bs[t.type||typeof o],this._easing=si[t.easing]||si.linear,this._start=Math.floor(Date.now()+(t.delay||0)),this._duration=this._total=Math.floor(t.duration),this._loop=!!t.loop,this._target=e,this._prop=i,this._from=o,this._to=s,this._promises=void 0}active(){return this._active}update(t,e,i){if(this._active){this._notify(!1);const s=this._target[this._prop],n=i-this._start,o=this._duration-n;this._start=i,this._duration=Math.floor(Math.max(o,t.duration)),this._total+=n,this._loop=!!t.loop,this._to=bi([t.to,e,s,t.from]),this._from=bi([t.from,s,e])}}cancel(){this._active&&(this.tick(Date.now()),this._active=!1,this._notify(!1))}tick(t){const e=t-this._start,i=this._duration,s=this._prop,n=this._from,o=this._loop,a=this._to;let r;if(this._active=n!==a&&(o||e<i),!this._active)return this._target[s]=a,void this._notify(!0);e<0?this._target[s]=n:(r=e/i%2,r=o&&r>1?2-r:r,r=this._easing(Math.min(1,Math.max(0,r))),this._target[s]=this._fn(n,a,r))}wait(){const t=this._promises||(this._promises=[]);return new Promise(((e,i)=>{t.push({res:e,rej:i})}))}_notify(t){const e=t?\"res\":\"rej\",i=this._promises||[];for(let t=0;t<i.length;t++)i[t][e]()}}ne.set(\"animation\",{delay:void 0,duration:1e3,easing:\"easeOutQuart\",fn:void 0,from:void 0,loop:void 0,to:void 0,type:void 0});const _s=Object.keys(ne.animation);ne.describe(\"animation\",{_fallback:!1,_indexable:!1,_scriptable:t=>\"onProgress\"!==t&&\"onComplete\"!==t&&\"fn\"!==t}),ne.set(\"animations\",{colors:{type:\"color\",properties:[\"color\",\"borderColor\",\"backgroundColor\"]},numbers:{type:\"number\",properties:[\"x\",\"y\",\"borderWidth\",\"radius\",\"tension\"]}}),ne.describe(\"animations\",{_fallback:\"animation\"}),ne.set(\"transitions\",{active:{animation:{duration:400}},resize:{animation:{duration:0}},show:{animations:{colors:{from:\"transparent\"},visible:{type:\"boolean\",duration:0}}},hide:{animations:{colors:{to:\"transparent\"},visible:{type:\"boolean\",easing:\"linear\",fn:t=>0|t}}}});class ys{constructor(t,e){this._chart=t,this._properties=new Map,this.configure(e)}configure(t){if(!n(t))return;const e=this._properties;Object.getOwnPropertyNames(t).forEach((i=>{const o=t[i];if(!n(o))return;const a={};for(const t of _s)a[t]=o[t];(s(o.properties)&&o.properties||[i]).forEach((t=>{t!==i&&e.has(t)||e.set(t,a)}))}))}_animateOptions(t,e){const i=e.options,s=function(t,e){if(!e)return;let i=t.options;if(!i)return void(t.options=e);i.$shared&&(t.options=i=Object.assign({},i,{$shared:!1,$animations:{}}));return i}(t,i);if(!s)return[];const n=this._createAnimations(s,i);return i.$shared&&function(t,e){const i=[],s=Object.keys(e);for(let e=0;e<s.length;e++){const n=t[s[e]];n&&n.active()&&i.push(n.wait())}return Promise.all(i)}(t.options.$animations,i).then((()=>{t.options=i}),(()=>{})),n}_createAnimations(t,e){const i=this._properties,s=[],n=t.$animations||(t.$animations={}),o=Object.keys(e),a=Date.now();let r;for(r=o.length-1;r>=0;--r){const l=o[r];if(\"$\"===l.charAt(0))continue;if(\"options\"===l){s.push(...this._animateOptions(t,e));continue}const h=e[l];let c=n[l];const d=i.get(l);if(c){if(d&&c.active()){c.update(d,h,a);continue}c.cancel()}d&&d.duration?(n[l]=c=new xs(d,t,l,h),s.push(c)):t[l]=h}return s}update(t,e){if(0===this._properties.size)return void Object.assign(t,e);const i=this._createAnimations(t,e);return i.length?(mt.add(this._chart,i),!0):void 0}}function vs(t,e){const i=t&&t.options||{},s=i.reverse,n=void 0===i.min?e:0,o=void 0===i.max?e:0;return{start:s?o:n,end:s?n:o}}function ws(t,e){const i=[],s=t._getSortedDatasetMetas(e);let n,o;for(n=0,o=s.length;n<o;++n)i.push(s[n].index);return i}function Ms(t,e,i,s={}){const n=t.keys,a=\"single\"===s.mode;let r,l,h,c;if(null!==e){for(r=0,l=n.length;r<l;++r){if(h=+n[r],h===i){if(s.all)continue;break}c=t.values[h],o(c)&&(a||0===e||z(e)===z(c))&&(e+=c)}return e}}function ks(t,e){const i=t&&t.options.stacked;return i||void 0===i&&void 0!==e.stack}function Ss(t,e,i){const s=t[e]||(t[e]={});return s[i]||(s[i]={})}function Ps(t,e,i,s){for(const n of e.getMatchingVisibleMetas(s).reverse()){const e=t[n.index];if(i&&e>0||!i&&e<0)return n.index}return null}function Ds(t,e){const{chart:i,_cachedMeta:s}=t,n=i._stacks||(i._stacks={}),{iScale:o,vScale:a,index:r}=s,l=o.axis,h=a.axis,c=function(t,e,i){return`${t.id}.${e.id}.${i.stack||i.type}`}(o,a,s),d=e.length;let u;for(let t=0;t<d;++t){const i=e[t],{[l]:o,[h]:d}=i;u=(i._stacks||(i._stacks={}))[h]=Ss(n,c,o),u[r]=d,u._top=Ps(u,a,!0,s.type),u._bottom=Ps(u,a,!1,s.type)}}function Os(t,e){const i=t.scales;return Object.keys(i).filter((t=>i[t].axis===e)).shift()}function Cs(t,e){const i=t.controller.index,s=t.vScale&&t.vScale.axis;if(s){e=e||t._parsed;for(const t of e){const e=t._stacks;if(!e||void 0===e[s]||void 0===e[s][i])return;delete e[s][i]}}}const As=t=>\"reset\"===t||\"none\"===t,Ts=(t,e)=>e?t:Object.assign({},t);class Ls{constructor(t,e){this.chart=t,this._ctx=t.ctx,this.index=e,this._cachedDataOpts={},this._cachedMeta=this.getMeta(),this._type=this._cachedMeta.type,this.options=void 0,this._parsing=!1,this._data=void 0,this._objectData=void 0,this._sharedOptions=void 0,this._drawStart=void 0,this._drawCount=void 0,this.enableOptionSharing=!1,this.supportsDecimation=!1,this.$context=void 0,this._syncList=[],this.initialize()}initialize(){const t=this._cachedMeta;this.configure(),this.linkScales(),t._stacked=ks(t.vScale,t),this.addElements()}updateIndex(t){this.index!==t&&Cs(this._cachedMeta),this.index=t}linkScales(){const t=this.chart,e=this._cachedMeta,i=this.getDataset(),s=(t,e,i,s)=>\"x\"===t?e:\"r\"===t?s:i,n=e.xAxisID=r(i.xAxisID,Os(t,\"x\")),o=e.yAxisID=r(i.yAxisID,Os(t,\"y\")),a=e.rAxisID=r(i.rAxisID,Os(t,\"r\")),l=e.indexAxis,h=e.iAxisID=s(l,n,o,a),c=e.vAxisID=s(l,o,n,a);e.xScale=this.getScaleForId(n),e.yScale=this.getScaleForId(o),e.rScale=this.getScaleForId(a),e.iScale=this.getScaleForId(h),e.vScale=this.getScaleForId(c)}getDataset(){return this.chart.data.datasets[this.index]}getMeta(){return this.chart.getDatasetMeta(this.index)}getScaleForId(t){return this.chart.scales[t]}_getOtherScale(t){const e=this._cachedMeta;return t===e.iScale?e.vScale:e.iScale}reset(){this._update(\"reset\")}_destroy(){const t=this._cachedMeta;this._data&&at(this._data,this),t._stacked&&Cs(t)}_dataCheck(){const t=this.getDataset(),e=t.data||(t.data=[]),i=this._data;if(n(e))this._data=function(t){const e=Object.keys(t),i=new Array(e.length);let s,n,o;for(s=0,n=e.length;s<n;++s)o=e[s],i[s]={x:o,y:t[o]};return i}(e);else if(i!==e){if(i){at(i,this);const t=this._cachedMeta;Cs(t),t._parsed=[]}e&&Object.isExtensible(e)&&ot(e,this),this._syncList=[],this._data=e}}addElements(){const t=this._cachedMeta;this._dataCheck(),this.datasetElementType&&(t.dataset=new this.datasetElementType)}buildOrUpdateElements(t){const e=this._cachedMeta,i=this.getDataset();let s=!1;this._dataCheck();const n=e._stacked;e._stacked=ks(e.vScale,e),e.stack!==i.stack&&(s=!0,Cs(e),e.stack=i.stack),this._resyncElements(t),(s||n!==e._stacked)&&Ds(this,e._parsed)}configure(){const t=this.chart.config,e=t.datasetScopeKeys(this._type),i=t.getOptionScopes(this.getDataset(),e,!0);this.options=t.createResolver(i,this.getContext()),this._parsing=this.options.parsing,this._cachedDataOpts={}}parse(t,e){const{_cachedMeta:i,_data:o}=this,{iScale:a,_stacked:r}=i,l=a.axis;let h,c,d,u=0===t&&e===o.length||i._sorted,f=t>0&&i._parsed[t-1];if(!1===this._parsing)i._parsed=o,i._sorted=!0,d=o;else{d=s(o[t])?this.parseArrayData(i,o,t,e):n(o[t])?this.parseObjectData(i,o,t,e):this.parsePrimitiveData(i,o,t,e);const a=()=>null===c[l]||f&&c[l]<f[l];for(h=0;h<e;++h)i._parsed[h+t]=c=d[h],u&&(a()&&(u=!1),f=c);i._sorted=u}r&&Ds(this,d)}parsePrimitiveData(t,e,i,s){const{iScale:n,vScale:o}=t,a=n.axis,r=o.axis,l=n.getLabels(),h=n===o,c=new Array(s);let d,u,f;for(d=0,u=s;d<u;++d)f=d+i,c[d]={[a]:h||n.parse(l[f],f),[r]:o.parse(e[f],f)};return c}parseArrayData(t,e,i,s){const{xScale:n,yScale:o}=t,a=new Array(s);let r,l,h,c;for(r=0,l=s;r<l;++r)h=r+i,c=e[h],a[r]={x:n.parse(c[0],h),y:o.parse(c[1],h)};return a}parseObjectData(t,e,i,s){const{xScale:n,yScale:o}=t,{xAxisKey:a=\"x\",yAxisKey:r=\"y\"}=this._parsing,l=new Array(s);let h,c,d,u;for(h=0,c=s;h<c;++h)d=h+i,u=e[d],l[h]={x:n.parse(y(u,a),d),y:o.parse(y(u,r),d)};return l}getParsed(t){return this._cachedMeta._parsed[t]}getDataElement(t){return this._cachedMeta.data[t]}applyStack(t,e,i){const s=this.chart,n=this._cachedMeta,o=e[t.axis];return Ms({keys:ws(s,!0),values:e._stacks[t.axis]},o,n.index,{mode:i})}updateRangeFromParsed(t,e,i,s){const n=i[e.axis];let o=null===n?NaN:n;const a=s&&i._stacks[e.axis];s&&a&&(s.values=a,o=Ms(s,n,this._cachedMeta.index)),t.min=Math.min(t.min,o),t.max=Math.max(t.max,o)}getMinMax(t,e){const i=this._cachedMeta,s=i._parsed,n=i._sorted&&t===i.iScale,a=s.length,r=this._getOtherScale(t),l=((t,e,i)=>t&&!e.hidden&&e._stacked&&{keys:ws(i,!0),values:null})(e,i,this.chart),h={min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY},{min:c,max:d}=function(t){const{min:e,max:i,minDefined:s,maxDefined:n}=t.getUserBounds();return{min:s?e:Number.NEGATIVE_INFINITY,max:n?i:Number.POSITIVE_INFINITY}}(r);let u,f;function g(){f=s[u];const e=f[r.axis];return!o(f[t.axis])||c>e||d<e}for(u=0;u<a&&(g()||(this.updateRangeFromParsed(h,t,f,l),!n));++u);if(n)for(u=a-1;u>=0;--u)if(!g()){this.updateRangeFromParsed(h,t,f,l);break}return h}getAllParsedValues(t){const e=this._cachedMeta._parsed,i=[];let s,n,a;for(s=0,n=e.length;s<n;++s)a=e[s][t.axis],o(a)&&i.push(a);return i}getMaxOverflow(){return!1}getLabelAndValue(t){const e=this._cachedMeta,i=e.iScale,s=e.vScale,n=this.getParsed(t);return{label:i?\"\"+i.getLabelForValue(n[i.axis]):\"\",value:s?\"\"+s.getLabelForValue(n[s.axis]):\"\"}}_update(t){const e=this._cachedMeta;this.update(t||\"default\"),e._clip=function(t){let e,i,s,o;return n(t)?(e=t.top,i=t.right,s=t.bottom,o=t.left):e=i=s=o=t,{top:e,right:i,bottom:s,left:o,disabled:!1===t}}(r(this.options.clip,function(t,e,i){if(!1===i)return!1;const s=vs(t,i),n=vs(e,i);return{top:n.end,right:s.end,bottom:n.start,left:s.start}}(e.xScale,e.yScale,this.getMaxOverflow())))}update(t){}draw(){const t=this._ctx,e=this.chart,i=this._cachedMeta,s=i.data||[],n=e.chartArea,o=[],a=this._drawStart||0,r=this._drawCount||s.length-a,l=this.options.drawActiveElementsOnTop;let h;for(i.dataset&&i.dataset.draw(t,n,a,r),h=a;h<a+r;++h){const e=s[h];e.hidden||(e.active&&l?o.push(e):e.draw(t,n))}for(h=0;h<o.length;++h)o[h].draw(t,n)}getStyle(t,e){const i=e?\"active\":\"default\";return void 0===t&&this._cachedMeta.dataset?this.resolveDatasetElementOptions(i):this.resolveDataElementOptions(t||0,i)}getContext(t,e,i){const s=this.getDataset();let n;if(t>=0&&t<this._cachedMeta.data.length){const e=this._cachedMeta.data[t];n=e.$context||(e.$context=function(t,e,i){return _i(t,{active:!1,dataIndex:e,parsed:void 0,raw:void 0,element:i,index:e,mode:\"default\",type:\"data\"})}(this.getContext(),t,e)),n.parsed=this.getParsed(t),n.raw=s.data[t],n.index=n.dataIndex=t}else n=this.$context||(this.$context=function(t,e){return _i(t,{active:!1,dataset:void 0,datasetIndex:e,index:e,mode:\"default\",type:\"dataset\"})}(this.chart.getContext(),this.index)),n.dataset=s,n.index=n.datasetIndex=this.index;return n.active=!!e,n.mode=i,n}resolveDatasetElementOptions(t){return this._resolveElementOptions(this.datasetElementType.id,t)}resolveDataElementOptions(t,e){return this._resolveElementOptions(this.dataElementType.id,e,t)}_resolveElementOptions(t,e=\"default\",i){const s=\"active\"===e,n=this._cachedDataOpts,o=t+\"-\"+e,a=n[o],r=this.enableOptionSharing&&M(i);if(a)return Ts(a,r);const l=this.chart.config,h=l.datasetElementScopeKeys(this._type,t),c=s?[`${t}Hover`,\"hover\",t,\"\"]:[t,\"\"],d=l.getOptionScopes(this.getDataset(),h),u=Object.keys(ne.elements[t]),f=l.resolveNamedOptions(d,u,(()=>this.getContext(i,s)),c);return f.$shared&&(f.$shared=r,n[o]=Object.freeze(Ts(f,r))),f}_resolveAnimations(t,e,i){const s=this.chart,n=this._cachedDataOpts,o=`animation-${e}`,a=n[o];if(a)return a;let r;if(!1!==s.options.animation){const s=this.chart.config,n=s.datasetAnimationScopeKeys(this._type,e),o=s.getOptionScopes(this.getDataset(),n);r=s.createResolver(o,this.getContext(t,i,e))}const l=new ys(s,r&&r.animations);return r&&r._cacheable&&(n[o]=Object.freeze(l)),l}getSharedOptions(t){if(t.$shared)return this._sharedOptions||(this._sharedOptions=Object.assign({},t))}includeOptions(t,e){return!e||As(t)||this.chart._animationsDisabled}_getSharedOptions(t,e){const i=this.resolveDataElementOptions(t,e),s=this._sharedOptions,n=this.getSharedOptions(i),o=this.includeOptions(e,n)||n!==s;return this.updateSharedOptions(n,e,i),{sharedOptions:n,includeOptions:o}}updateElement(t,e,i,s){As(s)?Object.assign(t,i):this._resolveAnimations(e,s).update(t,i)}updateSharedOptions(t,e,i){t&&!As(e)&&this._resolveAnimations(void 0,e).update(t,i)}_setStyle(t,e,i,s){t.active=s;const n=this.getStyle(e,s);this._resolveAnimations(e,i,s).update(t,{options:!s&&this.getSharedOptions(n)||n})}removeHoverStyle(t,e,i){this._setStyle(t,i,\"active\",!1)}setHoverStyle(t,e,i){this._setStyle(t,i,\"active\",!0)}_removeDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,\"active\",!1)}_setDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,\"active\",!0)}_resyncElements(t){const e=this._data,i=this._cachedMeta.data;for(const[t,e,i]of this._syncList)this[t](e,i);this._syncList=[];const s=i.length,n=e.length,o=Math.min(n,s);o&&this.parse(0,o),n>s?this._insertElements(s,n-s,t):n<s&&this._removeElements(n,s-n)}_insertElements(t,e,i=!0){const s=this._cachedMeta,n=s.data,o=t+e;let a;const r=t=>{for(t.length+=e,a=t.length-1;a>=o;a--)t[a]=t[a-e]};for(r(n),a=t;a<o;++a)n[a]=new this.dataElementType;this._parsing&&r(s._parsed),this.parse(t,e),i&&this.updateElements(n,t,e,\"reset\")}updateElements(t,e,i,s){}_removeElements(t,e){const i=this._cachedMeta;if(this._parsing){const s=i._parsed.splice(t,e);i._stacked&&Cs(i,s)}i.data.splice(t,e)}_sync(t){if(this._parsing)this._syncList.push(t);else{const[e,i,s]=t;this[e](i,s)}this.chart._dataChanges.push([this.index,...t])}_onDataPush(){const t=arguments.length;this._sync([\"_insertElements\",this.getDataset().data.length-t,t])}_onDataPop(){this._sync([\"_removeElements\",this._cachedMeta.data.length-1,1])}_onDataShift(){this._sync([\"_removeElements\",0,1])}_onDataSplice(t,e){e&&this._sync([\"_removeElements\",t,e]);const i=arguments.length-2;i&&this._sync([\"_insertElements\",t,i])}_onDataUnshift(){this._sync([\"_insertElements\",0,arguments.length])}}Ls.defaults={},Ls.prototype.datasetElementType=null,Ls.prototype.dataElementType=null;class Es{constructor(){this.x=void 0,this.y=void 0,this.active=!1,this.options=void 0,this.$animations=void 0}tooltipPosition(t){const{x:e,y:i}=this.getProps([\"x\",\"y\"],t);return{x:e,y:i}}hasValue(){return B(this.x)&&B(this.y)}getProps(t,e){const i=this.$animations;if(!e||!i)return this;const s={};return t.forEach((t=>{s[t]=i[t]&&i[t].active()?i[t]._to:this[t]})),s}}Es.defaults={},Es.defaultRoutes=void 0;const Rs={values:t=>s(t)?t:\"\"+t,numeric(t,e,i){if(0===t)return\"0\";const s=this.chart.options.locale;let n,o=t;if(i.length>1){const e=Math.max(Math.abs(i[0].value),Math.abs(i[i.length-1].value));(e<1e-4||e>1e15)&&(n=\"scientific\"),o=function(t,e){let i=e.length>3?e[2].value-e[1].value:e[1].value-e[0].value;Math.abs(i)>=1&&t!==Math.floor(t)&&(i=t-Math.floor(t));return i}(t,i)}const a=I(Math.abs(o)),r=Math.max(Math.min(-1*Math.floor(a),20),0),l={notation:n,minimumFractionDigits:r,maximumFractionDigits:r};return Object.assign(l,this.options.ticks.format),li(t,s,l)},logarithmic(t,e,i){if(0===t)return\"0\";const s=t/Math.pow(10,Math.floor(I(t)));return 1===s||2===s||5===s?Rs.numeric.call(this,t,e,i):\"\"}};var Is={formatters:Rs};function zs(t,e){const s=t.options.ticks,n=s.maxTicksLimit||function(t){const e=t.options.offset,i=t._tickSize(),s=t._length/i+(e?0:1),n=t._maxLength/i;return Math.floor(Math.min(s,n))}(t),o=s.major.enabled?function(t){const e=[];let i,s;for(i=0,s=t.length;i<s;i++)t[i].major&&e.push(i);return e}(e):[],a=o.length,r=o[0],l=o[a-1],h=[];if(a>n)return function(t,e,i,s){let n,o=0,a=i[0];for(s=Math.ceil(s),n=0;n<t.length;n++)n===a&&(e.push(t[n]),o++,a=i[o*s])}(e,h,o,a/n),h;const c=function(t,e,i){const s=function(t){const e=t.length;let i,s;if(e<2)return!1;for(s=t[0],i=1;i<e;++i)if(t[i]-t[i-1]!==s)return!1;return s}(t),n=e.length/i;if(!s)return Math.max(n,1);const o=V(s);for(let t=0,e=o.length-1;t<e;t++){const e=o[t];if(e>n)return e}return Math.max(n,1)}(o,e,n);if(a>0){let t,s;const n=a>1?Math.round((l-r)/(a-1)):null;for(Fs(e,h,c,i(n)?0:r-n,r),t=0,s=a-1;t<s;t++)Fs(e,h,c,o[t],o[t+1]);return Fs(e,h,c,l,i(n)?e.length:l+n),h}return Fs(e,h,c),h}function Fs(t,e,i,s,n){const o=r(s,0),a=Math.min(r(n,t.length),t.length);let l,h,c,d=0;for(i=Math.ceil(i),n&&(l=n-s,i=l/Math.floor(l/i)),c=o;c<0;)d++,c=Math.round(o+d*i);for(h=Math.max(o,0);h<a;h++)h===c&&(e.push(t[h]),d++,c=Math.round(o+d*i))}ne.set(\"scale\",{display:!0,offset:!1,reverse:!1,beginAtZero:!1,bounds:\"ticks\",grace:0,grid:{display:!0,lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickLength:8,tickWidth:(t,e)=>e.lineWidth,tickColor:(t,e)=>e.color,offset:!1,borderDash:[],borderDashOffset:0,borderWidth:1},title:{display:!1,text:\"\",padding:{top:4,bottom:4}},ticks:{minRotation:0,maxRotation:50,mirror:!1,textStrokeWidth:0,textStrokeColor:\"\",padding:3,display:!0,autoSkip:!0,autoSkipPadding:3,labelOffset:0,callback:Is.formatters.values,minor:{},major:{},align:\"center\",crossAlign:\"near\",showLabelBackdrop:!1,backdropColor:\"rgba(255, 255, 255, 0.75)\",backdropPadding:2}}),ne.route(\"scale.ticks\",\"color\",\"\",\"color\"),ne.route(\"scale.grid\",\"color\",\"\",\"borderColor\"),ne.route(\"scale.grid\",\"borderColor\",\"\",\"borderColor\"),ne.route(\"scale.title\",\"color\",\"\",\"color\"),ne.describe(\"scale\",{_fallback:!1,_scriptable:t=>!t.startsWith(\"before\")&&!t.startsWith(\"after\")&&\"callback\"!==t&&\"parser\"!==t,_indexable:t=>\"borderDash\"!==t&&\"tickBorderDash\"!==t}),ne.describe(\"scales\",{_fallback:\"scale\"}),ne.describe(\"scale.ticks\",{_scriptable:t=>\"backdropPadding\"!==t&&\"callback\"!==t,_indexable:t=>\"backdropPadding\"!==t});const Vs=(t,e,i)=>\"top\"===e||\"left\"===e?t[e]+i:t[e]-i;function Bs(t,e){const i=[],s=t.length/e,n=t.length;let o=0;for(;o<n;o+=s)i.push(t[Math.floor(o)]);return i}function Ns(t,e,i){const s=t.ticks.length,n=Math.min(e,s-1),o=t._startPixel,a=t._endPixel,r=1e-6;let l,h=t.getPixelForTick(n);if(!(i&&(l=1===s?Math.max(h-o,a-h):0===e?(t.getPixelForTick(1)-h)/2:(h-t.getPixelForTick(n-1))/2,h+=n<e?l:-l,h<o-r||h>a+r)))return h}function Ws(t){return t.drawTicks?t.tickLength:0}function js(t,e){if(!t.display)return 0;const i=mi(t.font,e),n=pi(t.padding);return(s(t.text)?t.text.length:1)*i.lineHeight+n.height}function Hs(t,e,i){let s=dt(t);return(i&&\"right\"!==e||!i&&\"right\"===e)&&(s=(t=>\"left\"===t?\"right\":\"right\"===t?\"left\":t)(s)),s}class $s extends Es{constructor(t){super(),this.id=t.id,this.type=t.type,this.options=void 0,this.ctx=t.ctx,this.chart=t.chart,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this._margins={left:0,right:0,top:0,bottom:0},this.maxWidth=void 0,this.maxHeight=void 0,this.paddingTop=void 0,this.paddingBottom=void 0,this.paddingLeft=void 0,this.paddingRight=void 0,this.axis=void 0,this.labelRotation=void 0,this.min=void 0,this.max=void 0,this._range=void 0,this.ticks=[],this._gridLineItems=null,this._labelItems=null,this._labelSizes=null,this._length=0,this._maxLength=0,this._longestTextCache={},this._startPixel=void 0,this._endPixel=void 0,this._reversePixels=!1,this._userMax=void 0,this._userMin=void 0,this._suggestedMax=void 0,this._suggestedMin=void 0,this._ticksLength=0,this._borderValue=0,this._cache={},this._dataLimitsCached=!1,this.$context=void 0}init(t){this.options=t.setContext(this.getContext()),this.axis=t.axis,this._userMin=this.parse(t.min),this._userMax=this.parse(t.max),this._suggestedMin=this.parse(t.suggestedMin),this._suggestedMax=this.parse(t.suggestedMax)}parse(t,e){return t}getUserBounds(){let{_userMin:t,_userMax:e,_suggestedMin:i,_suggestedMax:s}=this;return t=a(t,Number.POSITIVE_INFINITY),e=a(e,Number.NEGATIVE_INFINITY),i=a(i,Number.POSITIVE_INFINITY),s=a(s,Number.NEGATIVE_INFINITY),{min:a(t,i),max:a(e,s),minDefined:o(t),maxDefined:o(e)}}getMinMax(t){let e,{min:i,max:s,minDefined:n,maxDefined:o}=this.getUserBounds();if(n&&o)return{min:i,max:s};const r=this.getMatchingVisibleMetas();for(let a=0,l=r.length;a<l;++a)e=r[a].controller.getMinMax(this,t),n||(i=Math.min(i,e.min)),o||(s=Math.max(s,e.max));return i=o&&i>s?s:i,s=n&&i>s?i:s,{min:a(i,a(s,i)),max:a(s,a(i,s))}}getPadding(){return{left:this.paddingLeft||0,top:this.paddingTop||0,right:this.paddingRight||0,bottom:this.paddingBottom||0}}getTicks(){return this.ticks}getLabels(){const t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels||[]}beforeLayout(){this._cache={},this._dataLimitsCached=!1}beforeUpdate(){c(this.options.beforeUpdate,[this])}update(t,e,i){const{beginAtZero:s,grace:n,ticks:o}=this.options,a=o.sampleSize;this.beforeUpdate(),this.maxWidth=t,this.maxHeight=e,this._margins=i=Object.assign({left:0,right:0,top:0,bottom:0},i),this.ticks=null,this._labelSizes=null,this._gridLineItems=null,this._labelItems=null,this.beforeSetDimensions(),this.setDimensions(),this.afterSetDimensions(),this._maxLength=this.isHorizontal()?this.width+i.left+i.right:this.height+i.top+i.bottom,this._dataLimitsCached||(this.beforeDataLimits(),this.determineDataLimits(),this.afterDataLimits(),this._range=xi(this,n,s),this._dataLimitsCached=!0),this.beforeBuildTicks(),this.ticks=this.buildTicks()||[],this.afterBuildTicks();const r=a<this.ticks.length;this._convertTicksToLabels(r?Bs(this.ticks,a):this.ticks),this.configure(),this.beforeCalculateLabelRotation(),this.calculateLabelRotation(),this.afterCalculateLabelRotation(),o.display&&(o.autoSkip||\"auto\"===o.source)&&(this.ticks=zs(this,this.ticks),this._labelSizes=null,this.afterAutoSkip()),r&&this._convertTicksToLabels(this.ticks),this.beforeFit(),this.fit(),this.afterFit(),this.afterUpdate()}configure(){let t,e,i=this.options.reverse;this.isHorizontal()?(t=this.left,e=this.right):(t=this.top,e=this.bottom,i=!i),this._startPixel=t,this._endPixel=e,this._reversePixels=i,this._length=e-t,this._alignToPixels=this.options.alignToPixels}afterUpdate(){c(this.options.afterUpdate,[this])}beforeSetDimensions(){c(this.options.beforeSetDimensions,[this])}setDimensions(){this.isHorizontal()?(this.width=this.maxWidth,this.left=0,this.right=this.width):(this.height=this.maxHeight,this.top=0,this.bottom=this.height),this.paddingLeft=0,this.paddingTop=0,this.paddingRight=0,this.paddingBottom=0}afterSetDimensions(){c(this.options.afterSetDimensions,[this])}_callHooks(t){this.chart.notifyPlugins(t,this.getContext()),c(this.options[t],[this])}beforeDataLimits(){this._callHooks(\"beforeDataLimits\")}determineDataLimits(){}afterDataLimits(){this._callHooks(\"afterDataLimits\")}beforeBuildTicks(){this._callHooks(\"beforeBuildTicks\")}buildTicks(){return[]}afterBuildTicks(){this._callHooks(\"afterBuildTicks\")}beforeTickToLabelConversion(){c(this.options.beforeTickToLabelConversion,[this])}generateTickLabels(t){const e=this.options.ticks;let i,s,n;for(i=0,s=t.length;i<s;i++)n=t[i],n.label=c(e.callback,[n.value,i,t],this)}afterTickToLabelConversion(){c(this.options.afterTickToLabelConversion,[this])}beforeCalculateLabelRotation(){c(this.options.beforeCalculateLabelRotation,[this])}calculateLabelRotation(){const t=this.options,e=t.ticks,i=this.ticks.length,s=e.minRotation||0,n=e.maxRotation;let o,a,r,l=s;if(!this._isVisible()||!e.display||s>=n||i<=1||!this.isHorizontal())return void(this.labelRotation=s);const h=this._getLabelSizes(),c=h.widest.width,d=h.highest.height,u=Z(this.chart.width-c,0,this.maxWidth);o=t.offset?this.maxWidth/i:u/(i-1),c+6>o&&(o=u/(i-(t.offset?.5:1)),a=this.maxHeight-Ws(t.grid)-e.padding-js(t.title,this.chart.options.font),r=Math.sqrt(c*c+d*d),l=$(Math.min(Math.asin(Z((h.highest.height+6)/o,-1,1)),Math.asin(Z(a/r,-1,1))-Math.asin(Z(d/r,-1,1)))),l=Math.max(s,Math.min(n,l))),this.labelRotation=l}afterCalculateLabelRotation(){c(this.options.afterCalculateLabelRotation,[this])}afterAutoSkip(){}beforeFit(){c(this.options.beforeFit,[this])}fit(){const t={width:0,height:0},{chart:e,options:{ticks:i,title:s,grid:n}}=this,o=this._isVisible(),a=this.isHorizontal();if(o){const o=js(s,e.options.font);if(a?(t.width=this.maxWidth,t.height=Ws(n)+o):(t.height=this.maxHeight,t.width=Ws(n)+o),i.display&&this.ticks.length){const{first:e,last:s,widest:n,highest:o}=this._getLabelSizes(),r=2*i.padding,l=H(this.labelRotation),h=Math.cos(l),c=Math.sin(l);if(a){const e=i.mirror?0:c*n.width+h*o.height;t.height=Math.min(this.maxHeight,t.height+e+r)}else{const e=i.mirror?0:h*n.width+c*o.height;t.width=Math.min(this.maxWidth,t.width+e+r)}this._calculatePadding(e,s,c,h)}}this._handleMargins(),a?(this.width=this._length=e.width-this._margins.left-this._margins.right,this.height=t.height):(this.width=t.width,this.height=this._length=e.height-this._margins.top-this._margins.bottom)}_calculatePadding(t,e,i,s){const{ticks:{align:n,padding:o},position:a}=this.options,r=0!==this.labelRotation,l=\"top\"!==a&&\"x\"===this.axis;if(this.isHorizontal()){const a=this.getPixelForTick(0)-this.left,h=this.right-this.getPixelForTick(this.ticks.length-1);let c=0,d=0;r?l?(c=s*t.width,d=i*e.height):(c=i*t.height,d=s*e.width):\"start\"===n?d=e.width:\"end\"===n?c=t.width:\"inner\"!==n&&(c=t.width/2,d=e.width/2),this.paddingLeft=Math.max((c-a+o)*this.width/(this.width-a),0),this.paddingRight=Math.max((d-h+o)*this.width/(this.width-h),0)}else{let i=e.height/2,s=t.height/2;\"start\"===n?(i=0,s=t.height):\"end\"===n&&(i=e.height,s=0),this.paddingTop=i+o,this.paddingBottom=s+o}}_handleMargins(){this._margins&&(this._margins.left=Math.max(this.paddingLeft,this._margins.left),this._margins.top=Math.max(this.paddingTop,this._margins.top),this._margins.right=Math.max(this.paddingRight,this._margins.right),this._margins.bottom=Math.max(this.paddingBottom,this._margins.bottom))}afterFit(){c(this.options.afterFit,[this])}isHorizontal(){const{axis:t,position:e}=this.options;return\"top\"===e||\"bottom\"===e||\"x\"===t}isFullSize(){return this.options.fullSize}_convertTicksToLabels(t){let e,s;for(this.beforeTickToLabelConversion(),this.generateTickLabels(t),e=0,s=t.length;e<s;e++)i(t[e].label)&&(t.splice(e,1),s--,e--);this.afterTickToLabelConversion()}_getLabelSizes(){let t=this._labelSizes;if(!t){const e=this.options.ticks.sampleSize;let i=this.ticks;e<i.length&&(i=Bs(i,e)),this._labelSizes=t=this._computeLabelSizes(i,i.length)}return t}_computeLabelSizes(t,e){const{ctx:n,_longestTextCache:o}=this,a=[],r=[];let l,h,c,u,f,g,p,m,b,x,_,y=0,v=0;for(l=0;l<e;++l){if(u=t[l].label,f=this._resolveTickFontOptions(l),n.font=g=f.string,p=o[g]=o[g]||{data:{},gc:[]},m=f.lineHeight,b=x=0,i(u)||s(u)){if(s(u))for(h=0,c=u.length;h<c;++h)_=u[h],i(_)||s(_)||(b=_e(n,p.data,p.gc,b,_),x+=m)}else b=_e(n,p.data,p.gc,b,u),x=m;a.push(b),r.push(x),y=Math.max(b,y),v=Math.max(x,v)}!function(t,e){d(t,(t=>{const i=t.gc,s=i.length/2;let n;if(s>e){for(n=0;n<s;++n)delete t.data[i[n]];i.splice(0,s)}}))}(o,e);const w=a.indexOf(y),M=r.indexOf(v),k=t=>({width:a[t]||0,height:r[t]||0});return{first:k(0),last:k(e-1),widest:k(w),highest:k(M),widths:a,heights:r}}getLabelForValue(t){return t}getPixelForValue(t,e){return NaN}getValueForPixel(t){}getPixelForTick(t){const e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getPixelForDecimal(t){this._reversePixels&&(t=1-t);const e=this._startPixel+t*this._length;return J(this._alignToPixels?ve(this.chart,e,0):e)}getDecimalForPixel(t){const e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e}getBasePixel(){return this.getPixelForValue(this.getBaseValue())}getBaseValue(){const{min:t,max:e}=this;return t<0&&e<0?e:t>0&&e>0?t:0}getContext(t){const e=this.ticks||[];if(t>=0&&t<e.length){const i=e[t];return i.$context||(i.$context=function(t,e,i){return _i(t,{tick:i,index:e,type:\"tick\"})}(this.getContext(),t,i))}return this.$context||(this.$context=_i(this.chart.getContext(),{scale:this,type:\"scale\"}))}_tickSize(){const t=this.options.ticks,e=H(this.labelRotation),i=Math.abs(Math.cos(e)),s=Math.abs(Math.sin(e)),n=this._getLabelSizes(),o=t.autoSkipPadding||0,a=n?n.widest.width+o:0,r=n?n.highest.height+o:0;return this.isHorizontal()?r*i>a*s?a/i:r/s:r*s<a*i?r/i:a/s}_isVisible(){const t=this.options.display;return\"auto\"!==t?!!t:this.getMatchingVisibleMetas().length>0}_computeGridLineItems(t){const e=this.axis,i=this.chart,s=this.options,{grid:o,position:a}=s,l=o.offset,h=this.isHorizontal(),c=this.ticks.length+(l?1:0),d=Ws(o),u=[],f=o.setContext(this.getContext()),g=f.drawBorder?f.borderWidth:0,p=g/2,m=function(t){return ve(i,t,g)};let b,x,_,y,v,w,M,k,S,P,D,O;if(\"top\"===a)b=m(this.bottom),w=this.bottom-d,k=b-p,P=m(t.top)+p,O=t.bottom;else if(\"bottom\"===a)b=m(this.top),P=t.top,O=m(t.bottom)-p,w=b+p,k=this.top+d;else if(\"left\"===a)b=m(this.right),v=this.right-d,M=b-p,S=m(t.left)+p,D=t.right;else if(\"right\"===a)b=m(this.left),S=t.left,D=m(t.right)-p,v=b+p,M=this.left+d;else if(\"x\"===e){if(\"center\"===a)b=m((t.top+t.bottom)/2+.5);else if(n(a)){const t=Object.keys(a)[0],e=a[t];b=m(this.chart.scales[t].getPixelForValue(e))}P=t.top,O=t.bottom,w=b+p,k=w+d}else if(\"y\"===e){if(\"center\"===a)b=m((t.left+t.right)/2);else if(n(a)){const t=Object.keys(a)[0],e=a[t];b=m(this.chart.scales[t].getPixelForValue(e))}v=b-p,M=v-d,S=t.left,D=t.right}const C=r(s.ticks.maxTicksLimit,c),A=Math.max(1,Math.ceil(c/C));for(x=0;x<c;x+=A){const t=o.setContext(this.getContext(x)),e=t.lineWidth,s=t.color,n=t.borderDash||[],a=t.borderDashOffset,r=t.tickWidth,c=t.tickColor,d=t.tickBorderDash||[],f=t.tickBorderDashOffset;_=Ns(this,x,l),void 0!==_&&(y=ve(i,_,e),h?v=M=S=D=y:w=k=P=O=y,u.push({tx1:v,ty1:w,tx2:M,ty2:k,x1:S,y1:P,x2:D,y2:O,width:e,color:s,borderDash:n,borderDashOffset:a,tickWidth:r,tickColor:c,tickBorderDash:d,tickBorderDashOffset:f}))}return this._ticksLength=c,this._borderValue=b,u}_computeLabelItems(t){const e=this.axis,i=this.options,{position:o,ticks:a}=i,r=this.isHorizontal(),l=this.ticks,{align:h,crossAlign:c,padding:d,mirror:u}=a,f=Ws(i.grid),g=f+d,p=u?-d:g,m=-H(this.labelRotation),b=[];let x,_,y,v,w,M,k,S,P,D,O,C,A=\"middle\";if(\"top\"===o)M=this.bottom-p,k=this._getXAxisLabelAlignment();else if(\"bottom\"===o)M=this.top+p,k=this._getXAxisLabelAlignment();else if(\"left\"===o){const t=this._getYAxisLabelAlignment(f);k=t.textAlign,w=t.x}else if(\"right\"===o){const t=this._getYAxisLabelAlignment(f);k=t.textAlign,w=t.x}else if(\"x\"===e){if(\"center\"===o)M=(t.top+t.bottom)/2+g;else if(n(o)){const t=Object.keys(o)[0],e=o[t];M=this.chart.scales[t].getPixelForValue(e)+g}k=this._getXAxisLabelAlignment()}else if(\"y\"===e){if(\"center\"===o)w=(t.left+t.right)/2-g;else if(n(o)){const t=Object.keys(o)[0],e=o[t];w=this.chart.scales[t].getPixelForValue(e)}k=this._getYAxisLabelAlignment(f).textAlign}\"y\"===e&&(\"start\"===h?A=\"top\":\"end\"===h&&(A=\"bottom\"));const T=this._getLabelSizes();for(x=0,_=l.length;x<_;++x){y=l[x],v=y.label;const t=a.setContext(this.getContext(x));S=this.getPixelForTick(x)+a.labelOffset,P=this._resolveTickFontOptions(x),D=P.lineHeight,O=s(v)?v.length:1;const e=O/2,i=t.color,n=t.textStrokeColor,h=t.textStrokeWidth;let d,f=k;if(r?(w=S,\"inner\"===k&&(f=x===_-1?this.options.reverse?\"left\":\"right\":0===x?this.options.reverse?\"right\":\"left\":\"center\"),C=\"top\"===o?\"near\"===c||0!==m?-O*D+D/2:\"center\"===c?-T.highest.height/2-e*D+D:-T.highest.height+D/2:\"near\"===c||0!==m?D/2:\"center\"===c?T.highest.height/2-e*D:T.highest.height-O*D,u&&(C*=-1)):(M=S,C=(1-O)*D/2),t.showLabelBackdrop){const e=pi(t.backdropPadding),i=T.heights[x],s=T.widths[x];let n=M+C-e.top,o=w-e.left;switch(A){case\"middle\":n-=i/2;break;case\"bottom\":n-=i}switch(k){case\"center\":o-=s/2;break;case\"right\":o-=s}d={left:o,top:n,width:s+e.width,height:i+e.height,color:t.backdropColor}}b.push({rotation:m,label:v,font:P,color:i,strokeColor:n,strokeWidth:h,textOffset:C,textAlign:f,textBaseline:A,translation:[w,M],backdrop:d})}return b}_getXAxisLabelAlignment(){const{position:t,ticks:e}=this.options;if(-H(this.labelRotation))return\"top\"===t?\"left\":\"right\";let i=\"center\";return\"start\"===e.align?i=\"left\":\"end\"===e.align?i=\"right\":\"inner\"===e.align&&(i=\"inner\"),i}_getYAxisLabelAlignment(t){const{position:e,ticks:{crossAlign:i,mirror:s,padding:n}}=this.options,o=t+n,a=this._getLabelSizes().widest.width;let r,l;return\"left\"===e?s?(l=this.right+n,\"near\"===i?r=\"left\":\"center\"===i?(r=\"center\",l+=a/2):(r=\"right\",l+=a)):(l=this.right-o,\"near\"===i?r=\"right\":\"center\"===i?(r=\"center\",l-=a/2):(r=\"left\",l=this.left)):\"right\"===e?s?(l=this.left+n,\"near\"===i?r=\"right\":\"center\"===i?(r=\"center\",l-=a/2):(r=\"left\",l-=a)):(l=this.left+o,\"near\"===i?r=\"left\":\"center\"===i?(r=\"center\",l+=a/2):(r=\"right\",l=this.right)):r=\"right\",{textAlign:r,x:l}}_computeLabelArea(){if(this.options.ticks.mirror)return;const t=this.chart,e=this.options.position;return\"left\"===e||\"right\"===e?{top:0,left:this.left,bottom:t.height,right:this.right}:\"top\"===e||\"bottom\"===e?{top:this.top,left:0,bottom:this.bottom,right:t.width}:void 0}drawBackground(){const{ctx:t,options:{backgroundColor:e},left:i,top:s,width:n,height:o}=this;e&&(t.save(),t.fillStyle=e,t.fillRect(i,s,n,o),t.restore())}getLineWidthForValue(t){const e=this.options.grid;if(!this._isVisible()||!e.display)return 0;const i=this.ticks.findIndex((e=>e.value===t));if(i>=0){return e.setContext(this.getContext(i)).lineWidth}return 0}drawGrid(t){const e=this.options.grid,i=this.ctx,s=this._gridLineItems||(this._gridLineItems=this._computeGridLineItems(t));let n,o;const a=(t,e,s)=>{s.width&&s.color&&(i.save(),i.lineWidth=s.width,i.strokeStyle=s.color,i.setLineDash(s.borderDash||[]),i.lineDashOffset=s.borderDashOffset,i.beginPath(),i.moveTo(t.x,t.y),i.lineTo(e.x,e.y),i.stroke(),i.restore())};if(e.display)for(n=0,o=s.length;n<o;++n){const t=s[n];e.drawOnChartArea&&a({x:t.x1,y:t.y1},{x:t.x2,y:t.y2},t),e.drawTicks&&a({x:t.tx1,y:t.ty1},{x:t.tx2,y:t.ty2},{color:t.tickColor,width:t.tickWidth,borderDash:t.tickBorderDash,borderDashOffset:t.tickBorderDashOffset})}}drawBorder(){const{chart:t,ctx:e,options:{grid:i}}=this,s=i.setContext(this.getContext()),n=i.drawBorder?s.borderWidth:0;if(!n)return;const o=i.setContext(this.getContext(0)).lineWidth,a=this._borderValue;let r,l,h,c;this.isHorizontal()?(r=ve(t,this.left,n)-n/2,l=ve(t,this.right,o)+o/2,h=c=a):(h=ve(t,this.top,n)-n/2,c=ve(t,this.bottom,o)+o/2,r=l=a),e.save(),e.lineWidth=s.borderWidth,e.strokeStyle=s.borderColor,e.beginPath(),e.moveTo(r,h),e.lineTo(l,c),e.stroke(),e.restore()}drawLabels(t){if(!this.options.ticks.display)return;const e=this.ctx,i=this._computeLabelArea();i&&Pe(e,i);const s=this._labelItems||(this._labelItems=this._computeLabelItems(t));let n,o;for(n=0,o=s.length;n<o;++n){const t=s[n],i=t.font,o=t.label;t.backdrop&&(e.fillStyle=t.backdrop.color,e.fillRect(t.backdrop.left,t.backdrop.top,t.backdrop.width,t.backdrop.height)),Ae(e,o,0,t.textOffset,i,t)}i&&De(e)}drawTitle(){const{ctx:t,options:{position:e,title:i,reverse:o}}=this;if(!i.display)return;const a=mi(i.font),r=pi(i.padding),l=i.align;let h=a.lineHeight/2;\"bottom\"===e||\"center\"===e||n(e)?(h+=r.bottom,s(i.text)&&(h+=a.lineHeight*(i.text.length-1))):h+=r.top;const{titleX:c,titleY:d,maxWidth:u,rotation:f}=function(t,e,i,s){const{top:o,left:a,bottom:r,right:l,chart:h}=t,{chartArea:c,scales:d}=h;let u,f,g,p=0;const m=r-o,b=l-a;if(t.isHorizontal()){if(f=ut(s,a,l),n(i)){const t=Object.keys(i)[0],s=i[t];g=d[t].getPixelForValue(s)+m-e}else g=\"center\"===i?(c.bottom+c.top)/2+m-e:Vs(t,i,e);u=l-a}else{if(n(i)){const t=Object.keys(i)[0],s=i[t];f=d[t].getPixelForValue(s)-b+e}else f=\"center\"===i?(c.left+c.right)/2-b+e:Vs(t,i,e);g=ut(s,r,o),p=\"left\"===i?-L:L}return{titleX:f,titleY:g,maxWidth:u,rotation:p}}(this,h,e,l);Ae(t,i.text,0,0,a,{color:i.color,maxWidth:u,rotation:f,textAlign:Hs(l,e,o),textBaseline:\"middle\",translation:[c,d]})}draw(t){this._isVisible()&&(this.drawBackground(),this.drawGrid(t),this.drawBorder(),this.drawTitle(),this.drawLabels(t))}_layers(){const t=this.options,e=t.ticks&&t.ticks.z||0,i=r(t.grid&&t.grid.z,-1);return this._isVisible()&&this.draw===$s.prototype.draw?[{z:i,draw:t=>{this.drawBackground(),this.drawGrid(t),this.drawTitle()}},{z:i+1,draw:()=>{this.drawBorder()}},{z:e,draw:t=>{this.drawLabels(t)}}]:[{z:e,draw:t=>{this.draw(t)}}]}getMatchingVisibleMetas(t){const e=this.chart.getSortedVisibleDatasetMetas(),i=this.axis+\"AxisID\",s=[];let n,o;for(n=0,o=e.length;n<o;++n){const o=e[n];o[i]!==this.id||t&&o.type!==t||s.push(o)}return s}_resolveTickFontOptions(t){return mi(this.options.ticks.setContext(this.getContext(t)).font)}_maxDigits(){const t=this._resolveTickFontOptions(0).lineHeight;return(this.isHorizontal()?this.width:this.height)/t}}class Ys{constructor(t,e,i){this.type=t,this.scope=e,this.override=i,this.items=Object.create(null)}isForType(t){return Object.prototype.isPrototypeOf.call(this.type.prototype,t.prototype)}register(t){const e=Object.getPrototypeOf(t);let i;(function(t){return\"id\"in t&&\"defaults\"in t})(e)&&(i=this.register(e));const s=this.items,n=t.id,o=this.scope+\".\"+n;if(!n)throw new Error(\"class does not have id: \"+t);return n in s||(s[n]=t,function(t,e,i){const s=m(Object.create(null),[i?ne.get(i):{},ne.get(e),t.defaults]);ne.set(e,s),t.defaultRoutes&&function(t,e){Object.keys(e).forEach((i=>{const s=i.split(\".\"),n=s.pop(),o=[t].concat(s).join(\".\"),a=e[i].split(\".\"),r=a.pop(),l=a.join(\".\");ne.route(o,n,l,r)}))}(e,t.defaultRoutes);t.descriptors&&ne.describe(e,t.descriptors)}(t,o,i),this.override&&ne.override(t.id,t.overrides)),o}get(t){return this.items[t]}unregister(t){const e=this.items,i=t.id,s=this.scope;i in e&&delete e[i],s&&i in ne[s]&&(delete ne[s][i],this.override&&delete te[i])}}var Us=new class{constructor(){this.controllers=new Ys(Ls,\"datasets\",!0),this.elements=new Ys(Es,\"elements\"),this.plugins=new Ys(Object,\"plugins\"),this.scales=new Ys($s,\"scales\"),this._typedRegistries=[this.controllers,this.scales,this.elements]}add(...t){this._each(\"register\",t)}remove(...t){this._each(\"unregister\",t)}addControllers(...t){this._each(\"register\",t,this.controllers)}addElements(...t){this._each(\"register\",t,this.elements)}addPlugins(...t){this._each(\"register\",t,this.plugins)}addScales(...t){this._each(\"register\",t,this.scales)}getController(t){return this._get(t,this.controllers,\"controller\")}getElement(t){return this._get(t,this.elements,\"element\")}getPlugin(t){return this._get(t,this.plugins,\"plugin\")}getScale(t){return this._get(t,this.scales,\"scale\")}removeControllers(...t){this._each(\"unregister\",t,this.controllers)}removeElements(...t){this._each(\"unregister\",t,this.elements)}removePlugins(...t){this._each(\"unregister\",t,this.plugins)}removeScales(...t){this._each(\"unregister\",t,this.scales)}_each(t,e,i){[...e].forEach((e=>{const s=i||this._getRegistryForType(e);i||s.isForType(e)||s===this.plugins&&e.id?this._exec(t,s,e):d(e,(e=>{const s=i||this._getRegistryForType(e);this._exec(t,s,e)}))}))}_exec(t,e,i){const s=w(t);c(i[\"before\"+s],[],i),e[t](i),c(i[\"after\"+s],[],i)}_getRegistryForType(t){for(let e=0;e<this._typedRegistries.length;e++){const i=this._typedRegistries[e];if(i.isForType(t))return i}return this.plugins}_get(t,e,i){const s=e.get(t);if(void 0===s)throw new Error('\"'+t+'\" is not a registered '+i+\".\");return s}};class Xs{constructor(){this._init=[]}notify(t,e,i,s){\"beforeInit\"===e&&(this._init=this._createDescriptors(t,!0),this._notify(this._init,t,\"install\"));const n=s?this._descriptors(t).filter(s):this._descriptors(t),o=this._notify(n,t,e,i);return\"afterDestroy\"===e&&(this._notify(n,t,\"stop\"),this._notify(this._init,t,\"uninstall\")),o}_notify(t,e,i,s){s=s||{};for(const n of t){const t=n.plugin;if(!1===c(t[i],[e,s,n.options],t)&&s.cancelable)return!1}return!0}invalidate(){i(this._cache)||(this._oldCache=this._cache,this._cache=void 0)}_descriptors(t){if(this._cache)return this._cache;const e=this._cache=this._createDescriptors(t);return this._notifyStateChanges(t),e}_createDescriptors(t,e){const i=t&&t.config,s=r(i.options&&i.options.plugins,{}),n=function(t){const e={},i=[],s=Object.keys(Us.plugins.items);for(let t=0;t<s.length;t++)i.push(Us.getPlugin(s[t]));const n=t.plugins||[];for(let t=0;t<n.length;t++){const s=n[t];-1===i.indexOf(s)&&(i.push(s),e[s.id]=!0)}return{plugins:i,localIds:e}}(i);return!1!==s||e?function(t,{plugins:e,localIds:i},s,n){const o=[],a=t.getContext();for(const r of e){const e=r.id,l=qs(s[e],n);null!==l&&o.push({plugin:r,options:Ks(t.config,{plugin:r,local:i[e]},l,a)})}return o}(t,n,s,e):[]}_notifyStateChanges(t){const e=this._oldCache||[],i=this._cache,s=(t,e)=>t.filter((t=>!e.some((e=>t.plugin.id===e.plugin.id))));this._notify(s(e,i),t,\"stop\"),this._notify(s(i,e),t,\"start\")}}function qs(t,e){return e||!1!==t?!0===t?{}:t:null}function Ks(t,{plugin:e,local:i},s,n){const o=t.pluginScopeKeys(e),a=t.getOptionScopes(s,o);return i&&e.defaults&&a.push(e.defaults),t.createResolver(a,n,[\"\"],{scriptable:!1,indexable:!1,allKeys:!0})}function Gs(t,e){const i=ne.datasets[t]||{};return((e.datasets||{})[t]||{}).indexAxis||e.indexAxis||i.indexAxis||\"x\"}function Zs(t,e){return\"x\"===t||\"y\"===t?t:e.axis||(\"top\"===(i=e.position)||\"bottom\"===i?\"x\":\"left\"===i||\"right\"===i?\"y\":void 0)||t.charAt(0).toLowerCase();var i}function Js(t){const e=t.options||(t.options={});e.plugins=r(e.plugins,{}),e.scales=function(t,e){const i=te[t.type]||{scales:{}},s=e.scales||{},o=Gs(t.type,e),a=Object.create(null),r=Object.create(null);return Object.keys(s).forEach((t=>{const e=s[t];if(!n(e))return console.error(`Invalid scale configuration for scale: ${t}`);if(e._proxy)return console.warn(`Ignoring resolver passed as options for scale: ${t}`);const l=Zs(t,e),h=function(t,e){return t===e?\"_index_\":\"_value_\"}(l,o),c=i.scales||{};a[l]=a[l]||t,r[t]=b(Object.create(null),[{axis:l},e,c[l],c[h]])})),t.data.datasets.forEach((i=>{const n=i.type||t.type,o=i.indexAxis||Gs(n,e),l=(te[n]||{}).scales||{};Object.keys(l).forEach((t=>{const e=function(t,e){let i=t;return\"_index_\"===t?i=e:\"_value_\"===t&&(i=\"x\"===e?\"y\":\"x\"),i}(t,o),n=i[e+\"AxisID\"]||a[e]||e;r[n]=r[n]||Object.create(null),b(r[n],[{axis:e},s[n],l[t]])}))})),Object.keys(r).forEach((t=>{const e=r[t];b(e,[ne.scales[e.type],ne.scale])})),r}(t,e)}function Qs(t){return(t=t||{}).datasets=t.datasets||[],t.labels=t.labels||[],t}const tn=new Map,en=new Set;function sn(t,e){let i=tn.get(t);return i||(i=e(),tn.set(t,i),en.add(i)),i}const nn=(t,e,i)=>{const s=y(e,i);void 0!==s&&t.add(s)};class on{constructor(t){this._config=function(t){return(t=t||{}).data=Qs(t.data),Js(t),t}(t),this._scopeCache=new Map,this._resolverCache=new Map}get platform(){return this._config.platform}get type(){return this._config.type}set type(t){this._config.type=t}get data(){return this._config.data}set data(t){this._config.data=Qs(t)}get options(){return this._config.options}set options(t){this._config.options=t}get plugins(){return this._config.plugins}update(){const t=this._config;this.clearCache(),Js(t)}clearCache(){this._scopeCache.clear(),this._resolverCache.clear()}datasetScopeKeys(t){return sn(t,(()=>[[`datasets.${t}`,\"\"]]))}datasetAnimationScopeKeys(t,e){return sn(`${t}.transition.${e}`,(()=>[[`datasets.${t}.transitions.${e}`,`transitions.${e}`],[`datasets.${t}`,\"\"]]))}datasetElementScopeKeys(t,e){return sn(`${t}-${e}`,(()=>[[`datasets.${t}.elements.${e}`,`datasets.${t}`,`elements.${e}`,\"\"]]))}pluginScopeKeys(t){const e=t.id;return sn(`${this.type}-plugin-${e}`,(()=>[[`plugins.${e}`,...t.additionalOptionScopes||[]]]))}_cachedScopes(t,e){const i=this._scopeCache;let s=i.get(t);return s&&!e||(s=new Map,i.set(t,s)),s}getOptionScopes(t,e,i){const{options:s,type:n}=this,o=this._cachedScopes(t,i),a=o.get(e);if(a)return a;const r=new Set;e.forEach((e=>{t&&(r.add(t),e.forEach((e=>nn(r,t,e)))),e.forEach((t=>nn(r,s,t))),e.forEach((t=>nn(r,te[n]||{},t))),e.forEach((t=>nn(r,ne,t))),e.forEach((t=>nn(r,ee,t)))}));const l=Array.from(r);return 0===l.length&&l.push(Object.create(null)),en.has(e)&&o.set(e,l),l}chartOptionScopes(){const{options:t,type:e}=this;return[t,te[e]||{},ne.datasets[e]||{},{type:e},ne,ee]}resolveNamedOptions(t,e,i,n=[\"\"]){const o={$shared:!0},{resolver:a,subPrefixes:r}=an(this._resolverCache,t,n);let l=a;if(function(t,e){const{isScriptable:i,isIndexable:n}=Ie(t);for(const o of e){const e=i(o),a=n(o),r=(a||e)&&t[o];if(e&&(k(r)||rn(r))||a&&s(r))return!0}return!1}(a,e)){o.$shared=!1;l=Re(a,i=k(i)?i():i,this.createResolver(t,i,r))}for(const t of e)o[t]=l[t];return o}createResolver(t,e,i=[\"\"],s){const{resolver:o}=an(this._resolverCache,t,i);return n(e)?Re(o,e,void 0,s):o}}function an(t,e,i){let s=t.get(e);s||(s=new Map,t.set(e,s));const n=i.join();let o=s.get(n);if(!o){o={resolver:Ee(e,i),subPrefixes:i.filter((t=>!t.toLowerCase().includes(\"hover\")))},s.set(n,o)}return o}const rn=t=>n(t)&&Object.getOwnPropertyNames(t).reduce(((e,i)=>e||k(t[i])),!1);const ln=[\"top\",\"bottom\",\"left\",\"right\",\"chartArea\"];function hn(t,e){return\"top\"===t||\"bottom\"===t||-1===ln.indexOf(t)&&\"x\"===e}function cn(t,e){return function(i,s){return i[t]===s[t]?i[e]-s[e]:i[t]-s[t]}}function dn(t){const e=t.chart,i=e.options.animation;e.notifyPlugins(\"afterRender\"),c(i&&i.onComplete,[t],e)}function un(t){const e=t.chart,i=e.options.animation;c(i&&i.onProgress,[t],e)}function fn(t){return oe()&&\"string\"==typeof t?t=document.getElementById(t):t&&t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas),t}const gn={},pn=t=>{const e=fn(t);return Object.values(gn).filter((t=>t.canvas===e)).pop()};function mn(t,e,i){const s=Object.keys(t);for(const n of s){const s=+n;if(s>=e){const o=t[n];delete t[n],(i>0||s>e)&&(t[s+i]=o)}}}class bn{constructor(t,i){const s=this.config=new on(i),n=fn(t),o=pn(n);if(o)throw new Error(\"Canvas is already in use. Chart with ID '\"+o.id+\"' must be destroyed before the canvas with ID '\"+o.canvas.id+\"' can be reused.\");const a=s.createResolver(s.chartOptionScopes(),this.getContext());this.platform=new(s.platform||gs(n)),this.platform.updateConfig(s);const r=this.platform.acquireContext(n,a.aspectRatio),l=r&&r.canvas,h=l&&l.height,c=l&&l.width;this.id=e(),this.ctx=r,this.canvas=l,this.width=c,this.height=h,this._options=a,this._aspectRatio=this.aspectRatio,this._layers=[],this._metasets=[],this._stacks=void 0,this.boxes=[],this.currentDevicePixelRatio=void 0,this.chartArea=void 0,this._active=[],this._lastEvent=void 0,this._listeners={},this._responsiveListeners=void 0,this._sortedMetasets=[],this.scales={},this._plugins=new Xs,this.$proxies={},this._hiddenIndices={},this.attached=!1,this._animationsDisabled=void 0,this.$context=void 0,this._doResize=ct((t=>this.update(t)),a.resizeDelay||0),this._dataChanges=[],gn[this.id]=this,r&&l?(mt.listen(this,\"complete\",dn),mt.listen(this,\"progress\",un),this._initialize(),this.attached&&this.update()):console.error(\"Failed to create chart: can't acquire context from the given item\")}get aspectRatio(){const{options:{aspectRatio:t,maintainAspectRatio:e},width:s,height:n,_aspectRatio:o}=this;return i(t)?e&&o?o:n?s/n:null:t}get data(){return this.config.data}set data(t){this.config.data=t}get options(){return this._options}set options(t){this.config.options=t}_initialize(){return this.notifyPlugins(\"beforeInit\"),this.options.responsive?this.resize():pe(this,this.options.devicePixelRatio),this.bindEvents(),this.notifyPlugins(\"afterInit\"),this}clear(){return we(this.canvas,this.ctx),this}stop(){return mt.stop(this),this}resize(t,e){mt.running(this)?this._resizeBeforeDraw={width:t,height:e}:this._resize(t,e)}_resize(t,e){const i=this.options,s=this.canvas,n=i.maintainAspectRatio&&this.aspectRatio,o=this.platform.getMaximumSize(s,t,e,n),a=i.devicePixelRatio||this.platform.getDevicePixelRatio(),r=this.width?\"resize\":\"attach\";this.width=o.width,this.height=o.height,this._aspectRatio=this.aspectRatio,pe(this,a,!0)&&(this.notifyPlugins(\"resize\",{size:o}),c(i.onResize,[this,o],this),this.attached&&this._doResize(r)&&this.render())}ensureScalesHaveIDs(){d(this.options.scales||{},((t,e)=>{t.id=e}))}buildOrUpdateScales(){const t=this.options,e=t.scales,i=this.scales,s=Object.keys(i).reduce(((t,e)=>(t[e]=!1,t)),{});let n=[];e&&(n=n.concat(Object.keys(e).map((t=>{const i=e[t],s=Zs(t,i),n=\"r\"===s,o=\"x\"===s;return{options:i,dposition:n?\"chartArea\":o?\"bottom\":\"left\",dtype:n?\"radialLinear\":o?\"category\":\"linear\"}})))),d(n,(e=>{const n=e.options,o=n.id,a=Zs(o,n),l=r(n.type,e.dtype);void 0!==n.position&&hn(n.position,a)===hn(e.dposition)||(n.position=e.dposition),s[o]=!0;let h=null;if(o in i&&i[o].type===l)h=i[o];else{h=new(Us.getScale(l))({id:o,type:l,ctx:this.ctx,chart:this}),i[h.id]=h}h.init(n,t)})),d(s,((t,e)=>{t||delete i[e]})),d(i,(t=>{Zi.configure(this,t,t.options),Zi.addBox(this,t)}))}_updateMetasets(){const t=this._metasets,e=this.data.datasets.length,i=t.length;if(t.sort(((t,e)=>t.index-e.index)),i>e){for(let t=e;t<i;++t)this._destroyDatasetMeta(t);t.splice(e,i-e)}this._sortedMetasets=t.slice(0).sort(cn(\"order\",\"index\"))}_removeUnreferencedMetasets(){const{_metasets:t,data:{datasets:e}}=this;t.length>e.length&&delete this._stacks,t.forEach(((t,i)=>{0===e.filter((e=>e===t._dataset)).length&&this._destroyDatasetMeta(i)}))}buildOrUpdateControllers(){const t=[],e=this.data.datasets;let i,s;for(this._removeUnreferencedMetasets(),i=0,s=e.length;i<s;i++){const s=e[i];let n=this.getDatasetMeta(i);const o=s.type||this.config.type;if(n.type&&n.type!==o&&(this._destroyDatasetMeta(i),n=this.getDatasetMeta(i)),n.type=o,n.indexAxis=s.indexAxis||Gs(o,this.options),n.order=s.order||0,n.index=i,n.label=\"\"+s.label,n.visible=this.isDatasetVisible(i),n.controller)n.controller.updateIndex(i),n.controller.linkScales();else{const e=Us.getController(o),{datasetElementType:s,dataElementType:a}=ne.datasets[o];Object.assign(e.prototype,{dataElementType:Us.getElement(a),datasetElementType:s&&Us.getElement(s)}),n.controller=new e(this,i),t.push(n.controller)}}return this._updateMetasets(),t}_resetElements(){d(this.data.datasets,((t,e)=>{this.getDatasetMeta(e).controller.reset()}),this)}reset(){this._resetElements(),this.notifyPlugins(\"reset\")}update(t){const e=this.config;e.update();const i=this._options=e.createResolver(e.chartOptionScopes(),this.getContext()),s=this._animationsDisabled=!i.animation;if(this._updateScales(),this._checkEventBindings(),this._updateHiddenIndices(),this._plugins.invalidate(),!1===this.notifyPlugins(\"beforeUpdate\",{mode:t,cancelable:!0}))return;const n=this.buildOrUpdateControllers();this.notifyPlugins(\"beforeElementsUpdate\");let o=0;for(let t=0,e=this.data.datasets.length;t<e;t++){const{controller:e}=this.getDatasetMeta(t),i=!s&&-1===n.indexOf(e);e.buildOrUpdateElements(i),o=Math.max(+e.getMaxOverflow(),o)}o=this._minPadding=i.layout.autoPadding?o:0,this._updateLayout(o),s||d(n,(t=>{t.reset()})),this._updateDatasets(t),this.notifyPlugins(\"afterUpdate\",{mode:t}),this._layers.sort(cn(\"z\",\"_idx\"));const{_active:a,_lastEvent:r}=this;r?this._eventHandler(r,!0):a.length&&this._updateHoverStyles(a,a,!0),this.render()}_updateScales(){d(this.scales,(t=>{Zi.removeBox(this,t)})),this.ensureScalesHaveIDs(),this.buildOrUpdateScales()}_checkEventBindings(){const t=this.options,e=new Set(Object.keys(this._listeners)),i=new Set(t.events);S(e,i)&&!!this._responsiveListeners===t.responsive||(this.unbindEvents(),this.bindEvents())}_updateHiddenIndices(){const{_hiddenIndices:t}=this,e=this._getUniformDataChanges()||[];for(const{method:i,start:s,count:n}of e){mn(t,s,\"_removeElements\"===i?-n:n)}}_getUniformDataChanges(){const t=this._dataChanges;if(!t||!t.length)return;this._dataChanges=[];const e=this.data.datasets.length,i=e=>new Set(t.filter((t=>t[0]===e)).map(((t,e)=>e+\",\"+t.splice(1).join(\",\")))),s=i(0);for(let t=1;t<e;t++)if(!S(s,i(t)))return;return Array.from(s).map((t=>t.split(\",\"))).map((t=>({method:t[1],start:+t[2],count:+t[3]})))}_updateLayout(t){if(!1===this.notifyPlugins(\"beforeLayout\",{cancelable:!0}))return;Zi.update(this,this.width,this.height,t);const e=this.chartArea,i=e.width<=0||e.height<=0;this._layers=[],d(this.boxes,(t=>{i&&\"chartArea\"===t.position||(t.configure&&t.configure(),this._layers.push(...t._layers()))}),this),this._layers.forEach(((t,e)=>{t._idx=e})),this.notifyPlugins(\"afterLayout\")}_updateDatasets(t){if(!1!==this.notifyPlugins(\"beforeDatasetsUpdate\",{mode:t,cancelable:!0})){for(let t=0,e=this.data.datasets.length;t<e;++t)this.getDatasetMeta(t).controller.configure();for(let e=0,i=this.data.datasets.length;e<i;++e)this._updateDataset(e,k(t)?t({datasetIndex:e}):t);this.notifyPlugins(\"afterDatasetsUpdate\",{mode:t})}}_updateDataset(t,e){const i=this.getDatasetMeta(t),s={meta:i,index:t,mode:e,cancelable:!0};!1!==this.notifyPlugins(\"beforeDatasetUpdate\",s)&&(i.controller._update(e),s.cancelable=!1,this.notifyPlugins(\"afterDatasetUpdate\",s))}render(){!1!==this.notifyPlugins(\"beforeRender\",{cancelable:!0})&&(mt.has(this)?this.attached&&!mt.running(this)&&mt.start(this):(this.draw(),dn({chart:this})))}draw(){let t;if(this._resizeBeforeDraw){const{width:t,height:e}=this._resizeBeforeDraw;this._resize(t,e),this._resizeBeforeDraw=null}if(this.clear(),this.width<=0||this.height<=0)return;if(!1===this.notifyPlugins(\"beforeDraw\",{cancelable:!0}))return;const e=this._layers;for(t=0;t<e.length&&e[t].z<=0;++t)e[t].draw(this.chartArea);for(this._drawDatasets();t<e.length;++t)e[t].draw(this.chartArea);this.notifyPlugins(\"afterDraw\")}_getSortedDatasetMetas(t){const e=this._sortedMetasets,i=[];let s,n;for(s=0,n=e.length;s<n;++s){const n=e[s];t&&!n.visible||i.push(n)}return i}getSortedVisibleDatasetMetas(){return this._getSortedDatasetMetas(!0)}_drawDatasets(){if(!1===this.notifyPlugins(\"beforeDatasetsDraw\",{cancelable:!0}))return;const t=this.getSortedVisibleDatasetMetas();for(let e=t.length-1;e>=0;--e)this._drawDataset(t[e]);this.notifyPlugins(\"afterDatasetsDraw\")}_drawDataset(t){const e=this.ctx,i=t._clip,s=!i.disabled,n=this.chartArea,o={meta:t,index:t.index,cancelable:!0};!1!==this.notifyPlugins(\"beforeDatasetDraw\",o)&&(s&&Pe(e,{left:!1===i.left?0:n.left-i.left,right:!1===i.right?this.width:n.right+i.right,top:!1===i.top?0:n.top-i.top,bottom:!1===i.bottom?this.height:n.bottom+i.bottom}),t.controller.draw(),s&&De(e),o.cancelable=!1,this.notifyPlugins(\"afterDatasetDraw\",o))}isPointInArea(t){return Se(t,this.chartArea,this._minPadding)}getElementsAtEventForMode(t,e,i,s){const n=Vi.modes[e];return\"function\"==typeof n?n(this,t,i,s):[]}getDatasetMeta(t){const e=this.data.datasets[t],i=this._metasets;let s=i.filter((t=>t&&t._dataset===e)).pop();return s||(s={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e&&e.order||0,index:t,_dataset:e,_parsed:[],_sorted:!1},i.push(s)),s}getContext(){return this.$context||(this.$context=_i(null,{chart:this,type:\"chart\"}))}getVisibleDatasetCount(){return this.getSortedVisibleDatasetMetas().length}isDatasetVisible(t){const e=this.data.datasets[t];if(!e)return!1;const i=this.getDatasetMeta(t);return\"boolean\"==typeof i.hidden?!i.hidden:!e.hidden}setDatasetVisibility(t,e){this.getDatasetMeta(t).hidden=!e}toggleDataVisibility(t){this._hiddenIndices[t]=!this._hiddenIndices[t]}getDataVisibility(t){return!this._hiddenIndices[t]}_updateVisibility(t,e,i){const s=i?\"show\":\"hide\",n=this.getDatasetMeta(t),o=n.controller._resolveAnimations(void 0,s);M(e)?(n.data[e].hidden=!i,this.update()):(this.setDatasetVisibility(t,i),o.update(n,{visible:i}),this.update((e=>e.datasetIndex===t?s:void 0)))}hide(t,e){this._updateVisibility(t,e,!1)}show(t,e){this._updateVisibility(t,e,!0)}_destroyDatasetMeta(t){const e=this._metasets[t];e&&e.controller&&e.controller._destroy(),delete this._metasets[t]}_stop(){let t,e;for(this.stop(),mt.remove(this),t=0,e=this.data.datasets.length;t<e;++t)this._destroyDatasetMeta(t)}destroy(){this.notifyPlugins(\"beforeDestroy\");const{canvas:t,ctx:e}=this;this._stop(),this.config.clearCache(),t&&(this.unbindEvents(),we(t,e),this.platform.releaseContext(e),this.canvas=null,this.ctx=null),this.notifyPlugins(\"destroy\"),delete gn[this.id],this.notifyPlugins(\"afterDestroy\")}toBase64Image(...t){return this.canvas.toDataURL(...t)}bindEvents(){this.bindUserEvents(),this.options.responsive?this.bindResponsiveEvents():this.attached=!0}bindUserEvents(){const t=this._listeners,e=this.platform,i=(i,s)=>{e.addEventListener(this,i,s),t[i]=s},s=(t,e,i)=>{t.offsetX=e,t.offsetY=i,this._eventHandler(t)};d(this.options.events,(t=>i(t,s)))}bindResponsiveEvents(){this._responsiveListeners||(this._responsiveListeners={});const t=this._responsiveListeners,e=this.platform,i=(i,s)=>{e.addEventListener(this,i,s),t[i]=s},s=(i,s)=>{t[i]&&(e.removeEventListener(this,i,s),delete t[i])},n=(t,e)=>{this.canvas&&this.resize(t,e)};let o;const a=()=>{s(\"attach\",a),this.attached=!0,this.resize(),i(\"resize\",n),i(\"detach\",o)};o=()=>{this.attached=!1,s(\"resize\",n),this._stop(),this._resize(0,0),i(\"attach\",a)},e.isAttached(this.canvas)?a():o()}unbindEvents(){d(this._listeners,((t,e)=>{this.platform.removeEventListener(this,e,t)})),this._listeners={},d(this._responsiveListeners,((t,e)=>{this.platform.removeEventListener(this,e,t)})),this._responsiveListeners=void 0}updateHoverStyle(t,e,i){const s=i?\"set\":\"remove\";let n,o,a,r;for(\"dataset\"===e&&(n=this.getDatasetMeta(t[0].datasetIndex),n.controller[\"_\"+s+\"DatasetHoverStyle\"]()),a=0,r=t.length;a<r;++a){o=t[a];const e=o&&this.getDatasetMeta(o.datasetIndex).controller;e&&e[s+\"HoverStyle\"](o.element,o.datasetIndex,o.index)}}getActiveElements(){return this._active||[]}setActiveElements(t){const e=this._active||[],i=t.map((({datasetIndex:t,index:e})=>{const i=this.getDatasetMeta(t);if(!i)throw new Error(\"No dataset found at index \"+t);return{datasetIndex:t,element:i.data[e],index:e}}));!u(i,e)&&(this._active=i,this._lastEvent=null,this._updateHoverStyles(i,e))}notifyPlugins(t,e,i){return this._plugins.notify(this,t,e,i)}_updateHoverStyles(t,e,i){const s=this.options.hover,n=(t,e)=>t.filter((t=>!e.some((e=>t.datasetIndex===e.datasetIndex&&t.index===e.index)))),o=n(e,t),a=i?t:n(t,e);o.length&&this.updateHoverStyle(o,s.mode,!1),a.length&&s.mode&&this.updateHoverStyle(a,s.mode,!0)}_eventHandler(t,e){const i={event:t,replay:e,cancelable:!0,inChartArea:this.isPointInArea(t)},s=e=>(e.options.events||this.options.events).includes(t.native.type);if(!1===this.notifyPlugins(\"beforeEvent\",i,s))return;const n=this._handleEvent(t,e,i.inChartArea);return i.cancelable=!1,this.notifyPlugins(\"afterEvent\",i,s),(n||i.changed)&&this.render(),this}_handleEvent(t,e,i){const{_active:s=[],options:n}=this,o=e,a=this._getActiveElements(t,s,i,o),r=P(t),l=function(t,e,i,s){return i&&\"mouseout\"!==t.type?s?e:t:null}(t,this._lastEvent,i,r);i&&(this._lastEvent=null,c(n.onHover,[t,a,this],this),r&&c(n.onClick,[t,a,this],this));const h=!u(a,s);return(h||e)&&(this._active=a,this._updateHoverStyles(a,s,e)),this._lastEvent=l,h}_getActiveElements(t,e,i,s){if(\"mouseout\"===t.type)return[];if(!i)return e;const n=this.options.hover;return this.getElementsAtEventForMode(t,n.mode,n,s)}}const xn=()=>d(bn.instances,(t=>t._plugins.invalidate())),_n=!0;function yn(){throw new Error(\"This method is not implemented: Check that a complete date adapter is provided.\")}Object.defineProperties(bn,{defaults:{enumerable:_n,value:ne},instances:{enumerable:_n,value:gn},overrides:{enumerable:_n,value:te},registry:{enumerable:_n,value:Us},version:{enumerable:_n,value:\"3.9.1\"},getChart:{enumerable:_n,value:pn},register:{enumerable:_n,value:(...t)=>{Us.add(...t),xn()}},unregister:{enumerable:_n,value:(...t)=>{Us.remove(...t),xn()}}});class vn{constructor(t){this.options=t||{}}init(t){}formats(){return yn()}parse(t,e){return yn()}format(t,e){return yn()}add(t,e,i){return yn()}diff(t,e,i){return yn()}startOf(t,e,i){return yn()}endOf(t,e){return yn()}}vn.override=function(t){Object.assign(vn.prototype,t)};var wn={_date:vn};function Mn(t){const e=t.iScale,i=function(t,e){if(!t._cache.$bar){const i=t.getMatchingVisibleMetas(e);let s=[];for(let e=0,n=i.length;e<n;e++)s=s.concat(i[e].controller.getAllParsedValues(t));t._cache.$bar=rt(s.sort(((t,e)=>t-e)))}return t._cache.$bar}(e,t.type);let s,n,o,a,r=e._length;const l=()=>{32767!==o&&-32768!==o&&(M(a)&&(r=Math.min(r,Math.abs(o-a)||r)),a=o)};for(s=0,n=i.length;s<n;++s)o=e.getPixelForValue(i[s]),l();for(a=void 0,s=0,n=e.ticks.length;s<n;++s)o=e.getPixelForTick(s),l();return r}function kn(t,e,i,n){return s(t)?function(t,e,i,s){const n=i.parse(t[0],s),o=i.parse(t[1],s),a=Math.min(n,o),r=Math.max(n,o);let l=a,h=r;Math.abs(a)>Math.abs(r)&&(l=r,h=a),e[i.axis]=h,e._custom={barStart:l,barEnd:h,start:n,end:o,min:a,max:r}}(t,e,i,n):e[i.axis]=i.parse(t,n),e}function Sn(t,e,i,s){const n=t.iScale,o=t.vScale,a=n.getLabels(),r=n===o,l=[];let h,c,d,u;for(h=i,c=i+s;h<c;++h)u=e[h],d={},d[n.axis]=r||n.parse(a[h],h),l.push(kn(u,d,o,h));return l}function Pn(t){return t&&void 0!==t.barStart&&void 0!==t.barEnd}function Dn(t,e,i,s){let n=e.borderSkipped;const o={};if(!n)return void(t.borderSkipped=o);if(!0===n)return void(t.borderSkipped={top:!0,right:!0,bottom:!0,left:!0});const{start:a,end:r,reverse:l,top:h,bottom:c}=function(t){let e,i,s,n,o;return t.horizontal?(e=t.base>t.x,i=\"left\",s=\"right\"):(e=t.base<t.y,i=\"bottom\",s=\"top\"),e?(n=\"end\",o=\"start\"):(n=\"start\",o=\"end\"),{start:i,end:s,reverse:e,top:n,bottom:o}}(t);\"middle\"===n&&i&&(t.enableBorderRadius=!0,(i._top||0)===s?n=h:(i._bottom||0)===s?n=c:(o[On(c,a,r,l)]=!0,n=h)),o[On(n,a,r,l)]=!0,t.borderSkipped=o}function On(t,e,i,s){var n,o,a;return s?(a=i,t=Cn(t=(n=t)===(o=e)?a:n===a?o:n,i,e)):t=Cn(t,e,i),t}function Cn(t,e,i){return\"start\"===t?e:\"end\"===t?i:t}function An(t,{inflateAmount:e},i){t.inflateAmount=\"auto\"===e?1===i?.33:0:e}class Tn extends Ls{parsePrimitiveData(t,e,i,s){return Sn(t,e,i,s)}parseArrayData(t,e,i,s){return Sn(t,e,i,s)}parseObjectData(t,e,i,s){const{iScale:n,vScale:o}=t,{xAxisKey:a=\"x\",yAxisKey:r=\"y\"}=this._parsing,l=\"x\"===n.axis?a:r,h=\"x\"===o.axis?a:r,c=[];let d,u,f,g;for(d=i,u=i+s;d<u;++d)g=e[d],f={},f[n.axis]=n.parse(y(g,l),d),c.push(kn(y(g,h),f,o,d));return c}updateRangeFromParsed(t,e,i,s){super.updateRangeFromParsed(t,e,i,s);const n=i._custom;n&&e===this._cachedMeta.vScale&&(t.min=Math.min(t.min,n.min),t.max=Math.max(t.max,n.max))}getMaxOverflow(){return 0}getLabelAndValue(t){const e=this._cachedMeta,{iScale:i,vScale:s}=e,n=this.getParsed(t),o=n._custom,a=Pn(o)?\"[\"+o.start+\", \"+o.end+\"]\":\"\"+s.getLabelForValue(n[s.axis]);return{label:\"\"+i.getLabelForValue(n[i.axis]),value:a}}initialize(){this.enableOptionSharing=!0,super.initialize();this._cachedMeta.stack=this.getDataset().stack}update(t){const e=this._cachedMeta;this.updateElements(e.data,0,e.data.length,t)}updateElements(t,e,s,n){const o=\"reset\"===n,{index:a,_cachedMeta:{vScale:r}}=this,l=r.getBasePixel(),h=r.isHorizontal(),c=this._getRuler(),{sharedOptions:d,includeOptions:u}=this._getSharedOptions(e,n);for(let f=e;f<e+s;f++){const e=this.getParsed(f),s=o||i(e[r.axis])?{base:l,head:l}:this._calculateBarValuePixels(f),g=this._calculateBarIndexPixels(f,c),p=(e._stacks||{})[r.axis],m={horizontal:h,base:s.base,enableBorderRadius:!p||Pn(e._custom)||a===p._top||a===p._bottom,x:h?s.head:g.center,y:h?g.center:s.head,height:h?g.size:Math.abs(s.size),width:h?Math.abs(s.size):g.size};u&&(m.options=d||this.resolveDataElementOptions(f,t[f].active?\"active\":n));const b=m.options||t[f].options;Dn(m,b,p,a),An(m,b,c.ratio),this.updateElement(t[f],f,m,n)}}_getStacks(t,e){const{iScale:s}=this._cachedMeta,n=s.getMatchingVisibleMetas(this._type).filter((t=>t.controller.options.grouped)),o=s.options.stacked,a=[],r=t=>{const s=t.controller.getParsed(e),n=s&&s[t.vScale.axis];if(i(n)||isNaN(n))return!0};for(const i of n)if((void 0===e||!r(i))&&((!1===o||-1===a.indexOf(i.stack)||void 0===o&&void 0===i.stack)&&a.push(i.stack),i.index===t))break;return a.length||a.push(void 0),a}_getStackCount(t){return this._getStacks(void 0,t).length}_getStackIndex(t,e,i){const s=this._getStacks(t,i),n=void 0!==e?s.indexOf(e):-1;return-1===n?s.length-1:n}_getRuler(){const t=this.options,e=this._cachedMeta,i=e.iScale,s=[];let n,o;for(n=0,o=e.data.length;n<o;++n)s.push(i.getPixelForValue(this.getParsed(n)[i.axis],n));const a=t.barThickness;return{min:a||Mn(e),pixels:s,start:i._startPixel,end:i._endPixel,stackCount:this._getStackCount(),scale:i,grouped:t.grouped,ratio:a?1:t.categoryPercentage*t.barPercentage}}_calculateBarValuePixels(t){const{_cachedMeta:{vScale:e,_stacked:s},options:{base:n,minBarLength:o}}=this,a=n||0,r=this.getParsed(t),l=r._custom,h=Pn(l);let c,d,u=r[e.axis],f=0,g=s?this.applyStack(e,r,s):u;g!==u&&(f=g-u,g=u),h&&(u=l.barStart,g=l.barEnd-l.barStart,0!==u&&z(u)!==z(l.barEnd)&&(f=0),f+=u);const p=i(n)||h?f:n;let m=e.getPixelForValue(p);if(c=this.chart.getDataVisibility(t)?e.getPixelForValue(f+g):m,d=c-m,Math.abs(d)<o){d=function(t,e,i){return 0!==t?z(t):(e.isHorizontal()?1:-1)*(e.min>=i?1:-1)}(d,e,a)*o,u===a&&(m-=d/2);const t=e.getPixelForDecimal(0),i=e.getPixelForDecimal(1),s=Math.min(t,i),n=Math.max(t,i);m=Math.max(Math.min(m,n),s),c=m+d}if(m===e.getPixelForValue(a)){const t=z(d)*e.getLineWidthForValue(a)/2;m+=t,d-=t}return{size:d,base:m,head:c,center:c+d/2}}_calculateBarIndexPixels(t,e){const s=e.scale,n=this.options,o=n.skipNull,a=r(n.maxBarThickness,1/0);let l,h;if(e.grouped){const s=o?this._getStackCount(t):e.stackCount,r=\"flex\"===n.barThickness?function(t,e,i,s){const n=e.pixels,o=n[t];let a=t>0?n[t-1]:null,r=t<n.length-1?n[t+1]:null;const l=i.categoryPercentage;null===a&&(a=o-(null===r?e.end-e.start:r-o)),null===r&&(r=o+o-a);const h=o-(o-Math.min(a,r))/2*l;return{chunk:Math.abs(r-a)/2*l/s,ratio:i.barPercentage,start:h}}(t,e,n,s):function(t,e,s,n){const o=s.barThickness;let a,r;return i(o)?(a=e.min*s.categoryPercentage,r=s.barPercentage):(a=o*n,r=1),{chunk:a/n,ratio:r,start:e.pixels[t]-a/2}}(t,e,n,s),c=this._getStackIndex(this.index,this._cachedMeta.stack,o?t:void 0);l=r.start+r.chunk*c+r.chunk/2,h=Math.min(a,r.chunk*r.ratio)}else l=s.getPixelForValue(this.getParsed(t)[s.axis],t),h=Math.min(a,e.min*e.ratio);return{base:l-h/2,head:l+h/2,center:l,size:h}}draw(){const t=this._cachedMeta,e=t.vScale,i=t.data,s=i.length;let n=0;for(;n<s;++n)null!==this.getParsed(n)[e.axis]&&i[n].draw(this._ctx)}}Tn.id=\"bar\",Tn.defaults={datasetElementType:!1,dataElementType:\"bar\",categoryPercentage:.8,barPercentage:.9,grouped:!0,animations:{numbers:{type:\"number\",properties:[\"x\",\"y\",\"base\",\"width\",\"height\"]}}},Tn.overrides={scales:{_index_:{type:\"category\",offset:!0,grid:{offset:!0}},_value_:{type:\"linear\",beginAtZero:!0}}};class Ln extends Ls{initialize(){this.enableOptionSharing=!0,super.initialize()}parsePrimitiveData(t,e,i,s){const n=super.parsePrimitiveData(t,e,i,s);for(let t=0;t<n.length;t++)n[t]._custom=this.resolveDataElementOptions(t+i).radius;return n}parseArrayData(t,e,i,s){const n=super.parseArrayData(t,e,i,s);for(let t=0;t<n.length;t++){const s=e[i+t];n[t]._custom=r(s[2],this.resolveDataElementOptions(t+i).radius)}return n}parseObjectData(t,e,i,s){const n=super.parseObjectData(t,e,i,s);for(let t=0;t<n.length;t++){const s=e[i+t];n[t]._custom=r(s&&s.r&&+s.r,this.resolveDataElementOptions(t+i).radius)}return n}getMaxOverflow(){const t=this._cachedMeta.data;let e=0;for(let i=t.length-1;i>=0;--i)e=Math.max(e,t[i].size(this.resolveDataElementOptions(i))/2);return e>0&&e}getLabelAndValue(t){const e=this._cachedMeta,{xScale:i,yScale:s}=e,n=this.getParsed(t),o=i.getLabelForValue(n.x),a=s.getLabelForValue(n.y),r=n._custom;return{label:e.label,value:\"(\"+o+\", \"+a+(r?\", \"+r:\"\")+\")\"}}update(t){const e=this._cachedMeta.data;this.updateElements(e,0,e.length,t)}updateElements(t,e,i,s){const n=\"reset\"===s,{iScale:o,vScale:a}=this._cachedMeta,{sharedOptions:r,includeOptions:l}=this._getSharedOptions(e,s),h=o.axis,c=a.axis;for(let d=e;d<e+i;d++){const e=t[d],i=!n&&this.getParsed(d),u={},f=u[h]=n?o.getPixelForDecimal(.5):o.getPixelForValue(i[h]),g=u[c]=n?a.getBasePixel():a.getPixelForValue(i[c]);u.skip=isNaN(f)||isNaN(g),l&&(u.options=r||this.resolveDataElementOptions(d,e.active?\"active\":s),n&&(u.options.radius=0)),this.updateElement(e,d,u,s)}}resolveDataElementOptions(t,e){const i=this.getParsed(t);let s=super.resolveDataElementOptions(t,e);s.$shared&&(s=Object.assign({},s,{$shared:!1}));const n=s.radius;return\"active\"!==e&&(s.radius=0),s.radius+=r(i&&i._custom,n),s}}Ln.id=\"bubble\",Ln.defaults={datasetElementType:!1,dataElementType:\"point\",animations:{numbers:{type:\"number\",properties:[\"x\",\"y\",\"borderWidth\",\"radius\"]}}},Ln.overrides={scales:{x:{type:\"linear\"},y:{type:\"linear\"}},plugins:{tooltip:{callbacks:{title:()=>\"\"}}}};class En extends Ls{constructor(t,e){super(t,e),this.enableOptionSharing=!0,this.innerRadius=void 0,this.outerRadius=void 0,this.offsetX=void 0,this.offsetY=void 0}linkScales(){}parse(t,e){const i=this.getDataset().data,s=this._cachedMeta;if(!1===this._parsing)s._parsed=i;else{let o,a,r=t=>+i[t];if(n(i[t])){const{key:t=\"value\"}=this._parsing;r=e=>+y(i[e],t)}for(o=t,a=t+e;o<a;++o)s._parsed[o]=r(o)}}_getRotation(){return H(this.options.rotation-90)}_getCircumference(){return H(this.options.circumference)}_getRotationExtents(){let t=O,e=-O;for(let i=0;i<this.chart.data.datasets.length;++i)if(this.chart.isDatasetVisible(i)){const s=this.chart.getDatasetMeta(i).controller,n=s._getRotation(),o=s._getCircumference();t=Math.min(t,n),e=Math.max(e,n+o)}return{rotation:t,circumference:e-t}}update(t){const e=this.chart,{chartArea:i}=e,s=this._cachedMeta,n=s.data,o=this.getMaxBorderWidth()+this.getMaxOffset(n)+this.options.spacing,a=Math.max((Math.min(i.width,i.height)-o)/2,0),r=Math.min(l(this.options.cutout,a),1),c=this._getRingWeight(this.index),{circumference:d,rotation:u}=this._getRotationExtents(),{ratioX:f,ratioY:g,offsetX:p,offsetY:m}=function(t,e,i){let s=1,n=1,o=0,a=0;if(e<O){const r=t,l=r+e,h=Math.cos(r),c=Math.sin(r),d=Math.cos(l),u=Math.sin(l),f=(t,e,s)=>G(t,r,l,!0)?1:Math.max(e,e*i,s,s*i),g=(t,e,s)=>G(t,r,l,!0)?-1:Math.min(e,e*i,s,s*i),p=f(0,h,d),m=f(L,c,u),b=g(D,h,d),x=g(D+L,c,u);s=(p-b)/2,n=(m-x)/2,o=-(p+b)/2,a=-(m+x)/2}return{ratioX:s,ratioY:n,offsetX:o,offsetY:a}}(u,d,r),b=(i.width-o)/f,x=(i.height-o)/g,_=Math.max(Math.min(b,x)/2,0),y=h(this.options.radius,_),v=(y-Math.max(y*r,0))/this._getVisibleDatasetWeightTotal();this.offsetX=p*y,this.offsetY=m*y,s.total=this.calculateTotal(),this.outerRadius=y-v*this._getRingWeightOffset(this.index),this.innerRadius=Math.max(this.outerRadius-v*c,0),this.updateElements(n,0,n.length,t)}_circumference(t,e){const i=this.options,s=this._cachedMeta,n=this._getCircumference();return e&&i.animation.animateRotate||!this.chart.getDataVisibility(t)||null===s._parsed[t]||s.data[t].hidden?0:this.calculateCircumference(s._parsed[t]*n/O)}updateElements(t,e,i,s){const n=\"reset\"===s,o=this.chart,a=o.chartArea,r=o.options.animation,l=(a.left+a.right)/2,h=(a.top+a.bottom)/2,c=n&&r.animateScale,d=c?0:this.innerRadius,u=c?0:this.outerRadius,{sharedOptions:f,includeOptions:g}=this._getSharedOptions(e,s);let p,m=this._getRotation();for(p=0;p<e;++p)m+=this._circumference(p,n);for(p=e;p<e+i;++p){const e=this._circumference(p,n),i=t[p],o={x:l+this.offsetX,y:h+this.offsetY,startAngle:m,endAngle:m+e,circumference:e,outerRadius:u,innerRadius:d};g&&(o.options=f||this.resolveDataElementOptions(p,i.active?\"active\":s)),m+=e,this.updateElement(i,p,o,s)}}calculateTotal(){const t=this._cachedMeta,e=t.data;let i,s=0;for(i=0;i<e.length;i++){const n=t._parsed[i];null===n||isNaN(n)||!this.chart.getDataVisibility(i)||e[i].hidden||(s+=Math.abs(n))}return s}calculateCircumference(t){const e=this._cachedMeta.total;return e>0&&!isNaN(t)?O*(Math.abs(t)/e):0}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart,s=i.data.labels||[],n=li(e._parsed[t],i.options.locale);return{label:s[t]||\"\",value:n}}getMaxBorderWidth(t){let e=0;const i=this.chart;let s,n,o,a,r;if(!t)for(s=0,n=i.data.datasets.length;s<n;++s)if(i.isDatasetVisible(s)){o=i.getDatasetMeta(s),t=o.data,a=o.controller;break}if(!t)return 0;for(s=0,n=t.length;s<n;++s)r=a.resolveDataElementOptions(s),\"inner\"!==r.borderAlign&&(e=Math.max(e,r.borderWidth||0,r.hoverBorderWidth||0));return e}getMaxOffset(t){let e=0;for(let i=0,s=t.length;i<s;++i){const t=this.resolveDataElementOptions(i);e=Math.max(e,t.offset||0,t.hoverOffset||0)}return e}_getRingWeightOffset(t){let e=0;for(let i=0;i<t;++i)this.chart.isDatasetVisible(i)&&(e+=this._getRingWeight(i));return e}_getRingWeight(t){return Math.max(r(this.chart.data.datasets[t].weight,1),0)}_getVisibleDatasetWeightTotal(){return this._getRingWeightOffset(this.chart.data.datasets.length)||1}}En.id=\"doughnut\",En.defaults={datasetElementType:!1,dataElementType:\"arc\",animation:{animateRotate:!0,animateScale:!1},animations:{numbers:{type:\"number\",properties:[\"circumference\",\"endAngle\",\"innerRadius\",\"outerRadius\",\"startAngle\",\"x\",\"y\",\"offset\",\"borderWidth\",\"spacing\"]}},cutout:\"50%\",rotation:0,circumference:360,radius:\"100%\",spacing:0,indexAxis:\"r\"},En.descriptors={_scriptable:t=>\"spacing\"!==t,_indexable:t=>\"spacing\"!==t},En.overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){const e=t.data;if(e.labels.length&&e.datasets.length){const{labels:{pointStyle:i}}=t.legend.options;return e.labels.map(((e,s)=>{const n=t.getDatasetMeta(0).controller.getStyle(s);return{text:e,fillStyle:n.backgroundColor,strokeStyle:n.borderColor,lineWidth:n.borderWidth,pointStyle:i,hidden:!t.getDataVisibility(s),index:s}}))}return[]}},onClick(t,e,i){i.chart.toggleDataVisibility(e.index),i.chart.update()}},tooltip:{callbacks:{title:()=>\"\",label(t){let e=t.label;const i=\": \"+t.formattedValue;return s(e)?(e=e.slice(),e[0]+=i):e+=i,e}}}}};class Rn extends Ls{initialize(){this.enableOptionSharing=!0,this.supportsDecimation=!0,super.initialize()}update(t){const e=this._cachedMeta,{dataset:i,data:s=[],_dataset:n}=e,o=this.chart._animationsDisabled;let{start:a,count:r}=gt(e,s,o);this._drawStart=a,this._drawCount=r,pt(e)&&(a=0,r=s.length),i._chart=this.chart,i._datasetIndex=this.index,i._decimated=!!n._decimated,i.points=s;const l=this.resolveDatasetElementOptions(t);this.options.showLine||(l.borderWidth=0),l.segment=this.options.segment,this.updateElement(i,void 0,{animated:!o,options:l},t),this.updateElements(s,a,r,t)}updateElements(t,e,s,n){const o=\"reset\"===n,{iScale:a,vScale:r,_stacked:l,_dataset:h}=this._cachedMeta,{sharedOptions:c,includeOptions:d}=this._getSharedOptions(e,n),u=a.axis,f=r.axis,{spanGaps:g,segment:p}=this.options,m=B(g)?g:Number.POSITIVE_INFINITY,b=this.chart._animationsDisabled||o||\"none\"===n;let x=e>0&&this.getParsed(e-1);for(let g=e;g<e+s;++g){const e=t[g],s=this.getParsed(g),_=b?e:{},y=i(s[f]),v=_[u]=a.getPixelForValue(s[u],g),w=_[f]=o||y?r.getBasePixel():r.getPixelForValue(l?this.applyStack(r,s,l):s[f],g);_.skip=isNaN(v)||isNaN(w)||y,_.stop=g>0&&Math.abs(s[u]-x[u])>m,p&&(_.parsed=s,_.raw=h.data[g]),d&&(_.options=c||this.resolveDataElementOptions(g,e.active?\"active\":n)),b||this.updateElement(e,g,_,n),x=s}}getMaxOverflow(){const t=this._cachedMeta,e=t.dataset,i=e.options&&e.options.borderWidth||0,s=t.data||[];if(!s.length)return i;const n=s[0].size(this.resolveDataElementOptions(0)),o=s[s.length-1].size(this.resolveDataElementOptions(s.length-1));return Math.max(i,n,o)/2}draw(){const t=this._cachedMeta;t.dataset.updateControlPoints(this.chart.chartArea,t.iScale.axis),super.draw()}}Rn.id=\"line\",Rn.defaults={datasetElementType:\"line\",dataElementType:\"point\",showLine:!0,spanGaps:!1},Rn.overrides={scales:{_index_:{type:\"category\"},_value_:{type:\"linear\"}}};class In extends Ls{constructor(t,e){super(t,e),this.innerRadius=void 0,this.outerRadius=void 0}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart,s=i.data.labels||[],n=li(e._parsed[t].r,i.options.locale);return{label:s[t]||\"\",value:n}}parseObjectData(t,e,i,s){return Ue.bind(this)(t,e,i,s)}update(t){const e=this._cachedMeta.data;this._updateRadius(),this.updateElements(e,0,e.length,t)}getMinMax(){const t=this._cachedMeta,e={min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY};return t.data.forEach(((t,i)=>{const s=this.getParsed(i).r;!isNaN(s)&&this.chart.getDataVisibility(i)&&(s<e.min&&(e.min=s),s>e.max&&(e.max=s))})),e}_updateRadius(){const t=this.chart,e=t.chartArea,i=t.options,s=Math.min(e.right-e.left,e.bottom-e.top),n=Math.max(s/2,0),o=(n-Math.max(i.cutoutPercentage?n/100*i.cutoutPercentage:1,0))/t.getVisibleDatasetCount();this.outerRadius=n-o*this.index,this.innerRadius=this.outerRadius-o}updateElements(t,e,i,s){const n=\"reset\"===s,o=this.chart,a=o.options.animation,r=this._cachedMeta.rScale,l=r.xCenter,h=r.yCenter,c=r.getIndexAngle(0)-.5*D;let d,u=c;const f=360/this.countVisibleElements();for(d=0;d<e;++d)u+=this._computeAngle(d,s,f);for(d=e;d<e+i;d++){const e=t[d];let i=u,g=u+this._computeAngle(d,s,f),p=o.getDataVisibility(d)?r.getDistanceFromCenterForValue(this.getParsed(d).r):0;u=g,n&&(a.animateScale&&(p=0),a.animateRotate&&(i=g=c));const m={x:l,y:h,innerRadius:0,outerRadius:p,startAngle:i,endAngle:g,options:this.resolveDataElementOptions(d,e.active?\"active\":s)};this.updateElement(e,d,m,s)}}countVisibleElements(){const t=this._cachedMeta;let e=0;return t.data.forEach(((t,i)=>{!isNaN(this.getParsed(i).r)&&this.chart.getDataVisibility(i)&&e++})),e}_computeAngle(t,e,i){return this.chart.getDataVisibility(t)?H(this.resolveDataElementOptions(t,e).angle||i):0}}In.id=\"polarArea\",In.defaults={dataElementType:\"arc\",animation:{animateRotate:!0,animateScale:!0},animations:{numbers:{type:\"number\",properties:[\"x\",\"y\",\"startAngle\",\"endAngle\",\"innerRadius\",\"outerRadius\"]}},indexAxis:\"r\",startAngle:0},In.overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){const e=t.data;if(e.labels.length&&e.datasets.length){const{labels:{pointStyle:i}}=t.legend.options;return e.labels.map(((e,s)=>{const n=t.getDatasetMeta(0).controller.getStyle(s);return{text:e,fillStyle:n.backgroundColor,strokeStyle:n.borderColor,lineWidth:n.borderWidth,pointStyle:i,hidden:!t.getDataVisibility(s),index:s}}))}return[]}},onClick(t,e,i){i.chart.toggleDataVisibility(e.index),i.chart.update()}},tooltip:{callbacks:{title:()=>\"\",label:t=>t.chart.data.labels[t.dataIndex]+\": \"+t.formattedValue}}},scales:{r:{type:\"radialLinear\",angleLines:{display:!1},beginAtZero:!0,grid:{circular:!0},pointLabels:{display:!1},startAngle:0}}};class zn extends En{}zn.id=\"pie\",zn.defaults={cutout:0,rotation:0,circumference:360,radius:\"100%\"};class Fn extends Ls{getLabelAndValue(t){const e=this._cachedMeta.vScale,i=this.getParsed(t);return{label:e.getLabels()[t],value:\"\"+e.getLabelForValue(i[e.axis])}}parseObjectData(t,e,i,s){return Ue.bind(this)(t,e,i,s)}update(t){const e=this._cachedMeta,i=e.dataset,s=e.data||[],n=e.iScale.getLabels();if(i.points=s,\"resize\"!==t){const e=this.resolveDatasetElementOptions(t);this.options.showLine||(e.borderWidth=0);const o={_loop:!0,_fullLoop:n.length===s.length,options:e};this.updateElement(i,void 0,o,t)}this.updateElements(s,0,s.length,t)}updateElements(t,e,i,s){const n=this._cachedMeta.rScale,o=\"reset\"===s;for(let a=e;a<e+i;a++){const e=t[a],i=this.resolveDataElementOptions(a,e.active?\"active\":s),r=n.getPointPositionForValue(a,this.getParsed(a).r),l=o?n.xCenter:r.x,h=o?n.yCenter:r.y,c={x:l,y:h,angle:r.angle,skip:isNaN(l)||isNaN(h),options:i};this.updateElement(e,a,c,s)}}}Fn.id=\"radar\",Fn.defaults={datasetElementType:\"line\",dataElementType:\"point\",indexAxis:\"r\",showLine:!0,elements:{line:{fill:\"start\"}}},Fn.overrides={aspectRatio:1,scales:{r:{type:\"radialLinear\"}}};class Vn extends Ls{update(t){const e=this._cachedMeta,{data:i=[]}=e,s=this.chart._animationsDisabled;let{start:n,count:o}=gt(e,i,s);if(this._drawStart=n,this._drawCount=o,pt(e)&&(n=0,o=i.length),this.options.showLine){const{dataset:n,_dataset:o}=e;n._chart=this.chart,n._datasetIndex=this.index,n._decimated=!!o._decimated,n.points=i;const a=this.resolveDatasetElementOptions(t);a.segment=this.options.segment,this.updateElement(n,void 0,{animated:!s,options:a},t)}this.updateElements(i,n,o,t)}addElements(){const{showLine:t}=this.options;!this.datasetElementType&&t&&(this.datasetElementType=Us.getElement(\"line\")),super.addElements()}updateElements(t,e,s,n){const o=\"reset\"===n,{iScale:a,vScale:r,_stacked:l,_dataset:h}=this._cachedMeta,c=this.resolveDataElementOptions(e,n),d=this.getSharedOptions(c),u=this.includeOptions(n,d),f=a.axis,g=r.axis,{spanGaps:p,segment:m}=this.options,b=B(p)?p:Number.POSITIVE_INFINITY,x=this.chart._animationsDisabled||o||\"none\"===n;let _=e>0&&this.getParsed(e-1);for(let c=e;c<e+s;++c){const e=t[c],s=this.getParsed(c),p=x?e:{},y=i(s[g]),v=p[f]=a.getPixelForValue(s[f],c),w=p[g]=o||y?r.getBasePixel():r.getPixelForValue(l?this.applyStack(r,s,l):s[g],c);p.skip=isNaN(v)||isNaN(w)||y,p.stop=c>0&&Math.abs(s[f]-_[f])>b,m&&(p.parsed=s,p.raw=h.data[c]),u&&(p.options=d||this.resolveDataElementOptions(c,e.active?\"active\":n)),x||this.updateElement(e,c,p,n),_=s}this.updateSharedOptions(d,n,c)}getMaxOverflow(){const t=this._cachedMeta,e=t.data||[];if(!this.options.showLine){let t=0;for(let i=e.length-1;i>=0;--i)t=Math.max(t,e[i].size(this.resolveDataElementOptions(i))/2);return t>0&&t}const i=t.dataset,s=i.options&&i.options.borderWidth||0;if(!e.length)return s;const n=e[0].size(this.resolveDataElementOptions(0)),o=e[e.length-1].size(this.resolveDataElementOptions(e.length-1));return Math.max(s,n,o)/2}}Vn.id=\"scatter\",Vn.defaults={datasetElementType:!1,dataElementType:\"point\",showLine:!1,fill:!1},Vn.overrides={interaction:{mode:\"point\"},plugins:{tooltip:{callbacks:{title:()=>\"\",label:t=>\"(\"+t.label+\", \"+t.formattedValue+\")\"}}},scales:{x:{type:\"linear\"},y:{type:\"linear\"}}};var Bn=Object.freeze({__proto__:null,BarController:Tn,BubbleController:Ln,DoughnutController:En,LineController:Rn,PolarAreaController:In,PieController:zn,RadarController:Fn,ScatterController:Vn});function Nn(t,e,i){const{startAngle:s,pixelMargin:n,x:o,y:a,outerRadius:r,innerRadius:l}=e;let h=n/r;t.beginPath(),t.arc(o,a,r,s-h,i+h),l>n?(h=n/l,t.arc(o,a,l,i+h,s-h,!0)):t.arc(o,a,n,i+L,s-L),t.closePath(),t.clip()}function Wn(t,e,i,s){const n=ui(t.options.borderRadius,[\"outerStart\",\"outerEnd\",\"innerStart\",\"innerEnd\"]);const o=(i-e)/2,a=Math.min(o,s*e/2),r=t=>{const e=(i-Math.min(o,t))*s/2;return Z(t,0,Math.min(o,e))};return{outerStart:r(n.outerStart),outerEnd:r(n.outerEnd),innerStart:Z(n.innerStart,0,a),innerEnd:Z(n.innerEnd,0,a)}}function jn(t,e,i,s){return{x:i+t*Math.cos(e),y:s+t*Math.sin(e)}}function Hn(t,e,i,s,n,o){const{x:a,y:r,startAngle:l,pixelMargin:h,innerRadius:c}=e,d=Math.max(e.outerRadius+s+i-h,0),u=c>0?c+s+i+h:0;let f=0;const g=n-l;if(s){const t=((c>0?c-s:0)+(d>0?d-s:0))/2;f=(g-(0!==t?g*t/(t+s):g))/2}const p=(g-Math.max(.001,g*d-i/D)/d)/2,m=l+p+f,b=n-p-f,{outerStart:x,outerEnd:_,innerStart:y,innerEnd:v}=Wn(e,u,d,b-m),w=d-x,M=d-_,k=m+x/w,S=b-_/M,P=u+y,O=u+v,C=m+y/P,A=b-v/O;if(t.beginPath(),o){if(t.arc(a,r,d,k,S),_>0){const e=jn(M,S,a,r);t.arc(e.x,e.y,_,S,b+L)}const e=jn(O,b,a,r);if(t.lineTo(e.x,e.y),v>0){const e=jn(O,A,a,r);t.arc(e.x,e.y,v,b+L,A+Math.PI)}if(t.arc(a,r,u,b-v/u,m+y/u,!0),y>0){const e=jn(P,C,a,r);t.arc(e.x,e.y,y,C+Math.PI,m-L)}const i=jn(w,m,a,r);if(t.lineTo(i.x,i.y),x>0){const e=jn(w,k,a,r);t.arc(e.x,e.y,x,m-L,k)}}else{t.moveTo(a,r);const e=Math.cos(k)*d+a,i=Math.sin(k)*d+r;t.lineTo(e,i);const s=Math.cos(S)*d+a,n=Math.sin(S)*d+r;t.lineTo(s,n)}t.closePath()}function $n(t,e,i,s,n,o){const{options:a}=e,{borderWidth:r,borderJoinStyle:l}=a,h=\"inner\"===a.borderAlign;r&&(h?(t.lineWidth=2*r,t.lineJoin=l||\"round\"):(t.lineWidth=r,t.lineJoin=l||\"bevel\"),e.fullCircles&&function(t,e,i){const{x:s,y:n,startAngle:o,pixelMargin:a,fullCircles:r}=e,l=Math.max(e.outerRadius-a,0),h=e.innerRadius+a;let c;for(i&&Nn(t,e,o+O),t.beginPath(),t.arc(s,n,h,o+O,o,!0),c=0;c<r;++c)t.stroke();for(t.beginPath(),t.arc(s,n,l,o,o+O),c=0;c<r;++c)t.stroke()}(t,e,h),h&&Nn(t,e,n),Hn(t,e,i,s,n,o),t.stroke())}class Yn extends Es{constructor(t){super(),this.options=void 0,this.circumference=void 0,this.startAngle=void 0,this.endAngle=void 0,this.innerRadius=void 0,this.outerRadius=void 0,this.pixelMargin=0,this.fullCircles=0,t&&Object.assign(this,t)}inRange(t,e,i){const s=this.getProps([\"x\",\"y\"],i),{angle:n,distance:o}=U(s,{x:t,y:e}),{startAngle:a,endAngle:l,innerRadius:h,outerRadius:c,circumference:d}=this.getProps([\"startAngle\",\"endAngle\",\"innerRadius\",\"outerRadius\",\"circumference\"],i),u=this.options.spacing/2,f=r(d,l-a)>=O||G(n,a,l),g=Q(o,h+u,c+u);return f&&g}getCenterPoint(t){const{x:e,y:i,startAngle:s,endAngle:n,innerRadius:o,outerRadius:a}=this.getProps([\"x\",\"y\",\"startAngle\",\"endAngle\",\"innerRadius\",\"outerRadius\",\"circumference\"],t),{offset:r,spacing:l}=this.options,h=(s+n)/2,c=(o+a+l+r)/2;return{x:e+Math.cos(h)*c,y:i+Math.sin(h)*c}}tooltipPosition(t){return this.getCenterPoint(t)}draw(t){const{options:e,circumference:i}=this,s=(e.offset||0)/2,n=(e.spacing||0)/2,o=e.circular;if(this.pixelMargin=\"inner\"===e.borderAlign?.33:0,this.fullCircles=i>O?Math.floor(i/O):0,0===i||this.innerRadius<0||this.outerRadius<0)return;t.save();let a=0;if(s){a=s/2;const e=(this.startAngle+this.endAngle)/2;t.translate(Math.cos(e)*a,Math.sin(e)*a),this.circumference>=D&&(a=s)}t.fillStyle=e.backgroundColor,t.strokeStyle=e.borderColor;const r=function(t,e,i,s,n){const{fullCircles:o,startAngle:a,circumference:r}=e;let l=e.endAngle;if(o){Hn(t,e,i,s,a+O,n);for(let e=0;e<o;++e)t.fill();isNaN(r)||(l=a+r%O,r%O==0&&(l+=O))}return Hn(t,e,i,s,l,n),t.fill(),l}(t,this,a,n,o);$n(t,this,a,n,r,o),t.restore()}}function Un(t,e,i=e){t.lineCap=r(i.borderCapStyle,e.borderCapStyle),t.setLineDash(r(i.borderDash,e.borderDash)),t.lineDashOffset=r(i.borderDashOffset,e.borderDashOffset),t.lineJoin=r(i.borderJoinStyle,e.borderJoinStyle),t.lineWidth=r(i.borderWidth,e.borderWidth),t.strokeStyle=r(i.borderColor,e.borderColor)}function Xn(t,e,i){t.lineTo(i.x,i.y)}function qn(t,e,i={}){const s=t.length,{start:n=0,end:o=s-1}=i,{start:a,end:r}=e,l=Math.max(n,a),h=Math.min(o,r),c=n<a&&o<a||n>r&&o>r;return{count:s,start:l,loop:e.loop,ilen:h<l&&!c?s+h-l:h-l}}function Kn(t,e,i,s){const{points:n,options:o}=e,{count:a,start:r,loop:l,ilen:h}=qn(n,i,s),c=function(t){return t.stepped?Oe:t.tension||\"monotone\"===t.cubicInterpolationMode?Ce:Xn}(o);let d,u,f,{move:g=!0,reverse:p}=s||{};for(d=0;d<=h;++d)u=n[(r+(p?h-d:d))%a],u.skip||(g?(t.moveTo(u.x,u.y),g=!1):c(t,f,u,p,o.stepped),f=u);return l&&(u=n[(r+(p?h:0))%a],c(t,f,u,p,o.stepped)),!!l}function Gn(t,e,i,s){const n=e.points,{count:o,start:a,ilen:r}=qn(n,i,s),{move:l=!0,reverse:h}=s||{};let c,d,u,f,g,p,m=0,b=0;const x=t=>(a+(h?r-t:t))%o,_=()=>{f!==g&&(t.lineTo(m,g),t.lineTo(m,f),t.lineTo(m,p))};for(l&&(d=n[x(0)],t.moveTo(d.x,d.y)),c=0;c<=r;++c){if(d=n[x(c)],d.skip)continue;const e=d.x,i=d.y,s=0|e;s===u?(i<f?f=i:i>g&&(g=i),m=(b*m+e)/++b):(_(),t.lineTo(e,i),u=s,b=0,f=g=i),p=i}_()}function Zn(t){const e=t.options,i=e.borderDash&&e.borderDash.length;return!(t._decimated||t._loop||e.tension||\"monotone\"===e.cubicInterpolationMode||e.stepped||i)?Gn:Kn}Yn.id=\"arc\",Yn.defaults={borderAlign:\"center\",borderColor:\"#fff\",borderJoinStyle:void 0,borderRadius:0,borderWidth:2,offset:0,spacing:0,angle:void 0,circular:!0},Yn.defaultRoutes={backgroundColor:\"backgroundColor\"};const Jn=\"function\"==typeof Path2D;function Qn(t,e,i,s){Jn&&!e.options.segment?function(t,e,i,s){let n=e._path;n||(n=e._path=new Path2D,e.path(n,i,s)&&n.closePath()),Un(t,e.options),t.stroke(n)}(t,e,i,s):function(t,e,i,s){const{segments:n,options:o}=e,a=Zn(e);for(const r of n)Un(t,o,r.style),t.beginPath(),a(t,e,r,{start:i,end:i+s-1})&&t.closePath(),t.stroke()}(t,e,i,s)}class to extends Es{constructor(t){super(),this.animated=!0,this.options=void 0,this._chart=void 0,this._loop=void 0,this._fullLoop=void 0,this._path=void 0,this._points=void 0,this._segments=void 0,this._decimated=!1,this._pointsUpdated=!1,this._datasetIndex=void 0,t&&Object.assign(this,t)}updateControlPoints(t,e){const i=this.options;if((i.tension||\"monotone\"===i.cubicInterpolationMode)&&!i.stepped&&!this._pointsUpdated){const s=i.spanGaps?this._loop:this._fullLoop;Qe(this._points,i,t,s,e),this._pointsUpdated=!0}}set points(t){this._points=t,delete this._segments,delete this._path,this._pointsUpdated=!1}get points(){return this._points}get segments(){return this._segments||(this._segments=Di(this,this.options.segment))}first(){const t=this.segments,e=this.points;return t.length&&e[t[0].start]}last(){const t=this.segments,e=this.points,i=t.length;return i&&e[t[i-1].end]}interpolate(t,e){const i=this.options,s=t[e],n=this.points,o=Pi(this,{property:e,start:s,end:s});if(!o.length)return;const a=[],r=function(t){return t.stepped?oi:t.tension||\"monotone\"===t.cubicInterpolationMode?ai:ni}(i);let l,h;for(l=0,h=o.length;l<h;++l){const{start:h,end:c}=o[l],d=n[h],u=n[c];if(d===u){a.push(d);continue}const f=r(d,u,Math.abs((s-d[e])/(u[e]-d[e])),i.stepped);f[e]=t[e],a.push(f)}return 1===a.length?a[0]:a}pathSegment(t,e,i){return Zn(this)(t,this,e,i)}path(t,e,i){const s=this.segments,n=Zn(this);let o=this._loop;e=e||0,i=i||this.points.length-e;for(const a of s)o&=n(t,this,a,{start:e,end:e+i-1});return!!o}draw(t,e,i,s){const n=this.options||{};(this.points||[]).length&&n.borderWidth&&(t.save(),Qn(t,this,i,s),t.restore()),this.animated&&(this._pointsUpdated=!1,this._path=void 0)}}function eo(t,e,i,s){const n=t.options,{[i]:o}=t.getProps([i],s);return Math.abs(e-o)<n.radius+n.hitRadius}to.id=\"line\",to.defaults={borderCapStyle:\"butt\",borderDash:[],borderDashOffset:0,borderJoinStyle:\"miter\",borderWidth:3,capBezierPoints:!0,cubicInterpolationMode:\"default\",fill:!1,spanGaps:!1,stepped:!1,tension:0},to.defaultRoutes={backgroundColor:\"backgroundColor\",borderColor:\"borderColor\"},to.descriptors={_scriptable:!0,_indexable:t=>\"borderDash\"!==t&&\"fill\"!==t};class io extends Es{constructor(t){super(),this.options=void 0,this.parsed=void 0,this.skip=void 0,this.stop=void 0,t&&Object.assign(this,t)}inRange(t,e,i){const s=this.options,{x:n,y:o}=this.getProps([\"x\",\"y\"],i);return Math.pow(t-n,2)+Math.pow(e-o,2)<Math.pow(s.hitRadius+s.radius,2)}inXRange(t,e){return eo(this,t,\"x\",e)}inYRange(t,e){return eo(this,t,\"y\",e)}getCenterPoint(t){const{x:e,y:i}=this.getProps([\"x\",\"y\"],t);return{x:e,y:i}}size(t){let e=(t=t||this.options||{}).radius||0;e=Math.max(e,e&&t.hoverRadius||0);return 2*(e+(e&&t.borderWidth||0))}draw(t,e){const i=this.options;this.skip||i.radius<.1||!Se(this,e,this.size(i)/2)||(t.strokeStyle=i.borderColor,t.lineWidth=i.borderWidth,t.fillStyle=i.backgroundColor,Me(t,i,this.x,this.y))}getRange(){const t=this.options||{};return t.radius+t.hitRadius}}function so(t,e){const{x:i,y:s,base:n,width:o,height:a}=t.getProps([\"x\",\"y\",\"base\",\"width\",\"height\"],e);let r,l,h,c,d;return t.horizontal?(d=a/2,r=Math.min(i,n),l=Math.max(i,n),h=s-d,c=s+d):(d=o/2,r=i-d,l=i+d,h=Math.min(s,n),c=Math.max(s,n)),{left:r,top:h,right:l,bottom:c}}function no(t,e,i,s){return t?0:Z(e,i,s)}function oo(t){const e=so(t),i=e.right-e.left,s=e.bottom-e.top,o=function(t,e,i){const s=t.options.borderWidth,n=t.borderSkipped,o=fi(s);return{t:no(n.top,o.top,0,i),r:no(n.right,o.right,0,e),b:no(n.bottom,o.bottom,0,i),l:no(n.left,o.left,0,e)}}(t,i/2,s/2),a=function(t,e,i){const{enableBorderRadius:s}=t.getProps([\"enableBorderRadius\"]),o=t.options.borderRadius,a=gi(o),r=Math.min(e,i),l=t.borderSkipped,h=s||n(o);return{topLeft:no(!h||l.top||l.left,a.topLeft,0,r),topRight:no(!h||l.top||l.right,a.topRight,0,r),bottomLeft:no(!h||l.bottom||l.left,a.bottomLeft,0,r),bottomRight:no(!h||l.bottom||l.right,a.bottomRight,0,r)}}(t,i/2,s/2);return{outer:{x:e.left,y:e.top,w:i,h:s,radius:a},inner:{x:e.left+o.l,y:e.top+o.t,w:i-o.l-o.r,h:s-o.t-o.b,radius:{topLeft:Math.max(0,a.topLeft-Math.max(o.t,o.l)),topRight:Math.max(0,a.topRight-Math.max(o.t,o.r)),bottomLeft:Math.max(0,a.bottomLeft-Math.max(o.b,o.l)),bottomRight:Math.max(0,a.bottomRight-Math.max(o.b,o.r))}}}}function ao(t,e,i,s){const n=null===e,o=null===i,a=t&&!(n&&o)&&so(t,s);return a&&(n||Q(e,a.left,a.right))&&(o||Q(i,a.top,a.bottom))}function ro(t,e){t.rect(e.x,e.y,e.w,e.h)}function lo(t,e,i={}){const s=t.x!==i.x?-e:0,n=t.y!==i.y?-e:0,o=(t.x+t.w!==i.x+i.w?e:0)-s,a=(t.y+t.h!==i.y+i.h?e:0)-n;return{x:t.x+s,y:t.y+n,w:t.w+o,h:t.h+a,radius:t.radius}}io.id=\"point\",io.defaults={borderWidth:1,hitRadius:1,hoverBorderWidth:1,hoverRadius:4,pointStyle:\"circle\",radius:3,rotation:0},io.defaultRoutes={backgroundColor:\"backgroundColor\",borderColor:\"borderColor\"};class ho extends Es{constructor(t){super(),this.options=void 0,this.horizontal=void 0,this.base=void 0,this.width=void 0,this.height=void 0,this.inflateAmount=void 0,t&&Object.assign(this,t)}draw(t){const{inflateAmount:e,options:{borderColor:i,backgroundColor:s}}=this,{inner:n,outer:o}=oo(this),a=(r=o.radius).topLeft||r.topRight||r.bottomLeft||r.bottomRight?Le:ro;var r;t.save(),o.w===n.w&&o.h===n.h||(t.beginPath(),a(t,lo(o,e,n)),t.clip(),a(t,lo(n,-e,o)),t.fillStyle=i,t.fill(\"evenodd\")),t.beginPath(),a(t,lo(n,e)),t.fillStyle=s,t.fill(),t.restore()}inRange(t,e,i){return ao(this,t,e,i)}inXRange(t,e){return ao(this,t,null,e)}inYRange(t,e){return ao(this,null,t,e)}getCenterPoint(t){const{x:e,y:i,base:s,horizontal:n}=this.getProps([\"x\",\"y\",\"base\",\"horizontal\"],t);return{x:n?(e+s)/2:e,y:n?i:(i+s)/2}}getRange(t){return\"x\"===t?this.width/2:this.height/2}}ho.id=\"bar\",ho.defaults={borderSkipped:\"start\",borderWidth:0,borderRadius:0,inflateAmount:\"auto\",pointStyle:void 0},ho.defaultRoutes={backgroundColor:\"backgroundColor\",borderColor:\"borderColor\"};var co=Object.freeze({__proto__:null,ArcElement:Yn,LineElement:to,PointElement:io,BarElement:ho});function uo(t){if(t._decimated){const e=t._data;delete t._decimated,delete t._data,Object.defineProperty(t,\"data\",{value:e})}}function fo(t){t.data.datasets.forEach((t=>{uo(t)}))}var go={id:\"decimation\",defaults:{algorithm:\"min-max\",enabled:!1},beforeElementsUpdate:(t,e,s)=>{if(!s.enabled)return void fo(t);const n=t.width;t.data.datasets.forEach(((e,o)=>{const{_data:a,indexAxis:r}=e,l=t.getDatasetMeta(o),h=a||e.data;if(\"y\"===bi([r,t.options.indexAxis]))return;if(!l.controller.supportsDecimation)return;const c=t.scales[l.xAxisID];if(\"linear\"!==c.type&&\"time\"!==c.type)return;if(t.options.parsing)return;let{start:d,count:u}=function(t,e){const i=e.length;let s,n=0;const{iScale:o}=t,{min:a,max:r,minDefined:l,maxDefined:h}=o.getUserBounds();return l&&(n=Z(et(e,o.axis,a).lo,0,i-1)),s=h?Z(et(e,o.axis,r).hi+1,n,i)-n:i-n,{start:n,count:s}}(l,h);if(u<=(s.threshold||4*n))return void uo(e);let f;switch(i(a)&&(e._data=h,delete e.data,Object.defineProperty(e,\"data\",{configurable:!0,enumerable:!0,get:function(){return this._decimated},set:function(t){this._data=t}})),s.algorithm){case\"lttb\":f=function(t,e,i,s,n){const o=n.samples||s;if(o>=i)return t.slice(e,e+i);const a=[],r=(i-2)/(o-2);let l=0;const h=e+i-1;let c,d,u,f,g,p=e;for(a[l++]=t[p],c=0;c<o-2;c++){let s,n=0,o=0;const h=Math.floor((c+1)*r)+1+e,m=Math.min(Math.floor((c+2)*r)+1,i)+e,b=m-h;for(s=h;s<m;s++)n+=t[s].x,o+=t[s].y;n/=b,o/=b;const x=Math.floor(c*r)+1+e,_=Math.min(Math.floor((c+1)*r)+1,i)+e,{x:y,y:v}=t[p];for(u=f=-1,s=x;s<_;s++)f=.5*Math.abs((y-n)*(t[s].y-v)-(y-t[s].x)*(o-v)),f>u&&(u=f,d=t[s],g=s);a[l++]=d,p=g}return a[l++]=t[h],a}(h,d,u,n,s);break;case\"min-max\":f=function(t,e,s,n){let o,a,r,l,h,c,d,u,f,g,p=0,m=0;const b=[],x=e+s-1,_=t[e].x,y=t[x].x-_;for(o=e;o<e+s;++o){a=t[o],r=(a.x-_)/y*n,l=a.y;const e=0|r;if(e===h)l<f?(f=l,c=o):l>g&&(g=l,d=o),p=(m*p+a.x)/++m;else{const s=o-1;if(!i(c)&&!i(d)){const e=Math.min(c,d),i=Math.max(c,d);e!==u&&e!==s&&b.push({...t[e],x:p}),i!==u&&i!==s&&b.push({...t[i],x:p})}o>0&&s!==u&&b.push(t[s]),b.push(a),h=e,m=0,f=g=l,c=d=u=o}}return b}(h,d,u,n);break;default:throw new Error(`Unsupported decimation algorithm '${s.algorithm}'`)}e._decimated=f}))},destroy(t){fo(t)}};function po(t,e,i,s){if(s)return;let n=e[t],o=i[t];return\"angle\"===t&&(n=K(n),o=K(o)),{property:t,start:n,end:o}}function mo(t,e,i){for(;e>t;e--){const t=i[e];if(!isNaN(t.x)&&!isNaN(t.y))break}return e}function bo(t,e,i,s){return t&&e?s(t[i],e[i]):t?t[i]:e?e[i]:0}function xo(t,e){let i=[],n=!1;return s(t)?(n=!0,i=t):i=function(t,e){const{x:i=null,y:s=null}=t||{},n=e.points,o=[];return e.segments.forEach((({start:t,end:e})=>{e=mo(t,e,n);const a=n[t],r=n[e];null!==s?(o.push({x:a.x,y:s}),o.push({x:r.x,y:s})):null!==i&&(o.push({x:i,y:a.y}),o.push({x:i,y:r.y}))})),o}(t,e),i.length?new to({points:i,options:{tension:0},_loop:n,_fullLoop:n}):null}function _o(t){return t&&!1!==t.fill}function yo(t,e,i){let s=t[e].fill;const n=[e];let a;if(!i)return s;for(;!1!==s&&-1===n.indexOf(s);){if(!o(s))return s;if(a=t[s],!a)return!1;if(a.visible)return s;n.push(s),s=a.fill}return!1}function vo(t,e,i){const s=function(t){const e=t.options,i=e.fill;let s=r(i&&i.target,i);void 0===s&&(s=!!e.backgroundColor);if(!1===s||null===s)return!1;if(!0===s)return\"origin\";return s}(t);if(n(s))return!isNaN(s.value)&&s;let a=parseFloat(s);return o(a)&&Math.floor(a)===a?function(t,e,i,s){\"-\"!==t&&\"+\"!==t||(i=e+i);if(i===e||i<0||i>=s)return!1;return i}(s[0],e,a,i):[\"origin\",\"start\",\"end\",\"stack\",\"shape\"].indexOf(s)>=0&&s}function wo(t,e,i){const s=[];for(let n=0;n<i.length;n++){const o=i[n],{first:a,last:r,point:l}=Mo(o,e,\"x\");if(!(!l||a&&r))if(a)s.unshift(l);else if(t.push(l),!r)break}t.push(...s)}function Mo(t,e,i){const s=t.interpolate(e,i);if(!s)return{};const n=s[i],o=t.segments,a=t.points;let r=!1,l=!1;for(let t=0;t<o.length;t++){const e=o[t],s=a[e.start][i],h=a[e.end][i];if(Q(n,s,h)){r=n===s,l=n===h;break}}return{first:r,last:l,point:s}}class ko{constructor(t){this.x=t.x,this.y=t.y,this.radius=t.radius}pathSegment(t,e,i){const{x:s,y:n,radius:o}=this;return e=e||{start:0,end:O},t.arc(s,n,o,e.end,e.start,!0),!i.bounds}interpolate(t){const{x:e,y:i,radius:s}=this,n=t.angle;return{x:e+Math.cos(n)*s,y:i+Math.sin(n)*s,angle:n}}}function So(t){const{chart:e,fill:i,line:s}=t;if(o(i))return function(t,e){const i=t.getDatasetMeta(e);return i&&t.isDatasetVisible(e)?i.dataset:null}(e,i);if(\"stack\"===i)return function(t){const{scale:e,index:i,line:s}=t,n=[],o=s.segments,a=s.points,r=function(t,e){const i=[],s=t.getMatchingVisibleMetas(\"line\");for(let t=0;t<s.length;t++){const n=s[t];if(n.index===e)break;n.hidden||i.unshift(n.dataset)}return i}(e,i);r.push(xo({x:null,y:e.bottom},s));for(let t=0;t<o.length;t++){const e=o[t];for(let t=e.start;t<=e.end;t++)wo(n,a[t],r)}return new to({points:n,options:{}})}(t);if(\"shape\"===i)return!0;const a=function(t){if((t.scale||{}).getPointPositionForValue)return function(t){const{scale:e,fill:i}=t,s=e.options,o=e.getLabels().length,a=s.reverse?e.max:e.min,r=function(t,e,i){let s;return s=\"start\"===t?i:\"end\"===t?e.options.reverse?e.min:e.max:n(t)?t.value:e.getBaseValue(),s}(i,e,a),l=[];if(s.grid.circular){const t=e.getPointPositionForValue(0,a);return new ko({x:t.x,y:t.y,radius:e.getDistanceFromCenterForValue(r)})}for(let t=0;t<o;++t)l.push(e.getPointPositionForValue(t,r));return l}(t);return function(t){const{scale:e={},fill:i}=t,s=function(t,e){let i=null;return\"start\"===t?i=e.bottom:\"end\"===t?i=e.top:n(t)?i=e.getPixelForValue(t.value):e.getBasePixel&&(i=e.getBasePixel()),i}(i,e);if(o(s)){const t=e.isHorizontal();return{x:t?s:null,y:t?null:s}}return null}(t)}(t);return a instanceof ko?a:xo(a,s)}function Po(t,e,i){const s=So(e),{line:n,scale:o,axis:a}=e,r=n.options,l=r.fill,h=r.backgroundColor,{above:c=h,below:d=h}=l||{};s&&n.points.length&&(Pe(t,i),function(t,e){const{line:i,target:s,above:n,below:o,area:a,scale:r}=e,l=i._loop?\"angle\":e.axis;t.save(),\"x\"===l&&o!==n&&(Do(t,s,a.top),Oo(t,{line:i,target:s,color:n,scale:r,property:l}),t.restore(),t.save(),Do(t,s,a.bottom));Oo(t,{line:i,target:s,color:o,scale:r,property:l}),t.restore()}(t,{line:n,target:s,above:c,below:d,area:i,scale:o,axis:a}),De(t))}function Do(t,e,i){const{segments:s,points:n}=e;let o=!0,a=!1;t.beginPath();for(const r of s){const{start:s,end:l}=r,h=n[s],c=n[mo(s,l,n)];o?(t.moveTo(h.x,h.y),o=!1):(t.lineTo(h.x,i),t.lineTo(h.x,h.y)),a=!!e.pathSegment(t,r,{move:a}),a?t.closePath():t.lineTo(c.x,i)}t.lineTo(e.first().x,i),t.closePath(),t.clip()}function Oo(t,e){const{line:i,target:s,property:n,color:o,scale:a}=e,r=function(t,e,i){const s=t.segments,n=t.points,o=e.points,a=[];for(const t of s){let{start:s,end:r}=t;r=mo(s,r,n);const l=po(i,n[s],n[r],t.loop);if(!e.segments){a.push({source:t,target:l,start:n[s],end:n[r]});continue}const h=Pi(e,l);for(const e of h){const s=po(i,o[e.start],o[e.end],e.loop),r=Si(t,n,s);for(const t of r)a.push({source:t,target:e,start:{[i]:bo(l,s,\"start\",Math.max)},end:{[i]:bo(l,s,\"end\",Math.min)}})}}return a}(i,s,n);for(const{source:e,target:l,start:h,end:c}of r){const{style:{backgroundColor:r=o}={}}=e,d=!0!==s;t.save(),t.fillStyle=r,Co(t,a,d&&po(n,h,c)),t.beginPath();const u=!!i.pathSegment(t,e);let f;if(d){u?t.closePath():Ao(t,s,c,n);const e=!!s.pathSegment(t,l,{move:u,reverse:!0});f=u&&e,f||Ao(t,s,h,n)}t.closePath(),t.fill(f?\"evenodd\":\"nonzero\"),t.restore()}}function Co(t,e,i){const{top:s,bottom:n}=e.chart.chartArea,{property:o,start:a,end:r}=i||{};\"x\"===o&&(t.beginPath(),t.rect(a,s,r-a,n-s),t.clip())}function Ao(t,e,i,s){const n=e.interpolate(i,s);n&&t.lineTo(n.x,n.y)}var To={id:\"filler\",afterDatasetsUpdate(t,e,i){const s=(t.data.datasets||[]).length,n=[];let o,a,r,l;for(a=0;a<s;++a)o=t.getDatasetMeta(a),r=o.dataset,l=null,r&&r.options&&r instanceof to&&(l={visible:t.isDatasetVisible(a),index:a,fill:vo(r,a,s),chart:t,axis:o.controller.options.indexAxis,scale:o.vScale,line:r}),o.$filler=l,n.push(l);for(a=0;a<s;++a)l=n[a],l&&!1!==l.fill&&(l.fill=yo(n,a,i.propagate))},beforeDraw(t,e,i){const s=\"beforeDraw\"===i.drawTime,n=t.getSortedVisibleDatasetMetas(),o=t.chartArea;for(let e=n.length-1;e>=0;--e){const i=n[e].$filler;i&&(i.line.updateControlPoints(o,i.axis),s&&i.fill&&Po(t.ctx,i,o))}},beforeDatasetsDraw(t,e,i){if(\"beforeDatasetsDraw\"!==i.drawTime)return;const s=t.getSortedVisibleDatasetMetas();for(let e=s.length-1;e>=0;--e){const i=s[e].$filler;_o(i)&&Po(t.ctx,i,t.chartArea)}},beforeDatasetDraw(t,e,i){const s=e.meta.$filler;_o(s)&&\"beforeDatasetDraw\"===i.drawTime&&Po(t.ctx,s,t.chartArea)},defaults:{propagate:!0,drawTime:\"beforeDatasetDraw\"}};const Lo=(t,e)=>{let{boxHeight:i=e,boxWidth:s=e}=t;return t.usePointStyle&&(i=Math.min(i,e),s=t.pointStyleWidth||Math.min(s,e)),{boxWidth:s,boxHeight:i,itemHeight:Math.max(e,i)}};class Eo extends Es{constructor(t){super(),this._added=!1,this.legendHitBoxes=[],this._hoveredItem=null,this.doughnutMode=!1,this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this.legendItems=void 0,this.columnSizes=void 0,this.lineWidths=void 0,this.maxHeight=void 0,this.maxWidth=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.height=void 0,this.width=void 0,this._margins=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e,i){this.maxWidth=t,this.maxHeight=e,this._margins=i,this.setDimensions(),this.buildLabels(),this.fit()}setDimensions(){this.isHorizontal()?(this.width=this.maxWidth,this.left=this._margins.left,this.right=this.width):(this.height=this.maxHeight,this.top=this._margins.top,this.bottom=this.height)}buildLabels(){const t=this.options.labels||{};let e=c(t.generateLabels,[this.chart],this)||[];t.filter&&(e=e.filter((e=>t.filter(e,this.chart.data)))),t.sort&&(e=e.sort(((e,i)=>t.sort(e,i,this.chart.data)))),this.options.reverse&&e.reverse(),this.legendItems=e}fit(){const{options:t,ctx:e}=this;if(!t.display)return void(this.width=this.height=0);const i=t.labels,s=mi(i.font),n=s.size,o=this._computeTitleHeight(),{boxWidth:a,itemHeight:r}=Lo(i,n);let l,h;e.font=s.string,this.isHorizontal()?(l=this.maxWidth,h=this._fitRows(o,n,a,r)+10):(h=this.maxHeight,l=this._fitCols(o,n,a,r)+10),this.width=Math.min(l,t.maxWidth||this.maxWidth),this.height=Math.min(h,t.maxHeight||this.maxHeight)}_fitRows(t,e,i,s){const{ctx:n,maxWidth:o,options:{labels:{padding:a}}}=this,r=this.legendHitBoxes=[],l=this.lineWidths=[0],h=s+a;let c=t;n.textAlign=\"left\",n.textBaseline=\"middle\";let d=-1,u=-h;return this.legendItems.forEach(((t,f)=>{const g=i+e/2+n.measureText(t.text).width;(0===f||l[l.length-1]+g+2*a>o)&&(c+=h,l[l.length-(f>0?0:1)]=0,u+=h,d++),r[f]={left:0,top:u,row:d,width:g,height:s},l[l.length-1]+=g+a})),c}_fitCols(t,e,i,s){const{ctx:n,maxHeight:o,options:{labels:{padding:a}}}=this,r=this.legendHitBoxes=[],l=this.columnSizes=[],h=o-t;let c=a,d=0,u=0,f=0,g=0;return this.legendItems.forEach(((t,o)=>{const p=i+e/2+n.measureText(t.text).width;o>0&&u+s+2*a>h&&(c+=d+a,l.push({width:d,height:u}),f+=d+a,g++,d=u=0),r[o]={left:f,top:u,col:g,width:p,height:s},d=Math.max(d,p),u+=s+a})),c+=d,l.push({width:d,height:u}),c}adjustHitBoxes(){if(!this.options.display)return;const t=this._computeTitleHeight(),{legendHitBoxes:e,options:{align:i,labels:{padding:s},rtl:n}}=this,o=yi(n,this.left,this.width);if(this.isHorizontal()){let n=0,a=ut(i,this.left+s,this.right-this.lineWidths[n]);for(const r of e)n!==r.row&&(n=r.row,a=ut(i,this.left+s,this.right-this.lineWidths[n])),r.top+=this.top+t+s,r.left=o.leftForLtr(o.x(a),r.width),a+=r.width+s}else{let n=0,a=ut(i,this.top+t+s,this.bottom-this.columnSizes[n].height);for(const r of e)r.col!==n&&(n=r.col,a=ut(i,this.top+t+s,this.bottom-this.columnSizes[n].height)),r.top=a,r.left+=this.left+s,r.left=o.leftForLtr(o.x(r.left),r.width),a+=r.height+s}}isHorizontal(){return\"top\"===this.options.position||\"bottom\"===this.options.position}draw(){if(this.options.display){const t=this.ctx;Pe(t,this),this._draw(),De(t)}}_draw(){const{options:t,columnSizes:e,lineWidths:i,ctx:s}=this,{align:n,labels:o}=t,a=ne.color,l=yi(t.rtl,this.left,this.width),h=mi(o.font),{color:c,padding:d}=o,u=h.size,f=u/2;let g;this.drawTitle(),s.textAlign=l.textAlign(\"left\"),s.textBaseline=\"middle\",s.lineWidth=.5,s.font=h.string;const{boxWidth:p,boxHeight:m,itemHeight:b}=Lo(o,u),x=this.isHorizontal(),_=this._computeTitleHeight();g=x?{x:ut(n,this.left+d,this.right-i[0]),y:this.top+d+_,line:0}:{x:this.left+d,y:ut(n,this.top+_+d,this.bottom-e[0].height),line:0},vi(this.ctx,t.textDirection);const y=b+d;this.legendItems.forEach(((v,w)=>{s.strokeStyle=v.fontColor||c,s.fillStyle=v.fontColor||c;const M=s.measureText(v.text).width,k=l.textAlign(v.textAlign||(v.textAlign=o.textAlign)),S=p+f+M;let P=g.x,D=g.y;l.setWidth(this.width),x?w>0&&P+S+d>this.right&&(D=g.y+=y,g.line++,P=g.x=ut(n,this.left+d,this.right-i[g.line])):w>0&&D+y>this.bottom&&(P=g.x=P+e[g.line].width+d,g.line++,D=g.y=ut(n,this.top+_+d,this.bottom-e[g.line].height));!function(t,e,i){if(isNaN(p)||p<=0||isNaN(m)||m<0)return;s.save();const n=r(i.lineWidth,1);if(s.fillStyle=r(i.fillStyle,a),s.lineCap=r(i.lineCap,\"butt\"),s.lineDashOffset=r(i.lineDashOffset,0),s.lineJoin=r(i.lineJoin,\"miter\"),s.lineWidth=n,s.strokeStyle=r(i.strokeStyle,a),s.setLineDash(r(i.lineDash,[])),o.usePointStyle){const a={radius:m*Math.SQRT2/2,pointStyle:i.pointStyle,rotation:i.rotation,borderWidth:n},r=l.xPlus(t,p/2);ke(s,a,r,e+f,o.pointStyleWidth&&p)}else{const o=e+Math.max((u-m)/2,0),a=l.leftForLtr(t,p),r=gi(i.borderRadius);s.beginPath(),Object.values(r).some((t=>0!==t))?Le(s,{x:a,y:o,w:p,h:m,radius:r}):s.rect(a,o,p,m),s.fill(),0!==n&&s.stroke()}s.restore()}(l.x(P),D,v),P=ft(k,P+p+f,x?P+S:this.right,t.rtl),function(t,e,i){Ae(s,i.text,t,e+b/2,h,{strikethrough:i.hidden,textAlign:l.textAlign(i.textAlign)})}(l.x(P),D,v),x?g.x+=S+d:g.y+=y})),wi(this.ctx,t.textDirection)}drawTitle(){const t=this.options,e=t.title,i=mi(e.font),s=pi(e.padding);if(!e.display)return;const n=yi(t.rtl,this.left,this.width),o=this.ctx,a=e.position,r=i.size/2,l=s.top+r;let h,c=this.left,d=this.width;if(this.isHorizontal())d=Math.max(...this.lineWidths),h=this.top+l,c=ut(t.align,c,this.right-d);else{const e=this.columnSizes.reduce(((t,e)=>Math.max(t,e.height)),0);h=l+ut(t.align,this.top,this.bottom-e-t.labels.padding-this._computeTitleHeight())}const u=ut(a,c,c+d);o.textAlign=n.textAlign(dt(a)),o.textBaseline=\"middle\",o.strokeStyle=e.color,o.fillStyle=e.color,o.font=i.string,Ae(o,e.text,u,h,i)}_computeTitleHeight(){const t=this.options.title,e=mi(t.font),i=pi(t.padding);return t.display?e.lineHeight+i.height:0}_getLegendItemAt(t,e){let i,s,n;if(Q(t,this.left,this.right)&&Q(e,this.top,this.bottom))for(n=this.legendHitBoxes,i=0;i<n.length;++i)if(s=n[i],Q(t,s.left,s.left+s.width)&&Q(e,s.top,s.top+s.height))return this.legendItems[i];return null}handleEvent(t){const e=this.options;if(!function(t,e){if((\"mousemove\"===t||\"mouseout\"===t)&&(e.onHover||e.onLeave))return!0;if(e.onClick&&(\"click\"===t||\"mouseup\"===t))return!0;return!1}(t.type,e))return;const i=this._getLegendItemAt(t.x,t.y);if(\"mousemove\"===t.type||\"mouseout\"===t.type){const o=this._hoveredItem,a=(n=i,null!==(s=o)&&null!==n&&s.datasetIndex===n.datasetIndex&&s.index===n.index);o&&!a&&c(e.onLeave,[t,o,this],this),this._hoveredItem=i,i&&!a&&c(e.onHover,[t,i,this],this)}else i&&c(e.onClick,[t,i,this],this);var s,n}}var Ro={id:\"legend\",_element:Eo,start(t,e,i){const s=t.legend=new Eo({ctx:t.ctx,options:i,chart:t});Zi.configure(t,s,i),Zi.addBox(t,s)},stop(t){Zi.removeBox(t,t.legend),delete t.legend},beforeUpdate(t,e,i){const s=t.legend;Zi.configure(t,s,i),s.options=i},afterUpdate(t){const e=t.legend;e.buildLabels(),e.adjustHitBoxes()},afterEvent(t,e){e.replay||t.legend.handleEvent(e.event)},defaults:{display:!0,position:\"top\",align:\"center\",fullSize:!0,reverse:!1,weight:1e3,onClick(t,e,i){const s=e.datasetIndex,n=i.chart;n.isDatasetVisible(s)?(n.hide(s),e.hidden=!0):(n.show(s),e.hidden=!1)},onHover:null,onLeave:null,labels:{color:t=>t.chart.options.color,boxWidth:40,padding:10,generateLabels(t){const e=t.data.datasets,{labels:{usePointStyle:i,pointStyle:s,textAlign:n,color:o}}=t.legend.options;return t._getSortedDatasetMetas().map((t=>{const a=t.controller.getStyle(i?0:void 0),r=pi(a.borderWidth);return{text:e[t.index].label,fillStyle:a.backgroundColor,fontColor:o,hidden:!t.visible,lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:(r.width+r.height)/4,strokeStyle:a.borderColor,pointStyle:s||a.pointStyle,rotation:a.rotation,textAlign:n||a.textAlign,borderRadius:0,datasetIndex:t.index}}),this)}},title:{color:t=>t.chart.options.color,display:!1,position:\"center\",text:\"\"}},descriptors:{_scriptable:t=>!t.startsWith(\"on\"),labels:{_scriptable:t=>![\"generateLabels\",\"filter\",\"sort\"].includes(t)}}};class Io extends Es{constructor(t){super(),this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this._padding=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e){const i=this.options;if(this.left=0,this.top=0,!i.display)return void(this.width=this.height=this.right=this.bottom=0);this.width=this.right=t,this.height=this.bottom=e;const n=s(i.text)?i.text.length:1;this._padding=pi(i.padding);const o=n*mi(i.font).lineHeight+this._padding.height;this.isHorizontal()?this.height=o:this.width=o}isHorizontal(){const t=this.options.position;return\"top\"===t||\"bottom\"===t}_drawArgs(t){const{top:e,left:i,bottom:s,right:n,options:o}=this,a=o.align;let r,l,h,c=0;return this.isHorizontal()?(l=ut(a,i,n),h=e+t,r=n-i):(\"left\"===o.position?(l=i+t,h=ut(a,s,e),c=-.5*D):(l=n-t,h=ut(a,e,s),c=.5*D),r=s-e),{titleX:l,titleY:h,maxWidth:r,rotation:c}}draw(){const t=this.ctx,e=this.options;if(!e.display)return;const i=mi(e.font),s=i.lineHeight/2+this._padding.top,{titleX:n,titleY:o,maxWidth:a,rotation:r}=this._drawArgs(s);Ae(t,e.text,0,0,i,{color:e.color,maxWidth:a,rotation:r,textAlign:dt(e.align),textBaseline:\"middle\",translation:[n,o]})}}var zo={id:\"title\",_element:Io,start(t,e,i){!function(t,e){const i=new Io({ctx:t.ctx,options:e,chart:t});Zi.configure(t,i,e),Zi.addBox(t,i),t.titleBlock=i}(t,i)},stop(t){const e=t.titleBlock;Zi.removeBox(t,e),delete t.titleBlock},beforeUpdate(t,e,i){const s=t.titleBlock;Zi.configure(t,s,i),s.options=i},defaults:{align:\"center\",display:!1,font:{weight:\"bold\"},fullSize:!0,padding:10,position:\"top\",text:\"\",weight:2e3},defaultRoutes:{color:\"color\"},descriptors:{_scriptable:!0,_indexable:!1}};const Fo=new WeakMap;var Vo={id:\"subtitle\",start(t,e,i){const s=new Io({ctx:t.ctx,options:i,chart:t});Zi.configure(t,s,i),Zi.addBox(t,s),Fo.set(t,s)},stop(t){Zi.removeBox(t,Fo.get(t)),Fo.delete(t)},beforeUpdate(t,e,i){const s=Fo.get(t);Zi.configure(t,s,i),s.options=i},defaults:{align:\"center\",display:!1,font:{weight:\"normal\"},fullSize:!0,padding:0,position:\"top\",text:\"\",weight:1500},defaultRoutes:{color:\"color\"},descriptors:{_scriptable:!0,_indexable:!1}};const Bo={average(t){if(!t.length)return!1;let e,i,s=0,n=0,o=0;for(e=0,i=t.length;e<i;++e){const i=t[e].element;if(i&&i.hasValue()){const t=i.tooltipPosition();s+=t.x,n+=t.y,++o}}return{x:s/o,y:n/o}},nearest(t,e){if(!t.length)return!1;let i,s,n,o=e.x,a=e.y,r=Number.POSITIVE_INFINITY;for(i=0,s=t.length;i<s;++i){const s=t[i].element;if(s&&s.hasValue()){const t=X(e,s.getCenterPoint());t<r&&(r=t,n=s)}}if(n){const t=n.tooltipPosition();o=t.x,a=t.y}return{x:o,y:a}}};function No(t,e){return e&&(s(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function Wo(t){return(\"string\"==typeof t||t instanceof String)&&t.indexOf(\"\\n\")>-1?t.split(\"\\n\"):t}function jo(t,e){const{element:i,datasetIndex:s,index:n}=e,o=t.getDatasetMeta(s).controller,{label:a,value:r}=o.getLabelAndValue(n);return{chart:t,label:a,parsed:o.getParsed(n),raw:t.data.datasets[s].data[n],formattedValue:r,dataset:o.getDataset(),dataIndex:n,datasetIndex:s,element:i}}function Ho(t,e){const i=t.chart.ctx,{body:s,footer:n,title:o}=t,{boxWidth:a,boxHeight:r}=e,l=mi(e.bodyFont),h=mi(e.titleFont),c=mi(e.footerFont),u=o.length,f=n.length,g=s.length,p=pi(e.padding);let m=p.height,b=0,x=s.reduce(((t,e)=>t+e.before.length+e.lines.length+e.after.length),0);if(x+=t.beforeBody.length+t.afterBody.length,u&&(m+=u*h.lineHeight+(u-1)*e.titleSpacing+e.titleMarginBottom),x){m+=g*(e.displayColors?Math.max(r,l.lineHeight):l.lineHeight)+(x-g)*l.lineHeight+(x-1)*e.bodySpacing}f&&(m+=e.footerMarginTop+f*c.lineHeight+(f-1)*e.footerSpacing);let _=0;const y=function(t){b=Math.max(b,i.measureText(t).width+_)};return i.save(),i.font=h.string,d(t.title,y),i.font=l.string,d(t.beforeBody.concat(t.afterBody),y),_=e.displayColors?a+2+e.boxPadding:0,d(s,(t=>{d(t.before,y),d(t.lines,y),d(t.after,y)})),_=0,i.font=c.string,d(t.footer,y),i.restore(),b+=p.width,{width:b,height:m}}function $o(t,e,i,s){const{x:n,width:o}=i,{width:a,chartArea:{left:r,right:l}}=t;let h=\"center\";return\"center\"===s?h=n<=(r+l)/2?\"left\":\"right\":n<=o/2?h=\"left\":n>=a-o/2&&(h=\"right\"),function(t,e,i,s){const{x:n,width:o}=s,a=i.caretSize+i.caretPadding;return\"left\"===t&&n+o+a>e.width||\"right\"===t&&n-o-a<0||void 0}(h,t,e,i)&&(h=\"center\"),h}function Yo(t,e,i){const s=i.yAlign||e.yAlign||function(t,e){const{y:i,height:s}=e;return i<s/2?\"top\":i>t.height-s/2?\"bottom\":\"center\"}(t,i);return{xAlign:i.xAlign||e.xAlign||$o(t,e,i,s),yAlign:s}}function Uo(t,e,i,s){const{caretSize:n,caretPadding:o,cornerRadius:a}=t,{xAlign:r,yAlign:l}=i,h=n+o,{topLeft:c,topRight:d,bottomLeft:u,bottomRight:f}=gi(a);let g=function(t,e){let{x:i,width:s}=t;return\"right\"===e?i-=s:\"center\"===e&&(i-=s/2),i}(e,r);const p=function(t,e,i){let{y:s,height:n}=t;return\"top\"===e?s+=i:s-=\"bottom\"===e?n+i:n/2,s}(e,l,h);return\"center\"===l?\"left\"===r?g+=h:\"right\"===r&&(g-=h):\"left\"===r?g-=Math.max(c,u)+n:\"right\"===r&&(g+=Math.max(d,f)+n),{x:Z(g,0,s.width-e.width),y:Z(p,0,s.height-e.height)}}function Xo(t,e,i){const s=pi(i.padding);return\"center\"===e?t.x+t.width/2:\"right\"===e?t.x+t.width-s.right:t.x+s.left}function qo(t){return No([],Wo(t))}function Ko(t,e){const i=e&&e.dataset&&e.dataset.tooltip&&e.dataset.tooltip.callbacks;return i?t.override(i):t}class Go extends Es{constructor(t){super(),this.opacity=0,this._active=[],this._eventPosition=void 0,this._size=void 0,this._cachedAnimations=void 0,this._tooltipItems=[],this.$animations=void 0,this.$context=void 0,this.chart=t.chart||t._chart,this._chart=this.chart,this.options=t.options,this.dataPoints=void 0,this.title=void 0,this.beforeBody=void 0,this.body=void 0,this.afterBody=void 0,this.footer=void 0,this.xAlign=void 0,this.yAlign=void 0,this.x=void 0,this.y=void 0,this.height=void 0,this.width=void 0,this.caretX=void 0,this.caretY=void 0,this.labelColors=void 0,this.labelPointStyles=void 0,this.labelTextColors=void 0}initialize(t){this.options=t,this._cachedAnimations=void 0,this.$context=void 0}_resolveAnimations(){const t=this._cachedAnimations;if(t)return t;const e=this.chart,i=this.options.setContext(this.getContext()),s=i.enabled&&e.options.animation&&i.animations,n=new ys(this.chart,s);return s._cacheable&&(this._cachedAnimations=Object.freeze(n)),n}getContext(){return this.$context||(this.$context=(t=this.chart.getContext(),e=this,i=this._tooltipItems,_i(t,{tooltip:e,tooltipItems:i,type:\"tooltip\"})));var t,e,i}getTitle(t,e){const{callbacks:i}=e,s=i.beforeTitle.apply(this,[t]),n=i.title.apply(this,[t]),o=i.afterTitle.apply(this,[t]);let a=[];return a=No(a,Wo(s)),a=No(a,Wo(n)),a=No(a,Wo(o)),a}getBeforeBody(t,e){return qo(e.callbacks.beforeBody.apply(this,[t]))}getBody(t,e){const{callbacks:i}=e,s=[];return d(t,(t=>{const e={before:[],lines:[],after:[]},n=Ko(i,t);No(e.before,Wo(n.beforeLabel.call(this,t))),No(e.lines,n.label.call(this,t)),No(e.after,Wo(n.afterLabel.call(this,t))),s.push(e)})),s}getAfterBody(t,e){return qo(e.callbacks.afterBody.apply(this,[t]))}getFooter(t,e){const{callbacks:i}=e,s=i.beforeFooter.apply(this,[t]),n=i.footer.apply(this,[t]),o=i.afterFooter.apply(this,[t]);let a=[];return a=No(a,Wo(s)),a=No(a,Wo(n)),a=No(a,Wo(o)),a}_createItems(t){const e=this._active,i=this.chart.data,s=[],n=[],o=[];let a,r,l=[];for(a=0,r=e.length;a<r;++a)l.push(jo(this.chart,e[a]));return t.filter&&(l=l.filter(((e,s,n)=>t.filter(e,s,n,i)))),t.itemSort&&(l=l.sort(((e,s)=>t.itemSort(e,s,i)))),d(l,(e=>{const i=Ko(t.callbacks,e);s.push(i.labelColor.call(this,e)),n.push(i.labelPointStyle.call(this,e)),o.push(i.labelTextColor.call(this,e))})),this.labelColors=s,this.labelPointStyles=n,this.labelTextColors=o,this.dataPoints=l,l}update(t,e){const i=this.options.setContext(this.getContext()),s=this._active;let n,o=[];if(s.length){const t=Bo[i.position].call(this,s,this._eventPosition);o=this._createItems(i),this.title=this.getTitle(o,i),this.beforeBody=this.getBeforeBody(o,i),this.body=this.getBody(o,i),this.afterBody=this.getAfterBody(o,i),this.footer=this.getFooter(o,i);const e=this._size=Ho(this,i),a=Object.assign({},t,e),r=Yo(this.chart,i,a),l=Uo(i,a,r,this.chart);this.xAlign=r.xAlign,this.yAlign=r.yAlign,n={opacity:1,x:l.x,y:l.y,width:e.width,height:e.height,caretX:t.x,caretY:t.y}}else 0!==this.opacity&&(n={opacity:0});this._tooltipItems=o,this.$context=void 0,n&&this._resolveAnimations().update(this,n),t&&i.external&&i.external.call(this,{chart:this.chart,tooltip:this,replay:e})}drawCaret(t,e,i,s){const n=this.getCaretPosition(t,i,s);e.lineTo(n.x1,n.y1),e.lineTo(n.x2,n.y2),e.lineTo(n.x3,n.y3)}getCaretPosition(t,e,i){const{xAlign:s,yAlign:n}=this,{caretSize:o,cornerRadius:a}=i,{topLeft:r,topRight:l,bottomLeft:h,bottomRight:c}=gi(a),{x:d,y:u}=t,{width:f,height:g}=e;let p,m,b,x,_,y;return\"center\"===n?(_=u+g/2,\"left\"===s?(p=d,m=p-o,x=_+o,y=_-o):(p=d+f,m=p+o,x=_-o,y=_+o),b=p):(m=\"left\"===s?d+Math.max(r,h)+o:\"right\"===s?d+f-Math.max(l,c)-o:this.caretX,\"top\"===n?(x=u,_=x-o,p=m-o,b=m+o):(x=u+g,_=x+o,p=m+o,b=m-o),y=x),{x1:p,x2:m,x3:b,y1:x,y2:_,y3:y}}drawTitle(t,e,i){const s=this.title,n=s.length;let o,a,r;if(n){const l=yi(i.rtl,this.x,this.width);for(t.x=Xo(this,i.titleAlign,i),e.textAlign=l.textAlign(i.titleAlign),e.textBaseline=\"middle\",o=mi(i.titleFont),a=i.titleSpacing,e.fillStyle=i.titleColor,e.font=o.string,r=0;r<n;++r)e.fillText(s[r],l.x(t.x),t.y+o.lineHeight/2),t.y+=o.lineHeight+a,r+1===n&&(t.y+=i.titleMarginBottom-a)}}_drawColorBox(t,e,i,s,o){const a=this.labelColors[i],r=this.labelPointStyles[i],{boxHeight:l,boxWidth:h,boxPadding:c}=o,d=mi(o.bodyFont),u=Xo(this,\"left\",o),f=s.x(u),g=l<d.lineHeight?(d.lineHeight-l)/2:0,p=e.y+g;if(o.usePointStyle){const e={radius:Math.min(h,l)/2,pointStyle:r.pointStyle,rotation:r.rotation,borderWidth:1},i=s.leftForLtr(f,h)+h/2,n=p+l/2;t.strokeStyle=o.multiKeyBackground,t.fillStyle=o.multiKeyBackground,Me(t,e,i,n),t.strokeStyle=a.borderColor,t.fillStyle=a.backgroundColor,Me(t,e,i,n)}else{t.lineWidth=n(a.borderWidth)?Math.max(...Object.values(a.borderWidth)):a.borderWidth||1,t.strokeStyle=a.borderColor,t.setLineDash(a.borderDash||[]),t.lineDashOffset=a.borderDashOffset||0;const e=s.leftForLtr(f,h-c),i=s.leftForLtr(s.xPlus(f,1),h-c-2),r=gi(a.borderRadius);Object.values(r).some((t=>0!==t))?(t.beginPath(),t.fillStyle=o.multiKeyBackground,Le(t,{x:e,y:p,w:h,h:l,radius:r}),t.fill(),t.stroke(),t.fillStyle=a.backgroundColor,t.beginPath(),Le(t,{x:i,y:p+1,w:h-2,h:l-2,radius:r}),t.fill()):(t.fillStyle=o.multiKeyBackground,t.fillRect(e,p,h,l),t.strokeRect(e,p,h,l),t.fillStyle=a.backgroundColor,t.fillRect(i,p+1,h-2,l-2))}t.fillStyle=this.labelTextColors[i]}drawBody(t,e,i){const{body:s}=this,{bodySpacing:n,bodyAlign:o,displayColors:a,boxHeight:r,boxWidth:l,boxPadding:h}=i,c=mi(i.bodyFont);let u=c.lineHeight,f=0;const g=yi(i.rtl,this.x,this.width),p=function(i){e.fillText(i,g.x(t.x+f),t.y+u/2),t.y+=u+n},m=g.textAlign(o);let b,x,_,y,v,w,M;for(e.textAlign=o,e.textBaseline=\"middle\",e.font=c.string,t.x=Xo(this,m,i),e.fillStyle=i.bodyColor,d(this.beforeBody,p),f=a&&\"right\"!==m?\"center\"===o?l/2+h:l+2+h:0,y=0,w=s.length;y<w;++y){for(b=s[y],x=this.labelTextColors[y],e.fillStyle=x,d(b.before,p),_=b.lines,a&&_.length&&(this._drawColorBox(e,t,y,g,i),u=Math.max(c.lineHeight,r)),v=0,M=_.length;v<M;++v)p(_[v]),u=c.lineHeight;d(b.after,p)}f=0,u=c.lineHeight,d(this.afterBody,p),t.y-=n}drawFooter(t,e,i){const s=this.footer,n=s.length;let o,a;if(n){const r=yi(i.rtl,this.x,this.width);for(t.x=Xo(this,i.footerAlign,i),t.y+=i.footerMarginTop,e.textAlign=r.textAlign(i.footerAlign),e.textBaseline=\"middle\",o=mi(i.footerFont),e.fillStyle=i.footerColor,e.font=o.string,a=0;a<n;++a)e.fillText(s[a],r.x(t.x),t.y+o.lineHeight/2),t.y+=o.lineHeight+i.footerSpacing}}drawBackground(t,e,i,s){const{xAlign:n,yAlign:o}=this,{x:a,y:r}=t,{width:l,height:h}=i,{topLeft:c,topRight:d,bottomLeft:u,bottomRight:f}=gi(s.cornerRadius);e.fillStyle=s.backgroundColor,e.strokeStyle=s.borderColor,e.lineWidth=s.borderWidth,e.beginPath(),e.moveTo(a+c,r),\"top\"===o&&this.drawCaret(t,e,i,s),e.lineTo(a+l-d,r),e.quadraticCurveTo(a+l,r,a+l,r+d),\"center\"===o&&\"right\"===n&&this.drawCaret(t,e,i,s),e.lineTo(a+l,r+h-f),e.quadraticCurveTo(a+l,r+h,a+l-f,r+h),\"bottom\"===o&&this.drawCaret(t,e,i,s),e.lineTo(a+u,r+h),e.quadraticCurveTo(a,r+h,a,r+h-u),\"center\"===o&&\"left\"===n&&this.drawCaret(t,e,i,s),e.lineTo(a,r+c),e.quadraticCurveTo(a,r,a+c,r),e.closePath(),e.fill(),s.borderWidth>0&&e.stroke()}_updateAnimationTarget(t){const e=this.chart,i=this.$animations,s=i&&i.x,n=i&&i.y;if(s||n){const i=Bo[t.position].call(this,this._active,this._eventPosition);if(!i)return;const o=this._size=Ho(this,t),a=Object.assign({},i,this._size),r=Yo(e,t,a),l=Uo(t,a,r,e);s._to===l.x&&n._to===l.y||(this.xAlign=r.xAlign,this.yAlign=r.yAlign,this.width=o.width,this.height=o.height,this.caretX=i.x,this.caretY=i.y,this._resolveAnimations().update(this,l))}}_willRender(){return!!this.opacity}draw(t){const e=this.options.setContext(this.getContext());let i=this.opacity;if(!i)return;this._updateAnimationTarget(e);const s={width:this.width,height:this.height},n={x:this.x,y:this.y};i=Math.abs(i)<.001?0:i;const o=pi(e.padding),a=this.title.length||this.beforeBody.length||this.body.length||this.afterBody.length||this.footer.length;e.enabled&&a&&(t.save(),t.globalAlpha=i,this.drawBackground(n,t,s,e),vi(t,e.textDirection),n.y+=o.top,this.drawTitle(n,t,e),this.drawBody(n,t,e),this.drawFooter(n,t,e),wi(t,e.textDirection),t.restore())}getActiveElements(){return this._active||[]}setActiveElements(t,e){const i=this._active,s=t.map((({datasetIndex:t,index:e})=>{const i=this.chart.getDatasetMeta(t);if(!i)throw new Error(\"Cannot find a dataset at index \"+t);return{datasetIndex:t,element:i.data[e],index:e}})),n=!u(i,s),o=this._positionChanged(s,e);(n||o)&&(this._active=s,this._eventPosition=e,this._ignoreReplayEvents=!0,this.update(!0))}handleEvent(t,e,i=!0){if(e&&this._ignoreReplayEvents)return!1;this._ignoreReplayEvents=!1;const s=this.options,n=this._active||[],o=this._getActiveElements(t,n,e,i),a=this._positionChanged(o,t),r=e||!u(o,n)||a;return r&&(this._active=o,(s.enabled||s.external)&&(this._eventPosition={x:t.x,y:t.y},this.update(!0,e))),r}_getActiveElements(t,e,i,s){const n=this.options;if(\"mouseout\"===t.type)return[];if(!s)return e;const o=this.chart.getElementsAtEventForMode(t,n.mode,n,i);return n.reverse&&o.reverse(),o}_positionChanged(t,e){const{caretX:i,caretY:s,options:n}=this,o=Bo[n.position].call(this,t,e);return!1!==o&&(i!==o.x||s!==o.y)}}Go.positioners=Bo;var Zo={id:\"tooltip\",_element:Go,positioners:Bo,afterInit(t,e,i){i&&(t.tooltip=new Go({chart:t,options:i}))},beforeUpdate(t,e,i){t.tooltip&&t.tooltip.initialize(i)},reset(t,e,i){t.tooltip&&t.tooltip.initialize(i)},afterDraw(t){const e=t.tooltip;if(e&&e._willRender()){const i={tooltip:e};if(!1===t.notifyPlugins(\"beforeTooltipDraw\",i))return;e.draw(t.ctx),t.notifyPlugins(\"afterTooltipDraw\",i)}},afterEvent(t,e){if(t.tooltip){const i=e.replay;t.tooltip.handleEvent(e.event,i,e.inChartArea)&&(e.changed=!0)}},defaults:{enabled:!0,external:null,position:\"average\",backgroundColor:\"rgba(0,0,0,0.8)\",titleColor:\"#fff\",titleFont:{weight:\"bold\"},titleSpacing:2,titleMarginBottom:6,titleAlign:\"left\",bodyColor:\"#fff\",bodySpacing:2,bodyFont:{},bodyAlign:\"left\",footerColor:\"#fff\",footerSpacing:2,footerMarginTop:6,footerFont:{weight:\"bold\"},footerAlign:\"left\",padding:6,caretPadding:2,caretSize:5,cornerRadius:6,boxHeight:(t,e)=>e.bodyFont.size,boxWidth:(t,e)=>e.bodyFont.size,multiKeyBackground:\"#fff\",displayColors:!0,boxPadding:0,borderColor:\"rgba(0,0,0,0)\",borderWidth:0,animation:{duration:400,easing:\"easeOutQuart\"},animations:{numbers:{type:\"number\",properties:[\"x\",\"y\",\"width\",\"height\",\"caretX\",\"caretY\"]},opacity:{easing:\"linear\",duration:200}},callbacks:{beforeTitle:t,title(t){if(t.length>0){const e=t[0],i=e.chart.data.labels,s=i?i.length:0;if(this&&this.options&&\"dataset\"===this.options.mode)return e.dataset.label||\"\";if(e.label)return e.label;if(s>0&&e.dataIndex<s)return i[e.dataIndex]}return\"\"},afterTitle:t,beforeBody:t,beforeLabel:t,label(t){if(this&&this.options&&\"dataset\"===this.options.mode)return t.label+\": \"+t.formattedValue||t.formattedValue;let e=t.dataset.label||\"\";e&&(e+=\": \");const s=t.formattedValue;return i(s)||(e+=s),e},labelColor(t){const e=t.chart.getDatasetMeta(t.datasetIndex).controller.getStyle(t.dataIndex);return{borderColor:e.borderColor,backgroundColor:e.backgroundColor,borderWidth:e.borderWidth,borderDash:e.borderDash,borderDashOffset:e.borderDashOffset,borderRadius:0}},labelTextColor(){return this.options.bodyColor},labelPointStyle(t){const e=t.chart.getDatasetMeta(t.datasetIndex).controller.getStyle(t.dataIndex);return{pointStyle:e.pointStyle,rotation:e.rotation}},afterLabel:t,afterBody:t,beforeFooter:t,footer:t,afterFooter:t}},defaultRoutes:{bodyFont:\"font\",footerFont:\"font\",titleFont:\"font\"},descriptors:{_scriptable:t=>\"filter\"!==t&&\"itemSort\"!==t&&\"external\"!==t,_indexable:!1,callbacks:{_scriptable:!1,_indexable:!1},animation:{_fallback:!1},animations:{_fallback:\"animation\"}},additionalOptionScopes:[\"interaction\"]},Jo=Object.freeze({__proto__:null,Decimation:go,Filler:To,Legend:Ro,SubTitle:Vo,Title:zo,Tooltip:Zo});function Qo(t,e,i,s){const n=t.indexOf(e);if(-1===n)return((t,e,i,s)=>(\"string\"==typeof e?(i=t.push(e)-1,s.unshift({index:i,label:e})):isNaN(e)&&(i=null),i))(t,e,i,s);return n!==t.lastIndexOf(e)?i:n}class ta extends $s{constructor(t){super(t),this._startValue=void 0,this._valueRange=0,this._addedLabels=[]}init(t){const e=this._addedLabels;if(e.length){const t=this.getLabels();for(const{index:i,label:s}of e)t[i]===s&&t.splice(i,1);this._addedLabels=[]}super.init(t)}parse(t,e){if(i(t))return null;const s=this.getLabels();return((t,e)=>null===t?null:Z(Math.round(t),0,e))(e=isFinite(e)&&s[e]===t?e:Qo(s,t,r(e,t),this._addedLabels),s.length-1)}determineDataLimits(){const{minDefined:t,maxDefined:e}=this.getUserBounds();let{min:i,max:s}=this.getMinMax(!0);\"ticks\"===this.options.bounds&&(t||(i=0),e||(s=this.getLabels().length-1)),this.min=i,this.max=s}buildTicks(){const t=this.min,e=this.max,i=this.options.offset,s=[];let n=this.getLabels();n=0===t&&e===n.length-1?n:n.slice(t,e+1),this._valueRange=Math.max(n.length-(i?0:1),1),this._startValue=this.min-(i?.5:0);for(let i=t;i<=e;i++)s.push({value:i});return s}getLabelForValue(t){const e=this.getLabels();return t>=0&&t<e.length?e[t]:t}configure(){super.configure(),this.isHorizontal()||(this._reversePixels=!this._reversePixels)}getPixelForValue(t){return\"number\"!=typeof t&&(t=this.parse(t)),null===t?NaN:this.getPixelForDecimal((t-this._startValue)/this._valueRange)}getPixelForTick(t){const e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getValueForPixel(t){return Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange)}getBasePixel(){return this.bottom}}function ea(t,e,{horizontal:i,minRotation:s}){const n=H(s),o=(i?Math.sin(n):Math.cos(n))||.001,a=.75*e*(\"\"+t).length;return Math.min(e/o,a)}ta.id=\"category\",ta.defaults={ticks:{callback:ta.prototype.getLabelForValue}};class ia extends $s{constructor(t){super(t),this.start=void 0,this.end=void 0,this._startValue=void 0,this._endValue=void 0,this._valueRange=0}parse(t,e){return i(t)||(\"number\"==typeof t||t instanceof Number)&&!isFinite(+t)?null:+t}handleTickRangeOptions(){const{beginAtZero:t}=this.options,{minDefined:e,maxDefined:i}=this.getUserBounds();let{min:s,max:n}=this;const o=t=>s=e?s:t,a=t=>n=i?n:t;if(t){const t=z(s),e=z(n);t<0&&e<0?a(0):t>0&&e>0&&o(0)}if(s===n){let e=1;(n>=Number.MAX_SAFE_INTEGER||s<=Number.MIN_SAFE_INTEGER)&&(e=Math.abs(.05*n)),a(n+e),t||o(s-e)}this.min=s,this.max=n}getTickLimit(){const t=this.options.ticks;let e,{maxTicksLimit:i,stepSize:s}=t;return s?(e=Math.ceil(this.max/s)-Math.floor(this.min/s)+1,e>1e3&&(console.warn(`scales.${this.id}.ticks.stepSize: ${s} would result generating up to ${e} ticks. Limiting to 1000.`),e=1e3)):(e=this.computeTickLimit(),i=i||11),i&&(e=Math.min(i,e)),e}computeTickLimit(){return Number.POSITIVE_INFINITY}buildTicks(){const t=this.options,e=t.ticks;let s=this.getTickLimit();s=Math.max(2,s);const n=function(t,e){const s=[],{bounds:n,step:o,min:a,max:r,precision:l,count:h,maxTicks:c,maxDigits:d,includeBounds:u}=t,f=o||1,g=c-1,{min:p,max:m}=e,b=!i(a),x=!i(r),_=!i(h),y=(m-p)/(d+1);let v,w,M,k,S=F((m-p)/g/f)*f;if(S<1e-14&&!b&&!x)return[{value:p},{value:m}];k=Math.ceil(m/S)-Math.floor(p/S),k>g&&(S=F(k*S/g/f)*f),i(l)||(v=Math.pow(10,l),S=Math.ceil(S*v)/v),\"ticks\"===n?(w=Math.floor(p/S)*S,M=Math.ceil(m/S)*S):(w=p,M=m),b&&x&&o&&W((r-a)/o,S/1e3)?(k=Math.round(Math.min((r-a)/S,c)),S=(r-a)/k,w=a,M=r):_?(w=b?a:w,M=x?r:M,k=h-1,S=(M-w)/k):(k=(M-w)/S,k=N(k,Math.round(k),S/1e3)?Math.round(k):Math.ceil(k));const P=Math.max(Y(S),Y(w));v=Math.pow(10,i(l)?P:l),w=Math.round(w*v)/v,M=Math.round(M*v)/v;let D=0;for(b&&(u&&w!==a?(s.push({value:a}),w<a&&D++,N(Math.round((w+D*S)*v)/v,a,ea(a,y,t))&&D++):w<a&&D++);D<k;++D)s.push({value:Math.round((w+D*S)*v)/v});return x&&u&&M!==r?s.length&&N(s[s.length-1].value,r,ea(r,y,t))?s[s.length-1].value=r:s.push({value:r}):x&&M!==r||s.push({value:M}),s}({maxTicks:s,bounds:t.bounds,min:t.min,max:t.max,precision:e.precision,step:e.stepSize,count:e.count,maxDigits:this._maxDigits(),horizontal:this.isHorizontal(),minRotation:e.minRotation||0,includeBounds:!1!==e.includeBounds},this._range||this);return\"ticks\"===t.bounds&&j(n,this,\"value\"),t.reverse?(n.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),n}configure(){const t=this.ticks;let e=this.min,i=this.max;if(super.configure(),this.options.offset&&t.length){const s=(i-e)/Math.max(t.length-1,1)/2;e-=s,i+=s}this._startValue=e,this._endValue=i,this._valueRange=i-e}getLabelForValue(t){return li(t,this.chart.options.locale,this.options.ticks.format)}}class sa extends ia{determineDataLimits(){const{min:t,max:e}=this.getMinMax(!0);this.min=o(t)?t:0,this.max=o(e)?e:1,this.handleTickRangeOptions()}computeTickLimit(){const t=this.isHorizontal(),e=t?this.width:this.height,i=H(this.options.ticks.minRotation),s=(t?Math.sin(i):Math.cos(i))||.001,n=this._resolveTickFontOptions(0);return Math.ceil(e/Math.min(40,n.lineHeight/s))}getPixelForValue(t){return null===t?NaN:this.getPixelForDecimal((t-this._startValue)/this._valueRange)}getValueForPixel(t){return this._startValue+this.getDecimalForPixel(t)*this._valueRange}}function na(t){return 1===t/Math.pow(10,Math.floor(I(t)))}sa.id=\"linear\",sa.defaults={ticks:{callback:Is.formatters.numeric}};class oa extends $s{constructor(t){super(t),this.start=void 0,this.end=void 0,this._startValue=void 0,this._valueRange=0}parse(t,e){const i=ia.prototype.parse.apply(this,[t,e]);if(0!==i)return o(i)&&i>0?i:null;this._zero=!0}determineDataLimits(){const{min:t,max:e}=this.getMinMax(!0);this.min=o(t)?Math.max(0,t):null,this.max=o(e)?Math.max(0,e):null,this.options.beginAtZero&&(this._zero=!0),this.handleTickRangeOptions()}handleTickRangeOptions(){const{minDefined:t,maxDefined:e}=this.getUserBounds();let i=this.min,s=this.max;const n=e=>i=t?i:e,o=t=>s=e?s:t,a=(t,e)=>Math.pow(10,Math.floor(I(t))+e);i===s&&(i<=0?(n(1),o(10)):(n(a(i,-1)),o(a(s,1)))),i<=0&&n(a(s,-1)),s<=0&&o(a(i,1)),this._zero&&this.min!==this._suggestedMin&&i===a(this.min,0)&&n(a(i,-1)),this.min=i,this.max=s}buildTicks(){const t=this.options,e=function(t,e){const i=Math.floor(I(e.max)),s=Math.ceil(e.max/Math.pow(10,i)),n=[];let o=a(t.min,Math.pow(10,Math.floor(I(e.min)))),r=Math.floor(I(o)),l=Math.floor(o/Math.pow(10,r)),h=r<0?Math.pow(10,Math.abs(r)):1;do{n.push({value:o,major:na(o)}),++l,10===l&&(l=1,++r,h=r>=0?1:h),o=Math.round(l*Math.pow(10,r)*h)/h}while(r<i||r===i&&l<s);const c=a(t.max,o);return n.push({value:c,major:na(o)}),n}({min:this._userMin,max:this._userMax},this);return\"ticks\"===t.bounds&&j(e,this,\"value\"),t.reverse?(e.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),e}getLabelForValue(t){return void 0===t?\"0\":li(t,this.chart.options.locale,this.options.ticks.format)}configure(){const t=this.min;super.configure(),this._startValue=I(t),this._valueRange=I(this.max)-I(t)}getPixelForValue(t){return void 0!==t&&0!==t||(t=this.min),null===t||isNaN(t)?NaN:this.getPixelForDecimal(t===this.min?0:(I(t)-this._startValue)/this._valueRange)}getValueForPixel(t){const e=this.getDecimalForPixel(t);return Math.pow(10,this._startValue+e*this._valueRange)}}function aa(t){const e=t.ticks;if(e.display&&t.display){const t=pi(e.backdropPadding);return r(e.font&&e.font.size,ne.font.size)+t.height}return 0}function ra(t,e,i,s,n){return t===s||t===n?{start:e-i/2,end:e+i/2}:t<s||t>n?{start:e-i,end:e}:{start:e,end:e+i}}function la(t){const e={l:t.left+t._padding.left,r:t.right-t._padding.right,t:t.top+t._padding.top,b:t.bottom-t._padding.bottom},i=Object.assign({},e),n=[],o=[],a=t._pointLabels.length,r=t.options.pointLabels,l=r.centerPointLabels?D/a:0;for(let u=0;u<a;u++){const a=r.setContext(t.getPointLabelContext(u));o[u]=a.padding;const f=t.getPointPosition(u,t.drawingArea+o[u],l),g=mi(a.font),p=(h=t.ctx,c=g,d=s(d=t._pointLabels[u])?d:[d],{w:ye(h,c.string,d),h:d.length*c.lineHeight});n[u]=p;const m=K(t.getIndexAngle(u)+l),b=Math.round($(m));ha(i,e,m,ra(b,f.x,p.w,0,180),ra(b,f.y,p.h,90,270))}var h,c,d;t.setCenterPoint(e.l-i.l,i.r-e.r,e.t-i.t,i.b-e.b),t._pointLabelItems=function(t,e,i){const s=[],n=t._pointLabels.length,o=t.options,a=aa(o)/2,r=t.drawingArea,l=o.pointLabels.centerPointLabels?D/n:0;for(let o=0;o<n;o++){const n=t.getPointPosition(o,r+a+i[o],l),h=Math.round($(K(n.angle+L))),c=e[o],d=ua(n.y,c.h,h),u=ca(h),f=da(n.x,c.w,u);s.push({x:n.x,y:d,textAlign:u,left:f,top:d,right:f+c.w,bottom:d+c.h})}return s}(t,n,o)}function ha(t,e,i,s,n){const o=Math.abs(Math.sin(i)),a=Math.abs(Math.cos(i));let r=0,l=0;s.start<e.l?(r=(e.l-s.start)/o,t.l=Math.min(t.l,e.l-r)):s.end>e.r&&(r=(s.end-e.r)/o,t.r=Math.max(t.r,e.r+r)),n.start<e.t?(l=(e.t-n.start)/a,t.t=Math.min(t.t,e.t-l)):n.end>e.b&&(l=(n.end-e.b)/a,t.b=Math.max(t.b,e.b+l))}function ca(t){return 0===t||180===t?\"center\":t<180?\"left\":\"right\"}function da(t,e,i){return\"right\"===i?t-=e:\"center\"===i&&(t-=e/2),t}function ua(t,e,i){return 90===i||270===i?t-=e/2:(i>270||i<90)&&(t-=e),t}function fa(t,e,i,s){const{ctx:n}=t;if(i)n.arc(t.xCenter,t.yCenter,e,0,O);else{let i=t.getPointPosition(0,e);n.moveTo(i.x,i.y);for(let o=1;o<s;o++)i=t.getPointPosition(o,e),n.lineTo(i.x,i.y)}}oa.id=\"logarithmic\",oa.defaults={ticks:{callback:Is.formatters.logarithmic,major:{enabled:!0}}};class ga extends ia{constructor(t){super(t),this.xCenter=void 0,this.yCenter=void 0,this.drawingArea=void 0,this._pointLabels=[],this._pointLabelItems=[]}setDimensions(){const t=this._padding=pi(aa(this.options)/2),e=this.width=this.maxWidth-t.width,i=this.height=this.maxHeight-t.height;this.xCenter=Math.floor(this.left+e/2+t.left),this.yCenter=Math.floor(this.top+i/2+t.top),this.drawingArea=Math.floor(Math.min(e,i)/2)}determineDataLimits(){const{min:t,max:e}=this.getMinMax(!1);this.min=o(t)&&!isNaN(t)?t:0,this.max=o(e)&&!isNaN(e)?e:0,this.handleTickRangeOptions()}computeTickLimit(){return Math.ceil(this.drawingArea/aa(this.options))}generateTickLabels(t){ia.prototype.generateTickLabels.call(this,t),this._pointLabels=this.getLabels().map(((t,e)=>{const i=c(this.options.pointLabels.callback,[t,e],this);return i||0===i?i:\"\"})).filter(((t,e)=>this.chart.getDataVisibility(e)))}fit(){const t=this.options;t.display&&t.pointLabels.display?la(this):this.setCenterPoint(0,0,0,0)}setCenterPoint(t,e,i,s){this.xCenter+=Math.floor((t-e)/2),this.yCenter+=Math.floor((i-s)/2),this.drawingArea-=Math.min(this.drawingArea/2,Math.max(t,e,i,s))}getIndexAngle(t){return K(t*(O/(this._pointLabels.length||1))+H(this.options.startAngle||0))}getDistanceFromCenterForValue(t){if(i(t))return NaN;const e=this.drawingArea/(this.max-this.min);return this.options.reverse?(this.max-t)*e:(t-this.min)*e}getValueForDistanceFromCenter(t){if(i(t))return NaN;const e=t/(this.drawingArea/(this.max-this.min));return this.options.reverse?this.max-e:this.min+e}getPointLabelContext(t){const e=this._pointLabels||[];if(t>=0&&t<e.length){const i=e[t];return function(t,e,i){return _i(t,{label:i,index:e,type:\"pointLabel\"})}(this.getContext(),t,i)}}getPointPosition(t,e,i=0){const s=this.getIndexAngle(t)-L+i;return{x:Math.cos(s)*e+this.xCenter,y:Math.sin(s)*e+this.yCenter,angle:s}}getPointPositionForValue(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))}getBasePosition(t){return this.getPointPositionForValue(t||0,this.getBaseValue())}getPointLabelPosition(t){const{left:e,top:i,right:s,bottom:n}=this._pointLabelItems[t];return{left:e,top:i,right:s,bottom:n}}drawBackground(){const{backgroundColor:t,grid:{circular:e}}=this.options;if(t){const i=this.ctx;i.save(),i.beginPath(),fa(this,this.getDistanceFromCenterForValue(this._endValue),e,this._pointLabels.length),i.closePath(),i.fillStyle=t,i.fill(),i.restore()}}drawGrid(){const t=this.ctx,e=this.options,{angleLines:s,grid:n}=e,o=this._pointLabels.length;let a,r,l;if(e.pointLabels.display&&function(t,e){const{ctx:s,options:{pointLabels:n}}=t;for(let o=e-1;o>=0;o--){const e=n.setContext(t.getPointLabelContext(o)),a=mi(e.font),{x:r,y:l,textAlign:h,left:c,top:d,right:u,bottom:f}=t._pointLabelItems[o],{backdropColor:g}=e;if(!i(g)){const t=gi(e.borderRadius),i=pi(e.backdropPadding);s.fillStyle=g;const n=c-i.left,o=d-i.top,a=u-c+i.width,r=f-d+i.height;Object.values(t).some((t=>0!==t))?(s.beginPath(),Le(s,{x:n,y:o,w:a,h:r,radius:t}),s.fill()):s.fillRect(n,o,a,r)}Ae(s,t._pointLabels[o],r,l+a.lineHeight/2,a,{color:e.color,textAlign:h,textBaseline:\"middle\"})}}(this,o),n.display&&this.ticks.forEach(((t,e)=>{if(0!==e){r=this.getDistanceFromCenterForValue(t.value);!function(t,e,i,s){const n=t.ctx,o=e.circular,{color:a,lineWidth:r}=e;!o&&!s||!a||!r||i<0||(n.save(),n.strokeStyle=a,n.lineWidth=r,n.setLineDash(e.borderDash),n.lineDashOffset=e.borderDashOffset,n.beginPath(),fa(t,i,o,s),n.closePath(),n.stroke(),n.restore())}(this,n.setContext(this.getContext(e-1)),r,o)}})),s.display){for(t.save(),a=o-1;a>=0;a--){const i=s.setContext(this.getPointLabelContext(a)),{color:n,lineWidth:o}=i;o&&n&&(t.lineWidth=o,t.strokeStyle=n,t.setLineDash(i.borderDash),t.lineDashOffset=i.borderDashOffset,r=this.getDistanceFromCenterForValue(e.ticks.reverse?this.min:this.max),l=this.getPointPosition(a,r),t.beginPath(),t.moveTo(this.xCenter,this.yCenter),t.lineTo(l.x,l.y),t.stroke())}t.restore()}}drawBorder(){}drawLabels(){const t=this.ctx,e=this.options,i=e.ticks;if(!i.display)return;const s=this.getIndexAngle(0);let n,o;t.save(),t.translate(this.xCenter,this.yCenter),t.rotate(s),t.textAlign=\"center\",t.textBaseline=\"middle\",this.ticks.forEach(((s,a)=>{if(0===a&&!e.reverse)return;const r=i.setContext(this.getContext(a)),l=mi(r.font);if(n=this.getDistanceFromCenterForValue(this.ticks[a].value),r.showLabelBackdrop){t.font=l.string,o=t.measureText(s.label).width,t.fillStyle=r.backdropColor;const e=pi(r.backdropPadding);t.fillRect(-o/2-e.left,-n-l.size/2-e.top,o+e.width,l.size+e.height)}Ae(t,s.label,0,-n,l,{color:r.color})})),t.restore()}drawTitle(){}}ga.id=\"radialLinear\",ga.defaults={display:!0,animate:!0,position:\"chartArea\",angleLines:{display:!0,lineWidth:1,borderDash:[],borderDashOffset:0},grid:{circular:!1},startAngle:0,ticks:{showLabelBackdrop:!0,callback:Is.formatters.numeric},pointLabels:{backdropColor:void 0,backdropPadding:2,display:!0,font:{size:10},callback:t=>t,padding:5,centerPointLabels:!1}},ga.defaultRoutes={\"angleLines.color\":\"borderColor\",\"pointLabels.color\":\"color\",\"ticks.color\":\"color\"},ga.descriptors={angleLines:{_fallback:\"grid\"}};const pa={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},ma=Object.keys(pa);function ba(t,e){return t-e}function xa(t,e){if(i(e))return null;const s=t._adapter,{parser:n,round:a,isoWeekday:r}=t._parseOpts;let l=e;return\"function\"==typeof n&&(l=n(l)),o(l)||(l=\"string\"==typeof n?s.parse(l,n):s.parse(l)),null===l?null:(a&&(l=\"week\"!==a||!B(r)&&!0!==r?s.startOf(l,a):s.startOf(l,\"isoWeek\",r)),+l)}function _a(t,e,i,s){const n=ma.length;for(let o=ma.indexOf(t);o<n-1;++o){const t=pa[ma[o]],n=t.steps?t.steps:Number.MAX_SAFE_INTEGER;if(t.common&&Math.ceil((i-e)/(n*t.size))<=s)return ma[o]}return ma[n-1]}function ya(t,e,i){if(i){if(i.length){const{lo:s,hi:n}=tt(i,e);t[i[s]>=e?i[s]:i[n]]=!0}}else t[e]=!0}function va(t,e,i){const s=[],n={},o=e.length;let a,r;for(a=0;a<o;++a)r=e[a],n[r]=a,s.push({value:r,major:!1});return 0!==o&&i?function(t,e,i,s){const n=t._adapter,o=+n.startOf(e[0].value,s),a=e[e.length-1].value;let r,l;for(r=o;r<=a;r=+n.add(r,1,s))l=i[r],l>=0&&(e[l].major=!0);return e}(t,s,n,i):s}class wa extends $s{constructor(t){super(t),this._cache={data:[],labels:[],all:[]},this._unit=\"day\",this._majorUnit=void 0,this._offsets={},this._normalized=!1,this._parseOpts=void 0}init(t,e){const i=t.time||(t.time={}),s=this._adapter=new wn._date(t.adapters.date);s.init(e),b(i.displayFormats,s.formats()),this._parseOpts={parser:i.parser,round:i.round,isoWeekday:i.isoWeekday},super.init(t),this._normalized=e.normalized}parse(t,e){return void 0===t?null:xa(this,t)}beforeLayout(){super.beforeLayout(),this._cache={data:[],labels:[],all:[]}}determineDataLimits(){const t=this.options,e=this._adapter,i=t.time.unit||\"day\";let{min:s,max:n,minDefined:a,maxDefined:r}=this.getUserBounds();function l(t){a||isNaN(t.min)||(s=Math.min(s,t.min)),r||isNaN(t.max)||(n=Math.max(n,t.max))}a&&r||(l(this._getLabelBounds()),\"ticks\"===t.bounds&&\"labels\"===t.ticks.source||l(this.getMinMax(!1))),s=o(s)&&!isNaN(s)?s:+e.startOf(Date.now(),i),n=o(n)&&!isNaN(n)?n:+e.endOf(Date.now(),i)+1,this.min=Math.min(s,n-1),this.max=Math.max(s+1,n)}_getLabelBounds(){const t=this.getLabelTimestamps();let e=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;return t.length&&(e=t[0],i=t[t.length-1]),{min:e,max:i}}buildTicks(){const t=this.options,e=t.time,i=t.ticks,s=\"labels\"===i.source?this.getLabelTimestamps():this._generate();\"ticks\"===t.bounds&&s.length&&(this.min=this._userMin||s[0],this.max=this._userMax||s[s.length-1]);const n=this.min,o=st(s,n,this.max);return this._unit=e.unit||(i.autoSkip?_a(e.minUnit,this.min,this.max,this._getLabelCapacity(n)):function(t,e,i,s,n){for(let o=ma.length-1;o>=ma.indexOf(i);o--){const i=ma[o];if(pa[i].common&&t._adapter.diff(n,s,i)>=e-1)return i}return ma[i?ma.indexOf(i):0]}(this,o.length,e.minUnit,this.min,this.max)),this._majorUnit=i.major.enabled&&\"year\"!==this._unit?function(t){for(let e=ma.indexOf(t)+1,i=ma.length;e<i;++e)if(pa[ma[e]].common)return ma[e]}(this._unit):void 0,this.initOffsets(s),t.reverse&&o.reverse(),va(this,o,this._majorUnit)}afterAutoSkip(){this.options.offsetAfterAutoskip&&this.initOffsets(this.ticks.map((t=>+t.value)))}initOffsets(t){let e,i,s=0,n=0;this.options.offset&&t.length&&(e=this.getDecimalForValue(t[0]),s=1===t.length?1-e:(this.getDecimalForValue(t[1])-e)/2,i=this.getDecimalForValue(t[t.length-1]),n=1===t.length?i:(i-this.getDecimalForValue(t[t.length-2]))/2);const o=t.length<3?.5:.25;s=Z(s,0,o),n=Z(n,0,o),this._offsets={start:s,end:n,factor:1/(s+1+n)}}_generate(){const t=this._adapter,e=this.min,i=this.max,s=this.options,n=s.time,o=n.unit||_a(n.minUnit,e,i,this._getLabelCapacity(e)),a=r(n.stepSize,1),l=\"week\"===o&&n.isoWeekday,h=B(l)||!0===l,c={};let d,u,f=e;if(h&&(f=+t.startOf(f,\"isoWeek\",l)),f=+t.startOf(f,h?\"day\":o),t.diff(i,e,o)>1e5*a)throw new Error(e+\" and \"+i+\" are too far apart with stepSize of \"+a+\" \"+o);const g=\"data\"===s.ticks.source&&this.getDataTimestamps();for(d=f,u=0;d<i;d=+t.add(d,a,o),u++)ya(c,d,g);return d!==i&&\"ticks\"!==s.bounds&&1!==u||ya(c,d,g),Object.keys(c).sort(((t,e)=>t-e)).map((t=>+t))}getLabelForValue(t){const e=this._adapter,i=this.options.time;return i.tooltipFormat?e.format(t,i.tooltipFormat):e.format(t,i.displayFormats.datetime)}_tickFormatFunction(t,e,i,s){const n=this.options,o=n.time.displayFormats,a=this._unit,r=this._majorUnit,l=a&&o[a],h=r&&o[r],d=i[e],u=r&&h&&d&&d.major,f=this._adapter.format(t,s||(u?h:l)),g=n.ticks.callback;return g?c(g,[f,e,i],this):f}generateTickLabels(t){let e,i,s;for(e=0,i=t.length;e<i;++e)s=t[e],s.label=this._tickFormatFunction(s.value,e,t)}getDecimalForValue(t){return null===t?NaN:(t-this.min)/(this.max-this.min)}getPixelForValue(t){const e=this._offsets,i=this.getDecimalForValue(t);return this.getPixelForDecimal((e.start+i)*e.factor)}getValueForPixel(t){const e=this._offsets,i=this.getDecimalForPixel(t)/e.factor-e.end;return this.min+i*(this.max-this.min)}_getLabelSize(t){const e=this.options.ticks,i=this.ctx.measureText(t).width,s=H(this.isHorizontal()?e.maxRotation:e.minRotation),n=Math.cos(s),o=Math.sin(s),a=this._resolveTickFontOptions(0).size;return{w:i*n+a*o,h:i*o+a*n}}_getLabelCapacity(t){const e=this.options.time,i=e.displayFormats,s=i[e.unit]||i.millisecond,n=this._tickFormatFunction(t,0,va(this,[t],this._majorUnit),s),o=this._getLabelSize(n),a=Math.floor(this.isHorizontal()?this.width/o.w:this.height/o.h)-1;return a>0?a:1}getDataTimestamps(){let t,e,i=this._cache.data||[];if(i.length)return i;const s=this.getMatchingVisibleMetas();if(this._normalized&&s.length)return this._cache.data=s[0].controller.getAllParsedValues(this);for(t=0,e=s.length;t<e;++t)i=i.concat(s[t].controller.getAllParsedValues(this));return this._cache.data=this.normalize(i)}getLabelTimestamps(){const t=this._cache.labels||[];let e,i;if(t.length)return t;const s=this.getLabels();for(e=0,i=s.length;e<i;++e)t.push(xa(this,s[e]));return this._cache.labels=this._normalized?t:this.normalize(t)}normalize(t){return rt(t.sort(ba))}}function Ma(t,e,i){let s,n,o,a,r=0,l=t.length-1;i?(e>=t[r].pos&&e<=t[l].pos&&({lo:r,hi:l}=et(t,\"pos\",e)),({pos:s,time:o}=t[r]),({pos:n,time:a}=t[l])):(e>=t[r].time&&e<=t[l].time&&({lo:r,hi:l}=et(t,\"time\",e)),({time:s,pos:o}=t[r]),({time:n,pos:a}=t[l]));const h=n-s;return h?o+(a-o)*(e-s)/h:o}wa.id=\"time\",wa.defaults={bounds:\"data\",adapters:{},time:{parser:!1,unit:!1,round:!1,isoWeekday:!1,minUnit:\"millisecond\",displayFormats:{}},ticks:{source:\"auto\",major:{enabled:!1}}};class ka extends wa{constructor(t){super(t),this._table=[],this._minPos=void 0,this._tableRange=void 0}initOffsets(){const t=this._getTimestampsForTable(),e=this._table=this.buildLookupTable(t);this._minPos=Ma(e,this.min),this._tableRange=Ma(e,this.max)-this._minPos,super.initOffsets(t)}buildLookupTable(t){const{min:e,max:i}=this,s=[],n=[];let o,a,r,l,h;for(o=0,a=t.length;o<a;++o)l=t[o],l>=e&&l<=i&&s.push(l);if(s.length<2)return[{time:e,pos:0},{time:i,pos:1}];for(o=0,a=s.length;o<a;++o)h=s[o+1],r=s[o-1],l=s[o],Math.round((h+r)/2)!==l&&n.push({time:l,pos:o/(a-1)});return n}_getTimestampsForTable(){let t=this._cache.all||[];if(t.length)return t;const e=this.getDataTimestamps(),i=this.getLabelTimestamps();return t=e.length&&i.length?this.normalize(e.concat(i)):e.length?e:i,t=this._cache.all=t,t}getDecimalForValue(t){return(Ma(this._table,t)-this._minPos)/this._tableRange}getValueForPixel(t){const e=this._offsets,i=this.getDecimalForPixel(t)/e.factor-e.end;return Ma(this._table,i*this._tableRange+this._minPos,!0)}}ka.id=\"timeseries\",ka.defaults=wa.defaults;var Sa=Object.freeze({__proto__:null,CategoryScale:ta,LinearScale:sa,LogarithmicScale:oa,RadialLinearScale:ga,TimeScale:wa,TimeSeriesScale:ka});return bn.register(Bn,Sa,co,Jo),bn.helpers={...Ti},bn._adapters=wn,bn.Animation=xs,bn.Animations=ys,bn.animator=mt,bn.controllers=Us.controllers.items,bn.DatasetController=Ls,bn.Element=Es,bn.elements=co,bn.Interaction=Vi,bn.layouts=Zi,bn.platforms=ps,bn.Scale=$s,bn.Ticks=Is,Object.assign(bn,Bn,Sa,co,Jo,ps),bn.Chart=bn,\"undefined\"!=typeof window&&(window.Chart=bn),bn}));\n","chartjs/chartjs-adapter-moment.js":"/*!\n  * chartjs-adapter-moment v1.0.0\n  * https://www.chartjs.org\n  * (c) 2021 chartjs-adapter-moment Contributors\n  * Released under the MIT license\n  */\n(function (global, factory) {\ntypeof exports === 'object' && typeof module !== 'undefined' ? factory(require('moment'), require('chart.js')) :\ntypeof define === 'function' && define.amd ? define(['moment', 'chart.js'], factory) :\n(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.moment, global.Chart));\n}(this, (function (moment, chart_js) { 'use strict';\n\nfunction _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }\n\nvar moment__default = /*#__PURE__*/_interopDefaultLegacy(moment);\n\nconst FORMATS = {\n  datetime: 'MMM D, YYYY, h:mm:ss a',\n  millisecond: 'h:mm:ss.SSS a',\n  second: 'h:mm:ss a',\n  minute: 'h:mm a',\n  hour: 'hA',\n  day: 'MMM D',\n  week: 'll',\n  month: 'MMM YYYY',\n  quarter: '[Q]Q - YYYY',\n  year: 'YYYY'\n};\n\nchart_js._adapters._date.override(typeof moment__default['default'] === 'function' ? {\n  _id: 'moment', // DEBUG ONLY\n\n  formats: function() {\n    return FORMATS;\n  },\n\n  parse: function(value, format) {\n    if (typeof value === 'string' && typeof format === 'string') {\n      value = moment__default['default'](value, format);\n    } else if (!(value instanceof moment__default['default'])) {\n      value = moment__default['default'](value);\n    }\n    return value.isValid() ? value.valueOf() : null;\n  },\n\n  format: function(time, format) {\n    return moment__default['default'](time).format(format);\n  },\n\n  add: function(time, amount, unit) {\n    return moment__default['default'](time).add(amount, unit).valueOf();\n  },\n\n  diff: function(max, min, unit) {\n    return moment__default['default'](max).diff(moment__default['default'](min), unit);\n  },\n\n  startOf: function(time, unit, weekday) {\n    time = moment__default['default'](time);\n    if (unit === 'isoWeek') {\n      weekday = Math.trunc(Math.min(Math.max(0, weekday), 6));\n      return time.isoWeekday(weekday).startOf('day').valueOf();\n    }\n    return time.startOf(unit).valueOf();\n  },\n\n  endOf: function(time, unit) {\n    return moment__default['default'](time).endOf(unit).valueOf();\n  }\n} : {});\n\n})));\n","Magento_AsynchronousOperations/js/insert-form.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'Magento_Ui/js/form/components/insert-form',\n    'uiRegistry'\n], function (Insert, registry) {\n    'use strict';\n\n    return Insert.extend({\n        defaults: {\n            modalProvider: '${ $.parentName }',\n            titlePrefix: '',\n            imports: {\n                changeModalTitle: '${ $.modalProvider }:state'\n            },\n            listens: {\n                responseData: 'afterRetry'\n            },\n            modules: {\n                modal: '${ $.modalProvider }',\n                notificationListing: '${ $.columnsProvider }'\n            }\n        },\n\n        /** @inheritdoc */\n        initConfig: function () {\n            var modalTitleProvider;\n\n            this._super();\n            modalTitleProvider = this.modalTitleProvider.split(':');\n            this.modalTitleTarget = modalTitleProvider[0];\n            this.modalTitlePath = modalTitleProvider[1];\n        },\n\n        /**\n         * Change modal title.\n         *\n         * @param {Boolean} change\n         */\n        changeModalTitle: function (change) {\n            if (change) {\n                registry.get(this.modalTitleTarget, function (target) {\n                    this.modal().setTitle(this.titlePrefix + target.get(this.modalTitlePath));\n                }.bind(this));\n            } else {\n                this.modal().setTitle('');\n            }\n        },\n\n        /**\n         * Action after retry operation.\n         *\n         * @param {Object} data\n         */\n        afterRetry: function (data) {\n            if (!data.error) {\n                this.modal().closeModal();\n                this.notificationListing().reload();\n            }\n        }\n    });\n});\n","Magento_AsynchronousOperations/js/form/error.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'Magento_Ui/js/form/element/abstract'\n], function (Abstract) {\n    'use strict';\n\n    return Abstract.extend({\n        /** @inheritdoc */\n        onUpdate: function () {\n            this.bubble('update', this.hasChanged());\n        }\n    });\n});\n","Magento_AsynchronousOperations/js/grid/listing.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'Magento_AdminNotification/js/grid/listing',\n    'Magento_Ui/js/modal/alert',\n    'mage/translate',\n    'underscore',\n    'jquery'\n], function (Listing, uiAlert, $t, _, $) {\n    'use strict';\n\n    return Listing.extend({\n        defaults: {\n            isAllowed: true,\n            ajaxSettings: {\n                method: 'POST',\n                data: {},\n                url: '${ $.dismissUrl }'\n            }\n        },\n\n        /** @inheritdoc */\n        initialize: function () {\n            _.bindAll(this, 'reload', 'onError');\n\n            return this._super();\n        },\n\n        /**\n         * Dismiss all items.\n         */\n        dismissAll: function () {\n            var toDismiss = [];\n\n            _.each(this.rows, function (row) {\n                if (row.dismiss) {\n                    toDismiss.push(row.uuid);\n                }\n            });\n            toDismiss.length && this.dismiss(toDismiss);\n        },\n\n        /**\n         * Dismiss action.\n         *\n         * @param {Array} items\n         */\n        dismiss: function (items) {\n            var config = _.extend({}, this.ajaxSettings);\n\n            config.data.uuid = items;\n            this.showLoader();\n\n            $.ajax(config)\n                .done(this.reload)\n                .fail(this.onError);\n        },\n\n        /**\n         * Success callback for dismiss request.\n         */\n        reload: function () {\n            this.source.reload({\n                refresh: true\n            });\n        },\n\n        /**\n         * Error callback for dismiss request.\n         *\n         * @param {Object} xhr\n         */\n        onError: function (xhr) {\n            this.hideLoader();\n\n            if (xhr.statusText === 'abort') {\n                return;\n            }\n\n            uiAlert({\n                content: $t('Something went wrong.')\n            });\n        }\n    });\n});\n","Magento_Swatches/js/text.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n *  @api\n */\ndefine([\n    'jquery',\n    'mage/template',\n    'uiRegistry',\n    'jquery/ui',\n    'prototype',\n    'validation'\n], function (jQuery, mageTemplate, rg) {\n    'use strict';\n\n    return function (config) {\n        var swatchOptionTextDefaultInputType = 'radio',\n            swatchTextOption = {\n                table: $('swatch-text-options-table'),\n                itemCount: 0,\n                totalItems: 0,\n                rendered: 0,\n                isReadOnly: config.isReadOnly,\n                template: mageTemplate('#swatch-text-row-template'),\n\n                /**\n                 * Add option\n                 *\n                 * @param {Object} data\n                 * @param {Object} render\n                 */\n                add: function (data, render) {\n                    var isNewOption = false,\n                        element;\n\n                    if (typeof data.id == 'undefined') {\n                        data = {\n                            'id': 'option_' + this.itemCount,\n                            'sort_order': this.itemCount + 1\n                        };\n                        isNewOption = true;\n                    }\n\n                    if (!data.intype) {\n                        data.intype = swatchOptionTextDefaultInputType;\n                    }\n\n                    element = this.template({\n                        data: data\n                    });\n\n                    if (isNewOption && !this.isReadOnly) {\n                        this.enableNewOptionDeleteButton(data.id);\n                    }\n                    this.itemCount++;\n                    this.totalItems++;\n                    this.elements += element;\n\n                    if (render) {\n                        this.render();\n                    }\n                },\n\n                /**\n                 * Remove option\n                 *\n                 * @param {Object} event\n                 */\n                remove: function (event) {\n                    var element = $(Event.findElement(event, 'tr')),\n                        elementFlags; // !!! Button already have table parent in safari\n\n                    // Safari workaround\n                    element.ancestors().each(function (parentItem) {\n                        if (parentItem.hasClassName('option-row')) {\n                            element = parentItem;\n                            throw $break;\n                        } else if (parentItem.hasClassName('box')) {\n                            throw $break;\n                        }\n                    });\n\n                    if (element) {\n                        elementFlags = element.getElementsByClassName('delete-flag');\n\n                        if (elementFlags[0]) {\n                            elementFlags[0].value = 1;\n                        }\n\n                        element.addClassName('no-display');\n                        element.addClassName('template');\n                        element.hide();\n                        this.totalItems--;\n                        this.updateItemsCountField();\n                    }\n                },\n\n                /**\n                 * Update items count field\n                 */\n                updateItemsCountField: function () {\n                    $('swatch-text-option-count-check').value = this.totalItems > 0 ? '1' : '';\n                },\n\n                /**\n                 * Enable delete button for new option\n                 *\n                 * @param {String} id\n                 */\n                enableNewOptionDeleteButton: function (id) {\n                    $$('#delete_button_swatch_container_' + id + ' button').each(function (button) {\n                        button.enable();\n                        button.removeClassName('disabled');\n                    });\n                },\n\n                /**\n                 * Bind remove button\n                 */\n                bindRemoveButtons: function () {\n                    jQuery('#swatch-text-options-panel').on('click', '.delete-option', this.remove.bind(this));\n                },\n\n                /**\n                 * Render action\n                 */\n                render: function () {\n                    Element.insert($$('[data-role=swatch-text-options-container]')[0], this.elements);\n                    this.elements = '';\n                },\n\n                /**\n                 * Render action with delay (performance fix)\n                 *\n                 * @param {Object} data\n                 * @param {Number} from\n                 * @param {Number} step\n                 * @param {Number} delay\n                 * @returns {Boolean}\n                 */\n                renderWithDelay: function (data, from, step, delay) {\n                    var arrayLength = data.length,\n                        len;\n\n                    for (len = from + step; from < len && from < arrayLength; from++) {\n                        this.add(data[from]);\n                    }\n                    this.render();\n\n                    if (from === arrayLength) {\n                        this.updateItemsCountField();\n                        this.rendered = 1;\n                        jQuery('body').trigger('processStop');\n\n                        return true;\n                    }\n                    setTimeout(this.renderWithDelay.bind(this, data, from, step, delay), delay);\n                },\n\n                /**\n                 * Ignore validate action\n                 */\n                ignoreValidate: function () {\n                    var ignore = '.ignore-validate input, ' +\n                        '.ignore-validate select, ' +\n                        '.ignore-validate textarea';\n\n                    jQuery('#edit_form').data('validator').settings.forceIgnore = ignore;\n                }\n            };\n\n        if ($('add_new_swatch_text_option_button')) {\n            Event.observe(\n                'add_new_swatch_text_option_button',\n                'click',\n                swatchTextOption.add.bind(swatchTextOption, true)\n            );\n        }\n        jQuery('#swatch-text-options-panel').on('render', function () {\n            swatchTextOption.ignoreValidate();\n\n            if (swatchTextOption.rendered) {\n                return false;\n            }\n            jQuery('body').trigger('processStart');\n            swatchTextOption.renderWithDelay(config.attributesData, 0, 100, 300);\n            swatchTextOption.bindRemoveButtons();\n        });\n\n        if (config.isSortable) {\n            jQuery(function ($) {\n                $('[data-role=swatch-text-options-container]').sortable({\n                    distance: 8,\n                    tolerance: 'pointer',\n                    cancel: 'input, button',\n                    axis: 'y',\n\n                    /**\n                     * Update components\n                     */\n                    update: function () {\n                        $('[data-role=swatch-text-options-container] [data-role=order]').each(\n                            function (index, element) {\n                                $(element).val(index + 1);\n                            }\n                        );\n                    }\n                });\n            });\n        }\n\n        jQuery(function () {\n            if (jQuery('#frontend_input').val() !== 'swatch_text') {\n                jQuery('.swatch-text-field-0').removeClass('required-option');\n            }\n        });\n\n        window.swatchTextOption = swatchTextOption;\n        window.swatchOptionTextDefaultInputType = swatchOptionTextDefaultInputType;\n\n        rg.set('swatch-text-options-panel', swatchTextOption);\n    };\n});\n","Magento_Swatches/js/product-attributes.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'Magento_Ui/js/modal/alert',\n    'Magento_Ui/js/modal/prompt',\n    'uiRegistry',\n    'collapsable'\n], function ($, alert, prompt, rg) {\n    'use strict';\n\n    return function (optionConfig) {\n        var activePanelClass = 'selected-type-options',\n            swatchProductAttributes = {\n                frontendInput: $('#frontend_input'),\n                isFilterable: $('#is_filterable'),\n                isFilterableInSearch: $('#is_filterable_in_search'),\n                backendType: $('#backend_type'),\n                usedForSortBy: $('#used_for_sort_by'),\n                frontendClass: $('#frontend_class'),\n                isWysiwygEnabled: $('#is_wysiwyg_enabled'),\n                isHtmlAllowedOnFront: $('#is_html_allowed_on_front'),\n                isRequired: $('#is_required'),\n                isUnique: $('#is_unique'),\n                defaultValueText: $('#default_value_text'),\n                defaultValueTextarea: $('#default_value_textarea'),\n                defaultValueDate: $('#default_value_date'),\n                defaultValueDatetime: $('#default_value_datetime'),\n                defaultValueYesno: $('#default_value_yesno'),\n                isGlobal: $('#is_global'),\n                useProductImageForSwatch: $('#use_product_image_for_swatch'),\n                updateProductPreviewImage: $('#update_product_preview_image'),\n                usedInProductListing: $('#used_in_product_listing'),\n                isVisibleOnFront: $('#is_visible_on_front'),\n                position: $('#position'),\n                attrTabsFront: $('#product_attribute_tabs_front'),\n\n                /**\n                 * @returns {*|jQuery|HTMLElement}\n                 */\n                get tabsFront() {\n                    return this.attrTabsFront.length ? this.attrTabsFront.closest('li') : $('#front_fieldset-wrapper');\n                },\n                selectFields: ['boolean', 'select', 'multiselect', 'price', 'swatch_text', 'swatch_visual'],\n\n                /**\n                 * @this {swatchProductAttributes}\n                 */\n                toggleApplyVisibility: function (select) {\n                    if ($(select).val() === 1) {\n                        $(select).next('select').removeClass('no-display');\n                        $(select).next('select').removeClass('ignore-validate');\n                    } else {\n                        $(select).next('select').addClass('no-display');\n                        $(select).next('select').addClass('ignore-validate');\n                        $(select).next('select option:selected').each(function () {\n                            this.selected = false;\n                        });\n                    }\n                },\n\n                /**\n                 * @this {swatchProductAttributes}\n                 */\n                checkOptionsPanelVisibility: function () {\n                    var selectOptionsPanel = $('#manage-options-panel'),\n                        visualOptionsPanel = $('#swatch-visual-options-panel'),\n                        textOptionsPanel = $('#swatch-text-options-panel');\n\n                    this._hidePanel(selectOptionsPanel);\n                    this._hidePanel(visualOptionsPanel);\n                    this._hidePanel(textOptionsPanel);\n\n                    switch (this.frontendInput.val()) {\n                        case 'swatch_visual':\n                            this._showPanel(visualOptionsPanel);\n                            break;\n\n                        case 'swatch_text':\n                            this._showPanel(textOptionsPanel);\n                            break;\n\n                        case 'select':\n                        case 'multiselect':\n                            this._showPanel(selectOptionsPanel);\n                            break;\n                    }\n                },\n\n                /**\n                 * @this {swatchProductAttributes}\n                 */\n                bindAttributeInputType: function () {\n                    this.checkOptionsPanelVisibility();\n                    this.switchDefaultValueField();\n\n                    if (!~$.inArray(this.frontendInput.val(), this.selectFields)) {\n                        // not in array\n                        this.isFilterable.selectedIndex = 0;\n                        this._disable(this.isFilterable);\n                        this._disable(this.isFilterableInSearch);\n                    } else {\n                        // in array\n                        this._enable(this.isFilterable);\n                        this._enable(this.isFilterableInSearch);\n                        this.backendType.val('int');\n                    }\n\n                    if (this.frontendInput.val() === 'multiselect' ||\n                        this.frontendInput.val() === 'gallery' ||\n                        this.frontendInput.val() === 'textarea'\n                    ) {\n                        this._disable(this.usedForSortBy);\n                    } else {\n                        this._enable(this.usedForSortBy);\n                    }\n\n                    if (this.frontendInput.val() === 'swatch_text') {\n                        $('.swatch-text-field-0').addClass('required-option');\n                    } else {\n                        $('.swatch-text-field-0').removeClass('required-option');\n                    }\n\n                    this.setRowVisibility(this.isWysiwygEnabled, false);\n                    this.setRowVisibility(this.isHtmlAllowedOnFront, false);\n\n                    switch (this.frontendInput.val()) {\n                        case 'textarea':\n                            this.setRowVisibility(this.isWysiwygEnabled, true);\n\n                            if (this.isWysiwygEnabled.val() === '0') {\n                                this._enable(this.isHtmlAllowedOnFront);\n                            }\n                            this.frontendClass.val('');\n                            this._disable(this.frontendClass);\n                            break;\n\n                        case 'text':\n                            this.setRowVisibility(this.isHtmlAllowedOnFront, true);\n                            this._enable(this.frontendClass);\n                            break;\n\n                        case 'select':\n                        case 'multiselect':\n                            this.setRowVisibility(this.isHtmlAllowedOnFront, true);\n                            this.frontendClass.val('');\n                            this._disable(this.frontendClass);\n                            break;\n                        default:\n                            this.frontendClass.val('');\n                            this._disable(this.frontendClass);\n                    }\n\n                    this.switchIsFilterable();\n                },\n\n                /**\n                 * @this {swatchProductAttributes}\n                 */\n                switchIsFilterable: function () {\n                    if (this.isFilterable.selectedIndex === 0) {\n                        this._disable(this.position);\n                    } else {\n                        this._enable(this.position);\n                    }\n                },\n\n                /**\n                 * @this {swatchProductAttributes}\n                 */\n                switchDefaultValueField: function () {\n                    var currentValue = this.frontendInput.val(),\n                        defaultValueTextVisibility = false,\n                        defaultValueTextareaVisibility = false,\n                        defaultValueDateVisibility = false,\n                        defaultValueDatetimeVisibility = false,\n                        defaultValueYesnoVisibility = false,\n                        scopeVisibility = true,\n                        useProductImageForSwatch = false,\n                        defaultValueUpdateImage = false,\n                        optionDefaultInputType = '',\n                        isFrontTabHidden = false,\n                        thing = this;\n\n                    if (!this.frontendInput.length) {\n                        return;\n                    }\n\n                    switch (currentValue) {\n                        case 'select':\n                            optionDefaultInputType = 'radio';\n                            break;\n\n                        case 'multiselect':\n                            optionDefaultInputType = 'checkbox';\n                            break;\n\n                        case 'date':\n                            defaultValueDateVisibility = true;\n                            break;\n\n                        case 'datetime':\n                            defaultValueDatetimeVisibility = true;\n                            break;\n\n                        case 'boolean':\n                            defaultValueYesnoVisibility = true;\n                            break;\n\n                        case 'textarea':\n                        case 'texteditor':\n                            defaultValueTextareaVisibility = true;\n                            break;\n\n                        case 'media_image':\n                            defaultValueTextVisibility = false;\n                            break;\n\n                        case 'price':\n                            scopeVisibility = false;\n                            break;\n\n                        case 'swatch_visual':\n                            useProductImageForSwatch = true;\n                            defaultValueUpdateImage = true;\n                            defaultValueTextVisibility = false;\n                            break;\n\n                        case 'swatch_text':\n                            useProductImageForSwatch = false;\n                            defaultValueUpdateImage = true;\n                            defaultValueTextVisibility = false;\n                            break;\n                        default:\n                            defaultValueTextVisibility = true;\n                            break;\n                    }\n\n                    delete optionConfig.hiddenFields['swatch_visual'];\n                    delete optionConfig.hiddenFields['swatch_text'];\n\n                    if (currentValue === 'media_image') {\n                        this.tabsFront.hide();\n                        this.setRowVisibility(this.isRequired, false);\n                        this.setRowVisibility(this.isUnique, false);\n                        this.setRowVisibility(this.frontendClass, false);\n                    } else if (optionConfig.hiddenFields[currentValue]) {\n                        $.each(optionConfig.hiddenFields[currentValue], function (key, option) {\n                            switch (option) {\n                                case '_front_fieldset':\n                                    thing.tabsFront.hide();\n                                    isFrontTabHidden = true;\n                                    break;\n\n                                case '_default_value':\n                                    defaultValueTextVisibility = false;\n                                    defaultValueTextareaVisibility = false;\n                                    defaultValueDateVisibility = false;\n                                    defaultValueDatetimeVisibility = false;\n                                    defaultValueYesnoVisibility = false;\n                                    break;\n\n                                case '_scope':\n                                    scopeVisibility = false;\n                                    break;\n                                default:\n                                    thing.setRowVisibility($('#' + option), false);\n                            }\n                        });\n\n                        if (!isFrontTabHidden) {\n                            thing.tabsFront.show();\n                        }\n\n                    } else {\n                        this.tabsFront.show();\n                        this.showDefaultRows();\n                    }\n\n                    this.setRowVisibility(this.defaultValueText, defaultValueTextVisibility);\n                    this.setRowVisibility(this.defaultValueTextarea, defaultValueTextareaVisibility);\n                    this.setRowVisibility(this.defaultValueDate, defaultValueDateVisibility);\n                    this.setRowVisibility(this.defaultValueDatetime, defaultValueDatetimeVisibility);\n                    this.setRowVisibility(this.defaultValueYesno, defaultValueYesnoVisibility);\n                    this.setRowVisibility(this.isGlobal, scopeVisibility);\n\n                    /* swatch attributes */\n                    this.setRowVisibility(this.useProductImageForSwatch, useProductImageForSwatch);\n                    this.setRowVisibility(this.updateProductPreviewImage, defaultValueUpdateImage);\n\n                    $('input[name=\\'default[]\\']').each(function () {\n                        $(this).attr('type', optionDefaultInputType);\n                    });\n                },\n\n                /**\n                 * @this {swatchProductAttributes}\n                 */\n                showDefaultRows: function () {\n                    this.setRowVisibility(this.isRequired, true);\n                    this.setRowVisibility(this.isUnique, true);\n                    this.setRowVisibility(this.frontendClass, true);\n                },\n\n                /**\n                 * @param {Object} el\n                 * @param {Boolean} isVisible\n                 * @this {swatchProductAttributes}\n                 */\n                setRowVisibility: function (el, isVisible) {\n                    if (isVisible) {\n                        el.show();\n                        el.closest('.field').show();\n                    } else {\n                        el.hide();\n                        el.closest('.field').hide();\n                    }\n                },\n\n                /**\n                 * @param {Object} el\n                 * @this {swatchProductAttributes}\n                 */\n                _disable: function (el) {\n                    el.attr('disabled', 'disabled');\n                },\n\n                /**\n                 * @param {jQuery} el\n                 * @this {swatchProductAttributes}\n                 */\n                _enable: function (el) {\n                    if (!el.attr('readonly')) {\n                        el.prop('disabled', false);\n                    }\n                },\n\n                /**\n                 * @param {Object} el\n                 * @this {swatchProductAttributes}\n                 */\n                _showPanel: function (el) {\n                    el.closest('.fieldset').show();\n                    el.addClass(activePanelClass);\n                    this._render(el.attr('id'));\n                },\n\n                /**\n                 * @param {Object} el\n                 * @this {swatchProductAttributes}\n                 */\n                _hidePanel: function (el) {\n                    el.closest('.fieldset').hide();\n                    el.removeClass(activePanelClass);\n                },\n\n                /**\n                 * @param {String} id\n                 * @this {swatchProductAttributes}\n                 */\n                _render: function (id) {\n                    rg.get(id, function () {\n                        $('#' + id).trigger('render');\n                    });\n                },\n\n                /**\n                 * @param {String} promptMessage\n                 * @this {swatchProductAttributes}\n                 */\n                saveAttributeInNewSet: function (promptMessage) {\n\n                    prompt({\n                        content: promptMessage,\n                        actions: {\n\n                            /**\n                             * @param {String} val\n                             * @this {actions}\n                             */\n                            confirm: function (val) {\n                                var rules = ['required-entry', 'validate-no-html-tags'],\n                                    newAttributeSetNameInputId = $('#new_attribute_set_name'),\n                                    editForm = $('#edit_form'),\n                                    newAttributeSetName = val,\n                                    i;\n\n                                if (!newAttributeSetName) {\n                                    return;\n                                }\n\n                                for (i = 0; i < rules.length; i++) {\n                                    if (!$.validator.methods[rules[i]](newAttributeSetName)) {\n                                        alert({\n                                            content: $.validator.messages[rules[i]]\n                                        });\n\n                                        return;\n                                    }\n                                }\n\n                                if (newAttributeSetNameInputId.length) {\n                                    newAttributeSetNameInputId.val(newAttributeSetName);\n                                } else {\n                                    editForm.append(new Element('input', {\n                                            type: 'hidden',\n                                            id: newAttributeSetNameInputId,\n                                            name: 'new_attribute_set_name',\n                                            value: newAttributeSetName\n                                        })\n                                    );\n                                }\n                                // Temporary solution will replaced after refactoring of attributes functionality\n                                editForm.triggerHandler('save');\n                            }\n                        }\n                    });\n                }\n            };\n\n        $(function () {\n            var editForm = $('#edit_form'),\n                swatchVisualPanel = $('#swatch-visual-options-panel'),\n                swatchTextPanel = $('#swatch-text-options-panel'),\n                tableBody = $(),\n                activePanel = $();\n\n            $('#frontend_input').on('change', function () {\n                swatchProductAttributes.bindAttributeInputType();\n            });\n            $('#is_filterable').on('change', function () {\n                swatchProductAttributes.switchIsFilterable();\n            });\n\n            swatchProductAttributes.bindAttributeInputType();\n\n            // @todo: refactor collapsible component\n            $('.attribute-popup .collapse, [data-role=\"advanced_fieldset-content\"]')\n                .collapsable()\n                .collapse('hide');\n\n            editForm.on('beforeSubmit', function () {\n                var optionContainer, optionsValues;\n\n                activePanel = swatchTextPanel.hasClass(activePanelClass) ? swatchTextPanel : swatchVisualPanel;\n                optionContainer = activePanel.find('table tbody');\n\n                if (activePanel.hasClass(activePanelClass)) {\n                    optionsValues = $.map(\n                        optionContainer.find('tr'),\n                        function (row) {\n                            return $(row).find('input, select, textarea').serialize();\n                        }\n                    );\n                    $('<input>')\n                        .attr({\n                            type: 'hidden',\n                            name: 'serialized_options'\n                        })\n                        .val(JSON.stringify(optionsValues))\n                        .prependTo(editForm);\n                }\n\n                tableBody = optionContainer.detach();\n            });\n\n            editForm.on('afterValidate.error highlight.validate', function () {\n                if (activePanel.hasClass(activePanelClass)) {\n                    activePanel.find('table').append(tableBody);\n                    $('input[name=\"serialized_options\"]').remove();\n                }\n            });\n        });\n\n        window.saveAttributeInNewSet = swatchProductAttributes.saveAttributeInNewSet;\n        window.toggleApplyVisibility = swatchProductAttributes.toggleApplyVisibility;\n    };\n});\n","Magento_Swatches/js/swatch-renderer.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'underscore',\n    'mage/template',\n    'mage/smart-keyboard-handler',\n    'mage/translate',\n    'priceUtils',\n    'jquery-ui-modules/widget',\n    'jquery/jquery.parsequery',\n    'mage/validation/validation'\n], function ($, _, mageTemplate, keyboardHandler, $t, priceUtils) {\n    'use strict';\n\n    /**\n     * Extend form validation to support swatch accessibility\n     */\n    $.widget('mage.validation', $.mage.validation, {\n        /**\n         * Handle form with swatches validation. Focus on first invalid swatch block.\n         *\n         * @param {jQuery.Event} event\n         * @param {Object} validation\n         */\n        listenFormValidateHandler: function (event, validation) {\n            var swatchWrapper, firstActive, swatches, swatch, successList, errorList, firstSwatch;\n\n            this._superApply(arguments);\n\n            swatchWrapper = '.swatch-attribute-options';\n            swatches = $(event.target).find(swatchWrapper);\n\n            if (!swatches.length) {\n                return;\n            }\n\n            swatch = '.swatch-attribute';\n            firstActive = $(validation.errorList[0].element || []);\n            successList = validation.successList;\n            errorList = validation.errorList;\n            firstSwatch = $(firstActive).parent(swatch).find(swatchWrapper);\n\n            keyboardHandler.focus(swatches);\n\n            $.each(successList, function (index, item) {\n                $(item).parent(swatch).find(swatchWrapper).attr('aria-invalid', false);\n            });\n\n            $.each(errorList, function (index, item) {\n                $(item.element).parent(swatch).find(swatchWrapper).attr('aria-invalid', true);\n            });\n\n            if (firstSwatch.length) {\n                $(firstSwatch).trigger('focus');\n            }\n        }\n    });\n\n    /**\n     * Render tooltips by attributes (only to up).\n     * Required element attributes:\n     *  - data-option-type (integer, 0-3)\n     *  - data-option-label (string)\n     *  - data-option-tooltip-thumb\n     *  - data-option-tooltip-value\n     *  - data-thumb-width\n     *  - data-thumb-height\n     */\n    $.widget('mage.SwatchRendererTooltip', {\n        options: {\n            delay: 200,                             //how much ms before tooltip to show\n            tooltipClass: 'swatch-option-tooltip'  //configurable, but remember about css\n        },\n\n        /**\n         * @private\n         */\n        _init: function () {\n            var $widget = this,\n                $this = this.element,\n                $element = $('.' + $widget.options.tooltipClass),\n                timer,\n                type = parseInt($this.data('option-type'), 10),\n                label = $this.data('option-label'),\n                thumb = $this.data('option-tooltip-thumb'),\n                value = $this.data('option-tooltip-value'),\n                width = $this.data('thumb-width'),\n                height = $this.data('thumb-height'),\n                $image,\n                $title,\n                $corner;\n\n            if (!$element.length) {\n                $element = $('<div class=\"' +\n                    $widget.options.tooltipClass +\n                    '\"><div class=\"image\"></div><div class=\"title\"></div><div class=\"corner\"></div></div>'\n                );\n                $('body').append($element);\n            }\n\n            $image = $element.find('.image');\n            $title = $element.find('.title');\n            $corner = $element.find('.corner');\n\n            $this.on('mouseenter', function () {\n                if (!$this.hasClass('disabled')) {\n                    timer = setTimeout(\n                        function () {\n                            var leftOpt = null,\n                                leftCorner = 0,\n                                left,\n                                $window;\n\n                            if (type === 2) {\n                                // Image\n                                $image.css({\n                                    'background': 'url(\"' + thumb + '\") no-repeat center', //Background case\n                                    'background-size': 'initial',\n                                    'width': width + 'px',\n                                    'height': height + 'px'\n                                });\n                                $image.show();\n                            } else if (type === 1) {\n                                // Color\n                                $image.css({\n                                    background: value\n                                });\n                                $image.show();\n                            } else if (type === 0 || type === 3) {\n                                // Default\n                                $image.hide();\n                            }\n\n                            $title.text(label);\n\n                            leftOpt = $this.offset().left;\n                            left = leftOpt + $this.width() / 2 - $element.width() / 2;\n                            $window = $(window);\n\n                            // the numbers (5 and 5) is magick constants for offset from left or right page\n                            if (left < 0) {\n                                left = 5;\n                            } else if (left + $element.width() > $window.width()) {\n                                left = $window.width() - $element.width() - 5;\n                            }\n\n                            // the numbers (6,  3 and 18) is magick constants for offset tooltip\n                            leftCorner = 0;\n\n                            if ($element.width() < $this.width()) {\n                                leftCorner = $element.width() / 2 - 3;\n                            } else {\n                                leftCorner = (leftOpt > left ? leftOpt - left : left - leftOpt) + $this.width() / 2 - 6;\n                            }\n\n                            $corner.css({\n                                left: leftCorner\n                            });\n                            $element.css({\n                                left: left,\n                                top: $this.offset().top - $element.height() - $corner.height() - 18\n                            }).show();\n                        },\n                        $widget.options.delay\n                    );\n                }\n            });\n\n            $this.on('mouseleave', function () {\n                $element.hide();\n                clearTimeout(timer);\n            });\n\n            $(document).on('tap', function () {\n                $element.hide();\n                clearTimeout(timer);\n            });\n\n            $this.on('tap', function (event) {\n                event.stopPropagation();\n            });\n        }\n    });\n\n    /**\n     * Render swatch controls with options and use tooltips.\n     * Required two json:\n     *  - jsonConfig (magento's option config)\n     *  - jsonSwatchConfig (swatch's option config)\n     *\n     *  Tuning:\n     *  - numberToShow (show \"more\" button if options are more)\n     *  - onlySwatches (hide selectboxes)\n     *  - moreButtonText (text for \"more\" button)\n     *  - selectorProduct (selector for product container)\n     *  - selectorProductPrice (selector for change price)\n     */\n    $.widget('mage.SwatchRenderer', {\n        options: {\n            classes: {\n                attributeClass: 'swatch-attribute',\n                attributeLabelClass: 'swatch-attribute-label',\n                attributeSelectedOptionLabelClass: 'swatch-attribute-selected-option',\n                attributeOptionsWrapper: 'swatch-attribute-options',\n                attributeInput: 'swatch-input',\n                optionClass: 'swatch-option',\n                selectClass: 'swatch-select',\n                moreButton: 'swatch-more',\n                loader: 'swatch-option-loading'\n            },\n            // option's json config\n            jsonConfig: {},\n\n            // swatch's json config\n            jsonSwatchConfig: {},\n\n            // selector of parental block of prices and swatches (need to know where to seek for price block)\n            selectorProduct: '.product-info-main',\n\n            // selector of price wrapper (need to know where set price)\n            selectorProductPrice: '[data-role=priceBox]',\n\n            //selector of product images gallery wrapper\n            mediaGallerySelector: '[data-gallery-role=gallery-placeholder]',\n\n            // selector of category product tile wrapper\n            selectorProductTile: '.product-item',\n\n            // number of controls to show (false or zero = show all)\n            numberToShow: false,\n\n            // show only swatch controls\n            onlySwatches: false,\n\n            // enable label for control\n            enableControlLabel: true,\n\n            // control label id\n            controlLabelId: '',\n\n            // text for more button\n            moreButtonText: $t('More'),\n\n            // Callback url for media\n            mediaCallback: '',\n\n            // Local media cache\n            mediaCache: {},\n\n            // Cache for BaseProduct images. Needed when option unset\n            mediaGalleryInitial: [{}],\n\n            // Use ajax to get image data\n            useAjax: false,\n\n            /**\n             * Defines the mechanism of how images of a gallery should be\n             * updated when user switches between configurations of a product.\n             *\n             * As for now value of this option can be either 'replace' or 'prepend'.\n             *\n             * @type {String}\n             */\n            gallerySwitchStrategy: 'replace',\n\n            // whether swatches are rendered in product list or on product page\n            inProductList: false,\n\n            // sly-old-price block selector\n            slyOldPriceSelector: '.sly-old-price',\n\n            // tier prise selectors start\n            tierPriceTemplateSelector: '#tier-prices-template',\n            tierPriceBlockSelector: '[data-role=\"tier-price-block\"]',\n            tierPriceTemplate: '',\n            // tier prise selectors end\n\n            // A price label selector\n            normalPriceLabelSelector: '.product-info-main .normal-price .price-label',\n            qtyInfo: '#qty'\n        },\n\n        /**\n         * Get chosen product\n         *\n         * @returns int|null\n         */\n        getProduct: function () {\n            var products = this._CalcProducts();\n\n            return _.isArray(products) ? products[0] : null;\n        },\n\n        /**\n         * Get chosen product id\n         *\n         * @returns int|null\n         */\n        getProductId: function () {\n            var products = this._CalcProducts();\n\n            return _.isArray(products) && products.length === 1 ? products[0] : null;\n        },\n\n        /**\n         * @private\n         */\n        _init: function () {\n            // Don't render the same set of swatches twice\n            if ($(this.element).attr('data-rendered')) {\n                return;\n            }\n\n            $(this.element).attr('data-rendered', true);\n\n            if (_.isEmpty(this.options.jsonConfig.images)) {\n                this.options.useAjax = true;\n                // creates debounced variant of _LoadProductMedia()\n                // to use it in events handlers instead of _LoadProductMedia()\n                this._debouncedLoadProductMedia = _.debounce(this._LoadProductMedia.bind(this), 500);\n            }\n\n            this.options.tierPriceTemplate = $(this.options.tierPriceTemplateSelector).html();\n\n            if (this.options.jsonConfig !== '' && this.options.jsonSwatchConfig !== '') {\n                // store unsorted attributes\n                this.options.jsonConfig.mappedAttributes = _.clone(this.options.jsonConfig.attributes);\n                this._sortAttributes();\n                this._RenderControls();\n                this._setPreSelectedGallery();\n                $(this.element).trigger('swatch.initialized');\n            } else {\n                console.log('SwatchRenderer: No input data received');\n            }\n        },\n\n        /**\n         * @private\n         */\n        _sortAttributes: function () {\n            this.options.jsonConfig.attributes = _.sortBy(this.options.jsonConfig.attributes, function (attribute) {\n                return parseInt(attribute.position, 10);\n            });\n        },\n\n        /**\n         * @private\n         */\n        _create: function () {\n            var options = this.options,\n                gallery = $('[data-gallery-role=gallery-placeholder]', '.column.main'),\n                productData = this._determineProductData(),\n                $main = productData.isInProductView ?\n                    this.element.parents('.column.main') :\n                    this.element.parents('.product-item-info');\n\n            if (productData.isInProductView) {\n                gallery.data('gallery') ?\n                    this._onGalleryLoaded(gallery) :\n                    gallery.on('gallery:loaded', this._onGalleryLoaded.bind(this, gallery));\n            } else {\n                options.mediaGalleryInitial = [{\n                    'img': $main.find('.product-image-photo').attr('src')\n                }];\n            }\n\n            this.productForm = this.element.parents(this.options.selectorProductTile).find('form:first');\n            this.inProductList = this.productForm.length > 0;\n            $(this.options.qtyInfo).on('input', this._onQtyChanged.bind(this));\n        },\n\n        /**\n         * Determine product id and related data\n         *\n         * @returns {{productId: *, isInProductView: bool}}\n         * @private\n         */\n        _determineProductData: function () {\n            // Check if product is in a list of products.\n            var productId,\n                isInProductView = false;\n\n            productId = this.element.parents('.product-item-details')\n                    .find('.price-box.price-final_price').attr('data-product-id');\n\n            if (!productId) {\n                // Check individual product.\n                productId = $('[name=product]').val();\n                isInProductView = productId > 0;\n            }\n\n            return {\n                productId: productId,\n                isInProductView: isInProductView\n            };\n        },\n\n        /**\n         * Render controls\n         *\n         * @private\n         */\n        _RenderControls: function () {\n            var $widget = this,\n                container = this.element,\n                classes = this.options.classes,\n                chooseText = this.options.jsonConfig.chooseText,\n                showTooltip = this.options.showTooltip;\n\n            $widget.optionsMap = {};\n\n            $.each(this.options.jsonConfig.attributes, function () {\n                var item = this,\n                    controlLabelId = 'option-label-' + item.code + '-' + item.id,\n                    options = $widget._RenderSwatchOptions(item, controlLabelId),\n                    select = $widget._RenderSwatchSelect(item, chooseText),\n                    input = $widget._RenderFormInput(item),\n                    listLabel = '',\n                    label = '';\n\n                // Show only swatch controls\n                if ($widget.options.onlySwatches && !$widget.options.jsonSwatchConfig.hasOwnProperty(item.id)) {\n                    return;\n                }\n\n                if ($widget.options.enableControlLabel) {\n                    label +=\n                        '<span id=\"' + controlLabelId + '\" class=\"' + classes.attributeLabelClass + '\">' +\n                        $('<i></i>').text(item.label).html() +\n                        '</span>' +\n                        '<span class=\"' + classes.attributeSelectedOptionLabelClass + '\"></span>';\n                }\n\n                if ($widget.inProductList) {\n                    $widget.productForm.append(input);\n                    input = '';\n                    listLabel = 'aria-label=\"' + $('<i></i>').text(item.label).html() + '\"';\n                } else {\n                    listLabel = 'aria-labelledby=\"' + controlLabelId + '\"';\n                }\n\n                // Create new control\n                container.append(\n                    '<div class=\"' + classes.attributeClass + ' ' + item.code + '\" ' +\n                         'data-attribute-code=\"' + item.code + '\" ' +\n                         'data-attribute-id=\"' + item.id + '\">' +\n                        label +\n                        '<div aria-activedescendant=\"\" ' +\n                             'tabindex=\"0\" ' +\n                             'aria-invalid=\"false\" ' +\n                             'aria-required=\"true\" ' +\n                             'role=\"listbox\" ' + listLabel +\n                             'class=\"' + classes.attributeOptionsWrapper + ' clearfix\">' +\n                            options + select +\n                        '</div>' + input +\n                    '</div>'\n                );\n\n                $widget.optionsMap[item.id] = {};\n\n                // Aggregate options array to hash (key => value)\n                $.each(item.options, function () {\n                    if (this.products.length > 0) {\n                        $widget.optionsMap[item.id][this.id] = {\n                            price: parseInt(\n                                $widget.options.jsonConfig.optionPrices[this.products[0]].finalPrice.amount,\n                                10\n                            ),\n                            products: this.products\n                        };\n                    }\n                });\n            });\n\n            if (showTooltip === 1) {\n                // Connect Tooltip\n                container\n                    .find('[data-option-type=\"1\"], [data-option-type=\"2\"],' +\n                        ' [data-option-type=\"0\"], [data-option-type=\"3\"]')\n                    .SwatchRendererTooltip();\n            }\n\n            // Hide all elements below more button\n            $('.' + classes.moreButton).nextAll().hide();\n\n            // Handle events like click or change\n            $widget._EventListener();\n\n            // Rewind options\n            $widget._Rewind(container);\n\n            //Emulate click on all swatches from Request\n            $widget._EmulateSelected($.parseQuery());\n            $widget._EmulateSelected($widget._getSelectedAttributes());\n        },\n\n        disableSwatchForOutOfStockProducts: function () {\n            let $widget = this, container = this.element;\n\n            $.each(this.options.jsonConfig.attributes, function () {\n                let item = this;\n\n                if ($widget.options.jsonConfig.canDisplayShowOutOfStockStatus) {\n                    let salableProducts = $widget.options.jsonConfig.salable[item.id],\n                        swatchOptions = $(container).find(`[data-attribute-id='${item.id}']`).find('.swatch-option');\n\n                    swatchOptions.each(function (key, value) {\n                        let optionId = $(value).data('option-id');\n\n                        if (!salableProducts.hasOwnProperty(optionId)) {\n                            $(value).attr('disabled', true).addClass('disabled');\n                        }\n                    });\n                }\n            });\n        },\n\n        /**\n         * Render swatch options by part of config\n         *\n         * @param {Object} config\n         * @param {String} controlId\n         * @returns {String}\n         * @private\n         */\n        _RenderSwatchOptions: function (config, controlId) {\n            var optionConfig = this.options.jsonSwatchConfig[config.id],\n                optionClass = this.options.classes.optionClass,\n                sizeConfig = this.options.jsonSwatchImageSizeConfig,\n                moreLimit = parseInt(this.options.numberToShow, 10),\n                moreClass = this.options.classes.moreButton,\n                moreText = this.options.moreButtonText,\n                countAttributes = 0,\n                html = '';\n\n            if (!this.options.jsonSwatchConfig.hasOwnProperty(config.id)) {\n                return '';\n            }\n\n            $.each(config.options, function (index) {\n                var id,\n                    type,\n                    value,\n                    thumb,\n                    label,\n                    width,\n                    height,\n                    attr,\n                    swatchImageWidth,\n                    swatchImageHeight;\n\n                if (!optionConfig.hasOwnProperty(this.id)) {\n                    return '';\n                }\n\n                // Add more button\n                if (moreLimit === countAttributes++) {\n                    html += '<a href=\"#\" class=\"' + moreClass + '\"><span>' + moreText + '</span></a>';\n                }\n\n                id = this.id;\n                type = parseInt(optionConfig[id].type, 10);\n                value = optionConfig[id].hasOwnProperty('value') ?\n                    $('<i></i>').text(optionConfig[id].value).html() : '';\n                thumb = optionConfig[id].hasOwnProperty('thumb') ? optionConfig[id].thumb : '';\n                width = _.has(sizeConfig, 'swatchThumb') ? sizeConfig.swatchThumb.width : 110;\n                height = _.has(sizeConfig, 'swatchThumb') ? sizeConfig.swatchThumb.height : 90;\n                label = this.label ? $('<i></i>').text(this.label).html() : '';\n                attr =\n                    ' id=\"' + controlId + '-item-' + id + '\"' +\n                    ' index=\"' + index + '\"' +\n                    ' aria-checked=\"false\"' +\n                    ' aria-describedby=\"' + controlId + '\"' +\n                    ' tabindex=\"0\"' +\n                    ' data-option-type=\"' + type + '\"' +\n                    ' data-option-id=\"' + id + '\"' +\n                    ' data-option-label=\"' + label + '\"' +\n                    ' aria-label=\"' + label + '\"' +\n                    ' role=\"option\"' +\n                    ' data-thumb-width=\"' + width + '\"' +\n                    ' data-thumb-height=\"' + height + '\"';\n\n                attr += thumb !== '' ? ' data-option-tooltip-thumb=\"' + thumb + '\"' : '';\n                attr += value !== '' ? ' data-option-tooltip-value=\"' + value + '\"' : '';\n\n                swatchImageWidth = _.has(sizeConfig, 'swatchImage') ? sizeConfig.swatchImage.width : 30;\n                swatchImageHeight = _.has(sizeConfig, 'swatchImage') ? sizeConfig.swatchImage.height : 20;\n\n                if (!this.hasOwnProperty('products') || this.products.length <= 0) {\n                    attr += ' data-option-empty=\"true\"';\n                }\n\n                if (type === 0) {\n                    // Text\n                    html += '<div class=\"' + optionClass + ' text\" ' + attr + '>' + (value ? value : label) +\n                        '</div>';\n                } else if (type === 1) {\n                    // Color\n                    html += '<div class=\"' + optionClass + ' color\" ' + attr +\n                        ' style=\"background: ' + value +\n                        ' no-repeat center; background-size: initial;\">' + '' +\n                        '</div>';\n                } else if (type === 2) {\n                    // Image\n                    html += '<div class=\"' + optionClass + ' image\" ' + attr +\n                        ' style=\"background: url(' + value + ') no-repeat center; background-size: initial;width:' +\n                        swatchImageWidth + 'px; height:' + swatchImageHeight + 'px\">' + '' +\n                        '</div>';\n                } else if (type === 3) {\n                    // Clear\n                    html += '<div class=\"' + optionClass + '\" ' + attr + '></div>';\n                } else {\n                    // Default\n                    html += '<div class=\"' + optionClass + '\" ' + attr + '>' + label + '</div>';\n                }\n            });\n\n            return html;\n        },\n\n        /**\n         * Render select by part of config\n         *\n         * @param {Object} config\n         * @param {String} chooseText\n         * @returns {String}\n         * @private\n         */\n        _RenderSwatchSelect: function (config, chooseText) {\n            var html;\n\n            if (this.options.jsonSwatchConfig.hasOwnProperty(config.id)) {\n                return '';\n            }\n\n            html =\n                '<select class=\"' + this.options.classes.selectClass + ' ' + config.code + '\">' +\n                '<option value=\"0\" data-option-id=\"0\">' + chooseText + '</option>';\n\n            $.each(config.options, function () {\n                var label = this.label,\n                    attr = ' value=\"' + this.id + '\" data-option-id=\"' + this.id + '\"';\n\n                if (!this.hasOwnProperty('products') || this.products.length <= 0) {\n                    attr += ' data-option-empty=\"true\"';\n                }\n\n                html += '<option ' + attr + '>' + label + '</option>';\n            });\n\n            html += '</select>';\n\n            return html;\n        },\n\n        /**\n         * Input for submit form.\n         * This control shouldn't have \"type=hidden\", \"display: none\" for validation work :(\n         *\n         * @param {Object} config\n         * @private\n         */\n        _RenderFormInput: function (config) {\n            return '<input class=\"' + this.options.classes.attributeInput + ' super-attribute-select\" ' +\n                'name=\"super_attribute[' + config.id + ']\" ' +\n                'type=\"text\" ' +\n                'value=\"\" ' +\n                'data-selector=\"super_attribute[' + config.id + ']\" ' +\n                'data-validate=\"{required: true}\" ' +\n                'aria-required=\"true\" ' +\n                'aria-invalid=\"false\">';\n        },\n\n        /**\n         * Event listener\n         *\n         * @private\n         */\n        _EventListener: function () {\n            var $widget = this,\n                options = this.options.classes,\n                target;\n\n            $widget.element.on('click', '.' + options.optionClass, function () {\n                return $widget._OnClick($(this), $widget);\n            });\n\n            $widget.element.on('change', '.' + options.selectClass, function () {\n                return $widget._OnChange($(this), $widget);\n            });\n\n            $widget.element.on('click', '.' + options.moreButton, function (e) {\n                e.preventDefault();\n\n                return $widget._OnMoreClick($(this));\n            });\n\n            $widget.element.on('keydown', function (e) {\n                if (e.which === 13) {\n                    target = $(e.target);\n\n                    if (target.is('.' + options.optionClass)) {\n                        return $widget._OnClick(target, $widget);\n                    } else if (target.is('.' + options.selectClass)) {\n                        return $widget._OnChange(target, $widget);\n                    } else if (target.is('.' + options.moreButton)) {\n                        e.preventDefault();\n\n                        return $widget._OnMoreClick(target);\n                    }\n                }\n            });\n        },\n\n        /**\n         * Load media gallery using ajax or json config.\n         *\n         * @private\n         */\n        _loadMedia: function () {\n            var $main = this.inProductList ?\n                    this.element.parents('.product-item-info') :\n                    this.element.parents('.column.main'),\n                images;\n\n            if (this.options.useAjax) {\n                this._debouncedLoadProductMedia();\n            }  else {\n                images = this.options.jsonConfig.images[this.getProduct()];\n\n                if (!images) {\n                    images = this.options.mediaGalleryInitial;\n                }\n                this.updateBaseImage(this._sortImages(images), $main, !this.inProductList);\n            }\n        },\n\n        /**\n         * Sorting images array\n         *\n         * @private\n         */\n        _sortImages: function (images) {\n            return _.sortBy(images, function (image) {\n                return parseInt(image.position, 10);\n            });\n        },\n\n        /**\n         * Event for swatch options\n         *\n         * @param {Object} $this\n         * @param {Object} $widget\n         * @private\n         */\n        _OnClick: function ($this, $widget) {\n            var $parent = $this.parents('.' + $widget.options.classes.attributeClass),\n                $wrapper = $this.parents('.' + $widget.options.classes.attributeOptionsWrapper),\n                $label = $parent.find('.' + $widget.options.classes.attributeSelectedOptionLabelClass),\n                attributeId = $parent.data('attribute-id'),\n                $input = $parent.find('.' + $widget.options.classes.attributeInput),\n                checkAdditionalData = JSON.parse(this.options.jsonSwatchConfig[attributeId]['additional_data']),\n                $priceBox = $widget.element.parents($widget.options.selectorProduct)\n                    .find(this.options.selectorProductPrice);\n\n            if ($widget.inProductList) {\n                $input = $widget.productForm.find(\n                    '.' + $widget.options.classes.attributeInput + '[name=\"super_attribute[' + attributeId + ']\"]'\n                );\n            }\n\n            if ($this.hasClass('disabled')) {\n                return;\n            }\n\n            if ($this.hasClass('selected')) {\n                $parent.removeAttr('data-option-selected').find('.selected').removeClass('selected');\n                $input.val('');\n                $label.text('');\n                $this.attr('aria-checked', false);\n            } else {\n                $parent.attr('data-option-selected', $this.data('option-id')).find('.selected').removeClass('selected');\n                $label.text($this.data('option-label'));\n                $input.val($this.data('option-id'));\n                $input.attr('data-attr-name', this._getAttributeCodeById(attributeId));\n                $this.addClass('selected');\n                $widget._toggleCheckedAttributes($this, $wrapper);\n            }\n\n            $widget._Rebuild();\n\n            if ($priceBox.is(':data(mage-priceBox)')) {\n                $widget._UpdatePrice();\n            }\n\n            $(document).trigger('updateMsrpPriceBlock',\n                [\n                    this._getSelectedOptionPriceIndex(),\n                    $widget.options.jsonConfig.optionPrices,\n                    $priceBox\n                ]);\n\n            if (parseInt(checkAdditionalData['update_product_preview_image'], 10) === 1) {\n                $widget._loadMedia();\n            }\n\n            $input.trigger('change');\n        },\n\n        /**\n         * Get selected option price index\n         *\n         * @return {String|undefined}\n         * @private\n         */\n        _getSelectedOptionPriceIndex: function () {\n            var allowedProduct = this._getAllowedProductWithMinPrice(this._CalcProducts());\n\n            if (_.isEmpty(allowedProduct)) {\n                return undefined;\n            }\n\n            return allowedProduct;\n        },\n\n        /**\n         * Get human readable attribute code (eg. size, color) by it ID from configuration\n         *\n         * @param {Number} attributeId\n         * @returns {*}\n         * @private\n         */\n        _getAttributeCodeById: function (attributeId) {\n            var attribute = this.options.jsonConfig.mappedAttributes[attributeId];\n\n            return attribute ? attribute.code : attributeId;\n        },\n\n        /**\n         * Toggle accessibility attributes\n         *\n         * @param {Object} $this\n         * @param {Object} $wrapper\n         * @private\n         */\n        _toggleCheckedAttributes: function ($this, $wrapper) {\n            $wrapper.attr('aria-activedescendant', $this.attr('id'))\n                    .find('.' + this.options.classes.optionClass).attr('aria-checked', false);\n            $this.attr('aria-checked', true);\n        },\n\n        /**\n         * Event for select\n         *\n         * @param {Object} $this\n         * @param {Object} $widget\n         * @private\n         */\n        _OnChange: function ($this, $widget) {\n            var $parent = $this.parents('.' + $widget.options.classes.attributeClass),\n                attributeId = $parent.data('attribute-id'),\n                $input = $parent.find('.' + $widget.options.classes.attributeInput);\n\n            if ($widget.productForm.length > 0) {\n                $input = $widget.productForm.find(\n                    '.' + $widget.options.classes.attributeInput + '[name=\"super_attribute[' + attributeId + ']\"]'\n                );\n            }\n\n            if ($this.val() > 0) {\n                $parent.attr('data-option-selected', $this.val());\n                $input.val($this.val());\n            } else {\n                $parent.removeAttr('data-option-selected');\n                $input.val('');\n            }\n\n            $widget._Rebuild();\n            $widget._UpdatePrice();\n            $widget._loadMedia();\n            $input.trigger('change');\n        },\n\n        /**\n         * Event for more switcher\n         *\n         * @param {Object} $this\n         * @private\n         */\n        _OnMoreClick: function ($this) {\n            $this.nextAll().show();\n            $this.trigger('blur').remove();\n        },\n\n        /**\n         * Rewind options for controls\n         *\n         * @private\n         */\n        _Rewind: function (controls) {\n            controls.find('div[data-option-id], option[data-option-id]')\n                .removeClass('disabled')\n                .prop('disabled', false);\n            controls.find('div[data-option-empty], option[data-option-empty]')\n                .attr('disabled', true)\n                .addClass('disabled')\n                .attr('tabindex', '-1');\n            this.disableSwatchForOutOfStockProducts();\n        },\n\n        /**\n         * Rebuild container\n         *\n         * @private\n         */\n        _Rebuild: function () {\n            var $widget = this,\n                controls = $widget.element.find('.' + $widget.options.classes.attributeClass + '[data-attribute-id]'),\n                selected = controls.filter('[data-option-selected]');\n\n            // Enable all options\n            $widget._Rewind(controls);\n\n            // done if nothing selected\n            if (selected.length <= 0) {\n                return;\n            }\n\n            // Disable not available options\n            controls.each(function () {\n                var $this = $(this),\n                    id = $this.data('attribute-id'),\n                    products = $widget._CalcProducts(id);\n\n                if (selected.length === 1 && selected.first().data('attribute-id') === id) {\n                    return;\n                }\n\n                $this.find('[data-option-id]').each(function () {\n                    var $element = $(this),\n                        option = $element.data('option-id');\n\n                    if (!$widget.optionsMap.hasOwnProperty(id) || !$widget.optionsMap[id].hasOwnProperty(option) ||\n                        $element.hasClass('selected') ||\n                        $element.is(':selected')) {\n                        return;\n                    }\n\n                    if (_.intersection(products, $widget.optionsMap[id][option].products).length <= 0) {\n                        $element.attr('disabled', true).addClass('disabled');\n                    }\n                });\n            });\n        },\n\n        /**\n         * Get selected product list\n         *\n         * @returns {Array}\n         * @private\n         */\n        _CalcProducts: function ($skipAttributeId) {\n            var $widget = this,\n                selectedOptions = '.' + $widget.options.classes.attributeClass + '[data-option-selected]',\n                products = [];\n\n            // Generate intersection of products\n            $widget.element.find(selectedOptions).each(function () {\n                var id = $(this).data('attribute-id'),\n                    option = $(this).attr('data-option-selected');\n\n                if ($skipAttributeId !== undefined && $skipAttributeId === id) {\n                    return;\n                }\n\n                if (!$widget.optionsMap.hasOwnProperty(id) || !$widget.optionsMap[id].hasOwnProperty(option)) {\n                    return;\n                }\n\n                if (products.length === 0) {\n                    products = $widget.optionsMap[id][option].products;\n                } else {\n                    products = _.intersection(products, $widget.optionsMap[id][option].products);\n                }\n            });\n\n            return products;\n        },\n\n        /**\n         * Update total price\n         *\n         * @private\n         */\n        _UpdatePrice: function () {\n            var $widget = this,\n                $product = $widget.element.parents($widget.options.selectorProduct),\n                $productPrice = $product.find(this.options.selectorProductPrice),\n                result = $widget._getNewPrices(),\n                tierPriceHtml,\n                isShow;\n\n            $productPrice.trigger(\n                'updatePrice',\n                {\n                    'prices': $widget._getPrices(result, $productPrice.priceBox('option').prices)\n                }\n            );\n\n            isShow = typeof result != 'undefined' && result.oldPrice.amount !== result.finalPrice.amount;\n\n            $productPrice.find('span:first').toggleClass('special-price', isShow);\n\n            $product.find(this.options.slyOldPriceSelector)[isShow ? 'show' : 'hide']();\n\n            if (typeof result != 'undefined' && result.tierPrices && result.tierPrices.length) {\n                if (this.options.tierPriceTemplate) {\n                    tierPriceHtml = mageTemplate(\n                        this.options.tierPriceTemplate,\n                        {\n                            'tierPrices': result.tierPrices,\n                            '$t': $t,\n                            'currencyFormat': this.options.jsonConfig.currencyFormat,\n                            'priceUtils': priceUtils\n                        }\n                    );\n                    $(this.options.tierPriceBlockSelector).html(tierPriceHtml).show();\n                }\n            } else {\n                $(this.options.tierPriceBlockSelector).hide();\n            }\n\n            $(this.options.normalPriceLabelSelector).hide();\n\n            _.each($('.' + this.options.classes.attributeOptionsWrapper), function (attribute) {\n                if ($(attribute).find('.' + this.options.classes.optionClass + '.selected').length === 0) {\n                    if ($(attribute).find('.' + this.options.classes.selectClass).length > 0) {\n                        _.each($(attribute).find('.' + this.options.classes.selectClass), function (dropdown) {\n                            if ($(dropdown).val() === '0') {\n                                $(this.options.normalPriceLabelSelector).show();\n                            }\n                        }.bind(this));\n                    } else {\n                        $(this.options.normalPriceLabelSelector).show();\n                    }\n                }\n            }.bind(this));\n        },\n\n        /**\n         * Get new prices for selected options\n         *\n         * @returns {*}\n         * @private\n         */\n        _getNewPrices: function () {\n            var $widget = this,\n                newPrices = $widget.options.jsonConfig.prices,\n                allowedProduct = this._getAllowedProductWithMinPrice(this._CalcProducts());\n\n            if (!_.isEmpty(allowedProduct)) {\n                newPrices = this.options.jsonConfig.optionPrices[allowedProduct];\n            }\n\n            return newPrices;\n        },\n\n        /**\n         * Get prices\n         *\n         * @param {Object} newPrices\n         * @param {Object} displayPrices\n         * @returns {*}\n         * @private\n         */\n        _getPrices: function (newPrices, displayPrices) {\n            var $widget = this;\n\n            if (_.isEmpty(newPrices)) {\n                newPrices = $widget._getNewPrices();\n            }\n            _.each(displayPrices, function (price, code) {\n\n                if (newPrices[code]) {\n                    displayPrices[code].amount = newPrices[code].amount - displayPrices[code].amount;\n                }\n            });\n\n            return displayPrices;\n        },\n\n        /**\n         * Get product with minimum price from selected options.\n         *\n         * @param {Array} allowedProducts\n         * @returns {String}\n         * @private\n         */\n        _getAllowedProductWithMinPrice: function (allowedProducts) {\n            var optionPrices = this.options.jsonConfig.optionPrices,\n                product = {},\n                optionFinalPrice, optionMinPrice;\n\n            _.each(allowedProducts, function (allowedProduct) {\n                optionFinalPrice = parseFloat(optionPrices[allowedProduct].finalPrice.amount);\n\n                if (_.isEmpty(product) || optionFinalPrice < optionMinPrice) {\n                    optionMinPrice = optionFinalPrice;\n                    product = allowedProduct;\n                }\n            }, this);\n\n            return product;\n        },\n\n        /**\n         * Gets all product media and change current to the needed one\n         *\n         * @private\n         */\n        _LoadProductMedia: function () {\n            var $widget = this,\n                $this = $widget.element,\n                productData = this._determineProductData(),\n                mediaCallData,\n                mediaCacheKey,\n\n                /**\n                 * Processes product media data\n                 *\n                 * @param {Object} data\n                 * @returns void\n                 */\n                mediaSuccessCallback = function (data) {\n                    if (!(mediaCacheKey in $widget.options.mediaCache)) {\n                        $widget.options.mediaCache[mediaCacheKey] = data;\n                    }\n                    $widget._ProductMediaCallback($this, data, productData.isInProductView);\n                    setTimeout(function () {\n                        $widget._DisableProductMediaLoader($this);\n                    }, 300);\n                };\n\n            if (!$widget.options.mediaCallback) {\n                return;\n            }\n\n            mediaCallData = {\n                'product_id': this.getProduct()\n            };\n\n            mediaCacheKey = JSON.stringify(mediaCallData);\n\n            if (mediaCacheKey in $widget.options.mediaCache) {\n                $widget._XhrKiller();\n                $widget._EnableProductMediaLoader($this);\n                mediaSuccessCallback($widget.options.mediaCache[mediaCacheKey]);\n            } else {\n                mediaCallData.isAjax = true;\n                $widget._XhrKiller();\n                $widget._EnableProductMediaLoader($this);\n                $widget.xhr = $.ajax({\n                    url: $widget.options.mediaCallback,\n                    cache: true,\n                    type: 'GET',\n                    dataType: 'json',\n                    data: mediaCallData,\n                    success: mediaSuccessCallback\n                }).done(function () {\n                    $widget._XhrKiller();\n                });\n            }\n        },\n\n        /**\n         * Enable loader\n         *\n         * @param {Object} $this\n         * @private\n         */\n        _EnableProductMediaLoader: function ($this) {\n            var $widget = this;\n\n            if ($('body.catalog-product-view').length > 0) {\n                $this.parents('.column.main').find('.photo.image')\n                    .addClass($widget.options.classes.loader);\n            } else {\n                //Category View\n                $this.parents('.product-item-info').find('.product-image-photo')\n                    .addClass($widget.options.classes.loader);\n            }\n        },\n\n        /**\n         * Disable loader\n         *\n         * @param {Object} $this\n         * @private\n         */\n        _DisableProductMediaLoader: function ($this) {\n            var $widget = this;\n\n            if ($('body.catalog-product-view').length > 0) {\n                $this.parents('.column.main').find('.photo.image')\n                    .removeClass($widget.options.classes.loader);\n            } else {\n                //Category View\n                $this.parents('.product-item-info').find('.product-image-photo')\n                    .removeClass($widget.options.classes.loader);\n            }\n        },\n\n        /**\n         * Callback for product media\n         *\n         * @param {Object} $this\n         * @param {String} response\n         * @param {Boolean} isInProductView\n         * @private\n         */\n        _ProductMediaCallback: function ($this, response, isInProductView) {\n            var $main = isInProductView ? $this.parents('.column.main') : $this.parents('.product-item-info'),\n                $widget = this,\n                images = [],\n\n                /**\n                 * Check whether object supported or not\n                 *\n                 * @param {Object} e\n                 * @returns {*|Boolean}\n                 */\n                support = function (e) {\n                    return e.hasOwnProperty('large') && e.hasOwnProperty('medium') && e.hasOwnProperty('small');\n                };\n\n            if (_.size($widget) < 1 || !support(response)) {\n                this.updateBaseImage(this.options.mediaGalleryInitial, $main, isInProductView);\n\n                return;\n            }\n\n            images.push({\n                full: response.large,\n                img: response.medium,\n                thumb: response.small,\n                isMain: true\n            });\n\n            if (response.hasOwnProperty('gallery')) {\n                $.each(response.gallery, function () {\n                    if (!support(this) || response.large === this.large) {\n                        return;\n                    }\n                    images.push({\n                        full: this.large,\n                        img: this.medium,\n                        thumb: this.small\n                    });\n                });\n            }\n\n            this.updateBaseImage(images, $main, isInProductView);\n        },\n\n        /**\n         * Check if images to update are initial and set their type\n         * @param {Array} images\n         */\n        _setImageType: function (images) {\n\n            images.map(function (img) {\n                if (!img.type) {\n                    img.type = 'image';\n                }\n            });\n\n            return images;\n        },\n\n        /**\n         * Update [gallery-placeholder] or [product-image-photo]\n         * @param {Array} images\n         * @param {jQuery} context\n         * @param {Boolean} isInProductView\n         */\n        updateBaseImage: function (images, context, isInProductView) {\n            var justAnImage = images[0],\n                initialImages = this.options.mediaGalleryInitial,\n                imagesToUpdate,\n                gallery = context.find(this.options.mediaGallerySelector).data('gallery'),\n                isInitial;\n\n            if (isInProductView) {\n                if (_.isUndefined(gallery)) {\n                    context.find(this.options.mediaGallerySelector).on('gallery:loaded', function () {\n                        this.updateBaseImage(images, context, isInProductView);\n                    }.bind(this));\n\n                    return;\n                }\n\n                imagesToUpdate = images.length ? this._setImageType($.extend(true, [], images)) : [];\n                isInitial = _.isEqual(imagesToUpdate, initialImages);\n\n                if (this.options.gallerySwitchStrategy === 'prepend' && !isInitial) {\n                    imagesToUpdate = imagesToUpdate.concat(initialImages);\n                }\n\n                imagesToUpdate = this._setImageIndex(imagesToUpdate);\n\n                gallery.updateData(imagesToUpdate);\n                this._addFotoramaVideoEvents(isInitial);\n            } else if (justAnImage && justAnImage.img) {\n                context.find('.product-image-photo').attr('src', justAnImage.img);\n            }\n        },\n\n        /**\n         * Add video events\n         *\n         * @param {Boolean} isInitial\n         * @private\n         */\n        _addFotoramaVideoEvents: function (isInitial) {\n            if (_.isUndefined($.mage.AddFotoramaVideoEvents)) {\n                return;\n            }\n\n            if (isInitial) {\n                $(this.options.mediaGallerySelector).AddFotoramaVideoEvents();\n\n                return;\n            }\n\n            $(this.options.mediaGallerySelector).AddFotoramaVideoEvents({\n                selectedOption: this.getProduct(),\n                dataMergeStrategy: this.options.gallerySwitchStrategy\n            });\n        },\n\n        /**\n         * Set correct indexes for image set.\n         *\n         * @param {Array} images\n         * @private\n         */\n        _setImageIndex: function (images) {\n            var length = images.length,\n                i;\n\n            for (i = 0; length > i; i++) {\n                images[i].i = i + 1;\n            }\n\n            return images;\n        },\n\n        /**\n         * Kill doubled AJAX requests\n         *\n         * @private\n         */\n        _XhrKiller: function () {\n            var $widget = this;\n\n            if ($widget.xhr !== undefined && $widget.xhr !== null) {\n                $widget.xhr.abort();\n                $widget.xhr = null;\n            }\n        },\n\n        /**\n         * Emulate mouse click on all swatches that should be selected\n         * @param {Object} [selectedAttributes]\n         * @private\n         */\n        _EmulateSelected: function (selectedAttributes) {\n            $.each(selectedAttributes, $.proxy(function (attributeCode, optionId) {\n                var elem = this.element.find('.' + this.options.classes.attributeClass +\n                    '[data-attribute-code=\"' + attributeCode + '\"] [data-option-id=\"' + optionId + '\"]'),\n                    parentInput = elem.parent();\n\n                if (elem.hasClass('selected')) {\n                    return;\n                }\n\n                if (parentInput.hasClass(this.options.classes.selectClass)) {\n                    parentInput.val(optionId);\n                    parentInput.trigger('change');\n                } else {\n                    elem.trigger('click');\n                }\n            }, this));\n        },\n\n        /**\n         * Emulate mouse click or selection change on all swatches that should be selected\n         * @param {Object} [selectedAttributes]\n         * @private\n         */\n        _EmulateSelectedByAttributeId: function (selectedAttributes) {\n            $.each(selectedAttributes, $.proxy(function (attributeId, optionId) {\n                var elem = this.element.find('.' + this.options.classes.attributeClass +\n                    '[data-attribute-id=\"' + attributeId + '\"] [data-option-id=\"' + optionId + '\"]'),\n                    parentInput = elem.parent();\n\n                if (elem.hasClass('selected')) {\n                    return;\n                }\n\n                if (parentInput.hasClass(this.options.classes.selectClass)) {\n                    parentInput.val(optionId);\n                    parentInput.trigger('change');\n                } else {\n                    elem.trigger('click');\n                }\n            }, this));\n        },\n\n        /**\n         * Get default options values settings with either URL query parameters\n         * @private\n         */\n        _getSelectedAttributes: function () {\n            var hashIndex = window.location.href.indexOf('#'),\n                selectedAttributes = {},\n                params;\n\n            if (hashIndex !== -1) {\n                params = $.parseQuery(window.location.href.substr(hashIndex + 1));\n\n                selectedAttributes = _.invert(_.mapObject(_.invert(params), function (attributeId) {\n                    var attribute = this.options.jsonConfig.mappedAttributes[attributeId];\n\n                    return attribute ? attribute.code : attributeId;\n                }.bind(this)));\n            }\n\n            return selectedAttributes;\n        },\n\n        /**\n         * Callback which fired after gallery gets initialized.\n         *\n         * @param {HTMLElement} element - DOM element associated with a gallery.\n         */\n        _onGalleryLoaded: function (element) {\n            var galleryObject = element.data('gallery');\n\n            this.options.mediaGalleryInitial = galleryObject.returnCurrentImages();\n        },\n\n        /**\n         * Sets mediaCache for cases when jsonConfig contains preSelectedGallery on layered navigation result pages\n         *\n         * @private\n         */\n        _setPreSelectedGallery: function () {\n            var mediaCallData;\n\n            if (this.options.jsonConfig.preSelectedGallery) {\n                mediaCallData = {\n                    'product_id': this.getProduct()\n                };\n\n                this.options.mediaCache[JSON.stringify(mediaCallData)] = this.options.jsonConfig.preSelectedGallery;\n            }\n        },\n\n        /**\n         * Callback for quantity change event.\n         */\n        _onQtyChanged: function () {\n            var $price = this.element.parents(this.options.selectorProduct)\n                .find(this.options.selectorProductPrice);\n\n            $price.trigger(\n                'updatePrice',\n                {\n                    'prices': this._getPrices(this._getNewPrices(), $price.priceBox('option').prices)\n                }\n            );\n        }\n    });\n\n    return $.mage.SwatchRenderer;\n});\n","Magento_Swatches/js/visual.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global FORM_KEY */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'mage/template',\n    'uiRegistry',\n    'jquery/colorpicker/js/colorpicker',\n    'prototype',\n    'jquery/ui',\n    'validation'\n], function (jQuery, mageTemplate, rg) {\n    'use strict';\n\n    return function (config) {\n        var swatchOptionVisualDefaultInputType = 'radio',\n            swatchVisualOption = {\n                table: $('swatch-visual-options-table'),\n                itemCount: 0,\n                totalItems: 0,\n                rendered: 0,\n                isReadOnly: config.isReadOnly,\n                template: mageTemplate('#swatch-visual-row-template'),\n\n                /**\n                 * Add new option using template\n                 *\n                 * @param {Object} data\n                 * @param {Object} render\n                 */\n                add: function (data, render) {\n                    var isNewOption = false,\n                        element;\n\n                    if (typeof data.id == 'undefined') {\n                        data = {\n                            'id': 'option_' + this.itemCount,\n                            'sort_order': this.itemCount + 1,\n                            'empty_class': 'unavailable'\n                        };\n                        isNewOption = true;\n                    } else if (data.defaultswatch0 === '') {\n                        data['empty_class'] = 'unavailable';\n                    }\n\n                    if (!data.intype) {\n                        data.intype = swatchOptionVisualDefaultInputType;\n                    }\n\n                    element = this.template({\n                        data: data\n                    });\n\n                    if (isNewOption && !this.isReadOnly) {\n                        this.enableNewOptionDeleteButton(data.id);\n                    }\n                    this.itemCount++;\n                    this.totalItems++;\n                    this.elements += element;\n\n                    if (render) {\n                        this.render();\n                    }\n                },\n\n                /**\n                 * ColorPicker initialization process\n                 */\n                initColorPicker: function () {\n                    var element = this,\n                        hiddenColorPicker = !jQuery(element).data('colorpickerId');\n\n                    jQuery(this).ColorPicker({\n\n                        /**\n                         * ColorPicker onShow action\n                         */\n                        onShow: function () {\n                            var color = jQuery(element).parent().parent().prev().prev('input').val(),\n                                menu = jQuery(this).parents('.swatch_sub-menu_container');\n\n                            menu.hide();\n                            jQuery(element).ColorPickerSetColor(color);\n                        },\n\n                        /**\n                         * ColorPicker onSubmit action\n                         *\n                         * @param {String} hsb\n                         * @param {String} hex\n                         * @param {String} rgb\n                         * @param {String} el\n                         */\n                        onSubmit: function (hsb, hex, rgb, el) {\n                            var container = jQuery(el).parent().parent().prev();\n\n                            jQuery(el).ColorPickerHide();\n                            container.parent().removeClass('unavailable');\n                            container.prev('input').val('#' + hex);\n                            container.css('background', '#' + hex);\n                        }\n                    });\n\n                    if (hiddenColorPicker) {\n                        jQuery(this).ColorPickerShow();\n                    }\n                },\n\n                /**\n                 * Remove action\n                 *\n                 * @param {Object} event\n                 */\n                remove: function (event) {\n                    var element = $(Event.findElement(event, 'tr')),\n                        elementFlags; // !!! Button already have table parent in safari\n\n                    // Safari workaround\n                    element.ancestors().each(function (parentItem) {\n                        if (parentItem.hasClassName('option-row')) {\n                            element = parentItem;\n                            throw $break;\n                        } else if (parentItem.hasClassName('box')) {\n                            throw $break;\n                        }\n                    });\n\n                    if (element) {\n                        elementFlags = element.getElementsByClassName('delete-flag');\n\n                        if (elementFlags[0]) {\n                            elementFlags[0].value = 1;\n                        }\n\n                        element.addClassName('no-display');\n                        element.addClassName('template');\n                        element.hide();\n                        this.totalItems--;\n                        this.updateItemsCountField();\n                    }\n                },\n\n                /**\n                 * Update items count field\n                 */\n                updateItemsCountField: function () {\n                    $('swatch-visual-option-count-check').value = this.totalItems > 0 ? '1' : '';\n                },\n\n                /**\n                 * Enable delete button for new option\n                 *\n                 * @param {String} id\n                 */\n                enableNewOptionDeleteButton: function (id) {\n                    $$('#delete_button_swatch_container_' + id + ' button').each(function (button) {\n                        button.enable();\n                        button.removeClassName('disabled');\n                    });\n                },\n\n                /**\n                 * Bind remove button\n                 */\n                bindRemoveButtons: function () {\n                    jQuery('#swatch-visual-options-panel').on('click', '.delete-option', this.remove.bind(this));\n                },\n\n                /**\n                 * Render options\n                 */\n                render: function () {\n                    Element.insert($$('[data-role=swatch-visual-options-container]')[0], this.elements);\n                    this.elements = '';\n                },\n\n                /**\n                 * Render elements with delay (performance fix)\n                 *\n                 * @param {Object} data\n                 * @param {Number} from\n                 * @param {Number} step\n                 * @param {Number} delay\n                 * @returns {Boolean}\n                 */\n                renderWithDelay: function (data, from, step, delay) {\n                    var arrayLength = data.length,\n                        len;\n\n                    for (len = from + step; from < len && from < arrayLength; from++) {\n                        this.add(data[from]);\n                    }\n                    this.render();\n\n                    if (from === arrayLength) {\n                        this.updateItemsCountField();\n                        this.rendered = 1;\n                        jQuery('body').trigger('processStop');\n\n                        return true;\n                    }\n                    setTimeout(this.renderWithDelay.bind(this, data, from, step, delay), delay);\n                },\n\n                /**\n                 * Ignore validate action\n                 */\n                ignoreValidate: function () {\n                    var ignore = '.ignore-validate input, ' +\n                        '.ignore-validate select, ' +\n                        '.ignore-validate textarea';\n\n                    jQuery('#edit_form').data('validator').settings.forceIgnore = ignore;\n                }\n            };\n\n        if ($('add_new_swatch_visual_option_button')) {\n            Event.observe(\n                'add_new_swatch_visual_option_button',\n                'click',\n                swatchVisualOption.add.bind(swatchVisualOption, {}, true)\n            );\n        }\n\n        jQuery('#swatch-visual-options-panel').on('render', function () {\n            swatchVisualOption.ignoreValidate();\n\n            if (swatchVisualOption.rendered) {\n                return false;\n            }\n            jQuery('body').trigger('processStart');\n            swatchVisualOption.renderWithDelay(config.attributesData, 0, 100, 300);\n            swatchVisualOption.bindRemoveButtons();\n            jQuery('#swatch-visual-options-panel').on(\n                'click',\n                '.colorpicker_handler',\n                swatchVisualOption.initColorPicker\n            );\n        });\n        jQuery('body').on('click', function (event) {\n            var element = jQuery(event.target);\n\n            if (\n                element.parents('.swatch_sub-menu_container').length === 1 ||\n                element.next('div.swatch_sub-menu_container').length === 1\n            ) {\n                return true;\n            }\n            jQuery('.swatch_sub-menu_container').hide();\n        });\n\n        if (config.isSortable) {\n            jQuery(function ($) {\n                $('[data-role=swatch-visual-options-container]').sortable({\n                    distance: 8,\n                    tolerance: 'pointer',\n                    cancel: 'input, button',\n                    axis: 'y',\n\n                    /**\n                     * Update component\n                     */\n                    update: function () {\n                        $('[data-role=swatch-visual-options-container] [data-role=order]').each(\n                            function (index, element) {\n                                $(element).val(index + 1);\n                            }\n                        );\n                    }\n                });\n            });\n        }\n\n        window.swatchVisualOption = swatchVisualOption;\n        window.swatchOptionVisualDefaultInputType = swatchOptionVisualDefaultInputType;\n\n        rg.set('swatch-visual-options-panel', swatchVisualOption);\n\n        jQuery(function ($) {\n\n            var swatchComponents = {\n\n                /**\n                 * div wrapper for to hide all evement\n                 */\n                wrapper: null,\n\n                /**\n                 * iframe component to perform file upload without page reload\n                 */\n                iframe: null,\n\n                /**\n                 * form component for upload image\n                 */\n                form: null,\n\n                /**\n                 * Input file component for upload image\n                 */\n                inputFile: null,\n\n                /**\n                 * Create swatch component for upload files\n                 *\n                 * @this {swatchComponents}\n                 * @public\n                 */\n                create: function () {\n                    this.wrapper = $('<div>').css({\n                        display: 'none'\n                    }).appendTo($('body'));\n\n                    this.iframe = $('<iframe></iframe>', {\n                        id:  'upload_iframe',\n                        name: 'upload_iframe'\n                    }).appendTo(this.wrapper);\n\n                    this.form = $('<form></form>', {\n                        id: 'swatch_form_image_upload',\n                        name: 'swatch_form_image_upload',\n                        target: 'upload_iframe',\n                        method: 'post',\n                        enctype: 'multipart/form-data',\n                        class: 'ignore-validate',\n                        action: config.uploadActionUrl\n                    }).appendTo(this.wrapper);\n\n                    this.inputFile = $('<input />', {\n                        type: 'file',\n                        name: 'datafile',\n                        class: 'swatch_option_file'\n                    }).appendTo(this.form);\n\n                    $('<input />', {\n                        type: 'hidden',\n                        name: 'form_key',\n                        value: FORM_KEY\n                    }).appendTo(this.form);\n                }\n            };\n\n            /**\n             * Create swatch components\n             */\n            swatchComponents.create();\n\n            /**\n             * Register event for swatch input[type=file] change\n             */\n            swatchComponents.inputFile.change(function () {\n                var container = $('#' + $(this).attr('data-called-by')).parents().eq(2).children('.swatch_window'),\n\n                    /**\n                     * @this {iframe}\n                     */\n                    iframeHandler = function () {\n                        var imageParams = $.parseJSON($(this).contents().find('body').html()),\n                            fullMediaUrl = imageParams['swatch_path'] + imageParams['file_path'];\n\n                        container.prev('input').val(imageParams['file_path']);\n                        container.css({\n                            'background-image': 'url(' + fullMediaUrl + ')',\n                            'background-size': 'cover'\n                        });\n                        container.parent().removeClass('unavailable');\n                    };\n\n                swatchComponents.iframe.off('load');\n                swatchComponents.iframe.on('load', iframeHandler);\n                swatchComponents.form.submit();\n                $(this).val('');\n            });\n\n            /**\n             * Register event for choose \"upload image\" option\n             */\n            $(document).on('click', '.btn_choose_file_upload', function () {\n                swatchComponents.inputFile.attr('data-called-by', $(this).attr('id'));\n                swatchComponents.inputFile.trigger('click');\n            });\n\n            /**\n             * Register event for remove option\n             */\n            $(document).on('click', '.btn_remove_swatch', function () {\n                var optionPanel = $(this).parents().eq(2);\n\n                optionPanel.children('input').val('');\n                optionPanel.children('.swatch_window').css('background', '');\n\n                optionPanel.addClass('unavailable');\n\n                jQuery('.swatch_sub-menu_container').hide();\n            });\n\n            /**\n             * Toggle color upload chooser\n             */\n            $(document).on('click', '.swatches-visual-col', function () {\n                var currentElement = $(this).find('.swatch_sub-menu_container');\n\n                jQuery('.swatch_sub-menu_container').not(currentElement).hide();\n                currentElement.toggle();\n            });\n        });\n    };\n});\n","Magento_Swatches/js/form/element/swatch-visual.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/* global FORM_KEY */\n\n/**\n * @api\n */\ndefine([\n    'underscore',\n    'Magento_Ui/js/lib/view/utils/async',\n    'mage/template',\n    'uiRegistry',\n    'prototype',\n    'Magento_Ui/js/form/element/abstract',\n    'jquery/colorpicker/js/colorpicker',\n    'jquery/ui'\n], function (_, jQuery, mageTemplate, rg, prototype, Abstract) {\n    'use strict';\n\n    /**\n     * Former implementation.\n     *\n     * @param {*} value\n     * @param {Object} container\n     * @param {String} uploadUrl\n     * @param {String} elementName\n     */\n    function oldCode(value, container, uploadUrl, elementName) {\n        var swatchVisualOption = {\n            itemCount: 0,\n            totalItems: 0,\n            rendered: 0,\n            isReadOnly: false,\n\n            /**\n             * Initialize.\n             */\n            initialize: function () {\n                if (_.isEmpty(value)) {\n                    container.addClassName('unavailable');\n                }\n\n                jQuery(container).on(\n                    'click',\n                    '.colorpicker_handler',\n                    this.initColorPicker\n                );\n            },\n\n            /**\n             * ColorPicker initialization process\n             */\n            initColorPicker: function () {\n                var element = this,\n                    hiddenColorPicker = !jQuery(element).data('colorpickerId');\n\n                jQuery(this).ColorPicker({\n\n                    /**\n                     * ColorPicker onShow action\n                     */\n                    onShow: function () {\n                        var color = jQuery(element).parent().parent().prev().prev('input').val(),\n                            menu = jQuery(this).parents('.swatch_sub-menu_container');\n\n                        menu.hide();\n                        jQuery(element).ColorPickerSetColor(color);\n                    },\n\n                    /**\n                     * ColorPicker onSubmit action\n                     *\n                     * @param {String} hsb\n                     * @param {String} hex\n                     * @param {String} rgb\n                     * @param {String} el\n                     */\n                    onSubmit: function (hsb, hex, rgb, el) {\n                        var localContainer = jQuery(el).parent().parent().prev();\n\n                        jQuery(el).ColorPickerHide();\n                        localContainer.parent().removeClass('unavailable');\n                        localContainer.prev('input').val('#' + hex).trigger('change');\n                        localContainer.css('background', '#' + hex);\n                    }\n                });\n\n                if (hiddenColorPicker) {\n                    jQuery(this).ColorPickerShow();\n                }\n            },\n\n            /**\n             * Remove action\n             *\n             * @param {Object} event\n             */\n            remove: function (event) {\n                var element = $(Event.findElement(event, 'tr')),\n                    elementFlags; // !!! Button already have table parent in safari\n\n                // Safari workaround\n                element.ancestors().each(function (parentItem) {\n                    if (parentItem.hasClassName('option-row')) {\n                        element = parentItem;\n                        throw $break;\n                    } else if (parentItem.hasClassName('box')) {\n                        throw $break;\n                    }\n                });\n\n                if (element) {\n                    elementFlags = element.getElementsByClassName('delete-flag');\n\n                    if (elementFlags[0]) {\n                        elementFlags[0].value = 1;\n                    }\n\n                    element.addClassName('no-display');\n                    element.addClassName('template');\n                    element.hide();\n                    this.totalItems--;\n                    this.updateItemsCountField();\n                }\n            },\n\n            /**\n             * Update items count field\n             */\n            updateItemsCountField: function () {\n                $('swatch-visual-option-count-check').value = this.totalItems > 0 ? '1' : '';\n            }\n        };\n\n        //swatchVisualOption.initColorPicker();\n\n        jQuery('body').on('click', function (event) {\n            var element = jQuery(event.target);\n\n            if (\n                element.parents('.swatch_sub-menu_container').length === 1 ||\n                element.next('div.swatch_sub-menu_container').length === 1\n            ) {\n                return true;\n            }\n            jQuery('.swatch_sub-menu_container').hide();\n        });\n\n        jQuery(function ($) {\n\n            var swatchComponents = {\n\n                /**\n                 * div wrapper for to hide all evement\n                 */\n                wrapper: null,\n\n                /**\n                 * iframe component to perform file upload without page reload\n                 */\n                iframe: null,\n\n                /**\n                 * form component for upload image\n                 */\n                form: null,\n\n                /**\n                 * Input file component for upload image\n                 */\n                inputFile: null,\n\n                /**\n                 * Create swatch component for upload files\n                 *\n                 * @this {swatchComponents}\n                 * @public\n                 */\n                create: function () {\n                    this.wrapper = $('<div>').css({\n                        display: 'none'\n                    }).appendTo($('body'));\n\n                    this.iframe = $('<iframe></iframe>', {\n                        name: 'upload_iframe_' + elementName\n                    }).appendTo(this.wrapper);\n\n                    this.form = $('<form></form>', {\n                        name: 'swatch_form_image_upload_' + elementName,\n                        target: 'upload_iframe_' + elementName,\n                        method: 'post',\n                        enctype: 'multipart/form-data',\n                        class: 'ignore-validate',\n                        action: uploadUrl\n                    }).appendTo(this.wrapper);\n\n                    this.inputFile = $('<input />', {\n                        type: 'file',\n                        name: 'datafile',\n                        class: 'swatch_option_file'\n                    }).appendTo(this.form);\n\n                    $('<input />', {\n                        type: 'hidden',\n                        name: 'form_key',\n                        value: FORM_KEY\n                    }).appendTo(this.form);\n                }\n            };\n\n            swatchVisualOption.initialize();\n\n            /**\n             * Create swatch components\n             */\n            swatchComponents.create();\n\n            /**\n             * Register event for swatch input[type=file] change\n             */\n            swatchComponents.inputFile.change(function () {\n                var localContainer = $('.' + $(this).attr('data-called-by')).parents().eq(2).children('.swatch_window'),\n\n                    /**\n                     * @this {iframe}\n                     */\n                    iframeHandler = function () {\n                        var imageParams = $.parseJSON($(this).contents().find('body').html()),\n                            fullMediaUrl = imageParams['swatch_path'] + imageParams['file_path'];\n\n                        localContainer.prev('input').val(imageParams['file_path']).trigger('change');\n                        localContainer.css({\n                            'background-image': 'url(' + fullMediaUrl + ')',\n                            'background-size': 'cover'\n                        });\n                        localContainer.parent().removeClass('unavailable');\n                    };\n\n                swatchComponents.iframe.off('load');\n                swatchComponents.iframe.on('load', iframeHandler);\n                swatchComponents.form.submit();\n                $(this).val('');\n            });\n\n            /**\n             * Register event for choose \"upload image\" option\n             */\n            $(container).on('click', '.btn_choose_file_upload', function () {\n                swatchComponents.inputFile.attr('data-called-by', $(this).data('class'));\n                swatchComponents.inputFile.trigger('click');\n            });\n\n            /**\n             * Register event for remove option\n             */\n            $(container).on('click', '.btn_remove_swatch', function () {\n                var optionPanel = $(this).parents().eq(2);\n\n                optionPanel.children('input').val('').trigger('change');\n                optionPanel.children('.swatch_window').css('background', '');\n                optionPanel.addClass('unavailable');\n                jQuery('.swatch_sub-menu_container').hide();\n            });\n\n            /**\n             * Toggle color upload chooser\n             */\n            $(container).on('click', '.swatch_window', function () {\n                jQuery('.swatch_sub-menu_container').hide();\n                $(this).next('div').toggle();\n            });\n        });\n    }\n\n    return Abstract.extend({\n        defaults: {\n            elementId: 0,\n            prefixName: '',\n            prefixElementName: '',\n            elementName: '',\n            value: '',\n            uploadUrl: ''\n        },\n\n        /**\n         * Parses options and merges the result with instance\n         *\n         * @returns {Object} Chainable.\n         */\n        initConfig: function () {\n            this._super();\n\n            this.configureDataScope();\n\n            return this;\n        },\n\n        /**\n         * Initialize.\n         *\n         * @returns {Object} Chainable.\n         */\n        initialize: function () {\n            this._super()\n                .initOldCode()\n                .on('value', this.onChangeColor.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Handler function that execute when color changes.\n         *\n         * @param {String} data - color\n         */\n        onChangeColor: function (data) {\n            if (!data) {\n                jQuery('.' + this.elementName).parent().removeClass('unavailable');\n            }\n        },\n\n        /**\n         * Initialize wrapped former implementation.\n         *\n         * @returns {Object} Chainable.\n         */\n        initOldCode: function () {\n            jQuery.async('.' + this.elementName, this.name, function (elem) {\n                oldCode(this.value(), elem.parentElement, this.uploadUrl, this.elementName);\n            }.bind(this));\n\n            return this;\n        },\n\n        /**\n         * Configure data scope.\n         */\n        configureDataScope: function () {\n            var recordId, prefixName;\n\n            // Get recordId\n            recordId = this.parentName.split('.').last();\n\n            prefixName = this.dataScopeToHtmlArray(this.prefixName);\n            this.elementName = this.prefixElementName + recordId;\n\n            this.inputName = prefixName + '[' + this.elementName + ']';\n            this.exportDataLink = 'data.' + this.prefixName + '.' + this.elementName;\n            this.exports.value = this.provider + ':' + this.exportDataLink;\n        },\n\n        /** @inheritdoc */\n        destroy: function () {\n            this._super();\n\n            this.source.remove(this.exportDataLink);\n        },\n\n        /**\n         * Get HTML array from data scope.\n         *\n         * @param {String} dataScopeString\n         * @returns {String}\n         */\n        dataScopeToHtmlArray: function (dataScopeString) {\n            var dataScopeArray, dataScope, reduceFunction;\n\n            /**\n             * Add new level of nesting.\n             *\n             * @param {String} prev\n             * @param {String} curr\n             * @returns {String}\n             */\n            reduceFunction = function (prev, curr) {\n                return prev + '[' + curr + ']';\n            };\n\n            dataScopeArray = dataScopeString.split('.');\n\n            dataScope = dataScopeArray.shift();\n            dataScope += dataScopeArray.reduce(reduceFunction, '');\n\n            return dataScope;\n        }\n    });\n});\n","Magento_Security/js/escaper.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * A loose JavaScript version of Magento\\Framework\\Escaper\n *\n * Due to differences in how XML/HTML is processed in PHP vs JS there are a couple of minor differences in behavior\n * from the PHP counterpart.\n *\n * The first difference is that the default invocation of escapeHtml without allowedTags will double-escape existing\n * entities as the intention of such an invocation is that the input isn't supposed to contain any HTML.\n *\n * The second difference is that escapeHtml will not escape quotes. Since the input is actually being processed by the\n * DOM there is no chance of quotes being mixed with HTML syntax. And, since escapeHtml is not\n * intended to be used with raw injection into a HTML attribute, this is acceptable.\n *\n * @api\n */\ndefine([], function () {\n    'use strict';\n\n    return {\n        neverAllowedElements: ['script', 'img', 'embed', 'iframe', 'video', 'source', 'object', 'audio'],\n        generallyAllowedAttributes: ['id', 'class', 'href', 'title', 'style'],\n        forbiddenAttributesByElement: {\n            a: ['style']\n        },\n\n        /**\n         * Escape a string for safe injection into HTML\n         *\n         * @param {String} data\n         * @param {Array|null} allowedTags\n         * @returns {String}\n         */\n        escapeHtml: function (data, allowedTags) {\n            var domParser = new DOMParser(),\n                fragment = domParser.parseFromString('<div></div>', 'text/html');\n\n            fragment = fragment.body.childNodes[0];\n            allowedTags = typeof allowedTags === 'object' && allowedTags.length ? allowedTags : null;\n\n            if (allowedTags) {\n                fragment.innerHTML = data || '';\n                allowedTags = this._filterProhibitedTags(allowedTags);\n\n                this._removeComments(fragment);\n                this._removeNotAllowedElements(fragment, allowedTags);\n                this._removeNotAllowedAttributes(fragment);\n\n                return fragment.innerHTML;\n            }\n\n            fragment.textContent = data || '';\n\n            return fragment.innerHTML;\n        },\n\n        /**\n         * Remove the always forbidden tags from a list of provided tags\n         *\n         * @param {Array} tags\n         * @returns {Array}\n         * @private\n         */\n        _filterProhibitedTags: function (tags) {\n            return tags.filter(function (n) {\n                return this.neverAllowedElements.indexOf(n) === -1;\n            }.bind(this));\n        },\n\n        /**\n         * Remove comment nodes from the given node\n         *\n         * @param {Node} node\n         * @private\n         */\n        _removeComments: function (node) {\n            var treeWalker = node.ownerDocument.createTreeWalker(\n                    node,\n                    NodeFilter.SHOW_COMMENT,\n                    function () {\n                        return NodeFilter.FILTER_ACCEPT;\n                    },\n                    false\n                ),\n                nodesToRemove = [];\n\n            while (treeWalker.nextNode()) {\n                nodesToRemove.push(treeWalker.currentNode);\n            }\n\n            nodesToRemove.forEach(function (nodeToRemove) {\n                nodeToRemove.parentNode.removeChild(nodeToRemove);\n            });\n        },\n\n        /**\n         * Strip the given node of all disallowed tags while permitting any nested text nodes\n         *\n         * @param {Node} node\n         * @param {Array|null} allowedTags\n         * @private\n         */\n        _removeNotAllowedElements: function (node, allowedTags) {\n            var treeWalker = node.ownerDocument.createTreeWalker(\n                    node,\n                    NodeFilter.SHOW_ELEMENT,\n                    function (currentNode) {\n                        return allowedTags.indexOf(currentNode.nodeName.toLowerCase()) === -1 ?\n                            NodeFilter.FILTER_ACCEPT\n                            // SKIP instead of REJECT because REJECT also rejects child nodes\n                            : NodeFilter.FILTER_SKIP;\n                    },\n                false\n                ),\n                nodesToRemove = [];\n\n            while (treeWalker.nextNode()) {\n                if (allowedTags.indexOf(treeWalker.currentNode.nodeName.toLowerCase()) === -1) {\n                    nodesToRemove.push(treeWalker.currentNode);\n                }\n            }\n\n            nodesToRemove.forEach(function (nodeToRemove) {\n                nodeToRemove.parentNode.replaceChild(\n                    node.ownerDocument.createTextNode(nodeToRemove.textContent),\n                    nodeToRemove\n                );\n            });\n        },\n\n        /**\n         * Remove any invalid attributes from the given node\n         *\n         * @param {Node} node\n         * @private\n         */\n        _removeNotAllowedAttributes: function (node) {\n            var treeWalker = node.ownerDocument.createTreeWalker(\n                    node,\n                    NodeFilter.SHOW_ELEMENT,\n                    function () {\n                        return NodeFilter.FILTER_ACCEPT;\n                    },\n                false\n                ),\n                i,\n                attribute,\n                nodeName,\n                attributesToRemove = [];\n\n            while (treeWalker.nextNode()) {\n                for (i = 0; i < treeWalker.currentNode.attributes.length; i++) {\n                    attribute = treeWalker.currentNode.attributes[i];\n                    nodeName = treeWalker.currentNode.nodeName.toLowerCase();\n\n                    if (this.generallyAllowedAttributes.indexOf(attribute.name) === -1  || // eslint-disable-line max-depth,max-len\n                        this._checkHrefValue(attribute) ||\n                        this.forbiddenAttributesByElement[nodeName] &&\n                        this.forbiddenAttributesByElement[nodeName].indexOf(attribute.name) !== -1\n                    ) {\n                        attributesToRemove.push(attribute);\n                    }\n                }\n            }\n\n            attributesToRemove.forEach(function (attributeToRemove) {\n                attributeToRemove.ownerElement.removeAttribute(attributeToRemove.name);\n            });\n        },\n\n        /**\n         * Check that attribute contains script content\n         *\n         * @param {Object} attribute\n         * @private\n         */\n        _checkHrefValue: function (attribute) {\n            return attribute.nodeName === 'href' && attribute.nodeValue.startsWith('javascript');\n        }\n    };\n});\n","Magento_Security/js/confirm-redirect.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/*eslint-disable no-undef*/\ndefine(\n    ['jquery'],\n    function ($) {\n        'use strict';\n\n        return function (config, element) {\n            $(element).on('click', config, function () {\n                confirmSetLocation(config.message, config.url);\n            });\n        };\n    }\n);\n","Magento_Security/js/system/config/session-size.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'jquery',\n    'mage/translate',\n    'Magento_Ui/js/modal/confirm',\n    'domReady!'\n], function ($, $t, confirm) {\n    'use strict';\n\n    return function (config, inputEl) {\n        var $inputEl = $(inputEl);\n\n        $inputEl.on('blur', function () {\n            var inputVal = parseInt($inputEl.val(), 10);\n\n            if (inputVal < 256000) {\n                confirm({\n                    title: $t(config.modalTitleText),\n                    content: $t(config.modalContentBody),\n                    buttons: [{\n                        text: $t('No'),\n                        class: 'action-secondary action-dismiss',\n\n                        /**\n                         * Close modal and trigger 'cancel' action on click\n                         */\n                        click: function (event) {\n                            this.closeModal(event);\n                        }\n                    }, {\n                        text: $t('Yes'),\n                        class: 'action-primary action-accept',\n\n                        /**\n                         * Close modal and trigger 'confirm' action on click\n                         */\n                        click: function (event) {\n                            this.closeModal(event, true);\n                        }\n                    }],\n                    actions: {\n\n                        /**\n                         * Revert back to original value\n                         */\n                        cancel: function () {\n                            $inputEl.val(256000);\n                        }\n                    }\n                });\n            }\n        });\n    };\n});\n","Magento_GroupedProduct/js/grouped-product.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\n/**\n * @api\n */\ndefine([\n    'jquery',\n    'mage/template',\n    'jquery/ui',\n    'Magento_Ui/js/modal/modal',\n    'mage/translate',\n    'mage/adminhtml/grid'\n], function ($, mageTemplate) {\n    'use strict';\n\n    $.widget('mage.groupedProduct', {\n        /**\n         * Create widget\n         * @private\n         */\n        _create: function () {\n            this.$grid = this.element.find('[data-role=grouped-product-grid]');\n            this.$grid.sortable({\n                distance: 8,\n                items: '[data-role=row]',\n                tolerance: 'pointer',\n                cancel: ':input',\n                update: $.proxy(function () {\n                    this.element.trigger('resort');\n                }, this)\n            });\n\n            this.productTmpl = mageTemplate('#group-product-template');\n\n            $.each(\n                this.$grid.data('products'),\n                $.proxy(function (index, product) {\n                    this._add(null, product);\n                }, this)\n            );\n\n            this._on({\n                'add': '_add',\n                'resort': '_resort',\n                'click [data-column=actions] [data-role=delete]': '_remove'\n            });\n\n            this._bindDialog();\n            this._updateGridVisibility();\n        },\n\n        /**\n         * Add product to grouped grid\n         * @param {EventObject} event\n         * @param {Object} product\n         * @private\n         */\n        _add: function (event, product) {\n            var tmpl,\n                productExists;\n\n            productExists = this.$grid.find('[data-role=id]')\n                .filter(function (index, element) {\n                    return $(element).val() == product.id; //eslint-disable-line eqeqeq\n                }).length;\n\n            if (!productExists) {\n                tmpl = this.productTmpl({\n                    data: product\n                });\n\n                $(tmpl).appendTo(this.$grid.find('tbody'));\n            }\n        },\n\n        /**\n         * Remove product\n         * @param {EventObject} event\n         * @private\n         */\n        _remove: function (event) {\n            $(event.target).closest('[data-role=row]').remove();\n            this.element.trigger('resort');\n            this._updateGridVisibility();\n        },\n\n        /**\n         * Resort products\n         * @private\n         */\n        _resort: function () {\n            this.element.find('[data-role=position]').each($.proxy(function (index, element) {\n                $(element).val(index + 1);\n            }, this));\n        },\n\n        /**\n         * Create modal for show product\n         *\n         * @private\n         */\n        _bindDialog: function () {\n            var widget = this,\n                selectedProductList = {},\n                popup = $('[data-role=add-product-dialog]'),\n                gridPopup;\n\n            popup.modal({\n                type: 'slide',\n                innerScroll: true,\n                title: $.mage.__('Add Products to Group'),\n                modalClass: 'grouped',\n\n                /** @inheritdoc */\n                open: function () {\n                    $(this).addClass('admin__scope-old'); // ToDo UI: remove with old styles removal\n                },\n                buttons: [{\n                    id: 'grouped-product-dialog-apply-button',\n                    text: $.mage.__('Add Selected Products'),\n                    'class': 'action-primary action-add',\n\n                    /** @inheritdoc */\n                    click: function () {\n                        $.each(selectedProductList, function (index, product) {\n                            widget._add(null, product);\n                        });\n                        widget._resort();\n                        widget._updateGridVisibility();\n                        popup.modal('closeModal');\n                    }\n                }]\n            });\n\n            popup.on('click', '[data-role=row]', function (event) {\n                var target = $(event.target);\n\n                if (!target.is('input')) {\n                    target.closest('[data-role=row]')\n                        .find('[data-column=entity_ids] input')\n                        .prop('checked', function (element, value) {\n                            return !value;\n                        })\n                        .trigger('change');\n                }\n            });\n\n            popup.on(\n                'change',\n                '[data-role=row] [data-column=entity_ids] input',\n                $.proxy(function (event) {\n                    var element = $(event.target),\n                        product = {};\n\n                    if (element.is(':checked')) {\n                        product.id = element.val();\n                        product.qty = 0;\n                        element.closest('[data-role=row]').find('[data-column]').each(function (index, el) {\n                            let text = $(el).text();\n\n                            product[$(el).data('column')] = text.trim();\n                        });\n                        selectedProductList[product.id] = product;\n                    } else {\n                        delete selectedProductList[element.val()];\n                    }\n                }, this)\n            );\n\n            gridPopup = $(this.options.gridPopup).data('gridObject');\n\n            $('[data-role=add-product]').on('click', function (event) {\n                event.preventDefault();\n                popup.modal('openModal');\n                gridPopup.reload();\n                selectedProductList = {};\n            });\n\n            $('#' + gridPopup.containerId).on('gridajaxsettings', function (event, ajaxSettings) {\n                var ids = widget.$grid.find('[data-role=id]').map(function (index, element) {\n                    return $(element).val();\n                }).toArray();\n\n                ajaxSettings.data.filter = $.extend(ajaxSettings.data.filter || {}, {\n                    'entity_ids': ids\n                });\n            }).on('gridajax', function (event, ajaxRequest) {\n                ajaxRequest.done(function () {\n                    popup.find('[data-role=row] [data-column=entity_ids] input').each(function (index, element) {\n                        var $element = $(element);\n\n                        $element.prop('checked', !!selectedProductList[$element.val()]);\n                    });\n                });\n            });\n        },\n\n        /**\n         * Show or hide message\n         * @private\n         */\n        _updateGridVisibility: function () {\n            var showGrid = this.element.find('[data-role=id]').length > 0;\n\n            this.element.find('.grid-container').toggle(showGrid);\n            this.element.find('.no-products-message').toggle(!showGrid);\n        }\n    });\n\n    return $.mage.groupedProduct;\n});\n","Magento_GroupedProduct/js/grouped-product-grid.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore',\n    'uiRegistry',\n    'Magento_Ui/js/dynamic-rows/dynamic-rows-grid'\n], function (_, registry, dynamicRowsGrid) {\n    'use strict';\n\n    return dynamicRowsGrid.extend({\n\n        /**\n         * Set max element position\n         *\n         * @param {Number} position - element position\n         * @param {Object} elem - instance\n         */\n        setMaxPosition: function (position, elem) {\n\n            if (position || position === 0) {\n                this.checkMaxPosition(position);\n                this.sort(position, elem);\n\n                if (~~position === this.maxPosition && ~~position > this.getDefaultPageBoundary() + 1) {\n                    this.shiftNextPagesPositions(position);\n                }\n            } else {\n                this.maxPosition += 1;\n            }\n        },\n\n        /**\n         * Shift positions for next page elements\n         *\n         * @param {Number} position\n         */\n        shiftNextPagesPositions: function (position) {\n\n            var recordData = this.recordData(),\n                startIndex = ~~this.currentPage() * this.pageSize,\n                offset = position - startIndex + 1,\n                index = startIndex;\n\n            if (~~this.currentPage() === this.pages()) {\n                return false;\n            }\n\n            for (index; index < recordData.length; index++) {\n                recordData[index].position = index + offset;\n            }\n            this.recordData(recordData);\n        },\n\n        /**\n         * Update position for element after position from another page is entered\n         *\n         * @param {Object} data\n         * @param {Object} event\n         */\n        updateGridPosition: function (data, event) {\n            var inputValue = parseInt(event.target.value, 10),\n                recordData = this.recordData(),\n                record,\n                previousValue,\n                updatedRecord;\n\n            record = this.elems().find(function (obj) {\n                return obj.dataScope === data.parentScope;\n            });\n\n            previousValue = this.getCalculatedPosition(record);\n\n            if (isNaN(inputValue) || inputValue < 0 || inputValue === previousValue) {\n                return false;\n            }\n\n            this.elems([]);\n\n            updatedRecord = this.getUpdatedRecordIndex(recordData, record.data().id);\n\n            if (inputValue >= this.recordData().size() - 1) {\n                recordData[updatedRecord].position = this.getGlobalMaxPosition() + 1;\n            } else {\n                recordData.forEach(function (value, index) {\n                    if (~~value.id === ~~record.data().id) {\n                        recordData[index].position = inputValue;\n                    } else if (inputValue > previousValue && index <= inputValue) {\n                        recordData[index].position = index - 1;\n                    } else if (inputValue < previousValue && index >= inputValue) {\n                        recordData[index].position = index + 1;\n                    }\n                });\n            }\n\n            this.reloadGridData(recordData);\n\n        },\n\n        /**\n         * Get updated record index\n         *\n         * @param  {Array} recordData\n         * @param {Number} recordId\n         * @return {Number}\n         */\n        getUpdatedRecordIndex: function (recordData, recordId) {\n            return recordData.map(function (o) {\n                return ~~o.id;\n            }).indexOf(~~recordId);\n        },\n\n        /**\n         *\n         * @param {Array} recordData - to reprocess\n         */\n        reloadGridData: function (recordData) {\n            this.recordData(recordData.sort(function (a, b) {\n                return ~~a.position - ~~b.position;\n            }));\n            this._updateCollection();\n            this.reload();\n        },\n\n        /**\n         * Event handler for \"Send to bottom\" button\n         *\n         * @param {Object} positionObj\n         * @return {Boolean}\n         */\n        sendToBottom: function (positionObj) {\n\n            var objectToUpdate = this.getObjectToUpdate(positionObj),\n                recordData = this.recordData(),\n                updatedRecord;\n\n            if (~~this.currentPage() === this.pages) {\n                objectToUpdate.position = this.maxPosition;\n            } else {\n                this.elems([]);\n                updatedRecord = this.getUpdatedRecordIndex(recordData, objectToUpdate.data().id);\n                recordData[updatedRecord].position = this.getGlobalMaxPosition() + 1;\n                this.reloadGridData(recordData);\n            }\n\n            return false;\n        },\n\n        /**\n         * Event handler for \"Send to top\" button\n         *\n         * @param {Object} positionObj\n         * @return {Boolean}\n         */\n        sendToTop: function (positionObj) {\n            var objectToUpdate = this.getObjectToUpdate(positionObj),\n                recordData = this.recordData(),\n                updatedRecord;\n\n            //isFirst\n            if (~~this.currentPage() === 1) {\n                objectToUpdate.position = 0;\n            } else {\n                this.elems([]);\n                updatedRecord = this.getUpdatedRecordIndex(recordData, objectToUpdate.data().id);\n                recordData.forEach(function (value, index) {\n                    recordData[index].position = index === updatedRecord ? 0 : value.position + 1;\n                });\n                this.reloadGridData(recordData);\n            }\n\n            return false;\n        },\n\n        /**\n         * Get element from grid for update\n         *\n         * @param {Object} object\n         * @return {*}\n         */\n        getObjectToUpdate: function (object) {\n            return this.elems().filter(function (item) {\n                return item.name === object.parentName;\n            })[0];\n        },\n\n        /**\n         * Value function for position input\n         *\n         * @param {Object} data\n         * @return {Number}\n         */\n        getCalculatedPosition: function (data) {\n            return (~~this.currentPage() - 1) * this.pageSize + this.elems().pluck('name').indexOf(data.name);\n        },\n\n        /**\n         * Return Page Boundary\n         *\n         * @return {Number}\n         */\n        getDefaultPageBoundary: function () {\n            return ~~this.currentPage() * this.pageSize - 1;\n        },\n\n        /**\n         * Returns position for last element to be moved after\n         *\n         * @return {Number}\n         */\n        getGlobalMaxPosition: function () {\n            return _.max(this.recordData().map(function (r) {\n                return ~~r.position;\n            }));\n        }\n    });\n});\n","PayPal_Braintree/js/paypalButtonPreview.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine([\n    'underscore',\n    'jquery',\n    'braintree',\n    'braintreePayPalCheckout',\n    'domReady!'\n], function (_, $, braintree, paypalCheckout) {\n    'use strict';\n    let buttonIds = [];\n\n    return {\n        events: {\n            onClick: null\n        },\n\n        /**\n         * @param token\n         * @param currency\n         * @param env\n         * @param local\n         */\n        init: function (token, currency, env, local) {\n            buttonIds = [];\n            $('.action-braintree-paypal-logo').each(function () {\n                if (!$(this).hasClass(\"button-loaded\")) {\n                    $(this).addClass('button-loaded');\n                    buttonIds.push($(this).attr('id'));\n                }\n            });\n\n            if (buttonIds.length > 0) {\n                this.loadSDK(token, currency, env, local);\n            }\n        },\n\n        /**\n         * Load Braintree PayPal SDK\n         * @param token\n         * @param currency\n         * @param env\n         * @param local\n         */\n        loadSDK: function (token, currency, env, local) {\n            braintree.create({\n                authorization: token\n            }, function (clientErr, clientInstance) {\n                if (clientErr) {\n                    console.error('paypalCheckout error', clientErr);\n                    return this.showError(\"PayPal Checkout could not be initialized. Please contact the store owner.\");\n                }\n                paypalCheckout.create({\n                    client: clientInstance\n                }, function (err, paypalCheckoutInstance) {\n                    if (typeof paypal !== 'undefined' ) {\n                        this.renderPayPalButtons(buttonIds);\n                        this.renderPayPalMessages();\n                    } else {\n                        var configSDK = {\n                            components: 'buttons,messages,funding-eligibility',\n                            \"enable-funding\": \"paylater\",\n                            currency: currency\n                        };\n                        if (env === 'sandbox' && (local !== '' || local !== 'undefined')) {\n                            configSDK[\"buyer-country\"] = local;\n                        }\n                        paypalCheckoutInstance.loadPayPalSDK(configSDK, function () {\n                            this.renderPayPalButtons(buttonIds);\n                            this.renderPayPalMessages();\n                        }.bind(this));\n                    }\n                }.bind(this));\n            }.bind(this));\n        },\n\n        /**\n         * Render PayPal buttons\n         * @param ids\n         */\n        renderPayPalButtons: function (ids) {\n            _.each(ids, function (id) {\n                this.payPalButton(id);\n            }.bind(this));\n        },\n\n        /**\n         * Render PayPal messages\n         */\n        renderPayPalMessages: function () {\n            $('.action-braintree-paypal-message').each(function () {\n                let messages = paypal.Messages({\n                    amount: $(this).data('pp-amount'),\n                    pageType: $(this).data('pp-type'),\n                    style: {\n                        layout: $(this).data('messaging-layout'),\n                        text: {\n                            color:   $(this).data('messaging-text-color')\n                        },\n                        logo: {\n                            type: $(this).data('messaging-logo'),\n                            position: $(this).data('messaging-logo-position')\n                        }\n                    }\n                });\n\n                if ($('#' + $(this).attr('id')).length && $(this).data('messaging-show')) {\n                    messages.render('#' + $(this).attr('id'));\n                }\n            });\n        },\n\n        /**\n         * @param id\n         */\n        payPalButton: function (id) {\n            let data = $('#' + id);\n            let style = {\n                color: data.data('color'),\n                shape: data.data('shape'),\n                size: data.data('size'),\n                label: data.data('label')\n            };\n\n            if (data.data('fundingicons')) {\n                style.fundingicons = data.data('fundingicons');\n            }\n\n            // Render\n            var button = paypal.Buttons({\n                fundingSource: data.data('funding'),\n                style: style,\n\n                onInit: function (data, actions) {\n                    actions.disable();\n                }\n            });\n            if (!button.isEligible()) {\n                console.log('PayPal button is not elligible');\n                data.parent().remove();\n                return;\n            }\n            if ($('#' + data.attr('id')).length && data.data('show')) {\n                button.render('#' + data.attr('id'));\n            }\n        },\n    }\n});\n","PayPal_Braintree/js/form-builder.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\ndefine(\n    [\n        'jquery',\n        'underscore',\n        'mage/template'\n    ],\n    function ($, _, mageTemplate) {\n        'use strict';\n\n        return {\n\n            /**\n             * @param {Object} formData\n             * @returns {*|jQuery}\n             */\n            build: function (formData) {\n                var formTmpl = mageTemplate('<form action=\"<%= data.action %>\"' +\n                    ' method=\"POST\" hidden enctype=\"application/x-www-form-urlencoded\">' +\n                        '<% _.each(data.fields, function(val, key){ %>' +\n                            '<input value=\\'<%= val %>\\' name=\"<%= key %>\" type=\"hidden\">' +\n                        '<% }); %>' +\n                    '</form>');\n\n                return $(formTmpl({\n                    data: {\n                        action: formData.action,\n                        fields: formData.fields\n                    }\n                })).appendTo($('[data-container=\"body\"]'));\n            }\n        };\n    }\n);\n","PayPal_Braintree/js/system.js":"require(['jquery', 'Magento_Ui/js/modal/alert', 'mage/translate', 'domReady!'], function ($, alert, $t) {\n    function disablePayLaterMessages()\n    {\n        let merchantCountry = $('[data-ui-id=\"adminhtml-system-config-field-country-0-select-groups-account-fields-merchant-country-value\"]').val();\n        let payPalCredit = $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-fields-braintree-paypal-credit-active-value\"]').val();\n        let cart = $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-button-cart-fields-message-cart-enable-value\"]');\n        let product = $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-button-checkout-fields-message-checkout-enable-value\"]')\n        let checkout = $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-button-productpage-fields-message-productpage-enable-value\"]')\n        let allowedCountries = ['GB', 'FR', 'US', 'DE', 'AU'];\n\n        if($.inArray(merchantCountry, allowedCountries) === -1 || payPalCredit === 1){\n            //hide pay later message\n            cart.val(0).attr('readonly',true).click();\n            product.val(0).attr('readonly',true).click();\n            checkout.val(0).attr('readonly',true).click();\n        }\n        if (merchantCountry) {\n            if ( merchantCountry === 'GB') {\n                merchantCountry = 'UK'\n            }\n            cart.next().find('a').attr('href', cart.next().find('a').attr('href') + merchantCountry.toLowerCase());\n            product.next().find('a').attr('href', product.next().find('a').attr('href') + merchantCountry.toLowerCase());\n            checkout.next().find('a').attr('href', checkout.next().find('a').attr('href') + merchantCountry.toLowerCase());\n        }\n\n    }\n\n    window.braintreeValidator = function (endpoint, environmentId, skip = false) {\n        environmentId = $('[data-ui-id=\"' + environmentId + '\"]').val();\n\n        let merchantId = '', publicId = '', privateId = '';\n\n        if (environmentId === 'sandbox') {\n            merchantId = $('[data-ui-id=\"text-groups-braintree-section-groups-braintree-groups-braintree-required-fields-sandbox-merchant-id-value\"]').val();\n            publicId = $('[data-ui-id=\"password-groups-braintree-section-groups-braintree-groups-braintree-required-fields-sandbox-public-key-value\"]').val();\n            privateId = $('[data-ui-id=\"password-groups-braintree-section-groups-braintree-groups-braintree-required-fields-sandbox-private-key-value\"]').val();\n        } else {\n            merchantId = $('[data-ui-id=\"text-groups-braintree-section-groups-braintree-groups-braintree-required-fields-merchant-id-value\"]').val();\n            publicId = $('[data-ui-id=\"password-groups-braintree-section-groups-braintree-groups-braintree-required-fields-public-key-value\"]').val();\n            privateId = $('[data-ui-id=\"password-groups-braintree-section-groups-braintree-groups-braintree-required-fields-private-key-value\"]').val();\n        }\n\n        /* Remove previous success message if present */\n        if ($(\".braintree-credentials-success-message\")) {\n            $(\".braintree-credentials-success-message\").remove();\n        }\n\n        /* Basic field validation */\n        var errors = [];\n\n        if (!environmentId || environmentId !== 'sandbox' && environmentId !== 'production') {\n            errors.push($t(\"Please select an Environment\"));\n        }\n\n        if (!merchantId) {\n            errors.push($t(\"Please enter a Merchant ID\"));\n        }\n\n        if (!publicId) {\n            errors.push($t('Please enter a Public Key'));\n        }\n\n        if (!privateId) {\n            errors.push($t('Please enter a Private Key'));\n        }\n\n        if (errors.length > 0) {\n            alert({\n                title: $t('Braintree Credential Validation Failed'),\n                content:  errors.join('<br />')\n            });\n            return false;\n        }\n\n        $(this).text($t(\"We're validating your credentials...\")).attr('disabled', true);\n\n        var self = this;\n        $.ajax({\n            type: 'POST',\n            url: endpoint,\n            data: {\n                environment: environmentId,\n                merchant_id: merchantId,\n                public_key: publicId,\n                private_key: privateId\n            },\n            showLoader: true,\n            success: function (result) {\n                if (result.success === 'true') {\n                    if (skip === true) {\n                        $('<div class=\"message message-success braintree-credentials-success-message\">' + $t(\"Your credentials are valid.\") + '</div>').insertAfter($('.paypal-styling-buttons'));\n                    } else {\n                        $('<div class=\"message message-success braintree-credentials-success-message\">' + $t(\"Your credentials are valid.\") + '</div>').insertAfter(self);\n                    }\n                } else {\n                    alert({\n                        title: $t('Braintree Credential Validation Failed'),\n                        content: $t('Your Braintree Credentials could not be validated. Please ensure you have selected the correct environment and entered a valid Merchant ID, Public Key and Private Key.')\n                    });\n                }\n            }\n        }).always(function () {\n            $(self).text($t(\"Validate Credentials\")).attr('disabled', false);\n        });\n    };\n\n    window.applyForAll = function () {\n        let buttonShowStatus = '', buttonLabel = '', buttonColor = '', buttonShape = '', buttonSize = '';\n        let locations = ['checkout', 'productpage', 'cart'], buttonTypes = ['paypal', 'paylater', 'credit'];\n\n        let location = $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-fields-payment-location-value\"]').val();\n        let buttonType = $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-' + location + '-fields-paypal-location-' + location + '-button-type-value\"]').val();\n        buttonShowStatus = $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-' + location + '-groups-button-location-' + location + '-type-' + buttonType + '-fields-button-location-' + location + '-type-' + buttonType + '-show-value\"]').val();\n        buttonLabel = $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-' + location + '-groups-button-location-' + location + '-type-' + buttonType + '-fields-button-location-' + location + '-type-' + buttonType + '-label-value\"]').val();\n        buttonColor = $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-' + location + '-groups-button-location-' + location + '-type-' + buttonType + '-fields-button-location-' + location + '-type-' + buttonType + '-color-value\"]').val();\n        buttonShape = $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-' + location + '-groups-button-location-' + location + '-type-' + buttonType + '-fields-button-location-' + location + '-type-' + buttonType + '-shape-value\"]').val();\n        buttonSize = $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-' + location + '-groups-button-location-' + location + '-type-' + buttonType + '-fields-button-location-' + location + '-type-' + buttonType + '-size-value\"]').val();\n\n        // pay later messaging styling field values\n        let messagingShow = $('.' + location + '-messaging-show').val();\n        let messagingLayout = $('.' + location + '-messaging-layout').val();\n        let messagingLogo = $('.' + location + '-messaging-logo').val();\n        let messagingLogoPosition = $('.' + location + '-messaging-logo-position').val();\n        let messagingTextColor = $('.' + location + '-messaging-text-color').val();\n\n        locations.each(function (loc) {\n            buttonTypes.each(function (type) {\n                $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-' + loc + '-groups-button-location-' + loc + '-type-' + type + '-fields-button-location-' + loc + '-type-' + type + '-show-value\"]').val(buttonShowStatus).click();\n                $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-' + loc + '-groups-button-location-' + loc + '-type-' + type + '-fields-button-location-' + loc + '-type-' + type + '-label-value\"]').val(buttonLabel).click();\n                $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-' + loc + '-groups-button-location-' + loc + '-type-' + type + '-fields-button-location-' + loc + '-type-' + type + '-color-value\"]').val(buttonColor).click();\n                $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-' + loc + '-groups-button-location-' + loc + '-type-' + type + '-fields-button-location-' + loc + '-type-' + type + '-shape-value\"]').val(buttonShape).click();\n                $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-' + loc + '-groups-button-location-' + loc + '-type-' + type + '-fields-button-location-' + loc + '-type-' + type + '-size-value\"]').val(buttonSize).click();\n            });\n\n            // apply pay later messaging styling for all locations\n            $('.' + loc + '-messaging-show').val(messagingShow).click();\n            $('.' + loc + '-messaging-layout').val(messagingLayout).click();\n            $('.' + loc + '-messaging-logo').val(messagingLogo).click();\n            $('.' + loc + '-messaging-logo-position').val(messagingLogoPosition).click();\n            $('.' + loc + '-messaging-text-color').val(messagingTextColor).click();\n        });\n        $('#save').click();\n    };\n\n    window.resetAll = function () {\n        let locations = ['checkout', 'productpage', 'cart'], buttonTypes = ['paypal', 'paylater', 'credit'];\n        let buttonShowStatus = 1, buttonLabel = 'paypal', buttonColor = 'gold', buttonShape = 'rect', buttonSize = 'responsive';\n\n        locations.each(function (loc) {\n            buttonTypes.each(function (type) {\n                $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-' + loc + '-groups-button-location-' + loc + '-type-' + type + '-fields-button-location-' + loc + '-type-' + type + '-show-value\"]').val(buttonShowStatus).click();\n                $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-' + loc + '-groups-button-location-' + loc + '-type-' + type + '-fields-button-location-' + loc + '-type-' + type + '-label-value\"]').val(buttonLabel).click();\n                $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-' + loc + '-groups-button-location-' + loc + '-type-' + type + '-fields-button-location-' + loc + '-type-' + type + '-color-value\"]').val(buttonColor).click();\n                $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-' + loc + '-groups-button-location-' + loc + '-type-' + type + '-fields-button-location-' + loc + '-type-' + type + '-shape-value\"]').val(buttonShape).click();\n                $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-' + loc + '-groups-button-location-' + loc + '-type-' + type + '-fields-button-location-' + loc + '-type-' + type + '-size-value\"]').val(buttonSize).click();\n            });\n\n            // reset pay later messaging styling to recommended defaults\n            $('.' + loc + '-messaging-show').val(1).click();\n            $('.' + loc + '-messaging-layout').val('text').click();\n            $('.' + loc + '-messaging-logo').val('inline').click();\n            $('.' + loc + '-messaging-logo-position').val('left').click();\n            $('.' + loc + '-messaging-text-color').val('black').click();\n        });\n        $('#save').click();\n    };\n\n    window.applyButton = function () {\n        let locations = ['checkout', 'productpage', 'cart'], buttonTypes = ['paypal', 'paylater', 'credit'];\n\n        locations.each(function (loc) {\n            buttonTypes.each(function (type) {\n                $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-' + loc + '-groups-button-location-' + loc + '-type-' + type + '-fields-button-location-' + loc + '-type-' + type + '-show-value\"]').click();\n                $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-' + loc + '-groups-button-location-' + loc + '-type-' + type + '-fields-button-location-' + loc + '-type-' + type + '-label-value\"]').click();\n                $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-' + loc + '-groups-button-location-' + loc + '-type-' + type + '-fields-button-location-' + loc + '-type-' + type + '-color-value\"]').click();\n                $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-' + loc + '-groups-button-location-' + loc + '-type-' + type + '-fields-button-location-' + loc + '-type-' + type + '-shape-value\"]').click();\n                $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-' + loc + '-groups-button-location-' + loc + '-type-' + type + '-fields-button-location-' + loc + '-type-' + type + '-size-value\"]').click();\n            });\n\n            // apply pay later messaging styling to current location\n            $('.' + loc + '-messaging-show').click();\n            $('.' + loc + '-messaging-layout').click();\n            $('.' + loc + '-messaging-logo').click();\n            $('.' + loc + '-messaging-logo-position').click();\n            $('.' + loc + '-messaging-text-color').click();\n        });\n        $('#save').click();\n    };\n\n    var locations = ['checkout', 'productpage', 'cart'];\n    hidePaypalSections();\n    $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-fields-payment-location-value\"]').change(function () {\n        hidePaypalSections();\n    });\n    locations.each(function (loc) {\n        $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-'+loc+'-fields-paypal-location-'+loc+'-button-type-value\"]').change(function () {\n            hidePaypalSections();\n        });\n    });\n\n    function hidePaypalSections() {\n        var mainLocation, merchantCountryIndex, mainType;\n        var locations = ['checkout', 'productpage', 'cart'], buttonTypes = ['paypal', 'paylater', 'credit'];\n        mainLocation = $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-fields-payment-location-value\"]');\n        if (mainLocation.length < 1) {\n            return false;\n        }\n        merchantCountryIndex = mainLocation.attr('id').split('_')[1];\n        mainType = $('[data-ui-id=\"select-groups-braintree-section-groups-braintree-groups-braintree-paypal-groups-styling-groups-button-'+mainLocation.val()+'-fields-paypal-location-'+mainLocation.val()+'-button-type-value\"]');\n        locations.each(function (loc) {\n            $('#row_payment_' + merchantCountryIndex + '_braintree_section_braintree_braintree_paypal_styling_button_' + loc).hide();\n            buttonTypes.each(function (type) {\n                $('#row_payment_'+merchantCountryIndex+'_braintree_section_braintree_braintree_paypal_styling_button_'+loc+'_button_location_'+loc+'_type_' + type).hide();\n            });\n        });\n        $('#row_payment_'+merchantCountryIndex+'_braintree_section_braintree_braintree_paypal_styling_button_'+mainLocation.val()+'_button_location_'+mainLocation.val()+'_type_' + mainType.val()).show();\n        $('#row_payment_'+merchantCountryIndex+'_braintree_section_braintree_braintree_paypal_styling_button_' + mainLocation.val()).show();\n    }\n    disablePayLaterMessages();\n});\n","PayPal_Braintree/js/braintree.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/*browser:true*/\n/*global define*/\ndefine([\n    'jquery',\n    'uiComponent',\n    'Magento_Ui/js/modal/alert',\n    'Magento_Ui/js/lib/view/utils/dom-observer',\n    'mage/translate',\n    'PayPal_Braintree/js/validator',\n    'braintree',\n    'braintreeHostedFields'\n], function ($, Class, alert, domObserver, $t, validator, client, hostedFields) {\n    'use strict';\n\n    return Class.extend({\n\n        defaults: {\n            $selector: null,\n            selector: 'edit_form',\n            container: 'payment_form_braintree',\n            active: false,\n            scriptLoaded: false,\n            braintree: null,\n            selectedCardType: null,\n            imports: {\n                onActiveChange: 'active'\n            },\n            hostedFieldsInstance: null\n        },\n\n        /**\n         * Set list of observable attributes\n         * @returns {exports.initObservable}\n         */\n        initObservable: function () {\n            var self = this;\n\n            validator.setConfig(this);\n\n            self.$selector = $('#' + self.selector);\n            this._super()\n                .observe([\n                    'active',\n                    'scriptLoaded',\n                    'selectedCardType'\n                ]);\n\n            // re-init payment method events\n            self.$selector.off('changePaymentMethod.' + this.code)\n                .on('changePaymentMethod.' + this.code, this.changePaymentMethod.bind(this));\n\n            // listen block changes\n            domObserver.get('#' + self.container, function () {\n                if (self.scriptLoaded()) {\n                    self.$selector.off('submit');\n                    self.initBraintree();\n                }\n            });\n\n            return this;\n        },\n\n        /**\n         * Enable/disable current payment method\n         * @param {Object} event\n         * @param {String} method\n         * @returns {exports.changePaymentMethod}\n         */\n        changePaymentMethod: function (event, method) {\n            this.active(method === this.code);\n            return this;\n        },\n\n        /**\n         * Triggered when payment changed\n         * @param {Boolean} isActive\n         */\n        onActiveChange: function (isActive) {\n            if (!isActive) {\n                this.$selector.off('submitOrder.braintree');\n                this.$selector.on('submitOrder', function () {\n                    $('#payment_form_braintree').find('[type=\"submit\"]').trigger('click');\n                    $('#edit_form').trigger('realOrder');\n                });\n\n                return;\n            }\n            this.disableEventListeners();\n\n            if (typeof window.order !== 'undefined') {\n                window.order.addExcludedPaymentMethod(this.code);\n            }\n\n            if (!this.clientToken) {\n                this.error($.mage.__('This payment is not available'));\n\n                return;\n            }\n\n            this.enableEventListeners();\n\n            if (!this.scriptLoaded()) {\n                this.initBraintree();\n            }\n        },\n\n        /**\n         * Setup Braintree SDK\n         */\n        initBraintree: function () {\n            var self = this;\n            this.scriptLoaded(true);\n\n            self.disableEventListeners();\n\n            try {\n                $('body').trigger('processStart');\n\n                client.create({\n                    authorization: self.clientToken\n                }, function (clientErr, clientInstance) {\n                    if (clientErr) {\n                        console.error('Error!', clientErr);\n                        return self.error(response.clientErr);\n                    }\n\n                    hostedFields.create({\n                        client: clientInstance,\n                        fields: self.getHostedFields()\n                    }, function (createErr, hostedFieldsInstance) {\n                        if (createErr) {\n                            self.error($t(createErr));\n                            console.error('Error!', createErr);\n                            return;\n                        }\n\n                        self.hostedFieldsInstance = hostedFieldsInstance;\n                        self.enableEventListeners();\n\n                        $('body').trigger('processStop');\n                    }.bind(this));\n                }.bind(this));\n            } catch (e) {\n                $('body').trigger('processStop');\n                self.error(e.message);\n                console.log(e);\n            }\n        },\n\n        /**\n         * Get hosted fields configuration\n         * @returns {Object}\n         */\n        getHostedFields: function () {\n            var self = this,\n                fields = {\n                    number: {\n                        selector: self.getSelector('cc_number'),\n                        placeholder: $t('4111 1111 1111 1111')\n                    },\n                    expirationMonth: {\n                        selector: self.getSelector('cc_exp_month'),\n                        placeholder: $t('MM')\n                    },\n                    expirationYear: {\n                        selector: self.getSelector('cc_exp_year'),\n                        placeholder: $t('YY')\n                    }\n                };\n\n            if (self.useCvv) {\n                fields.cvv = {\n                    selector: self.getSelector('cc_cid'),\n                    placeholder: $t('123')\n                };\n            }\n\n            return fields;\n        },\n\n        /**\n         * Show alert message\n         * @param {String} message\n         */\n        error: function (message) {\n            alert({\n                content: message\n            });\n        },\n\n        /**\n         * Enable form event listeners\n         */\n        enableEventListeners: function () {\n            this.$selector.on('submitOrder.braintree', this.submitOrder.bind(this));\n        },\n\n        /**\n         * Disable form event listeners\n         */\n        disableEventListeners: function () {\n            this.$selector.off('submitOrder');\n            this.$selector.off('submit');\n        },\n\n        /**\n         * Store payment details\n         * @param {String} nonce\n         */\n        setPaymentDetails: function (nonce) {\n            var $container = $('#' + this.container);\n\n            $container.find('[name=\"payment[payment_method_nonce]\"]').val(nonce);\n        },\n\n        /**\n         * Trigger order submit\n         */\n        submitOrder: function () {\n            this.$selector.validate().form();\n            this.$selector.trigger('afterValidate.beforeSubmit');\n            $('body').trigger('processStop');\n\n            // validate parent form\n            if (this.$selector.validate().errorList.length) {\n                return false;\n            }\n\n            $('body').trigger('processStart');\n            this.tokenizeHostedFields();\n        },\n\n        /**\n         * Place order\n         */\n        placeOrder: function () {\n            $('#' + this.selector).trigger('realOrder');\n        },\n\n        /**\n         * Get list of currently available card types\n         * @returns {Array}\n         */\n        getCcAvailableTypes: function () {\n            var types = [],\n                $options = $(this.getSelector('cc_type')).find('option');\n\n            $.map($options, function (option) {\n                types.push($(option).val());\n            });\n\n            return types;\n        },\n\n        /**\n         * Get jQuery selector\n         * @param {String} field\n         * @returns {String}\n         */\n        getSelector: function (field) {\n            return '#' + this.code + '_' + field;\n        },\n\n        tokenizeHostedFields: function () {\n            this.hostedFieldsInstance.tokenize({\n                vault: false // vault or no?\n            }, function (tokenizeErr, payload) {\n                if (tokenizeErr) {\n                    $('body').trigger('processStop');\n                    switch (tokenizeErr.code) {\n                        case 'HOSTED_FIELDS_FIELDS_EMPTY':\n                            // occurs when none of the fields are filled in\n                            this.error($t('Please enter a card number, expiration date and CVV'));\n                            break;\n                        case 'HOSTED_FIELDS_FIELDS_INVALID':\n                            // occurs when certain fields do not pass client side validation\n                            this.error($t('Please correct the problems with the Credit Card fields.'));\n                            console.error('Some fields are invalid:', tokenizeErr.details.invalidFieldKeys);\n                            break;\n                        case 'HOSTED_FIELDS_TOKENIZATION_FAIL_ON_DUPLICATE':\n                            // occurs when:\n                            //   * the client token used for client authorization was generated\n                            //     with a customer ID and the fail on duplicate payment method\n                            //     option is set to true\n                            //   * the card being tokenized has previously been vaulted (with any customer)\n                            // See: https://developers.braintreepayments.com/reference/request/client-token/generate/#options.fail_on_duplicate_payment_method\n                            this.error($t('The payment method used, already exists in the user\\'s vault. Please use the vault option instead.'));\n                            break;\n                        case 'HOSTED_FIELDS_TOKENIZATION_CVV_VERIFICATION_FAILED':\n                            // occurs when:\n                            //   * the client token used for client authorization was generated\n                            //     with a customer ID and the verify card option is set to true\n                            //     and you have credit card verification turned on in the Braintree\n                            //     control panel\n                            //   * the cvv does not pass verfication (https://developers.braintreepayments.com/reference/general/testing/#avs-and-cvv/cid-responses)\n                            // See: https://developers.braintreepayments.com/reference/request/client-token/generate/#options.verify_card\n                            this.error($t('CVV did not pass verification'));\n                            break;\n                        case 'HOSTED_FIELDS_FAILED_TOKENIZATION':\n                            // occurs for any other tokenization error on the server\n                            this.error($t('There was an issue tokenizing the card. Please check the card is valid.'));\n                            console.error('Tokenization failed server side. Is the card valid?');\n                            break;\n                        case 'HOSTED_FIELDS_TOKENIZATION_NETWORK_ERROR':\n                            // occurs when the Braintree gateway cannot be contacted\n                            this.error($t('There was an error connecting to Braintree. Please try again.'));\n                            break;\n                        default:\n                            this.error($t('There was an issue processing the payment. Please try again.'));\n                            console.error('Braintree error', tokenizeErr);\n                            break;\n                    }\n                } else {\n                    this.setPaymentDetails(payload.nonce);\n                    $('#' + this.container).find('[type=\"submit\"]').trigger('click');\n                }\n            }.bind(this));\n        }\n    });\n});\n","PayPal_Braintree/js/validator.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/*browser:true*/\n/*global define*/\ndefine([\n    'underscore'\n], function (_) {\n    'use strict';\n\n    return {\n        config: {},\n\n        /**\n         * Set configuration\n         * @param {Object} config\n         */\n        setConfig: function (config) {\n            this.config = config;\n        },\n\n        /**\n         * Get List of available card types\n         * @returns {*|exports.defaults.availableCardTypes|{}}\n         */\n        getAvailableCardTypes: function () {\n            return this.config.availableCardTypes;\n        },\n\n        /**\n         * Get list of card types\n         * @returns {Object}\n         */\n        getCcTypesMapper: function () {\n            return this.config.ccTypesMapper;\n        },\n\n        /**\n         * Find mage card type by Braintree type\n         * @param {String} type\n         * @param {Object} availableTypes\n         * @returns {*}\n         */\n        getMageCardType: function (type, availableTypes) {\n            var storedCardType = null,\n                mapper = this.getCcTypesMapper();\n\n            if (type && typeof mapper[type] !== 'undefined') {\n                storedCardType = mapper[type];\n\n                if (_.indexOf(availableTypes, storedCardType) !== -1) {\n                    return storedCardType;\n                }\n            }\n\n            return null;\n        },\n\n        /**\n         * Filter list of available card types\n         * @param {Object} availableTypes\n         * @param {Object} countrySpecificCardTypes\n         * @returns {Object}\n         */\n        collectTypes: function (availableTypes, countrySpecificCardTypes) {\n            var key,\n                filteredTypes = [];\n\n            for (key in availableTypes) {\n                if (_.indexOf(countrySpecificCardTypes, availableTypes[key]) !== -1) {\n                    filteredTypes.push(availableTypes[key]);\n                }\n            }\n\n            return filteredTypes;\n        },\n\n        /**\n         * Get list of card types for country\n         * @param {String} countryId\n         * @returns {*}\n         */\n        getCountrySpecificCardTypes: function (countryId) {\n            if (typeof this.config.countrySpecificCardTypes[countryId] !== 'undefined') {\n                return this.config.countrySpecificCardTypes[countryId];\n            }\n\n            return false;\n        }\n    };\n});\n","PayPal_Braintree/js/virtual.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/*browser:true*/\n/*global define*/\ndefine([\n    'jquery',\n    'uiComponent',\n    'Magento_Ui/js/modal/alert',\n    'Magento_Ui/js/lib/view/utils/dom-observer',\n    'mage/translate',\n    'PayPal_Braintree/js/validator',\n    'braintree',\n    'braintreeHostedFields'\n], function ($, Class, alert, domObserver, $t, validator, client, hostedFields) {\n    'use strict';\n\n    return Class.extend({\n\n        defaults: {\n            $container: null,\n            container: 'payment_form_braintree',\n            braintree: null,\n            selectedCardType: null,\n            hostedFieldsInstance: null\n        },\n\n        /**\n         * Set list of observable attributes\n         * @returns {exports.initObservable}\n         */\n        initObservable: function () {\n            var self = this;\n\n            validator.setConfig(this);\n\n            self.$container = $('#' + self.container);\n            this._super()\n                .observe([\n                    'selectedCardType'\n                ]);\n\n            domObserver.get('#' + self.container, function () {\n                self.initBraintree();\n            });\n\n            return this;\n        },\n\n        /**\n         * Setup Braintree SDK\n         */\n        initBraintree: function () {\n            var self = this;\n\n            try {\n                $('body').trigger('processStart');\n\n                client.create({\n                    authorization: self.clientToken\n                }, function (clientErr, clientInstance) {\n                    if (clientErr) {\n                        alert({\n                            content: $t('Please configure your Braintree Payments account in order to use the virtual terminal.')\n                        });\n                        console.error('Error!', clientErr);\n                        return self.error(response.clientErr);\n                    }\n\n                    hostedFields.create({\n                        client: clientInstance,\n                        fields: self.getHostedFields()\n                    }, function (createErr, hostedFieldsInstance) {\n                        if (createErr) {\n                            self.error($t(createErr));\n                            console.error('Error!', createErr);\n                            return;\n                        }\n\n                        self.hostedFieldsInstance = hostedFieldsInstance;\n                        self.$container.on('takePayment', self.submitOrder.bind(self));\n\n                        $('body').trigger('processStop');\n                    }.bind(this));\n                }.bind(this));\n            } catch (e) {\n                $('body').trigger('processStop');\n                self.error(e.message);\n                console.log(e);\n            }\n        },\n\n        /**\n         * Get hosted fields configuration\n         * @returns {Object}\n         */\n        getHostedFields: function () {\n            return {\n                number: {\n                    selector: this.getSelector('cc_number'),\n                    placeholder: $t('4111 1111 1111 1111')\n                },\n                expirationMonth: {\n                    selector: this.getSelector('cc_exp_month'),\n                    placeholder: $t('MM')\n                },\n                expirationYear: {\n                    selector: this.getSelector('cc_exp_year'),\n                    placeholder: $t('YY')\n                },\n                cvv: {\n                    selector: this.getSelector('cc_cid'),\n                    placeholder: $t('123')\n                }\n            };\n        },\n\n        /**\n         * Show alert message\n         * @param {String} message\n         */\n        error: function (message) {\n            alert({\n                content: message\n            });\n        },\n\n        /**\n         * Store payment details\n         * @param {String} nonce\n         */\n        setPaymentDetails: function (nonce) {\n            var $container = $('#' + this.container);\n            $container.find('[name=\"payment_method_nonce\"]').val(nonce);\n        },\n\n        /**\n         * Trigger order submit\n         */\n        submitOrder: function (event) {\n            event.preventDefault();\n\n            this.$container.validate().form();\n            this.$container.trigger('afterValidate.beforeSubmit');\n            $('body').trigger('processStop');\n\n            // validate parent form\n            if (this.$container.validate().errorList.length) {\n                return false;\n            }\n\n            $('body').trigger('processStart');\n            this.tokenizeHostedFields();\n        },\n\n        /**\n         * Place order\n         */\n        placeOrder: function () {\n            this.$container.submit();\n        },\n\n        /**\n         * Get list of currently available card types\n         * @returns {Array}\n         */\n        getCcAvailableTypes: function () {\n            var types = [],\n                $options = $(this.getSelector('cc_type')).find('option');\n\n            $.map($options, function (option) {\n                types.push($(option).val());\n            });\n\n            return types;\n        },\n\n        /**\n         * Get jQuery selector\n         * @param {String} field\n         * @returns {String}\n         */\n        getSelector: function (field) {\n            return '#' + this.code + '_' + field;\n        },\n\n        tokenizeHostedFields: function () {\n            this.hostedFieldsInstance.tokenize({\n                vault: false // vault or no?\n            }, function (tokenizeErr, payload) {\n                if (tokenizeErr) {\n                    $('body').trigger('processStop');\n                    switch (tokenizeErr.code) {\n                        case 'HOSTED_FIELDS_FIELDS_EMPTY':\n                            // occurs when none of the fields are filled in\n                            this.error($t('Please enter a card number, expiration date and CVV'));\n                            break;\n                        case 'HOSTED_FIELDS_FIELDS_INVALID':\n                            // occurs when certain fields do not pass client side validation\n                            this.error($t('Please correct the problems with the Credit Card fields.'));\n                            console.error('Some fields are invalid:', tokenizeErr.details.invalidFieldKeys);\n                            break;\n                        case 'HOSTED_FIELDS_TOKENIZATION_FAIL_ON_DUPLICATE':\n                            // occurs when:\n                            //   * the client token used for client authorization was generated\n                            //     with a customer ID and the fail on duplicate payment method\n                            //     option is set to true\n                            //   * the card being tokenized has previously been vaulted (with any customer)\n                            // See: https://developers.braintreepayments.com/reference/request/client-token/generate/#options.fail_on_duplicate_payment_method\n                            this.error($t('The payment method used, already exists in the user\\'s vault. Please use the vault option instead.'));\n                            break;\n                        case 'HOSTED_FIELDS_TOKENIZATION_CVV_VERIFICATION_FAILED':\n                            // occurs when:\n                            //   * the client token used for client authorization was generated\n                            //     with a customer ID and the verify card option is set to true\n                            //     and you have credit card verification turned on in the Braintree\n                            //     control panel\n                            //   * the cvv does not pass verfication (https://developers.braintreepayments.com/reference/general/testing/#avs-and-cvv/cid-responses)\n                            // See: https://developers.braintreepayments.com/reference/request/client-token/generate/#options.verify_card\n                            this.error($t('CVV did not pass verification'));\n                            break;\n                        case 'HOSTED_FIELDS_FAILED_TOKENIZATION':\n                            // occurs for any other tokenization error on the server\n                            this.error($t('There was an issue tokenizing the card. Please check the card is valid.'));\n                            console.error('Tokenization failed server side. Is the card valid?');\n                            break;\n                        case 'HOSTED_FIELDS_TOKENIZATION_NETWORK_ERROR':\n                            // occurs when the Braintree gateway cannot be contacted\n                            this.error($t('There was an error connecting to Braintree. Please try again.'));\n                            break;\n                        default:\n                            this.error($t('There was an issue processing the payment. Please try again.'));\n                            console.error('Braintree error', tokenizeErr);\n                            break;\n                    }\n                } else {\n                    this.setPaymentDetails(payload.nonce);\n                    this.placeOrder();\n                }\n            }.bind(this));\n        }\n    });\n});\n","PayPal_Braintree/js/paypalStylingPreview.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\nrequire([\n    'underscore',\n    'jquery',\n    'domReady!'\n], function (_, $) {\n    'use strict';\n    let buttonIds = [], currentButtonId = '';\n    let location = '', buttonType = '', buttonShow = '', buttonLabel = '', buttonColor = '', buttonShape = '', buttonSize = '';\n    let messagingShow = '', messagingLayout = '', messagingLogo = '', messagingLogoPosition = '', messagingTextColor = '';\n\n    function getCurrentLocationAndButtonType()\n    {\n        location = $('.payment-location').val();\n        buttonType = $('.' + location + '-button-type').val();\n    }\n\n    $(document).ready(function () {\n        getCurrentLocationAndButtonType();\n\n        $('.payment-location').on('change', function (customEvent) {\n            location = $(this).val();\n            buttonType = $('.' + location + '-button-type').val();\n            buttonShow = $('.' + location + '-' + buttonType + '-show').val();\n            buttonLabel = $('.' + location + '-' + buttonType + '-label').val();\n            buttonColor = $('.' + location + '-' + buttonType + '-color').val();\n            buttonShape = $('.' + location + '-' + buttonType + '-shape').val();\n            buttonSize = $('.' + location + '-' + buttonType + '-size').val();\n\n            updatePayPalButtonStyling(location, buttonType, buttonShow, buttonLabel, buttonColor, buttonShape, buttonSize);\n\n            // render pay later messages when location changed\n            messagingShow = $('.' + location + '-messaging-show').val();\n            messagingLayout = $('.' + location + '-messaging-layout').val();\n            messagingLogo = $('.' + location + '-messaging-logo').val();\n            messagingLogoPosition = $('.' + location + '-messaging-logo-position').val();\n            messagingTextColor = $('.' + location + '-messaging-text-color').val();\n\n            renderPayLaterMessages(location, messagingShow, messagingLayout, messagingLogo, messagingLogoPosition, messagingTextColor);\n            customEvent.stopImmediatePropagation();\n        });\n\n        $(\"select\").change(function () {\n            $(document).on('change', '.' + location + '-button-type', function (customEvent) {\n                buttonType = $(this).val();\n                buttonShow = $('.' + location + '-' + buttonType + '-show').val();\n                buttonLabel = $('.' + location + '-' + buttonType + '-label').val();\n                buttonColor = $('.' + location + '-' + buttonType + '-color').val();\n                buttonShape = $('.' + location + '-' + buttonType + '-shape').val();\n                buttonSize = $('.' + location + '-' + buttonType + '-size').val();\n\n                updatePayPalButtonStyling(location, buttonType, buttonShow, buttonLabel, buttonColor, buttonShape, buttonSize);\n                customEvent.stopImmediatePropagation();\n            });\n\n            $(document).on('change', '.' + location + '-' + buttonType + '-show', function (customEvent) {\n                buttonShow = $(this).val();\n                buttonLabel = $('.' + location + '-' + buttonType + '-label').val();\n                buttonColor = $('.' + location + '-' + buttonType + '-color').val();\n                buttonShape = $('.' + location + '-' + buttonType + '-shape').val();\n                buttonSize = $('.' + location + '-' + buttonType + '-size').val();\n\n                updatePayPalButtonStyling(location, buttonType, buttonShow, buttonLabel, buttonColor, buttonShape, buttonSize);\n                customEvent.stopImmediatePropagation();\n            });\n\n\n            $(document).on('change', '.' + location + '-' + buttonType + '-label', function (customEvent) {\n                buttonLabel = $(this).val();\n                buttonShow = $('.' + location + '-' + buttonType + '-show').val();\n                buttonColor = $('.' + location + '-' + buttonType + '-color').val();\n                buttonShape = $('.' + location + '-' + buttonType + '-shape').val();\n                buttonSize = $('.' + location + '-' + buttonType + '-size').val();\n\n                updatePayPalButtonStyling(location, buttonType, buttonShow, buttonLabel, buttonColor, buttonShape, buttonSize);\n                customEvent.stopImmediatePropagation();\n            });\n\n            $(document).on('change', '.' + location + '-' + buttonType + '-color', function (customEvent) {\n                buttonColor = $(this).val();\n                buttonShow = $('.' + location + '-' + buttonType + '-show').val();\n                buttonLabel = $('.' + location + '-' + buttonType + '-label').val();\n                buttonShape = $('.' + location + '-' + buttonType + '-shape').val();\n                buttonSize = $('.' + location + '-' + buttonType + '-size').val();\n\n                updatePayPalButtonStyling(location, buttonType, buttonShow, buttonLabel, buttonColor, buttonShape, buttonSize);\n                customEvent.stopImmediatePropagation();\n            });\n\n            $(document).on('change', '.' + location + '-' + buttonType + '-shape', function (customEvent) {\n                buttonShape = $(this).val();\n                buttonShow = $('.' + location + '-' + buttonType + '-show').val();\n                buttonLabel = $('.' + location + '-' + buttonType + '-label').val();\n                buttonColor = $('.' + location + '-' + buttonType + '-color').val();\n                buttonSize = $('.' + location + '-' + buttonType + '-size').val();\n\n                updatePayPalButtonStyling(location, buttonType, buttonShow, buttonLabel, buttonColor, buttonShape, buttonSize);\n                customEvent.stopImmediatePropagation();\n            });\n\n            $(document).on('change', '.' + location + '-' + buttonType + '-size', function (customEvent) {\n                buttonSize = $(this).val();\n                buttonShow = $('.' + location + '-' + buttonType + '-show').val();\n                buttonLabel = $('.' + location + '-' + buttonType + '-label').val();\n                buttonColor = $('.' + location + '-' + buttonType + '-color').val();\n                buttonShape = $('.' + location + '-' + buttonType + '-shape').val();\n\n                updatePayPalButtonStyling(location, buttonType, buttonShow, buttonLabel, buttonColor, buttonShape, buttonSize);\n                customEvent.stopImmediatePropagation();\n            });\n\n            $(document).on('change', '.' + location + '-messaging-show', function (customEvent) {\n                messagingShow = $(this).val();\n                messagingLayout = $('.' + location + '-messaging-layout').val();\n                messagingLogo = $('.' + location + '-messaging-logo').val();\n                messagingLogoPosition = $('.' + location + '-messaging-logo-position').val();\n                messagingTextColor = $('.' + location + '-messaging-text-color').val();\n\n                renderPayLaterMessages(location, messagingShow, messagingLayout, messagingLogo, messagingLogoPosition, messagingTextColor);\n                customEvent.stopImmediatePropagation();\n            });\n\n            $(document).on('change', '.' + location + '-messaging-layout', function (customEvent) {\n                messagingShow = $('.' + location + '-messaging-show').val();\n                messagingLayout = $(this).val();\n                messagingLogo = $('.' + location + '-messaging-logo').val();\n                messagingLogoPosition = $('.' + location + '-messaging-logo-position').val();\n                messagingTextColor = $('.' + location + '-messaging-text-color').val();\n\n                renderPayLaterMessages(location, messagingShow, messagingLayout, messagingLogo, messagingLogoPosition, messagingTextColor);\n                customEvent.stopImmediatePropagation();\n            });\n\n            $(document).on('change', '.' + location + '-messaging-logo', function (customEvent) {\n                messagingShow = $('.' + location + '-messaging-show').val();\n                messagingLayout = $('.' + location + '-messaging-layout').val();\n                messagingLogo = $(this).val();\n                messagingLogoPosition = $('.' + location + '-messaging-logo-position').val();\n                messagingTextColor = $('.' + location + '-messaging-text-color').val();\n\n                renderPayLaterMessages(location, messagingShow, messagingLayout, messagingLogo, messagingLogoPosition, messagingTextColor);\n                customEvent.stopImmediatePropagation();\n            });\n\n            $(document).on('change', '.' + location + '-messaging-logo-position', function (customEvent) {\n                messagingShow = $('.' + location + '-messaging-show').val();\n                messagingLayout = $('.' + location + '-messaging-layout').val();\n                messagingLogo = $('.' + location + '-messaging-logo').val();\n                messagingLogoPosition = $(this).val();\n                messagingTextColor = $('.' + location + '-messaging-text-color').val();\n\n                renderPayLaterMessages(location, messagingShow, messagingLayout, messagingLogo, messagingLogoPosition, messagingTextColor);\n                customEvent.stopImmediatePropagation();\n            });\n\n            $(document).on('change', '.' + location + '-messaging-text-color', function (customEvent) {\n                messagingShow = $('.' + location + '-messaging-show').val();\n                messagingLayout = $('.' + location + '-messaging-layout').val();\n                messagingLogo = $('.' + location + '-messaging-logo').val();\n                messagingLogoPosition = $('.' + location + '-messaging-logo-position').val();\n                messagingTextColor = $(this).val();\n\n                renderPayLaterMessages(location, messagingShow, messagingLayout, messagingLogo, messagingLogoPosition, messagingTextColor);\n                customEvent.stopImmediatePropagation();\n            });\n        });\n    });\n\n    /**\n     * Update PayPal, Credit and Pay Later button styling if applicable\n     * @param location\n     * @param buttonType\n     * @param buttonShow\n     * @param buttonLabel\n     * @param buttonColor\n     * @param buttonShape\n     * @param buttonSize\n     */\n    let updatePayPalButtonStyling = function (location, buttonType, buttonShow, buttonLabel, buttonColor, buttonShape, buttonSize) {\n        $('.action-braintree-paypal-logo').each(function () {\n            if ($.inArray($(this).attr('id'), buttonIds) === -1) {\n                buttonIds.push($(this).attr('id'));\n            }\n        });\n\n        buttonIds.each(function (id) {\n            let result = id.startsWith(buttonType);\n            if (result === true) {\n                currentButtonId = id;\n            }\n        });\n\n        let currentButtonElement = $('#' + currentButtonId);\n        if (currentButtonElement.length) {\n            let style = {\n                color: buttonColor,\n                shape: buttonShape,\n                size: buttonSize,\n                label: buttonLabel\n            };\n            style.fundingicons = true;\n            let fundingSource = buttonType;\n\n            // Render\n            let button = paypal.Buttons({\n                fundingSource: fundingSource,\n                style: style,\n\n                onInit: function (data, actions) {\n                    actions.disable();\n                }\n            });\n            if (!button.isEligible()) {\n                console.log('PayPal button is not eligible');\n                currentButtonElement.parent().remove();\n                return;\n            }\n            if (currentButtonElement.length) {\n                currentButtonElement.empty();\n                if (buttonShow === '1') {\n                    button.render('#' + currentButtonElement.attr('id'));\n                }\n            }\n        }\n    };\n\n    /**\n     * Render and update Pay Later messaging style\n     * @param location\n     * @param messagingShow\n     * @param messagingLayout\n     * @param messagingLogo\n     * @param messagingLogoPosition\n     * @param messagingTextColor\n     */\n    let renderPayLaterMessages = function (location, messagingShow, messagingLayout, messagingLogo, messagingLogoPosition, messagingTextColor) {\n        $('.action-braintree-paypal-message').each(function () {\n            let messageElement = $('#' + $(this).attr('id'));\n\n            let payLaterMessageStyle = {\n                layout: messagingLayout,\n                text: {\n                    color: messagingTextColor\n                },\n                logo: {\n                    type: messagingLogo,\n                    position: messagingLogoPosition\n                }\n            };\n\n            let messageElementId = $(messageElement).attr('id');\n            let messageAmount = $(messageElement).data('pp-amount');\n            let parentElementId = messageElement.closest('tr').attr('id');\n\n            let messages = paypal.Messages({\n                amount: $(messageElement).data('pp-amount'),\n                pageType: location,\n                style: payLaterMessageStyle\n            });\n\n            if (messageElement.length) {\n                if (messagingShow === '1') {\n                    messageElement.remove();\n                    $('#' + parentElementId + ' td.value').append('<div class=\"action-braintree-paypal-message\" id=\"' + messageElementId + '\" data-pp-amount=\"' + messageAmount + '\" data-pp-type=\"' + location + '\" data-messaging-show=\"' + messagingShow + '\" data-messaging-layout=\"' + messagingLayout + '\" data-messaging-logo=\"' + messagingLogo + '\" data-messaging-logo-position=\"' + messagingLogoPosition + '\" data-messaging-text-color=\"' + messagingTextColor + '\"></div>');\n                    messages.render('#' + messageElementId);\n                } else {\n                    messageElement.hide();\n                }\n            }\n        });\n    };\n});\n","PayPal_Braintree/js/vault.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n/*browser:true*/\n/*global define*/\ndefine([\n    'jquery',\n    'uiComponent',\n    'Magento_Ui/js/modal/alert'\n], function ($, Class, alert) {\n    'use strict';\n\n    return Class.extend({\n        defaults: {\n            $selector: null,\n            selector: 'edit_form',\n            $container: null\n        },\n\n        /**\n         * Set list of observable attributes\n         * @returns {exports.initObservable}\n         */\n        initObservable: function () {\n            var self = this;\n\n            self.$selector = $('#' + self.selector);\n            self.$container =  $('#' + self.container);\n            self.$selector.on(\n                'setVaultNotActive.' + self.getCode(),\n                function () {\n                    self.$selector.off('submitOrder.' + self.getCode());\n                }\n            );\n            self._super();\n\n            self.initEventHandlers();\n\n            return self;\n        },\n\n        /**\n         * Get payment code\n         * @returns {String}\n         */\n        getCode: function () {\n            return this.code;\n        },\n\n        /**\n         * Init event handlers\n         */\n        initEventHandlers: function () {\n            $(this.$container).find('[name=\"payment[token_switcher]\"]')\n                .on('click', this.selectPaymentMethod.bind(this));\n        },\n\n        /**\n         * Select current payment token\n         */\n        selectPaymentMethod: function () {\n            this.disableEventListeners();\n            this.enableEventListeners();\n        },\n\n        /**\n         * Enable form event listeners\n         */\n        enableEventListeners: function () {\n            this.$selector.on('submitOrder.' + this.getCode(), this.submitOrder.bind(this));\n        },\n\n        /**\n         * Disable form event listeners\n         */\n        disableEventListeners: function () {\n            this.$selector.off('submitOrder');\n        },\n\n        /**\n         * Pre submit for order\n         * @returns {Boolean}\n         */\n        submitOrder: function () {\n            this.$selector.validate().form();\n            this.$selector.trigger('afterValidate.beforeSubmit');\n            $('body').trigger('processStop');\n\n            // validate parent form\n            if (this.$selector.validate().errorList.length) {\n                return false;\n            }\n            this.getPaymentMethodNonce();\n        },\n\n        /**\n         * Place order\n         */\n        placeOrder: function () {\n            this.$selector.trigger('realOrder');\n        },\n\n        /**\n         * Send request to get payment method nonce\n         */\n        getPaymentMethodNonce: function () {\n            var self = this;\n\n            $('body').trigger('processStart');\n\n            $.getJSON(self.nonceUrl, {\n                'public_hash': self.publicHash\n            }).done(function (response) {\n                self.setPaymentDetails(response.paymentMethodNonce);\n                self.placeOrder();\n            }).fail(function (response) {\n                var failed = JSON.parse(response.responseText);\n\n                self.error(failed.message);\n            }).always(function () {\n                $('body').trigger('processStop');\n            });\n        },\n\n        /**\n         * Store payment details\n         * @param {String} nonce\n         */\n        setPaymentDetails: function (nonce) {\n            this.createPublicHashSelector();\n\n            this.$selector.find('[name=\"payment[public_hash]\"]').val(this.publicHash);\n            this.$selector.find('[name=\"payment[payment_method_nonce]\"]').val(nonce).prop('disabled', false);\n        },\n\n        /**\n         * Creates public hash selector\n         */\n        createPublicHashSelector: function () {\n            var $input;\n\n            if (this.$selector.find('[name=\"payment[payment_method_nonce]\"]').length === 0) {\n                $input = $('<input>').attr(\n                    {\n                        type: 'hidden',\n                        id: this.getNonceSelectorName(),\n                        name: 'payment[payment_method_nonce]'\n                    }\n                );\n\n                $input.appendTo(this.$selector);\n                $input.prop('disabled', false);\n            }\n        },\n\n        /**\n         * Show alert message\n         * @param {String} message\n         */\n        error: function (message) {\n            alert({\n                content: message\n            });\n        },\n\n        /**\n         * Get selector name for nonce input\n         * @returns {String}\n         */\n        getNonceSelectorName: function () {\n            return 'nonce_' + this.getCode();\n        }\n    });\n});\n","PayPal_Braintree/js/grid/provider.js":"/**\n * Copyright \u00a9 Magento, Inc. All rights reserved.\n * See COPYING.txt for license details.\n */\n\ndefine([\n    'underscore',\n    'Magento_Ui/js/grid/provider'\n], function (_, Provider) {\n    'use strict';\n\n    return Provider.extend({\n\n        /**\n         * Reload grid\n         * @returns {exports}\n         */\n        reload: function () {\n            if (this.hasFilters()) {\n                this._super();\n\n                return this;\n            }\n\n            this.trigger('reload');\n\n            this.onReload({\n                items: [],\n                totalRecords: 0\n            });\n\n            return this;\n        },\n\n        /**\n         * Has filters checker\n         * @returns {Boolean}\n         */\n        hasFilters: function () {\n            var params = this.params,\n                filters = params.filters || {};\n\n            return _.keys(filters).length > 1;\n        }\n    });\n});\n"}
}});