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/frontend/Magento/blank/en_US/js/bundle/
Upload File :
Current File : /home/austenwhite.co.uk/www/dev/pub/static/frontend/Magento/blank/en_US/js/bundle/bundle6.js
require.config({"config": {
        "jsbuild":{"jquery/spectrum/spectrum.js":"// Spectrum Colorpicker v1.8.1\n// https://github.com/bgrins/spectrum\n// Author: Brian Grinstead\n// License: MIT\n\n(function (factory) {\n    \"use strict\";\n\n    if (typeof define === 'function' && define.amd) { // AMD\n        define(['jquery'], factory);\n    }\n    else if (typeof exports == \"object\" && typeof module == \"object\") { // CommonJS\n        module.exports = factory(require('jquery'));\n    }\n    else { // Browser\n        factory(jQuery);\n    }\n})(function($, undefined) {\n    \"use strict\";\n\n    var defaultOpts = {\n\n            // Callbacks\n            beforeShow: noop,\n            move: noop,\n            change: noop,\n            show: noop,\n            hide: noop,\n\n            // Options\n            color: false,\n            flat: false,\n            showInput: false,\n            allowEmpty: false,\n            showButtons: true,\n            clickoutFiresChange: true,\n            showInitial: false,\n            showPalette: false,\n            showPaletteOnly: false,\n            hideAfterPaletteSelect: false,\n            togglePaletteOnly: false,\n            showSelectionPalette: true,\n            localStorageKey: false,\n            appendTo: \"body\",\n            maxSelectionSize: 7,\n            cancelText: \"cancel\",\n            chooseText: \"choose\",\n            togglePaletteMoreText: \"more\",\n            togglePaletteLessText: \"less\",\n            clearText: \"Clear Color Selection\",\n            noColorSelectedText: \"No Color Selected\",\n            preferredFormat: false,\n            className: \"\", // Deprecated - use containerClassName and replacerClassName instead.\n            containerClassName: \"\",\n            replacerClassName: \"\",\n            showAlpha: false,\n            theme: \"sp-light\",\n            palette: [[\"#ffffff\", \"#000000\", \"#ff0000\", \"#ff8000\", \"#ffff00\", \"#008000\", \"#0000ff\", \"#4b0082\", \"#9400d3\"]],\n            selectionPalette: [],\n            disabled: false,\n            offset: null\n        },\n        spectrums = [],\n        IE = !!/msie/i.exec( window.navigator.userAgent ),\n        rgbaSupport = (function() {\n            function contains( str, substr ) {\n                return !!~('' + str).indexOf(substr);\n            }\n\n            var elem = document.createElement('div');\n            var style = elem.style;\n            style.cssText = 'background-color:rgba(0,0,0,.5)';\n            return contains(style.backgroundColor, 'rgba') || contains(style.backgroundColor, 'hsla');\n        })(),\n        replaceInput = [\n            \"<div class='sp-replacer'>\",\n            \"<div class='sp-preview'><div class='sp-preview-inner'></div></div>\",\n            \"<div class='sp-dd'>&#9660;</div>\",\n            \"</div>\"\n        ].join(''),\n        markup = (function () {\n\n            // IE does not support gradients with multiple stops, so we need to simulate\n            //  that for the rainbow slider with 8 divs that each have a single gradient\n            var gradientFix = \"\";\n            if (IE) {\n                for (var i = 1; i <= 6; i++) {\n                    gradientFix += \"<div class='sp-\" + i + \"'></div>\";\n                }\n            }\n\n            return [\n                \"<div class='sp-container sp-hidden'>\",\n                \"<div class='sp-palette-container'>\",\n                \"<div class='sp-palette sp-thumb sp-cf'></div>\",\n                \"<div class='sp-palette-button-container sp-cf'>\",\n                \"<button type='button' class='sp-palette-toggle'></button>\",\n                \"</div>\",\n                \"</div>\",\n                \"<div class='sp-picker-container'>\",\n                \"<div class='sp-top sp-cf'>\",\n                \"<div class='sp-fill'></div>\",\n                \"<div class='sp-top-inner'>\",\n                \"<div class='sp-color'>\",\n                \"<div class='sp-sat'>\",\n                \"<div class='sp-val'>\",\n                \"<div class='sp-dragger'></div>\",\n                \"</div>\",\n                \"</div>\",\n                \"</div>\",\n                \"<div class='sp-clear sp-clear-display'>\",\n                \"</div>\",\n                \"<div class='sp-hue'>\",\n                \"<div class='sp-slider'></div>\",\n                gradientFix,\n                \"</div>\",\n                \"</div>\",\n                \"<div class='sp-alpha'><div class='sp-alpha-inner'><div class='sp-alpha-handle'></div></div></div>\",\n                \"</div>\",\n                \"<div class='sp-input-container sp-cf'>\",\n                \"<input class='sp-input' type='text' spellcheck='false'  />\",\n                \"</div>\",\n                \"<div class='sp-initial sp-thumb sp-cf'></div>\",\n                \"<div class='sp-button-container sp-cf'>\",\n                \"<a class='sp-cancel' href='#'></a>\",\n                \"<button type='button' class='sp-choose'></button>\",\n                \"</div>\",\n                \"</div>\",\n                \"</div>\"\n            ].join(\"\");\n        })();\n\n    function paletteTemplate (p, color, className, opts) {\n        var html = [];\n        for (var i = 0; i < p.length; i++) {\n            var current = p[i];\n            if(current) {\n                var tiny = tinycolor(current);\n                var c = tiny.toHsl().l < 0.5 ? \"sp-thumb-el sp-thumb-dark\" : \"sp-thumb-el sp-thumb-light\";\n                c += (tinycolor.equals(color, current)) ? \" sp-thumb-active\" : \"\";\n                var formattedString = tiny.toString(opts.preferredFormat || \"rgb\");\n                var swatchStyle = rgbaSupport ? (\"background-color:\" + tiny.toRgbString()) : \"filter:\" + tiny.toFilter();\n                html.push('<span title=\"' + formattedString + '\" data-color=\"' + tiny.toRgbString() + '\" class=\"' + c + '\"><span class=\"sp-thumb-inner\" style=\"' + swatchStyle + ';\"></span></span>');\n            } else {\n                var cls = 'sp-clear-display';\n                html.push($('<div />')\n                    .append($('<span data-color=\"\" style=\"background-color:transparent;\" class=\"' + cls + '\"></span>')\n                        .attr('title', opts.noColorSelectedText)\n                    )\n                    .html()\n                );\n            }\n        }\n        return \"<div class='sp-cf \" + className + \"'>\" + html.join('') + \"</div>\";\n    }\n\n    function hideAll() {\n        for (var i = 0; i < spectrums.length; i++) {\n            if (spectrums[i]) {\n                spectrums[i].hide();\n            }\n        }\n    }\n\n    function instanceOptions(o, callbackContext) {\n        var opts = $.extend({}, defaultOpts, o);\n        opts.callbacks = {\n            'move': bind(opts.move, callbackContext),\n            'change': bind(opts.change, callbackContext),\n            'show': bind(opts.show, callbackContext),\n            'hide': bind(opts.hide, callbackContext),\n            'beforeShow': bind(opts.beforeShow, callbackContext)\n        };\n\n        return opts;\n    }\n\n    function spectrum(element, o) {\n\n        var opts = instanceOptions(o, element),\n            flat = opts.flat,\n            showSelectionPalette = opts.showSelectionPalette,\n            localStorageKey = opts.localStorageKey,\n            theme = opts.theme,\n            callbacks = opts.callbacks,\n            resize = throttle(reflow, 10),\n            visible = false,\n            isDragging = false,\n            dragWidth = 0,\n            dragHeight = 0,\n            dragHelperHeight = 0,\n            slideHeight = 0,\n            slideWidth = 0,\n            alphaWidth = 0,\n            alphaSlideHelperWidth = 0,\n            slideHelperHeight = 0,\n            currentHue = 0,\n            currentSaturation = 0,\n            currentValue = 0,\n            currentAlpha = 1,\n            palette = [],\n            paletteArray = [],\n            paletteLookup = {},\n            selectionPalette = opts.selectionPalette.slice(0),\n            maxSelectionSize = opts.maxSelectionSize,\n            draggingClass = \"sp-dragging\",\n            shiftMovementDirection = null;\n\n        var doc = element.ownerDocument,\n            body = doc.body,\n            boundElement = $(element),\n            disabled = false,\n            container = $(markup, doc).addClass(theme),\n            pickerContainer = container.find(\".sp-picker-container\"),\n            dragger = container.find(\".sp-color\"),\n            dragHelper = container.find(\".sp-dragger\"),\n            slider = container.find(\".sp-hue\"),\n            slideHelper = container.find(\".sp-slider\"),\n            alphaSliderInner = container.find(\".sp-alpha-inner\"),\n            alphaSlider = container.find(\".sp-alpha\"),\n            alphaSlideHelper = container.find(\".sp-alpha-handle\"),\n            textInput = container.find(\".sp-input\"),\n            paletteContainer = container.find(\".sp-palette\"),\n            initialColorContainer = container.find(\".sp-initial\"),\n            cancelButton = container.find(\".sp-cancel\"),\n            clearButton = container.find(\".sp-clear\"),\n            chooseButton = container.find(\".sp-choose\"),\n            toggleButton = container.find(\".sp-palette-toggle\"),\n            isInput = boundElement.is(\"input\"),\n            isInputTypeColor = isInput && boundElement.attr(\"type\") === \"color\" && inputTypeColorSupport(),\n            shouldReplace = isInput && !flat,\n            replacer = (shouldReplace) ? $(replaceInput).addClass(theme).addClass(opts.className).addClass(opts.replacerClassName) : $([]),\n            offsetElement = (shouldReplace) ? replacer : boundElement,\n            previewElement = replacer.find(\".sp-preview-inner\"),\n            initialColor = opts.color || (isInput && boundElement.val()),\n            colorOnShow = false,\n            currentPreferredFormat = opts.preferredFormat,\n            clickoutFiresChange = !opts.showButtons || opts.clickoutFiresChange,\n            isEmpty = !initialColor,\n            allowEmpty = opts.allowEmpty && !isInputTypeColor;\n\n        function applyOptions() {\n\n            if (opts.showPaletteOnly) {\n                opts.showPalette = true;\n            }\n\n            toggleButton.text(opts.showPaletteOnly ? opts.togglePaletteMoreText : opts.togglePaletteLessText);\n\n            if (opts.palette) {\n                palette = opts.palette.slice(0);\n                paletteArray = $.isArray(palette[0]) ? palette : [palette];\n                paletteLookup = {};\n                for (var i = 0; i < paletteArray.length; i++) {\n                    for (var j = 0; j < paletteArray[i].length; j++) {\n                        var rgb = tinycolor(paletteArray[i][j]).toRgbString();\n                        paletteLookup[rgb] = true;\n                    }\n                }\n            }\n\n            container.toggleClass(\"sp-flat\", flat);\n            container.toggleClass(\"sp-input-disabled\", !opts.showInput);\n            container.toggleClass(\"sp-alpha-enabled\", opts.showAlpha);\n            container.toggleClass(\"sp-clear-enabled\", allowEmpty);\n            container.toggleClass(\"sp-buttons-disabled\", !opts.showButtons);\n            container.toggleClass(\"sp-palette-buttons-disabled\", !opts.togglePaletteOnly);\n            container.toggleClass(\"sp-palette-disabled\", !opts.showPalette);\n            container.toggleClass(\"sp-palette-only\", opts.showPaletteOnly);\n            container.toggleClass(\"sp-initial-disabled\", !opts.showInitial);\n            container.addClass(opts.className).addClass(opts.containerClassName);\n\n            reflow();\n        }\n\n        function initialize() {\n\n            if (IE) {\n                container.find(\"*:not(input)\").attr(\"unselectable\", \"on\");\n            }\n\n            applyOptions();\n\n            if (shouldReplace) {\n                boundElement.after(replacer).hide();\n            }\n\n            if (!allowEmpty) {\n                clearButton.hide();\n            }\n\n            if (flat) {\n                boundElement.after(container).hide();\n            }\n            else {\n\n                var appendTo = opts.appendTo === \"parent\" ? boundElement.parent() : $(opts.appendTo);\n                if (appendTo.length !== 1) {\n                    appendTo = $(\"body\");\n                }\n\n                appendTo.append(container);\n            }\n\n            updateSelectionPaletteFromStorage();\n\n            offsetElement.on(\"click.spectrum touchstart.spectrum\", function (e) {\n                if (!disabled) {\n                    toggle();\n                }\n\n                e.stopPropagation();\n\n                if (!$(e.target).is(\"input\")) {\n                    e.preventDefault();\n                }\n            });\n\n            if(boundElement.is(\":disabled\") || (opts.disabled === true)) {\n                disable();\n            }\n\n            // Prevent clicks from bubbling up to document.  This would cause it to be hidden.\n            container.click(stopPropagation);\n\n            // Handle user typed input\n            textInput.change(setFromTextInput);\n            textInput.on(\"paste\", function () {\n                setTimeout(setFromTextInput, 1);\n            });\n            textInput.keydown(function (e) { if (e.keyCode == 13) { setFromTextInput(); } });\n\n            cancelButton.text(opts.cancelText);\n            cancelButton.on(\"click.spectrum\", function (e) {\n                e.stopPropagation();\n                e.preventDefault();\n                revert();\n                hide();\n            });\n\n            clearButton.attr(\"title\", opts.clearText);\n            clearButton.on(\"click.spectrum\", function (e) {\n                e.stopPropagation();\n                e.preventDefault();\n                isEmpty = true;\n                move();\n\n                if(flat) {\n                    //for the flat style, this is a change event\n                    updateOriginalInput(true);\n                }\n            });\n\n            chooseButton.text(opts.chooseText);\n            chooseButton.on(\"click.spectrum\", function (e) {\n                e.stopPropagation();\n                e.preventDefault();\n\n                if (IE && textInput.is(\":focus\")) {\n                    textInput.trigger('change');\n                }\n\n                if (isValid()) {\n                    updateOriginalInput(true);\n                    hide();\n                }\n            });\n\n            toggleButton.text(opts.showPaletteOnly ? opts.togglePaletteMoreText : opts.togglePaletteLessText);\n            toggleButton.on(\"click.spectrum\", function (e) {\n                e.stopPropagation();\n                e.preventDefault();\n\n                opts.showPaletteOnly = !opts.showPaletteOnly;\n\n                // To make sure the Picker area is drawn on the right, next to the\n                // Palette area (and not below the palette), first move the Palette\n                // to the left to make space for the picker, plus 5px extra.\n                // The 'applyOptions' function puts the whole container back into place\n                // and takes care of the button-text and the sp-palette-only CSS class.\n                if (!opts.showPaletteOnly && !flat) {\n                    container.css('left', '-=' + (pickerContainer.outerWidth(true) + 5));\n                }\n                applyOptions();\n            });\n\n            draggable(alphaSlider, function (dragX, dragY, e) {\n                currentAlpha = (dragX / alphaWidth);\n                isEmpty = false;\n                if (e.shiftKey) {\n                    currentAlpha = Math.round(currentAlpha * 10) / 10;\n                }\n\n                move();\n            }, dragStart, dragStop);\n\n            draggable(slider, function (dragX, dragY) {\n                currentHue = parseFloat(dragY / slideHeight);\n                isEmpty = false;\n                if (!opts.showAlpha) {\n                    currentAlpha = 1;\n                }\n                move();\n            }, dragStart, dragStop);\n\n            draggable(dragger, function (dragX, dragY, e) {\n\n                // shift+drag should snap the movement to either the x or y axis.\n                if (!e.shiftKey) {\n                    shiftMovementDirection = null;\n                }\n                else if (!shiftMovementDirection) {\n                    var oldDragX = currentSaturation * dragWidth;\n                    var oldDragY = dragHeight - (currentValue * dragHeight);\n                    var furtherFromX = Math.abs(dragX - oldDragX) > Math.abs(dragY - oldDragY);\n\n                    shiftMovementDirection = furtherFromX ? \"x\" : \"y\";\n                }\n\n                var setSaturation = !shiftMovementDirection || shiftMovementDirection === \"x\";\n                var setValue = !shiftMovementDirection || shiftMovementDirection === \"y\";\n\n                if (setSaturation) {\n                    currentSaturation = parseFloat(dragX / dragWidth);\n                }\n                if (setValue) {\n                    currentValue = parseFloat((dragHeight - dragY) / dragHeight);\n                }\n\n                isEmpty = false;\n                if (!opts.showAlpha) {\n                    currentAlpha = 1;\n                }\n\n                move();\n\n            }, dragStart, dragStop);\n\n            if (!!initialColor) {\n                set(initialColor);\n\n                // In case color was black - update the preview UI and set the format\n                // since the set function will not run (default color is black).\n                updateUI();\n                currentPreferredFormat = opts.preferredFormat || tinycolor(initialColor).format;\n\n                addColorToSelectionPalette(initialColor);\n            }\n            else {\n                updateUI();\n            }\n\n            if (flat) {\n                show();\n            }\n\n            function paletteElementClick(e) {\n                if (e.data && e.data.ignore) {\n                    set($(e.target).closest(\".sp-thumb-el\").data(\"color\"));\n                    move();\n                }\n                else {\n                    set($(e.target).closest(\".sp-thumb-el\").data(\"color\"));\n                    move();\n\n                    updateOriginalInput(true);\n                    if (opts.hideAfterPaletteSelect) {\n                        hide();\n                    }\n                }\n\n                return false;\n            }\n\n            var paletteEvent = IE ? \"mousedown.spectrum\" : \"click.spectrum touchstart.spectrum\";\n            paletteContainer.on(paletteEvent, \".sp-thumb-el\", paletteElementClick);\n            initialColorContainer.on(paletteEvent, \".sp-thumb-el:nth-child(1)\", { ignore: true }, paletteElementClick);\n        }\n\n        function updateSelectionPaletteFromStorage() {\n\n            if (localStorageKey && window.localStorage) {\n\n                // Migrate old palettes over to new format.  May want to remove this eventually.\n                try {\n                    var oldPalette = window.localStorage[localStorageKey].split(\",#\");\n                    if (oldPalette.length > 1) {\n                        delete window.localStorage[localStorageKey];\n                        $.each(oldPalette, function(i, c) {\n                            addColorToSelectionPalette(c);\n                        });\n                    }\n                }\n                catch(e) { }\n\n                try {\n                    selectionPalette = window.localStorage[localStorageKey].split(\";\");\n                }\n                catch (e) { }\n            }\n        }\n\n        function addColorToSelectionPalette(color) {\n            if (showSelectionPalette) {\n                var rgb = tinycolor(color).toRgbString();\n                if (!paletteLookup[rgb] && $.inArray(rgb, selectionPalette) === -1) {\n                    selectionPalette.push(rgb);\n                    while(selectionPalette.length > maxSelectionSize) {\n                        selectionPalette.shift();\n                    }\n                }\n\n                if (localStorageKey && window.localStorage) {\n                    try {\n                        window.localStorage[localStorageKey] = selectionPalette.join(\";\");\n                    }\n                    catch(e) { }\n                }\n            }\n        }\n\n        function getUniqueSelectionPalette() {\n            var unique = [];\n            if (opts.showPalette) {\n                for (var i = 0; i < selectionPalette.length; i++) {\n                    var rgb = tinycolor(selectionPalette[i]).toRgbString();\n\n                    if (!paletteLookup[rgb]) {\n                        unique.push(selectionPalette[i]);\n                    }\n                }\n            }\n\n            return unique.reverse().slice(0, opts.maxSelectionSize);\n        }\n\n        function drawPalette() {\n\n            var currentColor = get();\n\n            var html = $.map(paletteArray, function (palette, i) {\n                return paletteTemplate(palette, currentColor, \"sp-palette-row sp-palette-row-\" + i, opts);\n            });\n\n            updateSelectionPaletteFromStorage();\n\n            if (selectionPalette) {\n                html.push(paletteTemplate(getUniqueSelectionPalette(), currentColor, \"sp-palette-row sp-palette-row-selection\", opts));\n            }\n\n            paletteContainer.html(html.join(\"\"));\n        }\n\n        function drawInitial() {\n            if (opts.showInitial) {\n                var initial = colorOnShow;\n                var current = get();\n                initialColorContainer.html(paletteTemplate([initial, current], current, \"sp-palette-row-initial\", opts));\n            }\n        }\n\n        function dragStart() {\n            if (dragHeight <= 0 || dragWidth <= 0 || slideHeight <= 0) {\n                reflow();\n            }\n            isDragging = true;\n            container.addClass(draggingClass);\n            shiftMovementDirection = null;\n            boundElement.trigger('dragstart.spectrum', [ get() ]);\n        }\n\n        function dragStop() {\n            isDragging = false;\n            container.removeClass(draggingClass);\n            boundElement.trigger('dragstop.spectrum', [ get() ]);\n        }\n\n        function setFromTextInput() {\n\n            var value = textInput.val();\n\n            if ((value === null || value === \"\") && allowEmpty) {\n                set(null);\n                move();\n                updateOriginalInput();\n            }\n            else {\n                var tiny = tinycolor(value);\n                if (tiny.isValid()) {\n                    set(tiny);\n                    move();\n                    updateOriginalInput(true);\n                }\n                else {\n                    textInput.addClass(\"sp-validation-error\");\n                }\n            }\n        }\n\n        function toggle() {\n            if (visible) {\n                hide();\n            }\n            else {\n                show();\n            }\n        }\n\n        function show() {\n            var event = $.Event('beforeShow.spectrum');\n\n            if (visible) {\n                reflow();\n                return;\n            }\n\n            boundElement.trigger(event, [ get() ]);\n\n            if (callbacks.beforeShow(get()) === false || event.isDefaultPrevented()) {\n                return;\n            }\n\n            hideAll();\n            visible = true;\n\n            $(doc).on(\"keydown.spectrum\", onkeydown);\n            $(doc).on(\"click.spectrum\", clickout);\n            $(window).on(\"resize.spectrum\", resize);\n            replacer.addClass(\"sp-active\");\n            container.removeClass(\"sp-hidden\");\n\n            reflow();\n            updateUI();\n\n            colorOnShow = get();\n\n            drawInitial();\n            callbacks.show(colorOnShow);\n            boundElement.trigger('show.spectrum', [ colorOnShow ]);\n        }\n\n        function onkeydown(e) {\n            // Close on ESC\n            if (e.keyCode === 27) {\n                hide();\n            }\n        }\n\n        function clickout(e) {\n            // Return on right click.\n            if (e.button == 2) { return; }\n\n            // If a drag event was happening during the mouseup, don't hide\n            // on click.\n            if (isDragging) { return; }\n\n            if (clickoutFiresChange) {\n                updateOriginalInput(true);\n            }\n            else {\n                revert();\n            }\n            hide();\n        }\n\n        function hide() {\n            // Return if hiding is unnecessary\n            if (!visible || flat) { return; }\n            visible = false;\n\n            $(doc).off(\"keydown.spectrum\", onkeydown);\n            $(doc).off(\"click.spectrum\", clickout);\n            $(window).off(\"resize.spectrum\", resize);\n\n            replacer.removeClass(\"sp-active\");\n            container.addClass(\"sp-hidden\");\n\n            callbacks.hide(get());\n            boundElement.trigger('hide.spectrum', [ get() ]);\n        }\n\n        function revert() {\n            set(colorOnShow, true);\n            updateOriginalInput(true);\n        }\n\n        function set(color, ignoreFormatChange) {\n            if (tinycolor.equals(color, get())) {\n                // Update UI just in case a validation error needs\n                // to be cleared.\n                updateUI();\n                return;\n            }\n\n            var newColor, newHsv;\n            if (!color && allowEmpty) {\n                isEmpty = true;\n            } else {\n                isEmpty = false;\n                newColor = tinycolor(color);\n                newHsv = newColor.toHsv();\n\n                currentHue = (newHsv.h % 360) / 360;\n                currentSaturation = newHsv.s;\n                currentValue = newHsv.v;\n                currentAlpha = newHsv.a;\n            }\n            updateUI();\n\n            if (newColor && newColor.isValid() && !ignoreFormatChange) {\n                currentPreferredFormat = opts.preferredFormat || newColor.getFormat();\n            }\n        }\n\n        function get(opts) {\n            opts = opts || { };\n\n            if (allowEmpty && isEmpty) {\n                return null;\n            }\n\n            return tinycolor.fromRatio({\n                h: currentHue,\n                s: currentSaturation,\n                v: currentValue,\n                a: Math.round(currentAlpha * 1000) / 1000\n            }, { format: opts.format || currentPreferredFormat });\n        }\n\n        function isValid() {\n            return !textInput.hasClass(\"sp-validation-error\");\n        }\n\n        function move() {\n            updateUI();\n\n            callbacks.move(get());\n            boundElement.trigger('move.spectrum', [ get() ]);\n        }\n\n        function updateUI() {\n\n            textInput.removeClass(\"sp-validation-error\");\n\n            updateHelperLocations();\n\n            // Update dragger background color (gradients take care of saturation and value).\n            var flatColor = tinycolor.fromRatio({ h: currentHue, s: 1, v: 1 });\n            dragger.css(\"background-color\", flatColor.toHexString());\n\n            // Get a format that alpha will be included in (hex and names ignore alpha)\n            var format = currentPreferredFormat;\n            if (currentAlpha < 1 && !(currentAlpha === 0 && format === \"name\")) {\n                if (format === \"hex\" || format === \"hex3\" || format === \"hex6\" || format === \"name\") {\n                    format = \"rgb\";\n                }\n            }\n\n            var realColor = get({ format: format }),\n                displayColor = '';\n\n            //reset background info for preview element\n            previewElement.removeClass(\"sp-clear-display\");\n            previewElement.css('background-color', 'transparent');\n\n            if (!realColor && allowEmpty) {\n                // Update the replaced elements background with icon indicating no color selection\n                previewElement.addClass(\"sp-clear-display\");\n            }\n            else {\n                var realHex = realColor.toHexString(),\n                    realRgb = realColor.toRgbString();\n\n                // Update the replaced elements background color (with actual selected color)\n                if (rgbaSupport || realColor.alpha === 1) {\n                    previewElement.css(\"background-color\", realRgb);\n                }\n                else {\n                    previewElement.css(\"background-color\", \"transparent\");\n                    previewElement.css(\"filter\", realColor.toFilter());\n                }\n\n                if (opts.showAlpha) {\n                    var rgb = realColor.toRgb();\n                    rgb.a = 0;\n                    var realAlpha = tinycolor(rgb).toRgbString();\n                    var gradient = \"linear-gradient(left, \" + realAlpha + \", \" + realHex + \")\";\n\n                    if (IE) {\n                        alphaSliderInner.css(\"filter\", tinycolor(realAlpha).toFilter({ gradientType: 1 }, realHex));\n                    }\n                    else {\n                        alphaSliderInner.css(\"background\", \"-webkit-\" + gradient);\n                        alphaSliderInner.css(\"background\", \"-moz-\" + gradient);\n                        alphaSliderInner.css(\"background\", \"-ms-\" + gradient);\n                        // Use current syntax gradient on unprefixed property.\n                        alphaSliderInner.css(\"background\",\n                            \"linear-gradient(to right, \" + realAlpha + \", \" + realHex + \")\");\n                    }\n                }\n\n                displayColor = realColor.toString(format);\n            }\n\n            // Update the text entry input as it changes happen\n            if (opts.showInput) {\n                textInput.val(displayColor);\n            }\n\n            if (opts.showPalette) {\n                drawPalette();\n            }\n\n            drawInitial();\n        }\n\n        function updateHelperLocations() {\n            var s = currentSaturation;\n            var v = currentValue;\n\n            if(allowEmpty && isEmpty) {\n                //if selected color is empty, hide the helpers\n                alphaSlideHelper.hide();\n                slideHelper.hide();\n                dragHelper.hide();\n            }\n            else {\n                //make sure helpers are visible\n                alphaSlideHelper.show();\n                slideHelper.show();\n                dragHelper.show();\n\n                // Where to show the little circle in that displays your current selected color\n                var dragX = s * dragWidth;\n                var dragY = dragHeight - (v * dragHeight);\n                dragX = Math.max(\n                    -dragHelperHeight,\n                    Math.min(dragWidth - dragHelperHeight, dragX - dragHelperHeight)\n                );\n                dragY = Math.max(\n                    -dragHelperHeight,\n                    Math.min(dragHeight - dragHelperHeight, dragY - dragHelperHeight)\n                );\n                dragHelper.css({\n                    \"top\": dragY + \"px\",\n                    \"left\": dragX + \"px\"\n                });\n\n                var alphaX = currentAlpha * alphaWidth;\n                alphaSlideHelper.css({\n                    \"left\": (alphaX - (alphaSlideHelperWidth / 2)) + \"px\"\n                });\n\n                // Where to show the bar that displays your current selected hue\n                var slideY = (currentHue) * slideHeight;\n                slideHelper.css({\n                    \"top\": (slideY - slideHelperHeight) + \"px\"\n                });\n            }\n        }\n\n        function updateOriginalInput(fireCallback) {\n            var color = get(),\n                displayColor = '',\n                hasChanged = !tinycolor.equals(color, colorOnShow);\n\n            if (color) {\n                displayColor = color.toString(currentPreferredFormat);\n                // Update the selection palette with the current color\n                addColorToSelectionPalette(color);\n            }\n\n            if (isInput) {\n                boundElement.val(displayColor);\n            }\n\n            if (fireCallback && hasChanged) {\n                callbacks.change(color);\n                boundElement.trigger('change', [ color ]);\n            }\n        }\n\n        function reflow() {\n            if (!visible) {\n                return; // Calculations would be useless and wouldn't be reliable anyways\n            }\n            dragWidth = dragger.width();\n            dragHeight = dragger.height();\n            dragHelperHeight = dragHelper.height();\n            slideWidth = slider.width();\n            slideHeight = slider.height();\n            slideHelperHeight = slideHelper.height();\n            alphaWidth = alphaSlider.width();\n            alphaSlideHelperWidth = alphaSlideHelper.width();\n\n            if (!flat) {\n                container.css(\"position\", \"absolute\");\n                if (opts.offset) {\n                    container.offset(opts.offset);\n                } else {\n                    container.offset(getOffset(container, offsetElement));\n                }\n            }\n\n            updateHelperLocations();\n\n            if (opts.showPalette) {\n                drawPalette();\n            }\n\n            boundElement.trigger('reflow.spectrum');\n        }\n\n        function destroy() {\n            boundElement.show();\n            offsetElement.off(\"click.spectrum touchstart.spectrum\");\n            container.remove();\n            replacer.remove();\n            spectrums[spect.id] = null;\n        }\n\n        function option(optionName, optionValue) {\n            if (optionName === undefined) {\n                return $.extend({}, opts);\n            }\n            if (optionValue === undefined) {\n                return opts[optionName];\n            }\n\n            opts[optionName] = optionValue;\n\n            if (optionName === \"preferredFormat\") {\n                currentPreferredFormat = opts.preferredFormat;\n            }\n            applyOptions();\n        }\n\n        function enable() {\n            disabled = false;\n            boundElement.attr(\"disabled\", false);\n            offsetElement.removeClass(\"sp-disabled\");\n        }\n\n        function disable() {\n            hide();\n            disabled = true;\n            boundElement.attr(\"disabled\", true);\n            offsetElement.addClass(\"sp-disabled\");\n        }\n\n        function setOffset(coord) {\n            opts.offset = coord;\n            reflow();\n        }\n\n        initialize();\n\n        var spect = {\n            show: show,\n            hide: hide,\n            toggle: toggle,\n            reflow: reflow,\n            option: option,\n            enable: enable,\n            disable: disable,\n            offset: setOffset,\n            set: function (c) {\n                set(c);\n                updateOriginalInput();\n            },\n            get: get,\n            destroy: destroy,\n            container: container\n        };\n\n        spect.id = spectrums.push(spect) - 1;\n\n        return spect;\n    }\n\n    /**\n     * checkOffset - get the offset below/above and left/right element depending on screen position\n     * Thanks https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.datepicker.js\n     */\n    function getOffset(picker, input) {\n        var extraY = 0;\n        var dpWidth = picker.outerWidth();\n        var dpHeight = picker.outerHeight();\n        var inputHeight = input.outerHeight();\n        var doc = picker[0].ownerDocument;\n        var docElem = doc.documentElement;\n        var viewWidth = docElem.clientWidth + $(doc).scrollLeft();\n        var viewHeight = docElem.clientHeight + $(doc).scrollTop();\n        var offset = input.offset();\n        var offsetLeft = offset.left;\n        var offsetTop = offset.top;\n\n        offsetTop += inputHeight;\n\n        offsetLeft -=\n            Math.min(offsetLeft, (offsetLeft + dpWidth > viewWidth && viewWidth > dpWidth) ?\n                Math.abs(offsetLeft + dpWidth - viewWidth) : 0);\n\n        offsetTop -=\n            Math.min(offsetTop, ((offsetTop + dpHeight > viewHeight && viewHeight > dpHeight) ?\n                Math.abs(dpHeight + inputHeight - extraY) : extraY));\n\n        return {\n            top: offsetTop,\n            bottom: offset.bottom,\n            left: offsetLeft,\n            right: offset.right,\n            width: offset.width,\n            height: offset.height\n        };\n    }\n\n    /**\n     * noop - do nothing\n     */\n    function noop() {\n\n    }\n\n    /**\n     * stopPropagation - makes the code only doing this a little easier to read in line\n     */\n    function stopPropagation(e) {\n        e.stopPropagation();\n    }\n\n    /**\n     * Create a function bound to a given object\n     * Thanks to underscore.js\n     */\n    function bind(func, obj) {\n        var slice = Array.prototype.slice;\n        var args = slice.call(arguments, 2);\n        return function () {\n            return func.apply(obj, args.concat(slice.call(arguments)));\n        };\n    }\n\n    /**\n     * Lightweight drag helper.  Handles containment within the element, so that\n     * when dragging, the x is within [0,element.width] and y is within [0,element.height]\n     */\n    function draggable(element, onmove, onstart, onstop) {\n        onmove = onmove || function () { };\n        onstart = onstart || function () { };\n        onstop = onstop || function () { };\n        var doc = document;\n        var dragging = false;\n        var offset = {};\n        var maxHeight = 0;\n        var maxWidth = 0;\n        var hasTouch = ('ontouchstart' in window);\n\n        var duringDragEvents = {};\n        duringDragEvents[\"selectstart\"] = prevent;\n        duringDragEvents[\"dragstart\"] = prevent;\n        duringDragEvents[\"touchmove mousemove\"] = move;\n        duringDragEvents[\"touchend mouseup\"] = stop;\n\n        function prevent(e) {\n            if (e.stopPropagation) {\n                e.stopPropagation();\n            }\n            if (e.preventDefault) {\n                e.preventDefault();\n            }\n            e.returnValue = false;\n        }\n\n        function move(e) {\n            if (dragging) {\n                // Mouseup happened outside of window\n                if (IE && doc.documentMode < 9 && !e.button) {\n                    return stop();\n                }\n\n                var t0 = e.originalEvent && e.originalEvent.touches && e.originalEvent.touches[0];\n                var pageX = t0 && t0.pageX || e.pageX;\n                var pageY = t0 && t0.pageY || e.pageY;\n\n                var dragX = Math.max(0, Math.min(pageX - offset.left, maxWidth));\n                var dragY = Math.max(0, Math.min(pageY - offset.top, maxHeight));\n\n                if (hasTouch) {\n                    // Stop scrolling in iOS\n                    prevent(e);\n                }\n\n                onmove.apply(element, [dragX, dragY, e]);\n            }\n        }\n\n        function start(e) {\n            var rightclick = (e.which) ? (e.which == 3) : (e.button == 2);\n\n            if (!rightclick && !dragging) {\n                if (onstart.apply(element, arguments) !== false) {\n                    dragging = true;\n                    maxHeight = $(element).height();\n                    maxWidth = $(element).width();\n                    offset = $(element).offset();\n\n                    $(doc).on(duringDragEvents);\n                    $(doc.body).addClass(\"sp-dragging\");\n\n                    move(e);\n\n                    prevent(e);\n                }\n            }\n        }\n\n        function stop() {\n            if (dragging) {\n                $(doc).off(duringDragEvents);\n                $(doc.body).removeClass(\"sp-dragging\");\n\n                // Wait a tick before notifying observers to allow the click event\n                // to fire in Chrome.\n                setTimeout(function() {\n                    onstop.apply(element, arguments);\n                }, 0);\n            }\n            dragging = false;\n        }\n\n        $(element).on(\"touchstart mousedown\", start);\n    }\n\n    function throttle(func, wait, debounce) {\n        var timeout;\n        return function () {\n            var context = this, args = arguments;\n            var throttler = function () {\n                timeout = null;\n                func.apply(context, args);\n            };\n            if (debounce) clearTimeout(timeout);\n            if (debounce || !timeout) timeout = setTimeout(throttler, wait);\n        };\n    }\n\n    function inputTypeColorSupport() {\n        return $.fn.spectrum.inputTypeColorSupport();\n    }\n\n    /**\n     * Define a jQuery plugin\n     */\n    var dataID = \"spectrum.id\";\n    $.fn.spectrum = function (opts, extra) {\n\n        if (typeof opts == \"string\") {\n\n            var returnValue = this;\n            var args = Array.prototype.slice.call( arguments, 1 );\n\n            this.each(function () {\n                var spect = spectrums[$(this).data(dataID)];\n                if (spect) {\n                    var method = spect[opts];\n                    if (!method) {\n                        throw new Error( \"Spectrum: no such method: '\" + opts + \"'\" );\n                    }\n\n                    if (opts == \"get\") {\n                        returnValue = spect.get();\n                    }\n                    else if (opts == \"container\") {\n                        returnValue = spect.container;\n                    }\n                    else if (opts == \"option\") {\n                        returnValue = spect.option.apply(spect, args);\n                    }\n                    else if (opts == \"destroy\") {\n                        spect.destroy();\n                        $(this).removeData(dataID);\n                    }\n                    else {\n                        method.apply(spect, args);\n                    }\n                }\n            });\n\n            return returnValue;\n        }\n\n        // Initializing a new instance of spectrum\n        return this.spectrum(\"destroy\").each(function () {\n            var options = $.extend({}, $(this).data(), opts);\n            var spect = spectrum(this, options);\n            $(this).data(dataID, spect.id);\n        });\n    };\n\n    $.fn.spectrum.load = true;\n    $.fn.spectrum.loadOpts = {};\n    $.fn.spectrum.draggable = draggable;\n    $.fn.spectrum.defaults = defaultOpts;\n    $.fn.spectrum.inputTypeColorSupport = function inputTypeColorSupport() {\n        if (typeof inputTypeColorSupport._cachedResult === \"undefined\") {\n            var colorInput = $(\"<input type='color'/>\")[0]; // if color element is supported, value will default to not null\n            inputTypeColorSupport._cachedResult = colorInput.type === \"color\" && colorInput.value !== \"\";\n        }\n        return inputTypeColorSupport._cachedResult;\n    };\n\n    $.spectrum = { };\n    $.spectrum.localization = { };\n    $.spectrum.palettes = { };\n\n    $.fn.spectrum.processNativeColorInputs = function () {\n        var colorInputs = $(\"input[type=color]\");\n        if (colorInputs.length && !inputTypeColorSupport()) {\n            colorInputs.spectrum({\n                preferredFormat: \"hex6\"\n            });\n        }\n    };\n\n    // TinyColor v1.1.2\n    // https://github.com/bgrins/TinyColor\n    // Brian Grinstead, MIT License\n\n    (function() {\n\n        var trimLeft = /^[\\s,#]+/,\n            trimRight = /\\s+$/,\n            tinyCounter = 0,\n            math = Math,\n            mathRound = math.round,\n            mathMin = math.min,\n            mathMax = math.max,\n            mathRandom = math.random;\n\n        var tinycolor = function(color, opts) {\n\n            color = (color) ? color : '';\n            opts = opts || { };\n\n            // If input is already a tinycolor, return itself\n            if (color instanceof tinycolor) {\n                return color;\n            }\n            // If we are called as a function, call using new instead\n            if (!(this instanceof tinycolor)) {\n                return new tinycolor(color, opts);\n            }\n\n            var rgb = inputToRGB(color);\n            this._originalInput = color;\n            this._r = rgb.r;\n            this._g = rgb.g;\n            this._b = rgb.b;\n            this._a = rgb.a;\n            this._roundA = mathRound(1000 * this._a) / 1000;\n            this._format = opts.format || rgb.format;\n            this._gradientType = opts.gradientType;\n\n            // Don't let the range of [0,255] come back in [0,1].\n            // Potentially lose a little bit of precision here, but will fix issues where\n            // .5 gets interpreted as half of the total, instead of half of 1\n            // If it was supposed to be 128, this was already taken care of by `inputToRgb`\n            if (this._r < 1) { this._r = mathRound(this._r); }\n            if (this._g < 1) { this._g = mathRound(this._g); }\n            if (this._b < 1) { this._b = mathRound(this._b); }\n\n            this._ok = rgb.ok;\n            this._tc_id = tinyCounter++;\n        };\n\n        tinycolor.prototype = {\n            isDark: function() {\n                return this.getBrightness() < 128;\n            },\n            isLight: function() {\n                return !this.isDark();\n            },\n            isValid: function() {\n                return this._ok;\n            },\n            getOriginalInput: function() {\n                return this._originalInput;\n            },\n            getFormat: function() {\n                return this._format;\n            },\n            getAlpha: function() {\n                return this._a;\n            },\n            getBrightness: function() {\n                var rgb = this.toRgb();\n                return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000;\n            },\n            setAlpha: function(value) {\n                this._a = boundAlpha(value);\n                this._roundA = mathRound(1000 * this._a) / 1000;\n                return this;\n            },\n            toHsv: function() {\n                var hsv = rgbToHsv(this._r, this._g, this._b);\n                return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a };\n            },\n            toHsvString: function() {\n                var hsv = rgbToHsv(this._r, this._g, this._b);\n                var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);\n                return (this._a == 1) ?\n                    \"hsv(\"  + h + \", \" + s + \"%, \" + v + \"%)\" :\n                    \"hsva(\" + h + \", \" + s + \"%, \" + v + \"%, \"+ this._roundA + \")\";\n            },\n            toHsl: function() {\n                var hsl = rgbToHsl(this._r, this._g, this._b);\n                return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a };\n            },\n            toHslString: function() {\n                var hsl = rgbToHsl(this._r, this._g, this._b);\n                var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);\n                return (this._a == 1) ?\n                    \"hsl(\"  + h + \", \" + s + \"%, \" + l + \"%)\" :\n                    \"hsla(\" + h + \", \" + s + \"%, \" + l + \"%, \"+ this._roundA + \")\";\n            },\n            toHex: function(allow3Char) {\n                return rgbToHex(this._r, this._g, this._b, allow3Char);\n            },\n            toHexString: function(allow3Char) {\n                return '#' + this.toHex(allow3Char);\n            },\n            toHex8: function() {\n                return rgbaToHex(this._r, this._g, this._b, this._a);\n            },\n            toHex8String: function() {\n                return '#' + this.toHex8();\n            },\n            toRgb: function() {\n                return { r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a };\n            },\n            toRgbString: function() {\n                return (this._a == 1) ?\n                    \"rgb(\"  + mathRound(this._r) + \", \" + mathRound(this._g) + \", \" + mathRound(this._b) + \")\" :\n                    \"rgba(\" + mathRound(this._r) + \", \" + mathRound(this._g) + \", \" + mathRound(this._b) + \", \" + this._roundA + \")\";\n            },\n            toPercentageRgb: function() {\n                return { r: mathRound(bound01(this._r, 255) * 100) + \"%\", g: mathRound(bound01(this._g, 255) * 100) + \"%\", b: mathRound(bound01(this._b, 255) * 100) + \"%\", a: this._a };\n            },\n            toPercentageRgbString: function() {\n                return (this._a == 1) ?\n                    \"rgb(\"  + mathRound(bound01(this._r, 255) * 100) + \"%, \" + mathRound(bound01(this._g, 255) * 100) + \"%, \" + mathRound(bound01(this._b, 255) * 100) + \"%)\" :\n                    \"rgba(\" + mathRound(bound01(this._r, 255) * 100) + \"%, \" + mathRound(bound01(this._g, 255) * 100) + \"%, \" + mathRound(bound01(this._b, 255) * 100) + \"%, \" + this._roundA + \")\";\n            },\n            toName: function() {\n                if (this._a === 0) {\n                    return \"transparent\";\n                }\n\n                if (this._a < 1) {\n                    return false;\n                }\n\n                return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false;\n            },\n            toFilter: function(secondColor) {\n                var hex8String = '#' + rgbaToHex(this._r, this._g, this._b, this._a);\n                var secondHex8String = hex8String;\n                var gradientType = this._gradientType ? \"GradientType = 1, \" : \"\";\n\n                if (secondColor) {\n                    var s = tinycolor(secondColor);\n                    secondHex8String = s.toHex8String();\n                }\n\n                return \"progid:DXImageTransform.Microsoft.gradient(\"+gradientType+\"startColorstr=\"+hex8String+\",endColorstr=\"+secondHex8String+\")\";\n            },\n            toString: function(format) {\n                var formatSet = !!format;\n                format = format || this._format;\n\n                var formattedString = false;\n                var hasAlpha = this._a < 1 && this._a >= 0;\n                var needsAlphaFormat = !formatSet && hasAlpha && (format === \"hex\" || format === \"hex6\" || format === \"hex3\" || format === \"name\");\n\n                if (needsAlphaFormat) {\n                    // Special case for \"transparent\", all other non-alpha formats\n                    // will return rgba when there is transparency.\n                    if (format === \"name\" && this._a === 0) {\n                        return this.toName();\n                    }\n                    return this.toRgbString();\n                }\n                if (format === \"rgb\") {\n                    formattedString = this.toRgbString();\n                }\n                if (format === \"prgb\") {\n                    formattedString = this.toPercentageRgbString();\n                }\n                if (format === \"hex\" || format === \"hex6\") {\n                    formattedString = this.toHexString();\n                }\n                if (format === \"hex3\") {\n                    formattedString = this.toHexString(true);\n                }\n                if (format === \"hex8\") {\n                    formattedString = this.toHex8String();\n                }\n                if (format === \"name\") {\n                    formattedString = this.toName();\n                }\n                if (format === \"hsl\") {\n                    formattedString = this.toHslString();\n                }\n                if (format === \"hsv\") {\n                    formattedString = this.toHsvString();\n                }\n\n                return formattedString || this.toHexString();\n            },\n\n            _applyModification: function(fn, args) {\n                var color = fn.apply(null, [this].concat([].slice.call(args)));\n                this._r = color._r;\n                this._g = color._g;\n                this._b = color._b;\n                this.setAlpha(color._a);\n                return this;\n            },\n            lighten: function() {\n                return this._applyModification(lighten, arguments);\n            },\n            brighten: function() {\n                return this._applyModification(brighten, arguments);\n            },\n            darken: function() {\n                return this._applyModification(darken, arguments);\n            },\n            desaturate: function() {\n                return this._applyModification(desaturate, arguments);\n            },\n            saturate: function() {\n                return this._applyModification(saturate, arguments);\n            },\n            greyscale: function() {\n                return this._applyModification(greyscale, arguments);\n            },\n            spin: function() {\n                return this._applyModification(spin, arguments);\n            },\n\n            _applyCombination: function(fn, args) {\n                return fn.apply(null, [this].concat([].slice.call(args)));\n            },\n            analogous: function() {\n                return this._applyCombination(analogous, arguments);\n            },\n            complement: function() {\n                return this._applyCombination(complement, arguments);\n            },\n            monochromatic: function() {\n                return this._applyCombination(monochromatic, arguments);\n            },\n            splitcomplement: function() {\n                return this._applyCombination(splitcomplement, arguments);\n            },\n            triad: function() {\n                return this._applyCombination(triad, arguments);\n            },\n            tetrad: function() {\n                return this._applyCombination(tetrad, arguments);\n            }\n        };\n\n        // If input is an object, force 1 into \"1.0\" to handle ratios properly\n        // String input requires \"1.0\" as input, so 1 will be treated as 1\n        tinycolor.fromRatio = function(color, opts) {\n            if (typeof color == \"object\") {\n                var newColor = {};\n                for (var i in color) {\n                    if (color.hasOwnProperty(i)) {\n                        if (i === \"a\") {\n                            newColor[i] = color[i];\n                        }\n                        else {\n                            newColor[i] = convertToPercentage(color[i]);\n                        }\n                    }\n                }\n                color = newColor;\n            }\n\n            return tinycolor(color, opts);\n        };\n\n        // Given a string or object, convert that input to RGB\n        // Possible string inputs:\n        //\n        //     \"red\"\n        //     \"#f00\" or \"f00\"\n        //     \"#ff0000\" or \"ff0000\"\n        //     \"#ff000000\" or \"ff000000\"\n        //     \"rgb 255 0 0\" or \"rgb (255, 0, 0)\"\n        //     \"rgb 1.0 0 0\" or \"rgb (1, 0, 0)\"\n        //     \"rgba (255, 0, 0, 1)\" or \"rgba 255, 0, 0, 1\"\n        //     \"rgba (1.0, 0, 0, 1)\" or \"rgba 1.0, 0, 0, 1\"\n        //     \"hsl(0, 100%, 50%)\" or \"hsl 0 100% 50%\"\n        //     \"hsla(0, 100%, 50%, 1)\" or \"hsla 0 100% 50%, 1\"\n        //     \"hsv(0, 100%, 100%)\" or \"hsv 0 100% 100%\"\n        //\n        function inputToRGB(color) {\n\n            var rgb = { r: 0, g: 0, b: 0 };\n            var a = 1;\n            var ok = false;\n            var format = false;\n\n            if (typeof color == \"string\") {\n                color = stringInputToObject(color);\n            }\n\n            if (typeof color == \"object\") {\n                if (color.hasOwnProperty(\"r\") && color.hasOwnProperty(\"g\") && color.hasOwnProperty(\"b\")) {\n                    rgb = rgbToRgb(color.r, color.g, color.b);\n                    ok = true;\n                    format = String(color.r).substr(-1) === \"%\" ? \"prgb\" : \"rgb\";\n                }\n                else if (color.hasOwnProperty(\"h\") && color.hasOwnProperty(\"s\") && color.hasOwnProperty(\"v\")) {\n                    color.s = convertToPercentage(color.s);\n                    color.v = convertToPercentage(color.v);\n                    rgb = hsvToRgb(color.h, color.s, color.v);\n                    ok = true;\n                    format = \"hsv\";\n                }\n                else if (color.hasOwnProperty(\"h\") && color.hasOwnProperty(\"s\") && color.hasOwnProperty(\"l\")) {\n                    color.s = convertToPercentage(color.s);\n                    color.l = convertToPercentage(color.l);\n                    rgb = hslToRgb(color.h, color.s, color.l);\n                    ok = true;\n                    format = \"hsl\";\n                }\n\n                if (color.hasOwnProperty(\"a\")) {\n                    a = color.a;\n                }\n            }\n\n            a = boundAlpha(a);\n\n            return {\n                ok: ok,\n                format: color.format || format,\n                r: mathMin(255, mathMax(rgb.r, 0)),\n                g: mathMin(255, mathMax(rgb.g, 0)),\n                b: mathMin(255, mathMax(rgb.b, 0)),\n                a: a\n            };\n        }\n\n\n        // Conversion Functions\n        // --------------------\n\n        // `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:\n        // <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript>\n\n        // `rgbToRgb`\n        // Handle bounds / percentage checking to conform to CSS color spec\n        // <http://www.w3.org/TR/css3-color/>\n        // *Assumes:* r, g, b in [0, 255] or [0, 1]\n        // *Returns:* { r, g, b } in [0, 255]\n        function rgbToRgb(r, g, b){\n            return {\n                r: bound01(r, 255) * 255,\n                g: bound01(g, 255) * 255,\n                b: bound01(b, 255) * 255\n            };\n        }\n\n        // `rgbToHsl`\n        // Converts an RGB color value to HSL.\n        // *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]\n        // *Returns:* { h, s, l } in [0,1]\n        function rgbToHsl(r, g, b) {\n\n            r = bound01(r, 255);\n            g = bound01(g, 255);\n            b = bound01(b, 255);\n\n            var max = mathMax(r, g, b), min = mathMin(r, g, b);\n            var h, s, l = (max + min) / 2;\n\n            if(max == min) {\n                h = s = 0; // achromatic\n            }\n            else {\n                var d = max - min;\n                s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n                switch(max) {\n                    case r: h = (g - b) / d + (g < b ? 6 : 0); break;\n                    case g: h = (b - r) / d + 2; break;\n                    case b: h = (r - g) / d + 4; break;\n                }\n\n                h /= 6;\n            }\n\n            return { h: h, s: s, l: l };\n        }\n\n        // `hslToRgb`\n        // Converts an HSL color value to RGB.\n        // *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]\n        // *Returns:* { r, g, b } in the set [0, 255]\n        function hslToRgb(h, s, l) {\n            var r, g, b;\n\n            h = bound01(h, 360);\n            s = bound01(s, 100);\n            l = bound01(l, 100);\n\n            function hue2rgb(p, q, t) {\n                if(t < 0) t += 1;\n                if(t > 1) t -= 1;\n                if(t < 1/6) return p + (q - p) * 6 * t;\n                if(t < 1/2) return q;\n                if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;\n                return p;\n            }\n\n            if(s === 0) {\n                r = g = b = l; // achromatic\n            }\n            else {\n                var q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n                var p = 2 * l - q;\n                r = hue2rgb(p, q, h + 1/3);\n                g = hue2rgb(p, q, h);\n                b = hue2rgb(p, q, h - 1/3);\n            }\n\n            return { r: r * 255, g: g * 255, b: b * 255 };\n        }\n\n        // `rgbToHsv`\n        // Converts an RGB color value to HSV\n        // *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]\n        // *Returns:* { h, s, v } in [0,1]\n        function rgbToHsv(r, g, b) {\n\n            r = bound01(r, 255);\n            g = bound01(g, 255);\n            b = bound01(b, 255);\n\n            var max = mathMax(r, g, b), min = mathMin(r, g, b);\n            var h, s, v = max;\n\n            var d = max - min;\n            s = max === 0 ? 0 : d / max;\n\n            if(max == min) {\n                h = 0; // achromatic\n            }\n            else {\n                switch(max) {\n                    case r: h = (g - b) / d + (g < b ? 6 : 0); break;\n                    case g: h = (b - r) / d + 2; break;\n                    case b: h = (r - g) / d + 4; break;\n                }\n                h /= 6;\n            }\n            return { h: h, s: s, v: v };\n        }\n\n        // `hsvToRgb`\n        // Converts an HSV color value to RGB.\n        // *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]\n        // *Returns:* { r, g, b } in the set [0, 255]\n        function hsvToRgb(h, s, v) {\n\n            h = bound01(h, 360) * 6;\n            s = bound01(s, 100);\n            v = bound01(v, 100);\n\n            var i = math.floor(h),\n                f = h - i,\n                p = v * (1 - s),\n                q = v * (1 - f * s),\n                t = v * (1 - (1 - f) * s),\n                mod = i % 6,\n                r = [v, q, p, p, t, v][mod],\n                g = [t, v, v, q, p, p][mod],\n                b = [p, p, t, v, v, q][mod];\n\n            return { r: r * 255, g: g * 255, b: b * 255 };\n        }\n\n        // `rgbToHex`\n        // Converts an RGB color to hex\n        // Assumes r, g, and b are contained in the set [0, 255]\n        // Returns a 3 or 6 character hex\n        function rgbToHex(r, g, b, allow3Char) {\n\n            var hex = [\n                pad2(mathRound(r).toString(16)),\n                pad2(mathRound(g).toString(16)),\n                pad2(mathRound(b).toString(16))\n            ];\n\n            // Return a 3 character hex if possible\n            if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {\n                return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);\n            }\n\n            return hex.join(\"\");\n        }\n        // `rgbaToHex`\n        // Converts an RGBA color plus alpha transparency to hex\n        // Assumes r, g, b and a are contained in the set [0, 255]\n        // Returns an 8 character hex\n        function rgbaToHex(r, g, b, a) {\n\n            var hex = [\n                pad2(convertDecimalToHex(a)),\n                pad2(mathRound(r).toString(16)),\n                pad2(mathRound(g).toString(16)),\n                pad2(mathRound(b).toString(16))\n            ];\n\n            return hex.join(\"\");\n        }\n\n        // `equals`\n        // Can be called with any tinycolor input\n        tinycolor.equals = function (color1, color2) {\n            if (!color1 || !color2) { return false; }\n            return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();\n        };\n        tinycolor.random = function() {\n            return tinycolor.fromRatio({\n                r: mathRandom(),\n                g: mathRandom(),\n                b: mathRandom()\n            });\n        };\n\n\n        // Modification Functions\n        // ----------------------\n        // Thanks to less.js for some of the basics here\n        // <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js>\n\n        function desaturate(color, amount) {\n            amount = (amount === 0) ? 0 : (amount || 10);\n            var hsl = tinycolor(color).toHsl();\n            hsl.s -= amount / 100;\n            hsl.s = clamp01(hsl.s);\n            return tinycolor(hsl);\n        }\n\n        function saturate(color, amount) {\n            amount = (amount === 0) ? 0 : (amount || 10);\n            var hsl = tinycolor(color).toHsl();\n            hsl.s += amount / 100;\n            hsl.s = clamp01(hsl.s);\n            return tinycolor(hsl);\n        }\n\n        function greyscale(color) {\n            return tinycolor(color).desaturate(100);\n        }\n\n        function lighten (color, amount) {\n            amount = (amount === 0) ? 0 : (amount || 10);\n            var hsl = tinycolor(color).toHsl();\n            hsl.l += amount / 100;\n            hsl.l = clamp01(hsl.l);\n            return tinycolor(hsl);\n        }\n\n        function brighten(color, amount) {\n            amount = (amount === 0) ? 0 : (amount || 10);\n            var rgb = tinycolor(color).toRgb();\n            rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100))));\n            rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100))));\n            rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100))));\n            return tinycolor(rgb);\n        }\n\n        function darken (color, amount) {\n            amount = (amount === 0) ? 0 : (amount || 10);\n            var hsl = tinycolor(color).toHsl();\n            hsl.l -= amount / 100;\n            hsl.l = clamp01(hsl.l);\n            return tinycolor(hsl);\n        }\n\n        // Spin takes a positive or negative amount within [-360, 360] indicating the change of hue.\n        // Values outside of this range will be wrapped into this range.\n        function spin(color, amount) {\n            var hsl = tinycolor(color).toHsl();\n            var hue = (mathRound(hsl.h) + amount) % 360;\n            hsl.h = hue < 0 ? 360 + hue : hue;\n            return tinycolor(hsl);\n        }\n\n        // Combination Functions\n        // ---------------------\n        // Thanks to jQuery xColor for some of the ideas behind these\n        // <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js>\n\n        function complement(color) {\n            var hsl = tinycolor(color).toHsl();\n            hsl.h = (hsl.h + 180) % 360;\n            return tinycolor(hsl);\n        }\n\n        function triad(color) {\n            var hsl = tinycolor(color).toHsl();\n            var h = hsl.h;\n            return [\n                tinycolor(color),\n                tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),\n                tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })\n            ];\n        }\n\n        function tetrad(color) {\n            var hsl = tinycolor(color).toHsl();\n            var h = hsl.h;\n            return [\n                tinycolor(color),\n                tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),\n                tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),\n                tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })\n            ];\n        }\n\n        function splitcomplement(color) {\n            var hsl = tinycolor(color).toHsl();\n            var h = hsl.h;\n            return [\n                tinycolor(color),\n                tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),\n                tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})\n            ];\n        }\n\n        function analogous(color, results, slices) {\n            results = results || 6;\n            slices = slices || 30;\n\n            var hsl = tinycolor(color).toHsl();\n            var part = 360 / slices;\n            var ret = [tinycolor(color)];\n\n            for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {\n                hsl.h = (hsl.h + part) % 360;\n                ret.push(tinycolor(hsl));\n            }\n            return ret;\n        }\n\n        function monochromatic(color, results) {\n            results = results || 6;\n            var hsv = tinycolor(color).toHsv();\n            var h = hsv.h, s = hsv.s, v = hsv.v;\n            var ret = [];\n            var modification = 1 / results;\n\n            while (results--) {\n                ret.push(tinycolor({ h: h, s: s, v: v}));\n                v = (v + modification) % 1;\n            }\n\n            return ret;\n        }\n\n        // Utility Functions\n        // ---------------------\n\n        tinycolor.mix = function(color1, color2, amount) {\n            amount = (amount === 0) ? 0 : (amount || 50);\n\n            var rgb1 = tinycolor(color1).toRgb();\n            var rgb2 = tinycolor(color2).toRgb();\n\n            var p = amount / 100;\n            var w = p * 2 - 1;\n            var a = rgb2.a - rgb1.a;\n\n            var w1;\n\n            if (w * a == -1) {\n                w1 = w;\n            } else {\n                w1 = (w + a) / (1 + w * a);\n            }\n\n            w1 = (w1 + 1) / 2;\n\n            var w2 = 1 - w1;\n\n            var rgba = {\n                r: rgb2.r * w1 + rgb1.r * w2,\n                g: rgb2.g * w1 + rgb1.g * w2,\n                b: rgb2.b * w1 + rgb1.b * w2,\n                a: rgb2.a * p  + rgb1.a * (1 - p)\n            };\n\n            return tinycolor(rgba);\n        };\n\n\n        // Readability Functions\n        // ---------------------\n        // <http://www.w3.org/TR/AERT#color-contrast>\n\n        // `readability`\n        // Analyze the 2 colors and returns an object with the following properties:\n        //    `brightness`: difference in brightness between the two colors\n        //    `color`: difference in color/hue between the two colors\n        tinycolor.readability = function(color1, color2) {\n            var c1 = tinycolor(color1);\n            var c2 = tinycolor(color2);\n            var rgb1 = c1.toRgb();\n            var rgb2 = c2.toRgb();\n            var brightnessA = c1.getBrightness();\n            var brightnessB = c2.getBrightness();\n            var colorDiff = (\n                Math.max(rgb1.r, rgb2.r) - Math.min(rgb1.r, rgb2.r) +\n                Math.max(rgb1.g, rgb2.g) - Math.min(rgb1.g, rgb2.g) +\n                Math.max(rgb1.b, rgb2.b) - Math.min(rgb1.b, rgb2.b)\n            );\n\n            return {\n                brightness: Math.abs(brightnessA - brightnessB),\n                color: colorDiff\n            };\n        };\n\n        // `readable`\n        // http://www.w3.org/TR/AERT#color-contrast\n        // Ensure that foreground and background color combinations provide sufficient contrast.\n        // *Example*\n        //    tinycolor.isReadable(\"#000\", \"#111\") => false\n        tinycolor.isReadable = function(color1, color2) {\n            var readability = tinycolor.readability(color1, color2);\n            return readability.brightness > 125 && readability.color > 500;\n        };\n\n        // `mostReadable`\n        // Given a base color and a list of possible foreground or background\n        // colors for that base, returns the most readable color.\n        // *Example*\n        //    tinycolor.mostReadable(\"#123\", [\"#fff\", \"#000\"]) => \"#000\"\n        tinycolor.mostReadable = function(baseColor, colorList) {\n            var bestColor = null;\n            var bestScore = 0;\n            var bestIsReadable = false;\n            for (var i=0; i < colorList.length; i++) {\n\n                // We normalize both around the \"acceptable\" breaking point,\n                // but rank brightness constrast higher than hue.\n\n                var readability = tinycolor.readability(baseColor, colorList[i]);\n                var readable = readability.brightness > 125 && readability.color > 500;\n                var score = 3 * (readability.brightness / 125) + (readability.color / 500);\n\n                if ((readable && ! bestIsReadable) ||\n                    (readable && bestIsReadable && score > bestScore) ||\n                    ((! readable) && (! bestIsReadable) && score > bestScore)) {\n                    bestIsReadable = readable;\n                    bestScore = score;\n                    bestColor = tinycolor(colorList[i]);\n                }\n            }\n            return bestColor;\n        };\n\n\n        // Big List of Colors\n        // ------------------\n        // <http://www.w3.org/TR/css3-color/#svg-color>\n        var names = tinycolor.names = {\n            aliceblue: \"f0f8ff\",\n            antiquewhite: \"faebd7\",\n            aqua: \"0ff\",\n            aquamarine: \"7fffd4\",\n            azure: \"f0ffff\",\n            beige: \"f5f5dc\",\n            bisque: \"ffe4c4\",\n            black: \"000\",\n            blanchedalmond: \"ffebcd\",\n            blue: \"00f\",\n            blueviolet: \"8a2be2\",\n            brown: \"a52a2a\",\n            burlywood: \"deb887\",\n            burntsienna: \"ea7e5d\",\n            cadetblue: \"5f9ea0\",\n            chartreuse: \"7fff00\",\n            chocolate: \"d2691e\",\n            coral: \"ff7f50\",\n            cornflowerblue: \"6495ed\",\n            cornsilk: \"fff8dc\",\n            crimson: \"dc143c\",\n            cyan: \"0ff\",\n            darkblue: \"00008b\",\n            darkcyan: \"008b8b\",\n            darkgoldenrod: \"b8860b\",\n            darkgray: \"a9a9a9\",\n            darkgreen: \"006400\",\n            darkgrey: \"a9a9a9\",\n            darkkhaki: \"bdb76b\",\n            darkmagenta: \"8b008b\",\n            darkolivegreen: \"556b2f\",\n            darkorange: \"ff8c00\",\n            darkorchid: \"9932cc\",\n            darkred: \"8b0000\",\n            darksalmon: \"e9967a\",\n            darkseagreen: \"8fbc8f\",\n            darkslateblue: \"483d8b\",\n            darkslategray: \"2f4f4f\",\n            darkslategrey: \"2f4f4f\",\n            darkturquoise: \"00ced1\",\n            darkviolet: \"9400d3\",\n            deeppink: \"ff1493\",\n            deepskyblue: \"00bfff\",\n            dimgray: \"696969\",\n            dimgrey: \"696969\",\n            dodgerblue: \"1e90ff\",\n            firebrick: \"b22222\",\n            floralwhite: \"fffaf0\",\n            forestgreen: \"228b22\",\n            fuchsia: \"f0f\",\n            gainsboro: \"dcdcdc\",\n            ghostwhite: \"f8f8ff\",\n            gold: \"ffd700\",\n            goldenrod: \"daa520\",\n            gray: \"808080\",\n            green: \"008000\",\n            greenyellow: \"adff2f\",\n            grey: \"808080\",\n            honeydew: \"f0fff0\",\n            hotpink: \"ff69b4\",\n            indianred: \"cd5c5c\",\n            indigo: \"4b0082\",\n            ivory: \"fffff0\",\n            khaki: \"f0e68c\",\n            lavender: \"e6e6fa\",\n            lavenderblush: \"fff0f5\",\n            lawngreen: \"7cfc00\",\n            lemonchiffon: \"fffacd\",\n            lightblue: \"add8e6\",\n            lightcoral: \"f08080\",\n            lightcyan: \"e0ffff\",\n            lightgoldenrodyellow: \"fafad2\",\n            lightgray: \"d3d3d3\",\n            lightgreen: \"90ee90\",\n            lightgrey: \"d3d3d3\",\n            lightpink: \"ffb6c1\",\n            lightsalmon: \"ffa07a\",\n            lightseagreen: \"20b2aa\",\n            lightskyblue: \"87cefa\",\n            lightslategray: \"789\",\n            lightslategrey: \"789\",\n            lightsteelblue: \"b0c4de\",\n            lightyellow: \"ffffe0\",\n            lime: \"0f0\",\n            limegreen: \"32cd32\",\n            linen: \"faf0e6\",\n            magenta: \"f0f\",\n            maroon: \"800000\",\n            mediumaquamarine: \"66cdaa\",\n            mediumblue: \"0000cd\",\n            mediumorchid: \"ba55d3\",\n            mediumpurple: \"9370db\",\n            mediumseagreen: \"3cb371\",\n            mediumslateblue: \"7b68ee\",\n            mediumspringgreen: \"00fa9a\",\n            mediumturquoise: \"48d1cc\",\n            mediumvioletred: \"c71585\",\n            midnightblue: \"191970\",\n            mintcream: \"f5fffa\",\n            mistyrose: \"ffe4e1\",\n            moccasin: \"ffe4b5\",\n            navajowhite: \"ffdead\",\n            navy: \"000080\",\n            oldlace: \"fdf5e6\",\n            olive: \"808000\",\n            olivedrab: \"6b8e23\",\n            orange: \"ffa500\",\n            orangered: \"ff4500\",\n            orchid: \"da70d6\",\n            palegoldenrod: \"eee8aa\",\n            palegreen: \"98fb98\",\n            paleturquoise: \"afeeee\",\n            palevioletred: \"db7093\",\n            papayawhip: \"ffefd5\",\n            peachpuff: \"ffdab9\",\n            peru: \"cd853f\",\n            pink: \"ffc0cb\",\n            plum: \"dda0dd\",\n            powderblue: \"b0e0e6\",\n            purple: \"800080\",\n            rebeccapurple: \"663399\",\n            red: \"f00\",\n            rosybrown: \"bc8f8f\",\n            royalblue: \"4169e1\",\n            saddlebrown: \"8b4513\",\n            salmon: \"fa8072\",\n            sandybrown: \"f4a460\",\n            seagreen: \"2e8b57\",\n            seashell: \"fff5ee\",\n            sienna: \"a0522d\",\n            silver: \"c0c0c0\",\n            skyblue: \"87ceeb\",\n            slateblue: \"6a5acd\",\n            slategray: \"708090\",\n            slategrey: \"708090\",\n            snow: \"fffafa\",\n            springgreen: \"00ff7f\",\n            steelblue: \"4682b4\",\n            tan: \"d2b48c\",\n            teal: \"008080\",\n            thistle: \"d8bfd8\",\n            tomato: \"ff6347\",\n            turquoise: \"40e0d0\",\n            violet: \"ee82ee\",\n            wheat: \"f5deb3\",\n            white: \"fff\",\n            whitesmoke: \"f5f5f5\",\n            yellow: \"ff0\",\n            yellowgreen: \"9acd32\"\n        };\n\n        // Make it easy to access colors via `hexNames[hex]`\n        var hexNames = tinycolor.hexNames = flip(names);\n\n\n        // Utilities\n        // ---------\n\n        // `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }`\n        function flip(o) {\n            var flipped = { };\n            for (var i in o) {\n                if (o.hasOwnProperty(i)) {\n                    flipped[o[i]] = i;\n                }\n            }\n            return flipped;\n        }\n\n        // Return a valid alpha value [0,1] with all invalid values being set to 1\n        function boundAlpha(a) {\n            a = parseFloat(a);\n\n            if (isNaN(a) || a < 0 || a > 1) {\n                a = 1;\n            }\n\n            return a;\n        }\n\n        // Take input from [0, n] and return it as [0, 1]\n        function bound01(n, max) {\n            if (isOnePointZero(n)) { n = \"100%\"; }\n\n            var processPercent = isPercentage(n);\n            n = mathMin(max, mathMax(0, parseFloat(n)));\n\n            // Automatically convert percentage into number\n            if (processPercent) {\n                n = parseInt(n * max, 10) / 100;\n            }\n\n            // Handle floating point rounding errors\n            if ((math.abs(n - max) < 0.000001)) {\n                return 1;\n            }\n\n            // Convert into [0, 1] range if it isn't already\n            return (n % max) / parseFloat(max);\n        }\n\n        // Force a number between 0 and 1\n        function clamp01(val) {\n            return mathMin(1, mathMax(0, val));\n        }\n\n        // Parse a base-16 hex value into a base-10 integer\n        function parseIntFromHex(val) {\n            return parseInt(val, 16);\n        }\n\n        // Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1\n        // <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>\n        function isOnePointZero(n) {\n            return typeof n == \"string\" && n.indexOf('.') != -1 && parseFloat(n) === 1;\n        }\n\n        // Check to see if string passed in is a percentage\n        function isPercentage(n) {\n            return typeof n === \"string\" && n.indexOf('%') != -1;\n        }\n\n        // Force a hex value to have 2 characters\n        function pad2(c) {\n            return c.length == 1 ? '0' + c : '' + c;\n        }\n\n        // Replace a decimal with it's percentage value\n        function convertToPercentage(n) {\n            if (n <= 1) {\n                n = (n * 100) + \"%\";\n            }\n\n            return n;\n        }\n\n        // Converts a decimal to a hex value\n        function convertDecimalToHex(d) {\n            return Math.round(parseFloat(d) * 255).toString(16);\n        }\n        // Converts a hex value to a decimal\n        function convertHexToDecimal(h) {\n            return (parseIntFromHex(h) / 255);\n        }\n\n        var matchers = (function() {\n\n            // <http://www.w3.org/TR/css3-values/#integers>\n            var CSS_INTEGER = \"[-\\\\+]?\\\\d+%?\";\n\n            // <http://www.w3.org/TR/css3-values/#number-value>\n            var CSS_NUMBER = \"[-\\\\+]?\\\\d*\\\\.\\\\d+%?\";\n\n            // Allow positive/negative integer/number.  Don't capture the either/or, just the entire outcome.\n            var CSS_UNIT = \"(?:\" + CSS_NUMBER + \")|(?:\" + CSS_INTEGER + \")\";\n\n            // Actual matching.\n            // Parentheses and commas are optional, but not required.\n            // Whitespace can take the place of commas or opening paren\n            var PERMISSIVE_MATCH3 = \"[\\\\s|\\\\(]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")\\\\s*\\\\)?\";\n            var PERMISSIVE_MATCH4 = \"[\\\\s|\\\\(]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")\\\\s*\\\\)?\";\n\n            return {\n                rgb: new RegExp(\"rgb\" + PERMISSIVE_MATCH3),\n                rgba: new RegExp(\"rgba\" + PERMISSIVE_MATCH4),\n                hsl: new RegExp(\"hsl\" + PERMISSIVE_MATCH3),\n                hsla: new RegExp(\"hsla\" + PERMISSIVE_MATCH4),\n                hsv: new RegExp(\"hsv\" + PERMISSIVE_MATCH3),\n                hsva: new RegExp(\"hsva\" + PERMISSIVE_MATCH4),\n                hex3: /^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,\n                hex6: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,\n                hex8: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/\n            };\n        })();\n\n        // `stringInputToObject`\n        // Permissive string parsing.  Take in a number of formats, and output an object\n        // based on detected format.  Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`\n        function stringInputToObject(color) {\n\n            color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase();\n            var named = false;\n            if (names[color]) {\n                color = names[color];\n                named = true;\n            }\n            else if (color == 'transparent') {\n                return { r: 0, g: 0, b: 0, a: 0, format: \"name\" };\n            }\n\n            // Try to match string input using regular expressions.\n            // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]\n            // Just return an object and let the conversion functions handle that.\n            // This way the result will be the same whether the tinycolor is initialized with string or object.\n            var match;\n            if ((match = matchers.rgb.exec(color))) {\n                return { r: match[1], g: match[2], b: match[3] };\n            }\n            if ((match = matchers.rgba.exec(color))) {\n                return { r: match[1], g: match[2], b: match[3], a: match[4] };\n            }\n            if ((match = matchers.hsl.exec(color))) {\n                return { h: match[1], s: match[2], l: match[3] };\n            }\n            if ((match = matchers.hsla.exec(color))) {\n                return { h: match[1], s: match[2], l: match[3], a: match[4] };\n            }\n            if ((match = matchers.hsv.exec(color))) {\n                return { h: match[1], s: match[2], v: match[3] };\n            }\n            if ((match = matchers.hsva.exec(color))) {\n                return { h: match[1], s: match[2], v: match[3], a: match[4] };\n            }\n            if ((match = matchers.hex8.exec(color))) {\n                return {\n                    a: convertHexToDecimal(match[1]),\n                    r: parseIntFromHex(match[2]),\n                    g: parseIntFromHex(match[3]),\n                    b: parseIntFromHex(match[4]),\n                    format: named ? \"name\" : \"hex8\"\n                };\n            }\n            if ((match = matchers.hex6.exec(color))) {\n                return {\n                    r: parseIntFromHex(match[1]),\n                    g: parseIntFromHex(match[2]),\n                    b: parseIntFromHex(match[3]),\n                    format: named ? \"name\" : \"hex\"\n                };\n            }\n            if ((match = matchers.hex3.exec(color))) {\n                return {\n                    r: parseIntFromHex(match[1] + '' + match[1]),\n                    g: parseIntFromHex(match[2] + '' + match[2]),\n                    b: parseIntFromHex(match[3] + '' + match[3]),\n                    format: named ? \"name\" : \"hex\"\n                };\n            }\n\n            return false;\n        }\n\n        window.tinycolor = tinycolor;\n    })();\n\n    $(function () {\n        if ($.fn.spectrum.load) {\n            $.fn.spectrum.processNativeColorInputs();\n        }\n    });\n\n});\n","jquery/spectrum/tinycolor.js":"// TinyColor v1.4.2\n// https://github.com/bgrins/TinyColor\n// Brian Grinstead, MIT License\n\n(function(Math) {\n\n    var trimLeft = /^\\s+/,\n        trimRight = /\\s+$/,\n        tinyCounter = 0,\n        mathRound = Math.round,\n        mathMin = Math.min,\n        mathMax = Math.max,\n        mathRandom = Math.random;\n\n    function tinycolor (color, opts) {\n\n        color = (color) ? color : '';\n        opts = opts || { };\n\n        // If input is already a tinycolor, return itself\n        if (color instanceof tinycolor) {\n            return color;\n        }\n        // If we are called as a function, call using new instead\n        if (!(this instanceof tinycolor)) {\n            return new tinycolor(color, opts);\n        }\n\n        var rgb = inputToRGB(color);\n        this._originalInput = color,\n            this._r = rgb.r,\n            this._g = rgb.g,\n            this._b = rgb.b,\n            this._a = rgb.a,\n            this._roundA = mathRound(100*this._a) / 100,\n            this._format = opts.format || rgb.format;\n        this._gradientType = opts.gradientType;\n\n        // Don't let the range of [0,255] come back in [0,1].\n        // Potentially lose a little bit of precision here, but will fix issues where\n        // .5 gets interpreted as half of the total, instead of half of 1\n        // If it was supposed to be 128, this was already taken care of by `inputToRgb`\n        if (this._r < 1) { this._r = mathRound(this._r); }\n        if (this._g < 1) { this._g = mathRound(this._g); }\n        if (this._b < 1) { this._b = mathRound(this._b); }\n\n        this._ok = rgb.ok;\n        this._tc_id = tinyCounter++;\n    }\n\n    tinycolor.prototype = {\n        isDark: function() {\n            return this.getBrightness() < 128;\n        },\n        isLight: function() {\n            return !this.isDark();\n        },\n        isValid: function() {\n            return this._ok;\n        },\n        getOriginalInput: function() {\n            return this._originalInput;\n        },\n        getFormat: function() {\n            return this._format;\n        },\n        getAlpha: function() {\n            return this._a;\n        },\n        getBrightness: function() {\n            //http://www.w3.org/TR/AERT#color-contrast\n            var rgb = this.toRgb();\n            return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000;\n        },\n        getLuminance: function() {\n            //http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef\n            var rgb = this.toRgb();\n            var RsRGB, GsRGB, BsRGB, R, G, B;\n            RsRGB = rgb.r/255;\n            GsRGB = rgb.g/255;\n            BsRGB = rgb.b/255;\n\n            if (RsRGB <= 0.03928) {R = RsRGB / 12.92;} else {R = Math.pow(((RsRGB + 0.055) / 1.055), 2.4);}\n            if (GsRGB <= 0.03928) {G = GsRGB / 12.92;} else {G = Math.pow(((GsRGB + 0.055) / 1.055), 2.4);}\n            if (BsRGB <= 0.03928) {B = BsRGB / 12.92;} else {B = Math.pow(((BsRGB + 0.055) / 1.055), 2.4);}\n            return (0.2126 * R) + (0.7152 * G) + (0.0722 * B);\n        },\n        setAlpha: function(value) {\n            this._a = boundAlpha(value);\n            this._roundA = mathRound(100*this._a) / 100;\n            return this;\n        },\n        toHsv: function() {\n            var hsv = rgbToHsv(this._r, this._g, this._b);\n            return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a };\n        },\n        toHsvString: function() {\n            var hsv = rgbToHsv(this._r, this._g, this._b);\n            var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);\n            return (this._a == 1) ?\n                \"hsv(\"  + h + \", \" + s + \"%, \" + v + \"%)\" :\n                \"hsva(\" + h + \", \" + s + \"%, \" + v + \"%, \"+ this._roundA + \")\";\n        },\n        toHsl: function() {\n            var hsl = rgbToHsl(this._r, this._g, this._b);\n            return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a };\n        },\n        toHslString: function() {\n            var hsl = rgbToHsl(this._r, this._g, this._b);\n            var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);\n            return (this._a == 1) ?\n                \"hsl(\"  + h + \", \" + s + \"%, \" + l + \"%)\" :\n                \"hsla(\" + h + \", \" + s + \"%, \" + l + \"%, \"+ this._roundA + \")\";\n        },\n        toHex: function(allow3Char) {\n            return rgbToHex(this._r, this._g, this._b, allow3Char);\n        },\n        toHexString: function(allow3Char) {\n            return '#' + this.toHex(allow3Char);\n        },\n        toHex8: function(allow4Char) {\n            return rgbaToHex(this._r, this._g, this._b, this._a, allow4Char);\n        },\n        toHex8String: function(allow4Char) {\n            return '#' + this.toHex8(allow4Char);\n        },\n        toRgb: function() {\n            return { r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a };\n        },\n        toRgbString: function() {\n            return (this._a == 1) ?\n                \"rgb(\"  + mathRound(this._r) + \", \" + mathRound(this._g) + \", \" + mathRound(this._b) + \")\" :\n                \"rgba(\" + mathRound(this._r) + \", \" + mathRound(this._g) + \", \" + mathRound(this._b) + \", \" + this._roundA + \")\";\n        },\n        toPercentageRgb: function() {\n            return { r: mathRound(bound01(this._r, 255) * 100) + \"%\", g: mathRound(bound01(this._g, 255) * 100) + \"%\", b: mathRound(bound01(this._b, 255) * 100) + \"%\", a: this._a };\n        },\n        toPercentageRgbString: function() {\n            return (this._a == 1) ?\n                \"rgb(\"  + mathRound(bound01(this._r, 255) * 100) + \"%, \" + mathRound(bound01(this._g, 255) * 100) + \"%, \" + mathRound(bound01(this._b, 255) * 100) + \"%)\" :\n                \"rgba(\" + mathRound(bound01(this._r, 255) * 100) + \"%, \" + mathRound(bound01(this._g, 255) * 100) + \"%, \" + mathRound(bound01(this._b, 255) * 100) + \"%, \" + this._roundA + \")\";\n        },\n        toName: function() {\n            if (this._a === 0) {\n                return \"transparent\";\n            }\n\n            if (this._a < 1) {\n                return false;\n            }\n\n            return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false;\n        },\n        toFilter: function(secondColor) {\n            var hex8String = '#' + rgbaToArgbHex(this._r, this._g, this._b, this._a);\n            var secondHex8String = hex8String;\n            var gradientType = this._gradientType ? \"GradientType = 1, \" : \"\";\n\n            if (secondColor) {\n                var s = tinycolor(secondColor);\n                secondHex8String = '#' + rgbaToArgbHex(s._r, s._g, s._b, s._a);\n            }\n\n            return \"progid:DXImageTransform.Microsoft.gradient(\"+gradientType+\"startColorstr=\"+hex8String+\",endColorstr=\"+secondHex8String+\")\";\n        },\n        toString: function(format) {\n            var formatSet = !!format;\n            format = format || this._format;\n\n            var formattedString = false;\n            var hasAlpha = this._a < 1 && this._a >= 0;\n            var needsAlphaFormat = !formatSet && hasAlpha && (format === \"hex\" || format === \"hex6\" || format === \"hex3\" || format === \"hex4\" || format === \"hex8\" || format === \"name\");\n\n            if (needsAlphaFormat) {\n                // Special case for \"transparent\", all other non-alpha formats\n                // will return rgba when there is transparency.\n                if (format === \"name\" && this._a === 0) {\n                    return this.toName();\n                }\n                return this.toRgbString();\n            }\n            if (format === \"rgb\") {\n                formattedString = this.toRgbString();\n            }\n            if (format === \"prgb\") {\n                formattedString = this.toPercentageRgbString();\n            }\n            if (format === \"hex\" || format === \"hex6\") {\n                formattedString = this.toHexString();\n            }\n            if (format === \"hex3\") {\n                formattedString = this.toHexString(true);\n            }\n            if (format === \"hex4\") {\n                formattedString = this.toHex8String(true);\n            }\n            if (format === \"hex8\") {\n                formattedString = this.toHex8String();\n            }\n            if (format === \"name\") {\n                formattedString = this.toName();\n            }\n            if (format === \"hsl\") {\n                formattedString = this.toHslString();\n            }\n            if (format === \"hsv\") {\n                formattedString = this.toHsvString();\n            }\n\n            return formattedString || this.toHexString();\n        },\n        clone: function() {\n            return tinycolor(this.toString());\n        },\n\n        _applyModification: function(fn, args) {\n            var color = fn.apply(null, [this].concat([].slice.call(args)));\n            this._r = color._r;\n            this._g = color._g;\n            this._b = color._b;\n            this.setAlpha(color._a);\n            return this;\n        },\n        lighten: function() {\n            return this._applyModification(lighten, arguments);\n        },\n        brighten: function() {\n            return this._applyModification(brighten, arguments);\n        },\n        darken: function() {\n            return this._applyModification(darken, arguments);\n        },\n        desaturate: function() {\n            return this._applyModification(desaturate, arguments);\n        },\n        saturate: function() {\n            return this._applyModification(saturate, arguments);\n        },\n        greyscale: function() {\n            return this._applyModification(greyscale, arguments);\n        },\n        spin: function() {\n            return this._applyModification(spin, arguments);\n        },\n\n        _applyCombination: function(fn, args) {\n            return fn.apply(null, [this].concat([].slice.call(args)));\n        },\n        analogous: function() {\n            return this._applyCombination(analogous, arguments);\n        },\n        complement: function() {\n            return this._applyCombination(complement, arguments);\n        },\n        monochromatic: function() {\n            return this._applyCombination(monochromatic, arguments);\n        },\n        splitcomplement: function() {\n            return this._applyCombination(splitcomplement, arguments);\n        },\n        triad: function() {\n            return this._applyCombination(triad, arguments);\n        },\n        tetrad: function() {\n            return this._applyCombination(tetrad, arguments);\n        }\n    };\n\n// If input is an object, force 1 into \"1.0\" to handle ratios properly\n// String input requires \"1.0\" as input, so 1 will be treated as 1\n    tinycolor.fromRatio = function(color, opts) {\n        if (typeof color == \"object\") {\n            var newColor = {};\n            for (var i in color) {\n                if (color.hasOwnProperty(i)) {\n                    if (i === \"a\") {\n                        newColor[i] = color[i];\n                    }\n                    else {\n                        newColor[i] = convertToPercentage(color[i]);\n                    }\n                }\n            }\n            color = newColor;\n        }\n\n        return tinycolor(color, opts);\n    };\n\n// Given a string or object, convert that input to RGB\n// Possible string inputs:\n//\n//     \"red\"\n//     \"#f00\" or \"f00\"\n//     \"#ff0000\" or \"ff0000\"\n//     \"#ff000000\" or \"ff000000\"\n//     \"rgb 255 0 0\" or \"rgb (255, 0, 0)\"\n//     \"rgb 1.0 0 0\" or \"rgb (1, 0, 0)\"\n//     \"rgba (255, 0, 0, 1)\" or \"rgba 255, 0, 0, 1\"\n//     \"rgba (1.0, 0, 0, 1)\" or \"rgba 1.0, 0, 0, 1\"\n//     \"hsl(0, 100%, 50%)\" or \"hsl 0 100% 50%\"\n//     \"hsla(0, 100%, 50%, 1)\" or \"hsla 0 100% 50%, 1\"\n//     \"hsv(0, 100%, 100%)\" or \"hsv 0 100% 100%\"\n//\n    function inputToRGB(color) {\n\n        var rgb = { r: 0, g: 0, b: 0 };\n        var a = 1;\n        var s = null;\n        var v = null;\n        var l = null;\n        var ok = false;\n        var format = false;\n\n        if (typeof color == \"string\") {\n            color = stringInputToObject(color);\n        }\n\n        if (typeof color == \"object\") {\n            if (isValidCSSUnit(color.r) && isValidCSSUnit(color.g) && isValidCSSUnit(color.b)) {\n                rgb = rgbToRgb(color.r, color.g, color.b);\n                ok = true;\n                format = String(color.r).substr(-1) === \"%\" ? \"prgb\" : \"rgb\";\n            }\n            else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.v)) {\n                s = convertToPercentage(color.s);\n                v = convertToPercentage(color.v);\n                rgb = hsvToRgb(color.h, s, v);\n                ok = true;\n                format = \"hsv\";\n            }\n            else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.l)) {\n                s = convertToPercentage(color.s);\n                l = convertToPercentage(color.l);\n                rgb = hslToRgb(color.h, s, l);\n                ok = true;\n                format = \"hsl\";\n            }\n\n            if (color.hasOwnProperty(\"a\")) {\n                a = color.a;\n            }\n        }\n\n        a = boundAlpha(a);\n\n        return {\n            ok: ok,\n            format: color.format || format,\n            r: mathMin(255, mathMax(rgb.r, 0)),\n            g: mathMin(255, mathMax(rgb.g, 0)),\n            b: mathMin(255, mathMax(rgb.b, 0)),\n            a: a\n        };\n    }\n\n\n// Conversion Functions\n// --------------------\n\n// `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:\n// <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript>\n\n// `rgbToRgb`\n// Handle bounds / percentage checking to conform to CSS color spec\n// <http://www.w3.org/TR/css3-color/>\n// *Assumes:* r, g, b in [0, 255] or [0, 1]\n// *Returns:* { r, g, b } in [0, 255]\n    function rgbToRgb(r, g, b){\n        return {\n            r: bound01(r, 255) * 255,\n            g: bound01(g, 255) * 255,\n            b: bound01(b, 255) * 255\n        };\n    }\n\n// `rgbToHsl`\n// Converts an RGB color value to HSL.\n// *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]\n// *Returns:* { h, s, l } in [0,1]\n    function rgbToHsl(r, g, b) {\n\n        r = bound01(r, 255);\n        g = bound01(g, 255);\n        b = bound01(b, 255);\n\n        var max = mathMax(r, g, b), min = mathMin(r, g, b);\n        var h, s, l = (max + min) / 2;\n\n        if(max == min) {\n            h = s = 0; // achromatic\n        }\n        else {\n            var d = max - min;\n            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n            switch(max) {\n                case r: h = (g - b) / d + (g < b ? 6 : 0); break;\n                case g: h = (b - r) / d + 2; break;\n                case b: h = (r - g) / d + 4; break;\n            }\n\n            h /= 6;\n        }\n\n        return { h: h, s: s, l: l };\n    }\n\n// `hslToRgb`\n// Converts an HSL color value to RGB.\n// *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]\n// *Returns:* { r, g, b } in the set [0, 255]\n    function hslToRgb(h, s, l) {\n        var r, g, b;\n\n        h = bound01(h, 360);\n        s = bound01(s, 100);\n        l = bound01(l, 100);\n\n        function hue2rgb(p, q, t) {\n            if(t < 0) t += 1;\n            if(t > 1) t -= 1;\n            if(t < 1/6) return p + (q - p) * 6 * t;\n            if(t < 1/2) return q;\n            if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;\n            return p;\n        }\n\n        if(s === 0) {\n            r = g = b = l; // achromatic\n        }\n        else {\n            var q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n            var p = 2 * l - q;\n            r = hue2rgb(p, q, h + 1/3);\n            g = hue2rgb(p, q, h);\n            b = hue2rgb(p, q, h - 1/3);\n        }\n\n        return { r: r * 255, g: g * 255, b: b * 255 };\n    }\n\n// `rgbToHsv`\n// Converts an RGB color value to HSV\n// *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]\n// *Returns:* { h, s, v } in [0,1]\n    function rgbToHsv(r, g, b) {\n\n        r = bound01(r, 255);\n        g = bound01(g, 255);\n        b = bound01(b, 255);\n\n        var max = mathMax(r, g, b), min = mathMin(r, g, b);\n        var h, s, v = max;\n\n        var d = max - min;\n        s = max === 0 ? 0 : d / max;\n\n        if(max == min) {\n            h = 0; // achromatic\n        }\n        else {\n            switch(max) {\n                case r: h = (g - b) / d + (g < b ? 6 : 0); break;\n                case g: h = (b - r) / d + 2; break;\n                case b: h = (r - g) / d + 4; break;\n            }\n            h /= 6;\n        }\n        return { h: h, s: s, v: v };\n    }\n\n// `hsvToRgb`\n// Converts an HSV color value to RGB.\n// *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]\n// *Returns:* { r, g, b } in the set [0, 255]\n    function hsvToRgb(h, s, v) {\n\n        h = bound01(h, 360) * 6;\n        s = bound01(s, 100);\n        v = bound01(v, 100);\n\n        var i = Math.floor(h),\n            f = h - i,\n            p = v * (1 - s),\n            q = v * (1 - f * s),\n            t = v * (1 - (1 - f) * s),\n            mod = i % 6,\n            r = [v, q, p, p, t, v][mod],\n            g = [t, v, v, q, p, p][mod],\n            b = [p, p, t, v, v, q][mod];\n\n        return { r: r * 255, g: g * 255, b: b * 255 };\n    }\n\n// `rgbToHex`\n// Converts an RGB color to hex\n// Assumes r, g, and b are contained in the set [0, 255]\n// Returns a 3 or 6 character hex\n    function rgbToHex(r, g, b, allow3Char) {\n\n        var hex = [\n            pad2(mathRound(r).toString(16)),\n            pad2(mathRound(g).toString(16)),\n            pad2(mathRound(b).toString(16))\n        ];\n\n        // Return a 3 character hex if possible\n        if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {\n            return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);\n        }\n\n        return hex.join(\"\");\n    }\n\n// `rgbaToHex`\n// Converts an RGBA color plus alpha transparency to hex\n// Assumes r, g, b are contained in the set [0, 255] and\n// a in [0, 1]. Returns a 4 or 8 character rgba hex\n    function rgbaToHex(r, g, b, a, allow4Char) {\n\n        var hex = [\n            pad2(mathRound(r).toString(16)),\n            pad2(mathRound(g).toString(16)),\n            pad2(mathRound(b).toString(16)),\n            pad2(convertDecimalToHex(a))\n        ];\n\n        // Return a 4 character hex if possible\n        if (allow4Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1) && hex[3].charAt(0) == hex[3].charAt(1)) {\n            return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0) + hex[3].charAt(0);\n        }\n\n        return hex.join(\"\");\n    }\n\n// `rgbaToArgbHex`\n// Converts an RGBA color to an ARGB Hex8 string\n// Rarely used, but required for \"toFilter()\"\n    function rgbaToArgbHex(r, g, b, a) {\n\n        var hex = [\n            pad2(convertDecimalToHex(a)),\n            pad2(mathRound(r).toString(16)),\n            pad2(mathRound(g).toString(16)),\n            pad2(mathRound(b).toString(16))\n        ];\n\n        return hex.join(\"\");\n    }\n\n// `equals`\n// Can be called with any tinycolor input\n    tinycolor.equals = function (color1, color2) {\n        if (!color1 || !color2) { return false; }\n        return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();\n    };\n\n    tinycolor.random = function() {\n        return tinycolor.fromRatio({\n            r: mathRandom(),\n            g: mathRandom(),\n            b: mathRandom()\n        });\n    };\n\n\n// Modification Functions\n// ----------------------\n// Thanks to less.js for some of the basics here\n// <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js>\n\n    function desaturate(color, amount) {\n        amount = (amount === 0) ? 0 : (amount || 10);\n        var hsl = tinycolor(color).toHsl();\n        hsl.s -= amount / 100;\n        hsl.s = clamp01(hsl.s);\n        return tinycolor(hsl);\n    }\n\n    function saturate(color, amount) {\n        amount = (amount === 0) ? 0 : (amount || 10);\n        var hsl = tinycolor(color).toHsl();\n        hsl.s += amount / 100;\n        hsl.s = clamp01(hsl.s);\n        return tinycolor(hsl);\n    }\n\n    function greyscale(color) {\n        return tinycolor(color).desaturate(100);\n    }\n\n    function lighten (color, amount) {\n        amount = (amount === 0) ? 0 : (amount || 10);\n        var hsl = tinycolor(color).toHsl();\n        hsl.l += amount / 100;\n        hsl.l = clamp01(hsl.l);\n        return tinycolor(hsl);\n    }\n\n    function brighten(color, amount) {\n        amount = (amount === 0) ? 0 : (amount || 10);\n        var rgb = tinycolor(color).toRgb();\n        rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100))));\n        rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100))));\n        rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100))));\n        return tinycolor(rgb);\n    }\n\n    function darken (color, amount) {\n        amount = (amount === 0) ? 0 : (amount || 10);\n        var hsl = tinycolor(color).toHsl();\n        hsl.l -= amount / 100;\n        hsl.l = clamp01(hsl.l);\n        return tinycolor(hsl);\n    }\n\n// Spin takes a positive or negative amount within [-360, 360] indicating the change of hue.\n// Values outside of this range will be wrapped into this range.\n    function spin(color, amount) {\n        var hsl = tinycolor(color).toHsl();\n        var hue = (hsl.h + amount) % 360;\n        hsl.h = hue < 0 ? 360 + hue : hue;\n        return tinycolor(hsl);\n    }\n\n// Combination Functions\n// ---------------------\n// Thanks to jQuery xColor for some of the ideas behind these\n// <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js>\n\n    function complement(color) {\n        var hsl = tinycolor(color).toHsl();\n        hsl.h = (hsl.h + 180) % 360;\n        return tinycolor(hsl);\n    }\n\n    function triad(color) {\n        var hsl = tinycolor(color).toHsl();\n        var h = hsl.h;\n        return [\n            tinycolor(color),\n            tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),\n            tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })\n        ];\n    }\n\n    function tetrad(color) {\n        var hsl = tinycolor(color).toHsl();\n        var h = hsl.h;\n        return [\n            tinycolor(color),\n            tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),\n            tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),\n            tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })\n        ];\n    }\n\n    function splitcomplement(color) {\n        var hsl = tinycolor(color).toHsl();\n        var h = hsl.h;\n        return [\n            tinycolor(color),\n            tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),\n            tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})\n        ];\n    }\n\n    function analogous(color, results, slices) {\n        results = results || 6;\n        slices = slices || 30;\n\n        var hsl = tinycolor(color).toHsl();\n        var part = 360 / slices;\n        var ret = [tinycolor(color)];\n\n        for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {\n            hsl.h = (hsl.h + part) % 360;\n            ret.push(tinycolor(hsl));\n        }\n        return ret;\n    }\n\n    function monochromatic(color, results) {\n        results = results || 6;\n        var hsv = tinycolor(color).toHsv();\n        var h = hsv.h, s = hsv.s, v = hsv.v;\n        var ret = [];\n        var modification = 1 / results;\n\n        while (results--) {\n            ret.push(tinycolor({ h: h, s: s, v: v}));\n            v = (v + modification) % 1;\n        }\n\n        return ret;\n    }\n\n// Utility Functions\n// ---------------------\n\n    tinycolor.mix = function(color1, color2, amount) {\n        amount = (amount === 0) ? 0 : (amount || 50);\n\n        var rgb1 = tinycolor(color1).toRgb();\n        var rgb2 = tinycolor(color2).toRgb();\n\n        var p = amount / 100;\n\n        var rgba = {\n            r: ((rgb2.r - rgb1.r) * p) + rgb1.r,\n            g: ((rgb2.g - rgb1.g) * p) + rgb1.g,\n            b: ((rgb2.b - rgb1.b) * p) + rgb1.b,\n            a: ((rgb2.a - rgb1.a) * p) + rgb1.a\n        };\n\n        return tinycolor(rgba);\n    };\n\n\n// Readability Functions\n// ---------------------\n// <http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef (WCAG Version 2)\n\n// `contrast`\n// Analyze the 2 colors and returns the color contrast defined by (WCAG Version 2)\n    tinycolor.readability = function(color1, color2) {\n        var c1 = tinycolor(color1);\n        var c2 = tinycolor(color2);\n        return (Math.max(c1.getLuminance(),c2.getLuminance())+0.05) / (Math.min(c1.getLuminance(),c2.getLuminance())+0.05);\n    };\n\n// `isReadable`\n// Ensure that foreground and background color combinations meet WCAG2 guidelines.\n// The third argument is an optional Object.\n//      the 'level' property states 'AA' or 'AAA' - if missing or invalid, it defaults to 'AA';\n//      the 'size' property states 'large' or 'small' - if missing or invalid, it defaults to 'small'.\n// If the entire object is absent, isReadable defaults to {level:\"AA\",size:\"small\"}.\n\n// *Example*\n//    tinycolor.isReadable(\"#000\", \"#111\") => false\n//    tinycolor.isReadable(\"#000\", \"#111\",{level:\"AA\",size:\"large\"}) => false\n    tinycolor.isReadable = function(color1, color2, wcag2) {\n        var readability = tinycolor.readability(color1, color2);\n        var wcag2Parms, out;\n\n        out = false;\n\n        wcag2Parms = validateWCAG2Parms(wcag2);\n        switch (wcag2Parms.level + wcag2Parms.size) {\n            case \"AAsmall\":\n            case \"AAAlarge\":\n                out = readability >= 4.5;\n                break;\n            case \"AAlarge\":\n                out = readability >= 3;\n                break;\n            case \"AAAsmall\":\n                out = readability >= 7;\n                break;\n        }\n        return out;\n\n    };\n\n// `mostReadable`\n// Given a base color and a list of possible foreground or background\n// colors for that base, returns the most readable color.\n// Optionally returns Black or White if the most readable color is unreadable.\n// *Example*\n//    tinycolor.mostReadable(tinycolor.mostReadable(\"#123\", [\"#124\", \"#125\"],{includeFallbackColors:false}).toHexString(); // \"#112255\"\n//    tinycolor.mostReadable(tinycolor.mostReadable(\"#123\", [\"#124\", \"#125\"],{includeFallbackColors:true}).toHexString();  // \"#ffffff\"\n//    tinycolor.mostReadable(\"#a8015a\", [\"#faf3f3\"],{includeFallbackColors:true,level:\"AAA\",size:\"large\"}).toHexString(); // \"#faf3f3\"\n//    tinycolor.mostReadable(\"#a8015a\", [\"#faf3f3\"],{includeFallbackColors:true,level:\"AAA\",size:\"small\"}).toHexString(); // \"#ffffff\"\n    tinycolor.mostReadable = function(baseColor, colorList, args) {\n        var bestColor = null;\n        var bestScore = 0;\n        var readability;\n        var includeFallbackColors, level, size ;\n        args = args || {};\n        includeFallbackColors = args.includeFallbackColors ;\n        level = args.level;\n        size = args.size;\n\n        for (var i= 0; i < colorList.length ; i++) {\n            readability = tinycolor.readability(baseColor, colorList[i]);\n            if (readability > bestScore) {\n                bestScore = readability;\n                bestColor = tinycolor(colorList[i]);\n            }\n        }\n\n        if (tinycolor.isReadable(baseColor, bestColor, {\"level\":level,\"size\":size}) || !includeFallbackColors) {\n            return bestColor;\n        }\n        else {\n            args.includeFallbackColors=false;\n            return tinycolor.mostReadable(baseColor,[\"#fff\", \"#000\"],args);\n        }\n    };\n\n\n// Big List of Colors\n// ------------------\n// <http://www.w3.org/TR/css3-color/#svg-color>\n    var names = tinycolor.names = {\n        aliceblue: \"f0f8ff\",\n        antiquewhite: \"faebd7\",\n        aqua: \"0ff\",\n        aquamarine: \"7fffd4\",\n        azure: \"f0ffff\",\n        beige: \"f5f5dc\",\n        bisque: \"ffe4c4\",\n        black: \"000\",\n        blanchedalmond: \"ffebcd\",\n        blue: \"00f\",\n        blueviolet: \"8a2be2\",\n        brown: \"a52a2a\",\n        burlywood: \"deb887\",\n        burntsienna: \"ea7e5d\",\n        cadetblue: \"5f9ea0\",\n        chartreuse: \"7fff00\",\n        chocolate: \"d2691e\",\n        coral: \"ff7f50\",\n        cornflowerblue: \"6495ed\",\n        cornsilk: \"fff8dc\",\n        crimson: \"dc143c\",\n        cyan: \"0ff\",\n        darkblue: \"00008b\",\n        darkcyan: \"008b8b\",\n        darkgoldenrod: \"b8860b\",\n        darkgray: \"a9a9a9\",\n        darkgreen: \"006400\",\n        darkgrey: \"a9a9a9\",\n        darkkhaki: \"bdb76b\",\n        darkmagenta: \"8b008b\",\n        darkolivegreen: \"556b2f\",\n        darkorange: \"ff8c00\",\n        darkorchid: \"9932cc\",\n        darkred: \"8b0000\",\n        darksalmon: \"e9967a\",\n        darkseagreen: \"8fbc8f\",\n        darkslateblue: \"483d8b\",\n        darkslategray: \"2f4f4f\",\n        darkslategrey: \"2f4f4f\",\n        darkturquoise: \"00ced1\",\n        darkviolet: \"9400d3\",\n        deeppink: \"ff1493\",\n        deepskyblue: \"00bfff\",\n        dimgray: \"696969\",\n        dimgrey: \"696969\",\n        dodgerblue: \"1e90ff\",\n        firebrick: \"b22222\",\n        floralwhite: \"fffaf0\",\n        forestgreen: \"228b22\",\n        fuchsia: \"f0f\",\n        gainsboro: \"dcdcdc\",\n        ghostwhite: \"f8f8ff\",\n        gold: \"ffd700\",\n        goldenrod: \"daa520\",\n        gray: \"808080\",\n        green: \"008000\",\n        greenyellow: \"adff2f\",\n        grey: \"808080\",\n        honeydew: \"f0fff0\",\n        hotpink: \"ff69b4\",\n        indianred: \"cd5c5c\",\n        indigo: \"4b0082\",\n        ivory: \"fffff0\",\n        khaki: \"f0e68c\",\n        lavender: \"e6e6fa\",\n        lavenderblush: \"fff0f5\",\n        lawngreen: \"7cfc00\",\n        lemonchiffon: \"fffacd\",\n        lightblue: \"add8e6\",\n        lightcoral: \"f08080\",\n        lightcyan: \"e0ffff\",\n        lightgoldenrodyellow: \"fafad2\",\n        lightgray: \"d3d3d3\",\n        lightgreen: \"90ee90\",\n        lightgrey: \"d3d3d3\",\n        lightpink: \"ffb6c1\",\n        lightsalmon: \"ffa07a\",\n        lightseagreen: \"20b2aa\",\n        lightskyblue: \"87cefa\",\n        lightslategray: \"789\",\n        lightslategrey: \"789\",\n        lightsteelblue: \"b0c4de\",\n        lightyellow: \"ffffe0\",\n        lime: \"0f0\",\n        limegreen: \"32cd32\",\n        linen: \"faf0e6\",\n        magenta: \"f0f\",\n        maroon: \"800000\",\n        mediumaquamarine: \"66cdaa\",\n        mediumblue: \"0000cd\",\n        mediumorchid: \"ba55d3\",\n        mediumpurple: \"9370db\",\n        mediumseagreen: \"3cb371\",\n        mediumslateblue: \"7b68ee\",\n        mediumspringgreen: \"00fa9a\",\n        mediumturquoise: \"48d1cc\",\n        mediumvioletred: \"c71585\",\n        midnightblue: \"191970\",\n        mintcream: \"f5fffa\",\n        mistyrose: \"ffe4e1\",\n        moccasin: \"ffe4b5\",\n        navajowhite: \"ffdead\",\n        navy: \"000080\",\n        oldlace: \"fdf5e6\",\n        olive: \"808000\",\n        olivedrab: \"6b8e23\",\n        orange: \"ffa500\",\n        orangered: \"ff4500\",\n        orchid: \"da70d6\",\n        palegoldenrod: \"eee8aa\",\n        palegreen: \"98fb98\",\n        paleturquoise: \"afeeee\",\n        palevioletred: \"db7093\",\n        papayawhip: \"ffefd5\",\n        peachpuff: \"ffdab9\",\n        peru: \"cd853f\",\n        pink: \"ffc0cb\",\n        plum: \"dda0dd\",\n        powderblue: \"b0e0e6\",\n        purple: \"800080\",\n        rebeccapurple: \"663399\",\n        red: \"f00\",\n        rosybrown: \"bc8f8f\",\n        royalblue: \"4169e1\",\n        saddlebrown: \"8b4513\",\n        salmon: \"fa8072\",\n        sandybrown: \"f4a460\",\n        seagreen: \"2e8b57\",\n        seashell: \"fff5ee\",\n        sienna: \"a0522d\",\n        silver: \"c0c0c0\",\n        skyblue: \"87ceeb\",\n        slateblue: \"6a5acd\",\n        slategray: \"708090\",\n        slategrey: \"708090\",\n        snow: \"fffafa\",\n        springgreen: \"00ff7f\",\n        steelblue: \"4682b4\",\n        tan: \"d2b48c\",\n        teal: \"008080\",\n        thistle: \"d8bfd8\",\n        tomato: \"ff6347\",\n        turquoise: \"40e0d0\",\n        violet: \"ee82ee\",\n        wheat: \"f5deb3\",\n        white: \"fff\",\n        whitesmoke: \"f5f5f5\",\n        yellow: \"ff0\",\n        yellowgreen: \"9acd32\"\n    };\n\n// Make it easy to access colors via `hexNames[hex]`\n    var hexNames = tinycolor.hexNames = flip(names);\n\n\n// Utilities\n// ---------\n\n// `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }`\n    function flip(o) {\n        var flipped = { };\n        for (var i in o) {\n            if (o.hasOwnProperty(i)) {\n                flipped[o[i]] = i;\n            }\n        }\n        return flipped;\n    }\n\n// Return a valid alpha value [0,1] with all invalid values being set to 1\n    function boundAlpha(a) {\n        a = parseFloat(a);\n\n        if (isNaN(a) || a < 0 || a > 1) {\n            a = 1;\n        }\n\n        return a;\n    }\n\n// Take input from [0, n] and return it as [0, 1]\n    function bound01(n, max) {\n        if (isOnePointZero(n)) { n = \"100%\"; }\n\n        var processPercent = isPercentage(n);\n        n = mathMin(max, mathMax(0, parseFloat(n)));\n\n        // Automatically convert percentage into number\n        if (processPercent) {\n            n = parseInt(n * max, 10) / 100;\n        }\n\n        // Handle floating point rounding errors\n        if ((Math.abs(n - max) < 0.000001)) {\n            return 1;\n        }\n\n        // Convert into [0, 1] range if it isn't already\n        return (n % max) / parseFloat(max);\n    }\n\n// Force a number between 0 and 1\n    function clamp01(val) {\n        return mathMin(1, mathMax(0, val));\n    }\n\n// Parse a base-16 hex value into a base-10 integer\n    function parseIntFromHex(val) {\n        return parseInt(val, 16);\n    }\n\n// Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1\n// <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>\n    function isOnePointZero(n) {\n        return typeof n == \"string\" && n.indexOf('.') != -1 && parseFloat(n) === 1;\n    }\n\n// Check to see if string passed in is a percentage\n    function isPercentage(n) {\n        return typeof n === \"string\" && n.indexOf('%') != -1;\n    }\n\n// Force a hex value to have 2 characters\n    function pad2(c) {\n        return c.length == 1 ? '0' + c : '' + c;\n    }\n\n// Replace a decimal with it's percentage value\n    function convertToPercentage(n) {\n        if (n <= 1) {\n            n = (n * 100) + \"%\";\n        }\n\n        return n;\n    }\n\n// Converts a decimal to a hex value\n    function convertDecimalToHex(d) {\n        return Math.round(parseFloat(d) * 255).toString(16);\n    }\n// Converts a hex value to a decimal\n    function convertHexToDecimal(h) {\n        return (parseIntFromHex(h) / 255);\n    }\n\n    var matchers = (function() {\n\n        // <http://www.w3.org/TR/css3-values/#integers>\n        var CSS_INTEGER = \"[-\\\\+]?\\\\d+%?\";\n\n        // <http://www.w3.org/TR/css3-values/#number-value>\n        var CSS_NUMBER = \"[-\\\\+]?\\\\d*\\\\.\\\\d+%?\";\n\n        // Allow positive/negative integer/number.  Don't capture the either/or, just the entire outcome.\n        var CSS_UNIT = \"(?:\" + CSS_NUMBER + \")|(?:\" + CSS_INTEGER + \")\";\n\n        // Actual matching.\n        // Parentheses and commas are optional, but not required.\n        // Whitespace can take the place of commas or opening paren\n        var PERMISSIVE_MATCH3 = \"[\\\\s|\\\\(]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")\\\\s*\\\\)?\";\n        var PERMISSIVE_MATCH4 = \"[\\\\s|\\\\(]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")[,|\\\\s]+(\" + CSS_UNIT + \")\\\\s*\\\\)?\";\n\n        return {\n            CSS_UNIT: new RegExp(CSS_UNIT),\n            rgb: new RegExp(\"rgb\" + PERMISSIVE_MATCH3),\n            rgba: new RegExp(\"rgba\" + PERMISSIVE_MATCH4),\n            hsl: new RegExp(\"hsl\" + PERMISSIVE_MATCH3),\n            hsla: new RegExp(\"hsla\" + PERMISSIVE_MATCH4),\n            hsv: new RegExp(\"hsv\" + PERMISSIVE_MATCH3),\n            hsva: new RegExp(\"hsva\" + PERMISSIVE_MATCH4),\n            hex3: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,\n            hex6: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,\n            hex4: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,\n            hex8: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/\n        };\n    })();\n\n// `isValidCSSUnit`\n// Take in a single string / number and check to see if it looks like a CSS unit\n// (see `matchers` above for definition).\n    function isValidCSSUnit(color) {\n        return !!matchers.CSS_UNIT.exec(color);\n    }\n\n// `stringInputToObject`\n// Permissive string parsing.  Take in a number of formats, and output an object\n// based on detected format.  Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`\n    function stringInputToObject(color) {\n\n        color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase();\n        var named = false;\n        if (names[color]) {\n            color = names[color];\n            named = true;\n        }\n        else if (color == 'transparent') {\n            return { r: 0, g: 0, b: 0, a: 0, format: \"name\" };\n        }\n\n        // Try to match string input using regular expressions.\n        // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]\n        // Just return an object and let the conversion functions handle that.\n        // This way the result will be the same whether the tinycolor is initialized with string or object.\n        var match;\n        if ((match = matchers.rgb.exec(color))) {\n            return { r: match[1], g: match[2], b: match[3] };\n        }\n        if ((match = matchers.rgba.exec(color))) {\n            return { r: match[1], g: match[2], b: match[3], a: match[4] };\n        }\n        if ((match = matchers.hsl.exec(color))) {\n            return { h: match[1], s: match[2], l: match[3] };\n        }\n        if ((match = matchers.hsla.exec(color))) {\n            return { h: match[1], s: match[2], l: match[3], a: match[4] };\n        }\n        if ((match = matchers.hsv.exec(color))) {\n            return { h: match[1], s: match[2], v: match[3] };\n        }\n        if ((match = matchers.hsva.exec(color))) {\n            return { h: match[1], s: match[2], v: match[3], a: match[4] };\n        }\n        if ((match = matchers.hex8.exec(color))) {\n            return {\n                r: parseIntFromHex(match[1]),\n                g: parseIntFromHex(match[2]),\n                b: parseIntFromHex(match[3]),\n                a: convertHexToDecimal(match[4]),\n                format: named ? \"name\" : \"hex8\"\n            };\n        }\n        if ((match = matchers.hex6.exec(color))) {\n            return {\n                r: parseIntFromHex(match[1]),\n                g: parseIntFromHex(match[2]),\n                b: parseIntFromHex(match[3]),\n                format: named ? \"name\" : \"hex\"\n            };\n        }\n        if ((match = matchers.hex4.exec(color))) {\n            return {\n                r: parseIntFromHex(match[1] + '' + match[1]),\n                g: parseIntFromHex(match[2] + '' + match[2]),\n                b: parseIntFromHex(match[3] + '' + match[3]),\n                a: convertHexToDecimal(match[4] + '' + match[4]),\n                format: named ? \"name\" : \"hex8\"\n            };\n        }\n        if ((match = matchers.hex3.exec(color))) {\n            return {\n                r: parseIntFromHex(match[1] + '' + match[1]),\n                g: parseIntFromHex(match[2] + '' + match[2]),\n                b: parseIntFromHex(match[3] + '' + match[3]),\n                format: named ? \"name\" : \"hex\"\n            };\n        }\n\n        return false;\n    }\n\n    function validateWCAG2Parms(parms) {\n        // return valid WCAG2 parms for isReadable.\n        // If input parms are invalid, return {\"level\":\"AA\", \"size\":\"small\"}\n        var level, size;\n        parms = parms || {\"level\":\"AA\", \"size\":\"small\"};\n        level = (parms.level || \"AA\").toUpperCase();\n        size = (parms.size || \"small\").toLowerCase();\n        if (level !== \"AA\" && level !== \"AAA\") {\n            level = \"AA\";\n        }\n        if (size !== \"small\" && size !== \"large\") {\n            size = \"small\";\n        }\n        return {\"level\":level, \"size\":size};\n    }\n\n// Node: Export function\n    if (typeof module !== \"undefined\" && module.exports) {\n        module.exports = tinycolor;\n    }\n// AMD/requirejs: Define the module\n    else if (typeof define === 'function' && define.amd) {\n        define(function () {return tinycolor;});\n    }\n// Browser: Expose to window\n    else {\n        window.tinycolor = tinycolor;\n    }\n\n})(Math);\n"}
}});