simile-timeline-2.3.0/0000755000014500017510000000000012057725446014103 5ustar michaelstaffsimile-timeline-2.3.0/src/0000755000014500017510000000000011154003244014650 5ustar michaelstaffsimile-timeline-2.3.0/src/ajax/0000755000014500017510000000000011154003244015573 5ustar michaelstaffsimile-timeline-2.3.0/src/ajax/api/0000755000014500017510000000000011154003244016344 5ustar michaelstaffsimile-timeline-2.3.0/src/ajax/api/content/0000755000014500017510000000000011154003244020016 5ustar michaelstaffsimile-timeline-2.3.0/src/ajax/api/content/history.html0000644000014500017510000000014711154003244022407 0ustar michaelstaff Dummy Page for Keeping Track of History simile-timeline-2.3.0/src/ajax/api/images/0000755000014500017510000000000011154003244017611 5ustar michaelstaffsimile-timeline-2.3.0/src/ajax/api/images/bubble-arrow-point-down.png0000644000014500017510000000710611154003244025002 0ustar michaelstaffPNG  IHDR1d/X pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FqIDATxAKARhB9z^ij@J/bDHEB$9hXYlq(ufID70q}}vf8P4lLv1 !AB?CU,..t9D"_cm<Ҷ84p>pCr~~>]Fcx-^;gj/ӽ@^ :Y`eel6SJrx; @>>>eYm#gahat:1==N)ij T&8ϚyNS$ɟ4B7Msu_9F#aY֭%Ŏr0Օt*JJ̠(W\2Wu۶ʲa6 OeLMjPx4\.h$///m  Y[[zV5X,V%t{N* [pjbt`BjJx3!N.[4 nP*`Yַ_g1-(JC c/lY:f/ HR{:9LdbcRi cEovLӼuC&'Wdz`1&Ɇd}vvM6W6$I0LryT?,/pӉ4\<. ~\A8 :DȲ!^$#τ)5Xk"yxn'!AB !AB !AB !AB !AB !I3viIENDB`simile-timeline-2.3.0/src/ajax/api/images/bubble-arrow-point-left.png0000644000014500017510000000657711154003244025000 0ustar michaelstaffPNG  IHDRd1,  pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATxj@࣑F8-d0q[kBPmaY%,y>C&& S%S΁Hb>H3e`!A0 %'+8 , aB CREb˲vD 2`RA0F}1B K)?8&HC` H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATx_kP.t^r nG-̭k DDM꟤"E6vɉ&g7)d!k] zq~$Ȅ@B "\= ! @(B قˌ1#/nw*L @Oy*gC LsP(Tt]wb@D=‰ZDI4Mt:\__C4,i~>>>[) bא An UUil>fJҏnky>GHJ1M~v777,d>_z8nB )sWXq>*JEQ N( AQhy0l6&c6$IZ6Zg1\cA߇$Iz}[ոϸX`vm[`Y( ii:|0 :e<>>B$H{0z^lZ#O}2jӘ*Be>|xxh4\]]^T!i]E]׿C@DWN\i C4MȲx\ grd2 o5qX\.hZUZw#pB&;~c߷8<Q( ^ȔU!˘;'Y0X`꟒(aSKՑ V"X~gw[iLY,!;UZp#J$^z۷8!SbPa nч)VȪ{b q;#HFBO@B [?L>yRIENDB`simile-timeline-2.3.0/src/ajax/api/images/bubble-arrow-point-up.png0000644000014500017510000000652511154003244024463 0ustar michaelstaffPNG  IHDR1d/X pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATxNPm/(hd!RZILFH&a8l\#|yy TaSszEEDADADADADADADADADADADADA!0\xnNjVp8d C/b+aޫiڠh@J^'*6F{# ۉDRu]|z] 4ض 0t]h'bf!B}HR^g K+&t:)0 R}3"<;, Jra\Nr&vm)ep&!4o~ߙ{wjZJ q \7̷m 8, [[[J@.G%fZI)u~pp01/WWWKC5j0^X\X*fETbMU{PXJ>スM|+u|ߏ@)l6 Z{ƫmRJyyޓr9{ v=s'ömy\VK6bx 6*ʳroooqwwF#&>A" " ">A׃^IENDB`simile-timeline-2.3.0/src/ajax/api/images/bubble-bottom-left.png0000644000014500017510000000624011154003244024006 0ustar michaelstaffPNG  IHDR22? pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATxرjASQH ŵ)-,RRXۼAʼm+SY(),D!{f7 EܓYBcoϐc6Z@"D @"D X6;IENDB`simile-timeline-2.3.0/src/ajax/api/images/bubble-bottom-right.png0000644000014500017510000000633311154003244024174 0ustar michaelstaffPNG  IHDR22? pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATx=AwE4]ymtyi1 WH%$ V A񡸠3 dvݻCg=faET* |n#xKB)1%oq Qq>8RWk$y«!ٌ0 K Epb *^j=ZzZ$lHa4}l6Q*TY,- H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FZIDATx 1HҒQZkU @: @: @: @<e+ е<@~3 A$O3@?_fo%9]@ߚ+@     C(DIENDB`simile-timeline-2.3.0/src/ajax/api/images/bubble-left.png0000644000014500017510000000702111154003244022502 0ustar michaelstaffPNG  IHDR2re pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_F H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FOIDATxϱ Q2K/A-`[kMꨞ^={uV]fo'BҊQ&[IENDB`simile-timeline-2.3.0/src/ajax/api/images/bubble-top-left.png0000644000014500017510000000605311154003244023306 0ustar michaelstaffPNG  IHDR22? pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FVIDATx1k@NIDT\JADA2u%nZ(҆FAOރCO9鉨9AB !AB !AB 1&B'ۄ 2I,˞8[DC{Gvb 4ͳa (qA[1ѮUU]AKYtZg0Xr^w2!EKGPJVzm׮ԥҝ<2M( (6"m[;?aеcR7[,ZgE7e"#~Xa qgsoIENDB`simile-timeline-2.3.0/src/ajax/api/images/bubble-top-right.png0000644000014500017510000000625111154003244023471 0ustar michaelstaffPNG  IHDR22? pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATx!o@z]0 1!,edzd71;1C0L`1AB&HH $9Kw-lc]!%"rO߯w"14 G0! aC0! aC0!^GT-L{+OgObh4jndj"|>bp8h4ri6/j^Am:`6=u݇`0d?V5V_P_-wNjd2y8pr^.Q*6u<'JRA&rN|ÈB,"jڥl  mA! A|D\%^ZDR,:1B!`% iN"4LN֐zfK!Rq5+$oGIENDB`simile-timeline-2.3.0/src/ajax/api/images/bubble-top.png0000644000014500017510000000602711154003244022357 0ustar michaelstaffPNG  IHDR20 pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FBIDATx1@ Aii Ҍ*N@:t@@:t@@:t@@:t@@:t@@:t@@:t@s@@@_f{ P$ʼYt@t@t@A ` IENDB`simile-timeline-2.3.0/src/ajax/api/images/close-button.png0000644000014500017510000000116011154003244022733 0ustar michaelstaffPNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% (ĂMɓ@y ٿwtt|  W||| @ ߾}cxGAYː  ?>Y@@ GPP$_|e0=GZ刈0|ݻwpOfd?삷o2l+  7A@AN޷o'''???֭[8P@&L@!`ϣ($$ ##f+**^x_%+a%-ZTosAAp >~8q޼y0=~ +A`͟>}Y@ۋ#T]] 1  2, s.]z ]-@1R` 7BCp[IENDB`simile-timeline-2.3.0/src/ajax/api/images/copy.png0000644000014500017510000000030411154003244021266 0ustar michaelstaffPNG  IHDR gAMA7tEXtSoftwareAdobe ImageReadyqe<VIDATxb@ hhh`ĥ(  XcÜ@Ȋa @DY@Sb#d` IENDB`simile-timeline-2.3.0/src/ajax/api/images/message-bottom-left.png0000644000014500017510000000247311154003244024203 0ustar michaelstaffPNG  IHDR,7wYgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd```dd LXL0vy MMM3?8] Z!L7DV & 4Dh@O?Xi`bB_N+U@g8Ɏ1|z_1=zǃB&&@1YDaM[N= I8߽JLD~ ޾}ׯ@Uٳi'B,^1Ν{$LIy+yJׯ?Y'HL:8lĄĈc ϟ,1-t839i:{֬"n׏7n(MI(300#2>..o~`aa+//h1v/<69Bw0<yMM'@ܿGX燸8Od@Xg  BG;󖩩833[/9P"xc?qbSSoY&&ן󳱱/Ab@L(3 ;ML$XXX}vo,$  R5Y; 'Onܫiݻog<w` fdA0iKH222=yT3H$&"0zk 66{||44$?JI-##Di|:NTT΋ӄEP@D̀$;TȘrpBy`&Dw0@1) eRDj @DxV$#@diFE!2P!@1"( f22"6%&ԫ@DXBB` b! @8ܤLLdTs4%i? /0 @p0,hb&!hJ-B"XG[tu, f2QFKF"2Qa{ aL8ܚ?" rM#H(! @$dF KJG|b&0rMj Éubf 0hJv4@Q^eR!)3wR6#@13Pi 9'HdU h1HK5DYw&Z-@ڃU@T  v'@eIENDB`simile-timeline-2.3.0/src/ajax/api/images/message-bottom-right.png0000644000014500017510000000403211154003244024357 0ustar michaelstaffPNG  IHDR7ݸ$gAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb5Q0 F(` cbbMĮۨbwv)?(Da  FeQ0 F( F+Q0 F(`hhB`Q0 aM* }Q0 F(##=@V`Q0 Fϟuh> F(`|D7hB`Q0 ^s OϜ:@V`Q0 F tR>{j F+Q0 F(Pt;㫓h=qVh> F(`а׎,W/>{[N="'bP@(`Q@'p#3c۷O;@V`Q0 Fzh3A_c>܎N^G(` *s| ~ϟG+MDEMP<@V`Q0 Fz0}ȑ o;Od% }Q0 F( 2'wqE?~3s׬Y Td5hB`Q0 P?|͛/= X22bQ0 F(JoK|{ސ߽{VwX*o|"ǏQ0 F(?v+Wnp^MϯK)܄VQc F{`Q0 F9zرBv]TVMXǍ& @(`Q@ӧ,7_}?ץ'+sB=sNC4ZQ0 F(dTȕϟ)rC߿2{o߽{r޸ӧl0_~|q Ujb,/_5ZQ0 F(d7ol[R F(`Wk',{ @s`Q0 F+p3 5dW @=Q0 F(^:)5+؉xh}Q0 F( N0hB`Q0Z Ҋd@C`Q0 Fi><)9ɕ<@G(`*UJ+yW @(`Q@JԊhB`Q0 ȫԩ> }Q0 F(R"bQ0 F(4ҭ"bfehQ0 F(OC4ZQ0 F(|z FG(`Tt]@̣q8 F(` (`Q0*lB MMsLXAIENDB`simile-timeline-2.3.0/src/ajax/api/images/message-left.png0000644000014500017510000000131511154003244022673 0ustar michaelstaffPNG  IHDR,dgAMA7tEXtSoftwareAdobe ImageReadyqe<_IDATxbd```dd LXL0vy MMM3?8] 4 @t0#= @C.h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 h9 nx|IENDB`simile-timeline-2.3.0/src/ajax/api/images/message-right.png0000644000014500017510000000354411154003244023064 0ustar michaelstaffPNG  IHDRdp}gAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb5Q0 F(` cbbMĮۨbwv)?(Da  FeQ0 F( F+Q0 F(`G(`2 F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( F+Q0 F(`G(`ahB`Q0  }Q0 F( ɛDIENDB`simile-timeline-2.3.0/src/ajax/api/images/message-top-left.png0000644000014500017510000000162611154003244023500 0ustar michaelstaffPNG  IHDR,!IgAMA7tEXtSoftwareAdobe ImageReadyqe<(IDATxb?0222 bw@ 62  v$V=2HIZb  XC@,tp()$h@бT K[[311+2%>PY!@ر`vAB66vB:, FfR#~.cc(cddrIrҒz/--MD痜w&&Ȇ-2^&%JHO:4gggcfZWW棌wB ɀ Cu)T񕋋K: XhX.+[1) ć@'I1 ;8`>I51&@,4p, ]Z|ȱ,,LM~$Ց Uq`EV0s2(dq9G"b t:6)[c* J%ơ"C @[Js,-"" , %ޣY|Hd@,8 L t,cj8 ռDM1ԟX|&@,T]v^\7`:F .r( *.g4HX cu(L )0b*LL(R=@,d8gquM21 r&DZB X(`Ș $(//#Hu(@PfŀC`N b *zVZ ZR1%'V H`k6R,` @^ e"Z!R^, _ZfpՌBi'@|%Ԋ0R IENDB`simile-timeline-2.3.0/src/ajax/api/images/message-top-right.png0000644000014500017510000000310411154003244023654 0ustar michaelstaffPNG  IHDR!/RYgAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxbd```d`Q0 F>:?i2G`Q0 FA@;>@G(`+dƁh> F(`ֹO4h> F(`Viy@íBOfkk 9FhzVe$A@Պ ېh&aQ@@AJ;@Q0 F(+rFqUiYh> F(`P'rW]cy2 F(`?ߩ߿81J_NR ;X F+Q0 F(`zׯ'L߃B&'RUs2 F(`g|-w_Y?~}3ϟ!*~5aB!;:Q;B }Q0 F(  F(`PɓR(YTTLX*mF"*q;@Z? F(`$@hVo-.ŋ\Iw9ʀ:ΈćIG(`QGNb8\b|yy wNB9G(`"+y|=v|b|)) EK%N:@o`Q0 F2w>;vtqv_Rf-J^\CXhԍQ0 F(V;m^7D/8*v=@Q0 F(*x\ĮnGcggϕ=@(`Q@ANRGgaY*jls$M趵Q0 F([gRG6^]s i܎IENDB`simile-timeline-2.3.0/src/ajax/api/scripts/0000755000014500017510000000000011154003244020033 5ustar michaelstaffsimile-timeline-2.3.0/src/ajax/api/scripts/ajax.js0000644000014500017510000000274711154003244021326 0ustar michaelstaff/*================================================== * General, miscellaneous SimileAjax stuff *================================================== */ SimileAjax.ListenerQueue = function(wildcardHandlerName) { this._listeners = []; this._wildcardHandlerName = wildcardHandlerName; }; SimileAjax.ListenerQueue.prototype.add = function(listener) { this._listeners.push(listener); }; SimileAjax.ListenerQueue.prototype.remove = function(listener) { var listeners = this._listeners; for (var i = 0; i < listeners.length; i++) { if (listeners[i] == listener) { listeners.splice(i, 1); break; } } }; SimileAjax.ListenerQueue.prototype.fire = function(handlerName, args) { var listeners = [].concat(this._listeners); for (var i = 0; i < listeners.length; i++) { var listener = listeners[i]; if (handlerName in listener) { try { listener[handlerName].apply(listener, args); } catch (e) { SimileAjax.Debug.exception("Error firing event of name " + handlerName, e); } } else if (this._wildcardHandlerName != null && this._wildcardHandlerName in listener) { try { listener[this._wildcardHandlerName].apply(listener, [ handlerName ]); } catch (e) { SimileAjax.Debug.exception("Error firing event of name " + handlerName + " to wildcard handler", e); } } } }; simile-timeline-2.3.0/src/ajax/api/scripts/data-structure.js0000644000014500017510000002654211154003244023351 0ustar michaelstaff/** * A basic set (in the mathematical sense) data structure * * @constructor * @param {Array or SimileAjax.Set} [a] an initial collection */ SimileAjax.Set = function(a) { this._hash = {}; this._count = 0; if (a instanceof Array) { for (var i = 0; i < a.length; i++) { this.add(a[i]); } } else if (a instanceof SimileAjax.Set) { this.addSet(a); } } /** * Adds the given object to this set, assuming there it does not already exist * * @param {Object} o the object to add * @return {Boolean} true if the object was added, false if not */ SimileAjax.Set.prototype.add = function(o) { if (!(o in this._hash)) { this._hash[o] = true; this._count++; return true; } return false; } /** * Adds each element in the given set to this set * * @param {SimileAjax.Set} set the set of elements to add */ SimileAjax.Set.prototype.addSet = function(set) { for (var o in set._hash) { this.add(o); } } /** * Removes the given element from this set * * @param {Object} o the object to remove * @return {Boolean} true if the object was successfully removed, * false otherwise */ SimileAjax.Set.prototype.remove = function(o) { if (o in this._hash) { delete this._hash[o]; this._count--; return true; } return false; } /** * Removes the elements in this set that correspond to the elements in the * given set * * @param {SimileAjax.Set} set the set of elements to remove */ SimileAjax.Set.prototype.removeSet = function(set) { for (var o in set._hash) { this.remove(o); } } /** * Removes all elements in this set that are not present in the given set, i.e. * modifies this set to the intersection of the two sets * * @param {SimileAjax.Set} set the set to intersect */ SimileAjax.Set.prototype.retainSet = function(set) { for (var o in this._hash) { if (!set.contains(o)) { delete this._hash[o]; this._count--; } } } /** * Returns whether or not the given element exists in this set * * @param {SimileAjax.Set} o the object to test for * @return {Boolean} true if the object is present, false otherwise */ SimileAjax.Set.prototype.contains = function(o) { return (o in this._hash); } /** * Returns the number of elements in this set * * @return {Number} the number of elements in this set */ SimileAjax.Set.prototype.size = function() { return this._count; } /** * Returns the elements of this set as an array * * @return {Array} a new array containing the elements of this set */ SimileAjax.Set.prototype.toArray = function() { var a = []; for (var o in this._hash) { a.push(o); } return a; } /** * Iterates through the elements of this set, order unspecified, executing the * given function on each element until the function returns true * * @param {Function} f a function of form f(element) */ SimileAjax.Set.prototype.visit = function(f) { for (var o in this._hash) { if (f(o) == true) { break; } } } /** * A sorted array data structure * * @constructor */ SimileAjax.SortedArray = function(compare, initialArray) { this._a = (initialArray instanceof Array) ? initialArray : []; this._compare = compare; }; SimileAjax.SortedArray.prototype.add = function(elmt) { var sa = this; var index = this.find(function(elmt2) { return sa._compare(elmt2, elmt); }); if (index < this._a.length) { this._a.splice(index, 0, elmt); } else { this._a.push(elmt); } }; SimileAjax.SortedArray.prototype.remove = function(elmt) { var sa = this; var index = this.find(function(elmt2) { return sa._compare(elmt2, elmt); }); while (index < this._a.length && this._compare(this._a[index], elmt) == 0) { if (this._a[index] == elmt) { this._a.splice(index, 1); return true; } else { index++; } } return false; }; SimileAjax.SortedArray.prototype.removeAll = function() { this._a = []; }; SimileAjax.SortedArray.prototype.elementAt = function(index) { return this._a[index]; }; SimileAjax.SortedArray.prototype.length = function() { return this._a.length; }; SimileAjax.SortedArray.prototype.find = function(compare) { var a = 0; var b = this._a.length; while (a < b) { var mid = Math.floor((a + b) / 2); var c = compare(this._a[mid]); if (mid == a) { return c < 0 ? a+1 : a; } else if (c < 0) { a = mid; } else { b = mid; } } return a; }; SimileAjax.SortedArray.prototype.getFirst = function() { return (this._a.length > 0) ? this._a[0] : null; }; SimileAjax.SortedArray.prototype.getLast = function() { return (this._a.length > 0) ? this._a[this._a.length - 1] : null; }; /*================================================== * Event Index *================================================== */ SimileAjax.EventIndex = function(unit) { var eventIndex = this; this._unit = (unit != null) ? unit : SimileAjax.NativeDateUnit; this._events = new SimileAjax.SortedArray( function(event1, event2) { return eventIndex._unit.compare(event1.getStart(), event2.getStart()); } ); this._idToEvent = {}; this._indexed = true; }; SimileAjax.EventIndex.prototype.getUnit = function() { return this._unit; }; SimileAjax.EventIndex.prototype.getEvent = function(id) { return this._idToEvent[id]; }; SimileAjax.EventIndex.prototype.add = function(evt) { this._events.add(evt); this._idToEvent[evt.getID()] = evt; this._indexed = false; }; SimileAjax.EventIndex.prototype.removeAll = function() { this._events.removeAll(); this._idToEvent = {}; this._indexed = false; }; SimileAjax.EventIndex.prototype.getCount = function() { return this._events.length(); }; SimileAjax.EventIndex.prototype.getIterator = function(startDate, endDate) { if (!this._indexed) { this._index(); } return new SimileAjax.EventIndex._Iterator(this._events, startDate, endDate, this._unit); }; SimileAjax.EventIndex.prototype.getReverseIterator = function(startDate, endDate) { if (!this._indexed) { this._index(); } return new SimileAjax.EventIndex._ReverseIterator(this._events, startDate, endDate, this._unit); }; SimileAjax.EventIndex.prototype.getAllIterator = function() { return new SimileAjax.EventIndex._AllIterator(this._events); }; SimileAjax.EventIndex.prototype.getEarliestDate = function() { var evt = this._events.getFirst(); return (evt == null) ? null : evt.getStart(); }; SimileAjax.EventIndex.prototype.getLatestDate = function() { var evt = this._events.getLast(); if (evt == null) { return null; } if (!this._indexed) { this._index(); } var index = evt._earliestOverlapIndex; var date = this._events.elementAt(index).getEnd(); for (var i = index + 1; i < this._events.length(); i++) { date = this._unit.later(date, this._events.elementAt(i).getEnd()); } return date; }; SimileAjax.EventIndex.prototype._index = function() { /* * For each event, we want to find the earliest preceding * event that overlaps with it, if any. */ var l = this._events.length(); for (var i = 0; i < l; i++) { var evt = this._events.elementAt(i); evt._earliestOverlapIndex = i; } var toIndex = 1; for (var i = 0; i < l; i++) { var evt = this._events.elementAt(i); var end = evt.getEnd(); toIndex = Math.max(toIndex, i + 1); while (toIndex < l) { var evt2 = this._events.elementAt(toIndex); var start2 = evt2.getStart(); if (this._unit.compare(start2, end) < 0) { evt2._earliestOverlapIndex = i; toIndex++; } else { break; } } } this._indexed = true; }; SimileAjax.EventIndex._Iterator = function(events, startDate, endDate, unit) { this._events = events; this._startDate = startDate; this._endDate = endDate; this._unit = unit; this._currentIndex = events.find(function(evt) { return unit.compare(evt.getStart(), startDate); }); if (this._currentIndex - 1 >= 0) { this._currentIndex = this._events.elementAt(this._currentIndex - 1)._earliestOverlapIndex; } this._currentIndex--; this._maxIndex = events.find(function(evt) { return unit.compare(evt.getStart(), endDate); }); this._hasNext = false; this._next = null; this._findNext(); }; SimileAjax.EventIndex._Iterator.prototype = { hasNext: function() { return this._hasNext; }, next: function() { if (this._hasNext) { var next = this._next; this._findNext(); return next; } else { return null; } }, _findNext: function() { var unit = this._unit; while ((++this._currentIndex) < this._maxIndex) { var evt = this._events.elementAt(this._currentIndex); if (unit.compare(evt.getStart(), this._endDate) < 0 && unit.compare(evt.getEnd(), this._startDate) > 0) { this._next = evt; this._hasNext = true; return; } } this._next = null; this._hasNext = false; } }; SimileAjax.EventIndex._ReverseIterator = function(events, startDate, endDate, unit) { this._events = events; this._startDate = startDate; this._endDate = endDate; this._unit = unit; this._minIndex = events.find(function(evt) { return unit.compare(evt.getStart(), startDate); }); if (this._minIndex - 1 >= 0) { this._minIndex = this._events.elementAt(this._minIndex - 1)._earliestOverlapIndex; } this._maxIndex = events.find(function(evt) { return unit.compare(evt.getStart(), endDate); }); this._currentIndex = this._maxIndex; this._hasNext = false; this._next = null; this._findNext(); }; SimileAjax.EventIndex._ReverseIterator.prototype = { hasNext: function() { return this._hasNext; }, next: function() { if (this._hasNext) { var next = this._next; this._findNext(); return next; } else { return null; } }, _findNext: function() { var unit = this._unit; while ((--this._currentIndex) >= this._minIndex) { var evt = this._events.elementAt(this._currentIndex); if (unit.compare(evt.getStart(), this._endDate) < 0 && unit.compare(evt.getEnd(), this._startDate) > 0) { this._next = evt; this._hasNext = true; return; } } this._next = null; this._hasNext = false; } }; SimileAjax.EventIndex._AllIterator = function(events) { this._events = events; this._index = 0; }; SimileAjax.EventIndex._AllIterator.prototype = { hasNext: function() { return this._index < this._events.length(); }, next: function() { return this._index < this._events.length() ? this._events.elementAt(this._index++) : null; } };simile-timeline-2.3.0/src/ajax/api/scripts/date-time.js0000644000014500017510000003531311154003244022247 0ustar michaelstaff/** * @fileOverview A collection of date/time utility functions * @name SimileAjax.DateTime */ SimileAjax.DateTime = new Object(); SimileAjax.DateTime.MILLISECOND = 0; SimileAjax.DateTime.SECOND = 1; SimileAjax.DateTime.MINUTE = 2; SimileAjax.DateTime.HOUR = 3; SimileAjax.DateTime.DAY = 4; SimileAjax.DateTime.WEEK = 5; SimileAjax.DateTime.MONTH = 6; SimileAjax.DateTime.YEAR = 7; SimileAjax.DateTime.DECADE = 8; SimileAjax.DateTime.CENTURY = 9; SimileAjax.DateTime.MILLENNIUM = 10; SimileAjax.DateTime.EPOCH = -1; SimileAjax.DateTime.ERA = -2; /** * An array of unit lengths, expressed in milliseconds, of various lengths of * time. The array indices are predefined and stored as properties of the * SimileAjax.DateTime object, e.g. SimileAjax.DateTime.YEAR. * @type Array */ SimileAjax.DateTime.gregorianUnitLengths = []; (function() { var d = SimileAjax.DateTime; var a = d.gregorianUnitLengths; a[d.MILLISECOND] = 1; a[d.SECOND] = 1000; a[d.MINUTE] = a[d.SECOND] * 60; a[d.HOUR] = a[d.MINUTE] * 60; a[d.DAY] = a[d.HOUR] * 24; a[d.WEEK] = a[d.DAY] * 7; a[d.MONTH] = a[d.DAY] * 31; a[d.YEAR] = a[d.DAY] * 365; a[d.DECADE] = a[d.YEAR] * 10; a[d.CENTURY] = a[d.YEAR] * 100; a[d.MILLENNIUM] = a[d.YEAR] * 1000; })(); SimileAjax.DateTime._dateRegexp = new RegExp( "^(-?)([0-9]{4})(" + [ "(-?([0-9]{2})(-?([0-9]{2}))?)", // -month-dayOfMonth "(-?([0-9]{3}))", // -dayOfYear "(-?W([0-9]{2})(-?([1-7]))?)" // -Wweek-dayOfWeek ].join("|") + ")?$" ); SimileAjax.DateTime._timezoneRegexp = new RegExp( "Z|(([-+])([0-9]{2})(:?([0-9]{2}))?)$" ); SimileAjax.DateTime._timeRegexp = new RegExp( "^([0-9]{2})(:?([0-9]{2})(:?([0-9]{2})(\.([0-9]+))?)?)?$" ); /** * Takes a date object and a string containing an ISO 8601 date and sets the * the date using information parsed from the string. Note that this method * does not parse any time information. * * @param {Date} dateObject the date object to modify * @param {String} string an ISO 8601 string to parse * @return {Date} the modified date object */ SimileAjax.DateTime.setIso8601Date = function(dateObject, string) { /* * This function has been adapted from dojo.date, v.0.3.0 * http://dojotoolkit.org/. */ var d = string.match(SimileAjax.DateTime._dateRegexp); if(!d) { throw new Error("Invalid date string: " + string); } var sign = (d[1] == "-") ? -1 : 1; // BC or AD var year = sign * d[2]; var month = d[5]; var date = d[7]; var dayofyear = d[9]; var week = d[11]; var dayofweek = (d[13]) ? d[13] : 1; dateObject.setUTCFullYear(year); if (dayofyear) { dateObject.setUTCMonth(0); dateObject.setUTCDate(Number(dayofyear)); } else if (week) { dateObject.setUTCMonth(0); dateObject.setUTCDate(1); var gd = dateObject.getUTCDay(); var day = (gd) ? gd : 7; var offset = Number(dayofweek) + (7 * Number(week)); if (day <= 4) { dateObject.setUTCDate(offset + 1 - day); } else { dateObject.setUTCDate(offset + 8 - day); } } else { if (month) { dateObject.setUTCDate(1); dateObject.setUTCMonth(month - 1); } if (date) { dateObject.setUTCDate(date); } } return dateObject; }; /** * Takes a date object and a string containing an ISO 8601 time and sets the * the time using information parsed from the string. Note that this method * does not parse any date information. * * @param {Date} dateObject the date object to modify * @param {String} string an ISO 8601 string to parse * @return {Date} the modified date object */ SimileAjax.DateTime.setIso8601Time = function (dateObject, string) { /* * This function has been adapted from dojo.date, v.0.3.0 * http://dojotoolkit.org/. */ var d = string.match(SimileAjax.DateTime._timeRegexp); if(!d) { SimileAjax.Debug.warn("Invalid time string: " + string); return false; } var hours = d[1]; var mins = Number((d[3]) ? d[3] : 0); var secs = (d[5]) ? d[5] : 0; var ms = d[7] ? (Number("0." + d[7]) * 1000) : 0; dateObject.setUTCHours(hours); dateObject.setUTCMinutes(mins); dateObject.setUTCSeconds(secs); dateObject.setUTCMilliseconds(ms); return dateObject; }; /** * The timezone offset in minutes in the user's browser. * @type Number */ SimileAjax.DateTime.timezoneOffset = new Date().getTimezoneOffset(); /** * Takes a date object and a string containing an ISO 8601 date and time and * sets the date object using information parsed from the string. * * @param {Date} dateObject the date object to modify * @param {String} string an ISO 8601 string to parse * @return {Date} the modified date object */ SimileAjax.DateTime.setIso8601 = function (dateObject, string){ /* * This function has been adapted from dojo.date, v.0.3.0 * http://dojotoolkit.org/. */ var offset = null; var comps = (string.indexOf("T") == -1) ? string.split(" ") : string.split("T"); SimileAjax.DateTime.setIso8601Date(dateObject, comps[0]); if (comps.length == 2) { // first strip timezone info from the end var d = comps[1].match(SimileAjax.DateTime._timezoneRegexp); if (d) { if (d[0] == 'Z') { offset = 0; } else { offset = (Number(d[3]) * 60) + Number(d[5]); offset *= ((d[2] == '-') ? 1 : -1); } comps[1] = comps[1].substr(0, comps[1].length - d[0].length); } SimileAjax.DateTime.setIso8601Time(dateObject, comps[1]); } if (offset == null) { offset = dateObject.getTimezoneOffset(); // local time zone if no tz info } dateObject.setTime(dateObject.getTime() + offset * 60000); return dateObject; }; /** * Takes a string containing an ISO 8601 date and returns a newly instantiated * date object with the parsed date and time information from the string. * * @param {String} string an ISO 8601 string to parse * @return {Date} a new date object created from the string */ SimileAjax.DateTime.parseIso8601DateTime = function (string) { try { return SimileAjax.DateTime.setIso8601(new Date(0), string); } catch (e) { return null; } }; /** * Takes a string containing a Gregorian date and time and returns a newly * instantiated date object with the parsed date and time information from the * string. If the param is actually an instance of Date instead of a string, * simply returns the given date instead. * * @param {Object} o an object, to either return or parse as a string * @return {Date} the date object */ SimileAjax.DateTime.parseGregorianDateTime = function(o) { if (o == null) { return null; } else if (o instanceof Date) { return o; } var s = o.toString(); if (s.length > 0 && s.length < 8) { var space = s.indexOf(" "); if (space > 0) { var year = parseInt(s.substr(0, space)); var suffix = s.substr(space + 1); if (suffix.toLowerCase() == "bc") { year = 1 - year; } } else { var year = parseInt(s); } var d = new Date(0); d.setUTCFullYear(year); return d; } try { return new Date(Date.parse(s)); } catch (e) { return null; } }; /** * Rounds date objects down to the nearest interval or multiple of an interval. * This method modifies the given date object, converting it to the given * timezone if specified. * * @param {Date} date the date object to round * @param {Number} intervalUnit a constant, integer index specifying an * interval, e.g. SimileAjax.DateTime.HOUR * @param {Number} timeZone a timezone shift, given in hours * @param {Number} multiple a multiple of the interval to round by * @param {Number} firstDayOfWeek an integer specifying the first day of the * week, 0 corresponds to Sunday, 1 to Monday, etc. */ SimileAjax.DateTime.roundDownToInterval = function(date, intervalUnit, timeZone, multiple, firstDayOfWeek) { var timeShift = timeZone * SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR]; var date2 = new Date(date.getTime() + timeShift); var clearInDay = function(d) { d.setUTCMilliseconds(0); d.setUTCSeconds(0); d.setUTCMinutes(0); d.setUTCHours(0); }; var clearInYear = function(d) { clearInDay(d); d.setUTCDate(1); d.setUTCMonth(0); }; switch(intervalUnit) { case SimileAjax.DateTime.MILLISECOND: var x = date2.getUTCMilliseconds(); date2.setUTCMilliseconds(x - (x % multiple)); break; case SimileAjax.DateTime.SECOND: date2.setUTCMilliseconds(0); var x = date2.getUTCSeconds(); date2.setUTCSeconds(x - (x % multiple)); break; case SimileAjax.DateTime.MINUTE: date2.setUTCMilliseconds(0); date2.setUTCSeconds(0); var x = date2.getUTCMinutes(); date2.setTime(date2.getTime() - (x % multiple) * SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.MINUTE]); break; case SimileAjax.DateTime.HOUR: date2.setUTCMilliseconds(0); date2.setUTCSeconds(0); date2.setUTCMinutes(0); var x = date2.getUTCHours(); date2.setUTCHours(x - (x % multiple)); break; case SimileAjax.DateTime.DAY: clearInDay(date2); break; case SimileAjax.DateTime.WEEK: clearInDay(date2); var d = (date2.getUTCDay() + 7 - firstDayOfWeek) % 7; date2.setTime(date2.getTime() - d * SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.DAY]); break; case SimileAjax.DateTime.MONTH: clearInDay(date2); date2.setUTCDate(1); var x = date2.getUTCMonth(); date2.setUTCMonth(x - (x % multiple)); break; case SimileAjax.DateTime.YEAR: clearInYear(date2); var x = date2.getUTCFullYear(); date2.setUTCFullYear(x - (x % multiple)); break; case SimileAjax.DateTime.DECADE: clearInYear(date2); date2.setUTCFullYear(Math.floor(date2.getUTCFullYear() / 10) * 10); break; case SimileAjax.DateTime.CENTURY: clearInYear(date2); date2.setUTCFullYear(Math.floor(date2.getUTCFullYear() / 100) * 100); break; case SimileAjax.DateTime.MILLENNIUM: clearInYear(date2); date2.setUTCFullYear(Math.floor(date2.getUTCFullYear() / 1000) * 1000); break; } date.setTime(date2.getTime() - timeShift); }; /** * Rounds date objects up to the nearest interval or multiple of an interval. * This method modifies the given date object, converting it to the given * timezone if specified. * * @param {Date} date the date object to round * @param {Number} intervalUnit a constant, integer index specifying an * interval, e.g. SimileAjax.DateTime.HOUR * @param {Number} timeZone a timezone shift, given in hours * @param {Number} multiple a multiple of the interval to round by * @param {Number} firstDayOfWeek an integer specifying the first day of the * week, 0 corresponds to Sunday, 1 to Monday, etc. * @see SimileAjax.DateTime.roundDownToInterval */ SimileAjax.DateTime.roundUpToInterval = function(date, intervalUnit, timeZone, multiple, firstDayOfWeek) { var originalTime = date.getTime(); SimileAjax.DateTime.roundDownToInterval(date, intervalUnit, timeZone, multiple, firstDayOfWeek); if (date.getTime() < originalTime) { date.setTime(date.getTime() + SimileAjax.DateTime.gregorianUnitLengths[intervalUnit] * multiple); } }; /** * Increments a date object by a specified interval, taking into * consideration the timezone. * * @param {Date} date the date object to increment * @param {Number} intervalUnit a constant, integer index specifying an * interval, e.g. SimileAjax.DateTime.HOUR * @param {Number} timeZone the timezone offset in hours */ SimileAjax.DateTime.incrementByInterval = function(date, intervalUnit, timeZone) { timeZone = (typeof timeZone == 'undefined') ? 0 : timeZone; var timeShift = timeZone * SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR]; var date2 = new Date(date.getTime() + timeShift); switch(intervalUnit) { case SimileAjax.DateTime.MILLISECOND: date2.setTime(date2.getTime() + 1) break; case SimileAjax.DateTime.SECOND: date2.setTime(date2.getTime() + 1000); break; case SimileAjax.DateTime.MINUTE: date2.setTime(date2.getTime() + SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.MINUTE]); break; case SimileAjax.DateTime.HOUR: date2.setTime(date2.getTime() + SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR]); break; case SimileAjax.DateTime.DAY: date2.setUTCDate(date2.getUTCDate() + 1); break; case SimileAjax.DateTime.WEEK: date2.setUTCDate(date2.getUTCDate() + 7); break; case SimileAjax.DateTime.MONTH: date2.setUTCMonth(date2.getUTCMonth() + 1); break; case SimileAjax.DateTime.YEAR: date2.setUTCFullYear(date2.getUTCFullYear() + 1); break; case SimileAjax.DateTime.DECADE: date2.setUTCFullYear(date2.getUTCFullYear() + 10); break; case SimileAjax.DateTime.CENTURY: date2.setUTCFullYear(date2.getUTCFullYear() + 100); break; case SimileAjax.DateTime.MILLENNIUM: date2.setUTCFullYear(date2.getUTCFullYear() + 1000); break; } date.setTime(date2.getTime() - timeShift); }; /** * Returns a new date object with the given time offset removed. * * @param {Date} date the starting date * @param {Number} timeZone a timezone specified in an hour offset to remove * @return {Date} a new date object with the offset removed */ SimileAjax.DateTime.removeTimeZoneOffset = function(date, timeZone) { return new Date(date.getTime() + timeZone * SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR]); }; /** * Returns the timezone of the user's browser. * * @return {Number} the timezone in the user's locale in hours */ SimileAjax.DateTime.getTimezone = function() { var d = new Date().getTimezoneOffset(); return d / -60; }; simile-timeline-2.3.0/src/ajax/api/scripts/debug.js0000644000014500017510000000520011154003244021454 0ustar michaelstaff/*================================================== * Debug Utility Functions *================================================== */ SimileAjax.Debug = { silent: false }; SimileAjax.Debug.log = function(msg) { var f; if ("console" in window && "log" in window.console) { // FireBug installed f = function(msg2) { console.log(msg2); } } else { f = function(msg2) { if (!SimileAjax.Debug.silent) { alert(msg2); } } } SimileAjax.Debug.log = f; f(msg); }; SimileAjax.Debug.warn = function(msg) { var f; if ("console" in window && "warn" in window.console) { // FireBug installed f = function(msg2) { console.warn(msg2); } } else { f = function(msg2) { if (!SimileAjax.Debug.silent) { alert(msg2); } } } SimileAjax.Debug.warn = f; f(msg); }; SimileAjax.Debug.exception = function(e, msg) { var f, params = SimileAjax.parseURLParameters(); if (params.errors == "throw" || SimileAjax.params.errors == "throw") { f = function(e2, msg2) { throw(e2); // do not hide from browser's native debugging features }; } else if ("console" in window && "error" in window.console) { // FireBug installed f = function(e2, msg2) { if (msg2 != null) { console.error(msg2 + " %o", e2); } else { console.error(e2); } throw(e2); // do not hide from browser's native debugging features }; } else { f = function(e2, msg2) { if (!SimileAjax.Debug.silent) { alert("Caught exception: " + msg2 + "\n\nDetails: " + ("description" in e2 ? e2.description : e2)); } throw(e2); // do not hide from browser's native debugging features }; } SimileAjax.Debug.exception = f; f(e, msg); }; SimileAjax.Debug.objectToString = function(o) { return SimileAjax.Debug._objectToString(o, ""); }; SimileAjax.Debug._objectToString = function(o, indent) { var indent2 = indent + " "; if (typeof o == "object") { var s = "{"; for (n in o) { s += indent2 + n + ": " + SimileAjax.Debug._objectToString(o[n], indent2) + "\n"; } s += indent + "}"; return s; } else if (typeof o == "array") { var s = "["; for (var n = 0; n < o.length; n++) { s += SimileAjax.Debug._objectToString(o[n], indent2) + "\n"; } s += indent + "]"; return s; } else { return o; } }; simile-timeline-2.3.0/src/ajax/api/scripts/dom.js0000644000014500017510000002474111154003244021160 0ustar michaelstaff/*================================================== * DOM Utility Functions *================================================== */ SimileAjax.DOM = new Object(); SimileAjax.DOM.registerEventWithObject = function(elmt, eventName, obj, handlerName) { SimileAjax.DOM.registerEvent(elmt, eventName, function(elmt2, evt, target) { return obj[handlerName].call(obj, elmt2, evt, target); }); }; SimileAjax.DOM.registerEvent = function(elmt, eventName, handler) { var handler2 = function(evt) { evt = (evt) ? evt : ((event) ? event : null); if (evt) { var target = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null); if (target) { target = (target.nodeType == 1 || target.nodeType == 9) ? target : target.parentNode; } return handler(elmt, evt, target); } return true; } if (SimileAjax.Platform.browser.isIE) { elmt.attachEvent("on" + eventName, handler2); } else { elmt.addEventListener(eventName, handler2, false); } }; SimileAjax.DOM.getPageCoordinates = function(elmt) { var left = 0; var top = 0; if (elmt.nodeType != 1) { elmt = elmt.parentNode; } var elmt2 = elmt; while (elmt2 != null) { left += elmt2.offsetLeft; top += elmt2.offsetTop; elmt2 = elmt2.offsetParent; } var body = document.body; while (elmt != null && elmt != body) { if ("scrollLeft" in elmt) { left -= elmt.scrollLeft; top -= elmt.scrollTop; } elmt = elmt.parentNode; } return { left: left, top: top }; }; SimileAjax.DOM.getSize = function(elmt) { var w = this.getStyle(elmt,"width"); var h = this.getStyle(elmt,"height"); if (w.indexOf("px") > -1) w = w.replace("px",""); if (h.indexOf("px") > -1) h = h.replace("px",""); return { w: w, h: h } } SimileAjax.DOM.getStyle = function(elmt, styleProp) { if (elmt.currentStyle) { // IE var style = elmt.currentStyle[styleProp]; } else if (window.getComputedStyle) { // standard DOM var style = document.defaultView.getComputedStyle(elmt, null).getPropertyValue(styleProp); } else { var style = ""; } return style; } SimileAjax.DOM.getEventRelativeCoordinates = function(evt, elmt) { if (SimileAjax.Platform.browser.isIE) { if (evt.type == "mousewheel") { var coords = SimileAjax.DOM.getPageCoordinates(elmt); return { x: evt.clientX - coords.left, y: evt.clientY - coords.top }; } else { return { x: evt.offsetX, y: evt.offsetY }; } } else { var coords = SimileAjax.DOM.getPageCoordinates(elmt); if ((evt.type == "DOMMouseScroll") && SimileAjax.Platform.browser.isFirefox && (SimileAjax.Platform.browser.majorVersion == 2)) { // Due to: https://bugzilla.mozilla.org/show_bug.cgi?id=352179 return { x: evt.screenX - coords.left, y: evt.screenY - coords.top }; } else { return { x: evt.pageX - coords.left, y: evt.pageY - coords.top }; } } }; SimileAjax.DOM.getEventPageCoordinates = function(evt) { if (SimileAjax.Platform.browser.isIE) { return { x: evt.clientX + document.body.scrollLeft, y: evt.clientY + document.body.scrollTop }; } else { return { x: evt.pageX, y: evt.pageY }; } }; SimileAjax.DOM.hittest = function(x, y, except) { return SimileAjax.DOM._hittest(document.body, x, y, except); }; SimileAjax.DOM._hittest = function(elmt, x, y, except) { var childNodes = elmt.childNodes; outer: for (var i = 0; i < childNodes.length; i++) { var childNode = childNodes[i]; for (var j = 0; j < except.length; j++) { if (childNode == except[j]) { continue outer; } } if (childNode.offsetWidth == 0 && childNode.offsetHeight == 0) { /* * Sometimes SPAN elements have zero width and height but * they have children like DIVs that cover non-zero areas. */ var hitNode = SimileAjax.DOM._hittest(childNode, x, y, except); if (hitNode != childNode) { return hitNode; } } else { var top = 0; var left = 0; var node = childNode; while (node) { top += node.offsetTop; left += node.offsetLeft; node = node.offsetParent; } if (left <= x && top <= y && (x - left) < childNode.offsetWidth && (y - top) < childNode.offsetHeight) { return SimileAjax.DOM._hittest(childNode, x, y, except); } else if (childNode.nodeType == 1 && childNode.tagName == "TR") { /* * Table row might have cells that span several rows. */ var childNode2 = SimileAjax.DOM._hittest(childNode, x, y, except); if (childNode2 != childNode) { return childNode2; } } } } return elmt; }; SimileAjax.DOM.cancelEvent = function(evt) { evt.returnValue = false; evt.cancelBubble = true; if ("preventDefault" in evt) { evt.preventDefault(); } }; SimileAjax.DOM.appendClassName = function(elmt, className) { var classes = elmt.className.split(" "); for (var i = 0; i < classes.length; i++) { if (classes[i] == className) { return; } } classes.push(className); elmt.className = classes.join(" "); }; SimileAjax.DOM.createInputElement = function(type) { var div = document.createElement("div"); div.innerHTML = ""; return div.firstChild; }; SimileAjax.DOM.createDOMFromTemplate = function(template) { var result = {}; result.elmt = SimileAjax.DOM._createDOMFromTemplate(template, result, null); return result; }; SimileAjax.DOM._createDOMFromTemplate = function(templateNode, result, parentElmt) { if (templateNode == null) { /* var node = doc.createTextNode("--null--"); if (parentElmt != null) { parentElmt.appendChild(node); } return node; */ return null; } else if (typeof templateNode != "object") { var node = document.createTextNode(templateNode); if (parentElmt != null) { parentElmt.appendChild(node); } return node; } else { var elmt = null; if ("tag" in templateNode) { var tag = templateNode.tag; if (parentElmt != null) { if (tag == "tr") { elmt = parentElmt.insertRow(parentElmt.rows.length); } else if (tag == "td") { elmt = parentElmt.insertCell(parentElmt.cells.length); } } if (elmt == null) { elmt = tag == "input" ? SimileAjax.DOM.createInputElement(templateNode.type) : document.createElement(tag); if (parentElmt != null) { parentElmt.appendChild(elmt); } } } else { elmt = templateNode.elmt; if (parentElmt != null) { parentElmt.appendChild(elmt); } } for (var attribute in templateNode) { var value = templateNode[attribute]; if (attribute == "field") { result[value] = elmt; } else if (attribute == "className") { elmt.className = value; } else if (attribute == "id") { elmt.id = value; } else if (attribute == "title") { elmt.title = value; } else if (attribute == "type" && elmt.tagName == "input") { // do nothing } else if (attribute == "style") { for (n in value) { var v = value[n]; if (n == "float") { n = SimileAjax.Platform.browser.isIE ? "styleFloat" : "cssFloat"; } elmt.style[n] = v; } } else if (attribute == "children") { for (var i = 0; i < value.length; i++) { SimileAjax.DOM._createDOMFromTemplate(value[i], result, elmt); } } else if (attribute != "tag" && attribute != "elmt") { elmt.setAttribute(attribute, value); } } return elmt; } } SimileAjax.DOM._cachedParent = null; SimileAjax.DOM.createElementFromString = function(s) { if (SimileAjax.DOM._cachedParent == null) { SimileAjax.DOM._cachedParent = document.createElement("div"); } SimileAjax.DOM._cachedParent.innerHTML = s; return SimileAjax.DOM._cachedParent.firstChild; }; SimileAjax.DOM.createDOMFromString = function(root, s, fieldElmts) { var elmt = typeof root == "string" ? document.createElement(root) : root; elmt.innerHTML = s; var dom = { elmt: elmt }; SimileAjax.DOM._processDOMChildrenConstructedFromString(dom, elmt, fieldElmts != null ? fieldElmts : {} ); return dom; }; SimileAjax.DOM._processDOMConstructedFromString = function(dom, elmt, fieldElmts) { var id = elmt.id; if (id != null && id.length > 0) { elmt.removeAttribute("id"); if (id in fieldElmts) { var parentElmt = elmt.parentNode; parentElmt.insertBefore(fieldElmts[id], elmt); parentElmt.removeChild(elmt); dom[id] = fieldElmts[id]; return; } else { dom[id] = elmt; } } if (elmt.hasChildNodes()) { SimileAjax.DOM._processDOMChildrenConstructedFromString(dom, elmt, fieldElmts); } }; SimileAjax.DOM._processDOMChildrenConstructedFromString = function(dom, elmt, fieldElmts) { var node = elmt.firstChild; while (node != null) { var node2 = node.nextSibling; if (node.nodeType == 1) { SimileAjax.DOM._processDOMConstructedFromString(dom, node, fieldElmts); } node = node2; } }; simile-timeline-2.3.0/src/ajax/api/scripts/graphics.js0000644000014500017510000006074511154003244022205 0ustar michaelstaff/** * @fileOverview Graphics utility functions and constants * @name SimileAjax.Graphics */ SimileAjax.Graphics = new Object(); /** * A boolean value indicating whether PNG translucency is supported on the * user's browser or not. * * @type Boolean */ SimileAjax.Graphics.pngIsTranslucent = (!SimileAjax.Platform.browser.isIE) || (SimileAjax.Platform.browser.majorVersion > 6); if (!SimileAjax.Graphics.pngIsTranslucent) { SimileAjax.includeCssFile(document, SimileAjax.urlPrefix + "styles/graphics-ie6.css"); } /*================================================== * Opacity, translucency *================================================== */ SimileAjax.Graphics._createTranslucentImage1 = function(url, verticalAlign) { var elmt = document.createElement("img"); elmt.setAttribute("src", url); if (verticalAlign != null) { elmt.style.verticalAlign = verticalAlign; } return elmt; }; SimileAjax.Graphics._createTranslucentImage2 = function(url, verticalAlign) { var elmt = document.createElement("img"); elmt.style.width = "1px"; // just so that IE will calculate the size property elmt.style.height = "1px"; elmt.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + url +"', sizingMethod='image')"; elmt.style.verticalAlign = (verticalAlign != null) ? verticalAlign : "middle"; return elmt; }; /** * Creates a DOM element for an img tag using the URL given. This * is a convenience method that automatically includes the necessary CSS to * allow for translucency, even on IE. * * @function * @param {String} url the URL to the image * @param {String} verticalAlign the CSS value for the image's vertical-align * @return {Element} a DOM element containing the img tag */ SimileAjax.Graphics.createTranslucentImage = SimileAjax.Graphics.pngIsTranslucent ? SimileAjax.Graphics._createTranslucentImage1 : SimileAjax.Graphics._createTranslucentImage2; SimileAjax.Graphics._createTranslucentImageHTML1 = function(url, verticalAlign) { return ""; }; SimileAjax.Graphics._createTranslucentImageHTML2 = function(url, verticalAlign) { var style = "width: 1px; height: 1px; " + "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + url +"', sizingMethod='image');" + (verticalAlign != null ? " vertical-align: " + verticalAlign + ";" : ""); return ""; }; /** * Creates an HTML string for an img tag using the URL given. * This is a convenience method that automatically includes the necessary CSS * to allow for translucency, even on IE. * * @function * @param {String} url the URL to the image * @param {String} verticalAlign the CSS value for the image's vertical-align * @return {String} a string containing the img tag */ SimileAjax.Graphics.createTranslucentImageHTML = SimileAjax.Graphics.pngIsTranslucent ? SimileAjax.Graphics._createTranslucentImageHTML1 : SimileAjax.Graphics._createTranslucentImageHTML2; /** * Sets the opacity on the given DOM element. * * @param {Element} elmt the DOM element to set the opacity on * @param {Number} opacity an integer from 0 to 100 specifying the opacity */ SimileAjax.Graphics.setOpacity = function(elmt, opacity) { if (SimileAjax.Platform.browser.isIE) { elmt.style.filter = "progid:DXImageTransform.Microsoft.Alpha(Style=0,Opacity=" + opacity + ")"; } else { var o = (opacity / 100).toString(); elmt.style.opacity = o; elmt.style.MozOpacity = o; } }; /*================================================== * Bubble *================================================== */ SimileAjax.Graphics.bubbleConfig = { containerCSSClass: "simileAjax-bubble-container", innerContainerCSSClass: "simileAjax-bubble-innerContainer", contentContainerCSSClass: "simileAjax-bubble-contentContainer", borderGraphicSize: 50, borderGraphicCSSClassPrefix: "simileAjax-bubble-border-", arrowGraphicTargetOffset: 33, // from tip of arrow to the side of the graphic that touches the content of the bubble arrowGraphicLength: 100, // dimension of arrow graphic along the direction that the arrow points arrowGraphicWidth: 49, // dimension of arrow graphic perpendicular to the direction that the arrow points arrowGraphicCSSClassPrefix: "simileAjax-bubble-arrow-", closeGraphicCSSClass: "simileAjax-bubble-close", extraPadding: 20 }; /** * Creates a nice, rounded bubble popup with the given content in a div, * page coordinates and a suggested width. The bubble will point to the * location on the page as described by pageX and pageY. All measurements * should be given in pixels. * * @param {Element} the content div * @param {Number} pageX the x coordinate of the point to point to * @param {Number} pageY the y coordinate of the point to point to * @param {Number} contentWidth a suggested width of the content * @param {String} orientation a string ("top", "bottom", "left", or "right") * that describes the orientation of the arrow on the bubble * @param {Number} maxHeight. Add a scrollbar div if bubble would be too tall. * Default of 0 or null means no maximum */ SimileAjax.Graphics.createBubbleForContentAndPoint = function( div, pageX, pageY, contentWidth, orientation, maxHeight) { if (typeof contentWidth != "number") { contentWidth = 300; } if (typeof maxHeight != "number") { maxHeight = 0; } div.style.position = "absolute"; div.style.left = "-5000px"; div.style.top = "0px"; div.style.width = contentWidth + "px"; document.body.appendChild(div); window.setTimeout(function() { var width = div.scrollWidth + 10; var height = div.scrollHeight + 10; var scrollDivW = 0; // width of the possible inner container when we want vertical scrolling if (maxHeight > 0 && height > maxHeight) { height = maxHeight; scrollDivW = width - 25; } var bubble = SimileAjax.Graphics.createBubbleForPoint(pageX, pageY, width, height, orientation); document.body.removeChild(div); div.style.position = "static"; div.style.left = ""; div.style.top = ""; // create a scroll div if needed if (scrollDivW > 0) { var scrollDiv = document.createElement("div"); div.style.width = ""; scrollDiv.style.width = scrollDivW + "px"; scrollDiv.appendChild(div); bubble.content.appendChild(scrollDiv); } else { div.style.width = width + "px"; bubble.content.appendChild(div); } }, 200); }; /** * Creates a nice, rounded bubble popup with the given page coordinates and * content dimensions. The bubble will point to the location on the page * as described by pageX and pageY. All measurements should be given in * pixels. * * @param {Number} pageX the x coordinate of the point to point to * @param {Number} pageY the y coordinate of the point to point to * @param {Number} contentWidth the width of the content box in the bubble * @param {Number} contentHeight the height of the content box in the bubble * @param {String} orientation a string ("top", "bottom", "left", or "right") * that describes the orientation of the arrow on the bubble * @return {Element} a DOM element for the newly created bubble */ SimileAjax.Graphics.createBubbleForPoint = function(pageX, pageY, contentWidth, contentHeight, orientation) { contentWidth = parseInt(contentWidth, 10); // harden against bad input bugs contentHeight = parseInt(contentHeight, 10); // getting numbers-as-strings var bubbleConfig = SimileAjax.Graphics.bubbleConfig; var pngTransparencyClassSuffix = SimileAjax.Graphics.pngIsTranslucent ? "pngTranslucent" : "pngNotTranslucent"; var bubbleWidth = contentWidth + 2 * bubbleConfig.borderGraphicSize; var bubbleHeight = contentHeight + 2 * bubbleConfig.borderGraphicSize; var generatePngSensitiveClass = function(className) { return className + " " + className + "-" + pngTransparencyClassSuffix; }; /* * Render container divs */ var div = document.createElement("div"); div.className = generatePngSensitiveClass(bubbleConfig.containerCSSClass); div.style.width = contentWidth + "px"; div.style.height = contentHeight + "px"; var divInnerContainer = document.createElement("div"); divInnerContainer.className = generatePngSensitiveClass(bubbleConfig.innerContainerCSSClass); div.appendChild(divInnerContainer); /* * Create layer for bubble */ var close = function() { if (!bubble._closed) { document.body.removeChild(bubble._div); bubble._doc = null; bubble._div = null; bubble._content = null; bubble._closed = true; } } var bubble = { _closed: false }; var layer = SimileAjax.WindowManager.pushLayer(close, true, div); bubble._div = div; bubble.close = function() { SimileAjax.WindowManager.popLayer(layer); } /* * Render border graphics */ var createBorder = function(classNameSuffix) { var divBorderGraphic = document.createElement("div"); divBorderGraphic.className = generatePngSensitiveClass(bubbleConfig.borderGraphicCSSClassPrefix + classNameSuffix); divInnerContainer.appendChild(divBorderGraphic); }; createBorder("top-left"); createBorder("top-right"); createBorder("bottom-left"); createBorder("bottom-right"); createBorder("left"); createBorder("right"); createBorder("top"); createBorder("bottom"); /* * Render content */ var divContentContainer = document.createElement("div"); divContentContainer.className = generatePngSensitiveClass(bubbleConfig.contentContainerCSSClass); divInnerContainer.appendChild(divContentContainer); bubble.content = divContentContainer; /* * Render close button */ var divClose = document.createElement("div"); divClose.className = generatePngSensitiveClass(bubbleConfig.closeGraphicCSSClass); divInnerContainer.appendChild(divClose); SimileAjax.WindowManager.registerEventWithObject(divClose, "click", bubble, "close"); (function() { var dims = SimileAjax.Graphics.getWindowDimensions(); var docWidth = dims.w; var docHeight = dims.h; var halfArrowGraphicWidth = Math.ceil(bubbleConfig.arrowGraphicWidth / 2); var createArrow = function(classNameSuffix) { var divArrowGraphic = document.createElement("div"); divArrowGraphic.className = generatePngSensitiveClass(bubbleConfig.arrowGraphicCSSClassPrefix + "point-" + classNameSuffix); divInnerContainer.appendChild(divArrowGraphic); return divArrowGraphic; }; if (pageX - halfArrowGraphicWidth - bubbleConfig.borderGraphicSize - bubbleConfig.extraPadding > 0 && pageX + halfArrowGraphicWidth + bubbleConfig.borderGraphicSize + bubbleConfig.extraPadding < docWidth) { /* * Bubble can be positioned above or below the target point. */ var left = pageX - Math.round(contentWidth / 2); left = pageX < (docWidth / 2) ? Math.max(left, bubbleConfig.extraPadding + bubbleConfig.borderGraphicSize) : Math.min(left, docWidth - bubbleConfig.extraPadding - bubbleConfig.borderGraphicSize - contentWidth); if ((orientation && orientation == "top") || (!orientation && (pageY - bubbleConfig.arrowGraphicTargetOffset - contentHeight - bubbleConfig.borderGraphicSize - bubbleConfig.extraPadding > 0))) { /* * Position bubble above the target point. */ var divArrow = createArrow("down"); divArrow.style.left = (pageX - halfArrowGraphicWidth - left) + "px"; div.style.left = left + "px"; div.style.top = (pageY - bubbleConfig.arrowGraphicTargetOffset - contentHeight) + "px"; return; } else if ((orientation && orientation == "bottom") || (!orientation && (pageY + bubbleConfig.arrowGraphicTargetOffset + contentHeight + bubbleConfig.borderGraphicSize + bubbleConfig.extraPadding < docHeight))) { /* * Position bubble below the target point. */ var divArrow = createArrow("up"); divArrow.style.left = (pageX - halfArrowGraphicWidth - left) + "px"; div.style.left = left + "px"; div.style.top = (pageY + bubbleConfig.arrowGraphicTargetOffset) + "px"; return; } } var top = pageY - Math.round(contentHeight / 2); top = pageY < (docHeight / 2) ? Math.max(top, bubbleConfig.extraPadding + bubbleConfig.borderGraphicSize) : Math.min(top, docHeight - bubbleConfig.extraPadding - bubbleConfig.borderGraphicSize - contentHeight); if ((orientation && orientation == "left") || (!orientation && (pageX - bubbleConfig.arrowGraphicTargetOffset - contentWidth - bubbleConfig.borderGraphicSize - bubbleConfig.extraPadding > 0))) { /* * Position bubble left of the target point. */ var divArrow = createArrow("right"); divArrow.style.top = (pageY - halfArrowGraphicWidth - top) + "px"; div.style.top = top + "px"; div.style.left = (pageX - bubbleConfig.arrowGraphicTargetOffset - contentWidth) + "px"; } else { /* * Position bubble right of the target point, as the last resort. */ var divArrow = createArrow("left"); divArrow.style.top = (pageY - halfArrowGraphicWidth - top) + "px"; div.style.top = top + "px"; div.style.left = (pageX + bubbleConfig.arrowGraphicTargetOffset) + "px"; } })(); document.body.appendChild(div); return bubble; }; SimileAjax.Graphics.getWindowDimensions = function() { if (typeof window.innerHeight == 'number') { return { w:window.innerWidth, h:window.innerHeight }; // Non-IE } else if (document.documentElement && document.documentElement.clientHeight) { return { // IE6+, in "standards compliant mode" w:document.documentElement.clientWidth, h:document.documentElement.clientHeight }; } else if (document.body && document.body.clientHeight) { return { // IE 4 compatible w:document.body.clientWidth, h:document.body.clientHeight }; } }; /** * Creates a floating, rounded message bubble in the center of the window for * displaying modal information, e.g. "Loading..." * * @param {Document} doc the root document for the page to render on * @param {Object} an object with two properties, contentDiv and containerDiv, * consisting of the newly created DOM elements */ SimileAjax.Graphics.createMessageBubble = function(doc) { var containerDiv = doc.createElement("div"); if (SimileAjax.Graphics.pngIsTranslucent) { var topDiv = doc.createElement("div"); topDiv.style.height = "33px"; topDiv.style.background = "url(" + SimileAjax.urlPrefix + "images/message-top-left.png) top left no-repeat"; topDiv.style.paddingLeft = "44px"; containerDiv.appendChild(topDiv); var topRightDiv = doc.createElement("div"); topRightDiv.style.height = "33px"; topRightDiv.style.background = "url(" + SimileAjax.urlPrefix + "images/message-top-right.png) top right no-repeat"; topDiv.appendChild(topRightDiv); var middleDiv = doc.createElement("div"); middleDiv.style.background = "url(" + SimileAjax.urlPrefix + "images/message-left.png) top left repeat-y"; middleDiv.style.paddingLeft = "44px"; containerDiv.appendChild(middleDiv); var middleRightDiv = doc.createElement("div"); middleRightDiv.style.background = "url(" + SimileAjax.urlPrefix + "images/message-right.png) top right repeat-y"; middleRightDiv.style.paddingRight = "44px"; middleDiv.appendChild(middleRightDiv); var contentDiv = doc.createElement("div"); middleRightDiv.appendChild(contentDiv); var bottomDiv = doc.createElement("div"); bottomDiv.style.height = "55px"; bottomDiv.style.background = "url(" + SimileAjax.urlPrefix + "images/message-bottom-left.png) bottom left no-repeat"; bottomDiv.style.paddingLeft = "44px"; containerDiv.appendChild(bottomDiv); var bottomRightDiv = doc.createElement("div"); bottomRightDiv.style.height = "55px"; bottomRightDiv.style.background = "url(" + SimileAjax.urlPrefix + "images/message-bottom-right.png) bottom right no-repeat"; bottomDiv.appendChild(bottomRightDiv); } else { containerDiv.style.border = "2px solid #7777AA"; containerDiv.style.padding = "20px"; containerDiv.style.background = "white"; SimileAjax.Graphics.setOpacity(containerDiv, 90); var contentDiv = doc.createElement("div"); containerDiv.appendChild(contentDiv); } return { containerDiv: containerDiv, contentDiv: contentDiv }; }; /*================================================== * Animation *================================================== */ /** * Creates an animation for a function, and an interval of values. The word * "animation" here is used in the sense of repeatedly calling a function with * a current value from within an interval, and a delta value. * * @param {Function} f a function to be called every 50 milliseconds throughout * the animation duration, of the form f(current, delta), where current is * the current value within the range and delta is the current change. * @param {Number} from a starting value * @param {Number} to an ending value * @param {Number} duration the duration of the animation in milliseconds * @param {Function} [cont] an optional function that is called at the end of * the animation, i.e. a continuation. * @return {SimileAjax.Graphics._Animation} a new animation object */ SimileAjax.Graphics.createAnimation = function(f, from, to, duration, cont) { return new SimileAjax.Graphics._Animation(f, from, to, duration, cont); }; SimileAjax.Graphics._Animation = function(f, from, to, duration, cont) { this.f = f; this.cont = (typeof cont == "function") ? cont : function() {}; this.from = from; this.to = to; this.current = from; this.duration = duration; this.start = new Date().getTime(); this.timePassed = 0; }; /** * Runs this animation. */ SimileAjax.Graphics._Animation.prototype.run = function() { var a = this; window.setTimeout(function() { a.step(); }, 50); }; /** * Increments this animation by one step, and then continues the animation with * run(). */ SimileAjax.Graphics._Animation.prototype.step = function() { this.timePassed += 50; var timePassedFraction = this.timePassed / this.duration; var parameterFraction = -Math.cos(timePassedFraction * Math.PI) / 2 + 0.5; var current = parameterFraction * (this.to - this.from) + this.from; try { this.f(current, current - this.current); } catch (e) { } this.current = current; if (this.timePassed < this.duration) { this.run(); } else { this.f(this.to, 0); this["cont"](); } }; /*================================================== * CopyPasteButton * * Adapted from http://spaces.live.com/editorial/rayozzie/demo/liveclip/liveclipsample/techPreview.html. *================================================== */ /** * Creates a button and textarea for displaying structured data and copying it * to the clipboard. The data is dynamically generated by the given * createDataFunction parameter. * * @param {String} image an image URL to use as the background for the * generated box * @param {Number} width the width in pixels of the generated box * @param {Number} height the height in pixels of the generated box * @param {Function} createDataFunction a function that is called with no * arguments to generate the structured data * @return a new DOM element */ SimileAjax.Graphics.createStructuredDataCopyButton = function(image, width, height, createDataFunction) { var div = document.createElement("div"); div.style.position = "relative"; div.style.display = "inline"; div.style.width = width + "px"; div.style.height = height + "px"; div.style.overflow = "hidden"; div.style.margin = "2px"; if (SimileAjax.Graphics.pngIsTranslucent) { div.style.background = "url(" + image + ") no-repeat"; } else { div.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + image +"', sizingMethod='image')"; } var style; if (SimileAjax.Platform.browser.isIE) { style = "filter:alpha(opacity=0)"; } else { style = "opacity: 0"; } div.innerHTML = "