From 6f3e3ce429db7f1858820e5c2ec5242efa7f0d72 Mon Sep 17 00:00:00 2001 From: Steve Wang Date: Tue, 16 Aug 2011 17:11:09 -0700 Subject: [PATCH] Updated jsdocs. --- doc/jsdoc/css/all.css | 366 ----------- doc/jsdoc/css/fonts/mplus-1m-bold-webfont.eot | Bin 18590 -> 0 bytes doc/jsdoc/css/fonts/mplus-1m-bold-webfont.svg | 134 ---- doc/jsdoc/css/fonts/mplus-1m-bold-webfont.ttf | Bin 18428 -> 0 bytes .../css/fonts/mplus-1m-bold-webfont.woff | Bin 11772 -> 0 bytes .../css/fonts/mplus-1m-regular-webfont.eot | Bin 19518 -> 0 bytes .../css/fonts/mplus-1m-regular-webfont.svg | 134 ---- .../css/fonts/mplus-1m-regular-webfont.ttf | Bin 19344 -> 0 bytes .../css/fonts/mplus-1m-regular-webfont.woff | Bin 12304 -> 0 bytes doc/jsdoc/css/handheld.css | 217 ------- doc/jsdoc/css/screen.css | 297 --------- doc/jsdoc/files.html | 98 ++- doc/jsdoc/index.html | 2 +- doc/jsdoc/javascript/all.js | 326 ---------- doc/jsdoc/javascript/html5.js | 6 - doc/jsdoc/symbols/Group#now.html | 2 +- doc/jsdoc/symbols/Group.html | 2 +- doc/jsdoc/symbols/User#now.html | 2 +- doc/jsdoc/symbols/User#user.html | 36 +- doc/jsdoc/symbols/User.html | 2 +- doc/jsdoc/symbols/_global_.html | 354 +++++++++- doc/jsdoc/symbols/nowjs.html | 61 +- .../src/flotype_now_lib_fileServer.js.html | 121 ++++ .../src/flotype_now_lib_function.js.html | 59 ++ .../symbols/src/flotype_now_lib_group.js.html | 607 +++++++++--------- .../src/flotype_now_lib_handlers.js.html | 148 +++++ .../symbols/src/flotype_now_lib_now.js.html | 347 +++++----- .../src/flotype_now_lib_nowUtil.js.html | 172 +++++ .../symbols/src/flotype_now_lib_proxy.js.html | 81 +++ .../src/flotype_now_lib_scopeTable.js.html | 71 ++ .../src/flotype_now_lib_server.js.html | 15 + .../src/flotype_now_lib_support.js.html | 110 ++++ .../symbols/src/flotype_now_lib_user.js.html | 378 +++++------ lib/client/now.js | 61 +- lib/group.js | 9 + 35 files changed, 2058 insertions(+), 2160 deletions(-) delete mode 100644 doc/jsdoc/css/all.css delete mode 100644 doc/jsdoc/css/fonts/mplus-1m-bold-webfont.eot delete mode 100644 doc/jsdoc/css/fonts/mplus-1m-bold-webfont.svg delete mode 100644 doc/jsdoc/css/fonts/mplus-1m-bold-webfont.ttf delete mode 100644 doc/jsdoc/css/fonts/mplus-1m-bold-webfont.woff delete mode 100644 doc/jsdoc/css/fonts/mplus-1m-regular-webfont.eot delete mode 100644 doc/jsdoc/css/fonts/mplus-1m-regular-webfont.svg delete mode 100644 doc/jsdoc/css/fonts/mplus-1m-regular-webfont.ttf delete mode 100644 doc/jsdoc/css/fonts/mplus-1m-regular-webfont.woff delete mode 100644 doc/jsdoc/css/handheld.css delete mode 100644 doc/jsdoc/css/screen.css delete mode 100644 doc/jsdoc/javascript/all.js delete mode 100644 doc/jsdoc/javascript/html5.js create mode 100644 doc/jsdoc/symbols/src/flotype_now_lib_fileServer.js.html create mode 100644 doc/jsdoc/symbols/src/flotype_now_lib_function.js.html create mode 100644 doc/jsdoc/symbols/src/flotype_now_lib_handlers.js.html create mode 100644 doc/jsdoc/symbols/src/flotype_now_lib_nowUtil.js.html create mode 100644 doc/jsdoc/symbols/src/flotype_now_lib_proxy.js.html create mode 100644 doc/jsdoc/symbols/src/flotype_now_lib_scopeTable.js.html create mode 100644 doc/jsdoc/symbols/src/flotype_now_lib_server.js.html create mode 100644 doc/jsdoc/symbols/src/flotype_now_lib_support.js.html diff --git a/doc/jsdoc/css/all.css b/doc/jsdoc/css/all.css deleted file mode 100644 index a0d855e..0000000 --- a/doc/jsdoc/css/all.css +++ /dev/null @@ -1,366 +0,0 @@ -/* TABLE OF CONTENTS: - * - Browser reset - * - HTML elements - * - JsDoc styling - */ - - - - - - -/* - * BEGIN BROWSER RESET - */ - -body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,p,pre,form,fieldset,input,textarea,p,blockquote,th,td { - margin:0; - padding:0 -} -html { - height:100%; - overflow:-moz-scrollbars-vertical; - overflow-x:auto -} -table { - border:0; - border-collapse:collapse; - border-spacing:0 -} -fieldset,img { - border:0 -} -address,caption,cite,code,dfn,em,strong,th,var { - font-style:normal; - font-weight:normal -} -em,cite { - font-style:italic -} -strong { - font-weight:bold -} -ol,ul { - list-style:none -} -caption,th { - text-align:left -} -h1,h2,h3,h4,h5,h6 { - font-size:100%; - font-weight:normal; - margin:0; - padding:0 -} -q:before,q:after { - content:'' -} -abbr,acronym { - border:0 -} -section,article,header,footer,nav,aside,hgroup { - display:block -} - -/* - * END BROWSER RESET - */ - - - - - - -/* - * HTML ELEMENTS - */ - -@font-face { - font-family: 'M1m'; - src: url('fonts/mplus-1m-regular-webfont.eot'); - src: local('☺'), url('fonts/mplus-1m-regular-webfont.woff') format('woff'), url('fonts/mplus-1m-regular-webfont.ttf') format('truetype'), url('fonts/mplus-1m-regular-webfont.svg#webfontVd14f4NN') format('svg'); - font-weight: normal; - font-style: normal; -} - -@font-face { - font-family: 'M1m'; - src: url('fonts/mplus-1m-bold-webfont.eot'); - src: local('☺'), url('fonts/mplus-1m-bold-webfont.woff') format('woff'), url('fonts/mplus-1m-bold-webfont.ttf') format('truetype'), url('fonts/mplus-1m-bold-webfont.svg#webfontIjI5mZqE') format('svg'); - font-weight: bold; - font-style: normal; -} - - - -* { - line-height: 1.4em; -} - -html { - font-size: 100%; -} - -body { - font-size: 0.75em; - padding: 15px 0; - background: #eee; - background-image: -moz-linear-gradient(left, #dddddd, #f9f9f9) fixed; - background-image: -webkit-gradient(linear,left bottom,right bottom,color-stop(0, #dddddd),color-stop(1, #f9f9f9)) fixed; - } - -body, -input, -select, -textarea { - color: #000; - font-family: Arial, Geneva, sans-serif; -} - -a:link, -a:hover, -a:active, -a:visited { - color: #19199e; -} -a:hover, -a:focus { - color: #00f; - text-decoration: none; -} - -p { - margin: 0 0 1.5em 0; -} - -/* - * END HTML ELEMENTS - */ - - - -/* - * BEGIN HACK - */ - -div.containerMain:after, -div.safeBox:after { - content:""; - display:block; - height:0; - clear:both; -} - -/* - * END HACK - */ - - - -/* - * BEGIN JSDOC - */ - -/* Start menu */ -div.index *.heading1 { - margin-bottom: 0.5em; - border-bottom: 1px solid #999999; - font-family: M1m, Arial, sans-serif; - font-size: 1.6em; - letter-spacing: 1px; - line-height: 1.3em; -} - -div.index div.menu { - background-color: #FFFFFF; -} -*+html div.index div.menu { - background-color: #FFFFFF; -} -* html div.index div.menu { - background-color: #FFFFFF; -} - -div.index div.menu div { - text-align: left; -} - -div.index div.menu a { - text-decoration: none; -} -div.index div.menu a:hover { - text-decoration: underline; -} - -div.index ul.classList { - padding-left: 0; -} - -div.index ul.classList a { - display: block; - margin: 1px 0; - padding: 4px 0 2px 10px; - text-indent: -10px; -} - -div.index div.fineprint { - color: #777; - font-size: 0.9em; -} -div.index div.fineprint a { - color: #777; -} -/* End menu */ - - - -/* Start content */ -div.content ul { - padding-left: 0; -} - -div.content *.classTitle { - font-size: 1.2em; - font-weight: bold; - line-height: 1em; -} - -div.content *.classTitle span { - display: block; - font-size: 2em; - letter-spacing: 2px; - line-height: 1em; - padding-top: 5px; - text-shadow: 1px 1px 1px #999999; - word-wrap: break-word; -} - -div.content p.summary { - font-size: 1.25em; -} - -div.content ul *.classname a, -div.content ul *.filename a { - font-family: Consolas, "Courier New", Courier, monospace; - text-decoration: none; - font-weight: bold; -} -div.content ul *.classname a:hover, -div.content ul *.filename a:hover { - text-decoration: underline; -} - -div.content div.props { - -moz-border-radius: 5px; - -webkit-border-radius: 5px; - border-radius: 5px; - background: #fff; - background: -moz-linear-gradient(top, rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0.2)); /* FF3.6 */ - background: -webkit-gradient(linear,left top,left bottom,color-stop(0, rgba(255, 255, 255, 0.7)),color-stop(1, rgba(255, 255, 255, 0.2))); - -moz-box-shadow: 0px 0px 10px #ccc; - -webkit-box-shadow: 0px 0px 5px #bbb; - box-shadow: 0px 0px 5px #bbb; -} - - - -*.sectionTitle { - font-family: M1m, sans-serif; - font-size: 1.6em; - letter-spacing: 1px; -} - -table.summaryTable td, -table.summaryTable th { - vertical-align: top; -} -table.summaryTable tr:last-child td { - padding-bottom: 0; -} - -table.summaryTable th { - font-weight: bold; -} - -table.summaryTable td.attributes { - font-family: Consolas, "Courier New", Courier, monospace; - color: #666; -} - -table.summaryTable td.nameDescription div.fixedFont { - font-weight: bold; -} - -table.summaryTable div.description { - color: #333; -} - - - -dl.detailList dt { - font-weight: bold; -} - -dl.inheritsList dd + dt { - margin-top: 10px; -} - -dl.inheritsList dd { - display: inline; -} - - - -.fixedFont { - font-family: Consolas, "Courier New", Courier, monospace; -} - -.fixedFont.heading { - font-size: 1.25em; - line-height: 1.1em -} - -.fixedFont.heading + .description { - font-size: 1.2em; -} - -.fixedFont.heading .light, -.fixedFont.heading .lighter { - font-weight: bold; -} - -pre.code { - overflow: auto; - font-family: Consolas, "Courier New", Courier, monospace; - background: #eee; -} -/* Start content */ - - - -/* Start general styles */ -.light { - color: #666; -} - -.lighter { - color: #999; -} - -span.break { - font-size: 1px; - line-height: 1px; -} -/* End general styles */ - -ul.desc, ol.desc { - list-style: disc; -} - -ul.desc li, ol.desc li { - margin-left: 20px; -} - -/* - * END JSDOC - */ \ No newline at end of file diff --git a/doc/jsdoc/css/fonts/mplus-1m-bold-webfont.eot b/doc/jsdoc/css/fonts/mplus-1m-bold-webfont.eot deleted file mode 100644 index 6c64f8d71d2dc6a375c4305c90921ec5359d72cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18590 zcmc(Hd3;>emFB&#_WixuOHxU-XtPUFNmZ6);Z5G;-If<@$uSt&@`f#8EGHJh2BHAQ z8pjw&y9uPz?tq6h-ErP4RT3cJ);Q^g&d{B}k5Omb9>z%%20|xc=xipqJm0zRm2J97 z_xyhI$H;#Ba_>F&+;hJ3o%`x5OBwrU31gf|jQ%8-%^^u9NwRVFqBym(*TmR;32w9d z#T~TL_ui}t9=&$z+K!#AVhPs9hH%Etwy`_dJ~oK`Dz=gBUDjPq)8Kzbow*xltClQU+{6ByS#jKm>}Mus zW6bgfuDf^byKCobkKTV0$9TuA-rYL}2LI*pzdFR&{8n7=*o_mmG1I*`-i_nh-9raQ z-}zejuW@`F<-Nb}j_m{Of7$R5V+#-C`iDaUqx<=v@<$n4G>YTI@W9ZH%7?p-;P`Re zf6x9qMh?Dm=BIa}rBSNy{sTMq-}3$M+{M_E7jb_#7Lo@0n>Sj%MB7)E&iaRITe{-K zf+z7O;Z75~8*9i-bS~$=l3rvM9E@Yj*l~T!FR?Z**&Ww={yvDqZsQ5uBRYCjCXrzH zmrR+qTs_D(n>Mkx4HdvG_=AFor3$6d-47Qv&Cw&JDe`J$Lo_7e;^nNN20Nc%BpyE4O*S9 zt*dWnoHjkv)ZCJ7ZOi3nw0CsQ?7C^z>^XDib9XZ3R<2sTrg!bS^&4*9 zxT&vy^QX4la_iRH25uc?PiDB7@N=Lv88M;o29ZQl?7I)(|h~W<)7(SS$bYnwPyO}^ow&x z`V()cJkSztR(Vt6g6hsRt5Va7b$yG|{mEw4)U+p>P`i8kl4^H=hrEyW)~>4}H7Y^hWkUSn(0 zYQ?GUYp3i@ekIYBZB`vki6d0V_wfFNYN}h7PN?Sk z2GZk+@w6x|t+I7}YB%mg`>0s8dj}oh8Lud5&Qvs+tV~ReLkxIm8R~YkQ8&~NxA~gV zi7BJ-bfRy?`pTrr`}@Yxpk?XtbYgtjczS?pLd~Hy)kmgo@S__PY5?u{|5XD}(R5FG z;P%^YYzaLYXhI{#kCNDy52nX$YNEGqcI70l1e+#UH}77sfUkH?hLVUi-F!1@o)}-( zm)?fjrx#RW!_x~O`R;Xn1&rT?+ZPmgf@7m5wyUunRidVNW2i~RS;z&eW?fq)*aivX z-h>gEWQO+aJ*;4+_gl;?XwDRHE+bxTo>Ez^ zXtS^c-p+FqlFe+-XeP_Mswt~UmUl%N8nY;VRqASO3*=2{TYElq=Goww@3eHGq`Y_P z6qVJ(U*%^_Zc)};hWe{go*HArYgtYdWt%EmEzFM-R#`Kl6_Plj5;T)l@uQTkF0_ZE z3=4FR})z+$unw4#S8Ne{q`ISWt?h7 zi)wFCD`YKZy{y`0&1SuP{bIO9b+@QtSqtH!Th?6IRLB!jg)NYoFp0I5)@n?iaK!A` z3Ck1CunRjOdBPKN<2G5W6|oM|n(m2+d+=0LJcV~wmfurVeovh4nW!$`SwrVd-BHO@ zw&=2Qqcv~&1Al6F1q9yNp6^U!$=k#dO55^S(w$i5aa;<{jpi5nkNTUjWM)NMyF*7q z%~<}pIof~`6Apl=}S0QU~#&gRXBw9)RD?SIUB_Q;MF`7 zw1v{`^$qReNP7!!pV5If!JCEZ8*J^?P%skeXrIA%bY>=p^L6#P_U6GY!_#XMEyEo> zGx!%08y1{%?AR|?9#04VDtYsq{_WD>es}0-Ou7G$9J4#W@h6_{PCy~%y!spdGwCg~ z(8U5Q0v-G*r8ZW%OMkp(5QKc4@ zVQASdqeP9{E}JG8mrT_6=x8nI!Wc6vuf>>HVrB>O;$~ik>QV3CV;08xl3qWmJ zbkY6oLvQXBqN{H4s;)_`%6?h3PQp4(gsfG8jCmqVn-`4RT&hc+sBu+e+|`S91FZ|V zmApgR>Q($*1)Rf1t?yE6y4bg^u28tDroN#(`Z%4bs=nb2`h{!L@Te+xX$}(voXm7} zsbNJ`&>uXb_>0~^w4xRr)!N2VP~~uBF7(?blsp%P-bd!}e8_5xq#La1RDJu5NCWQ5 z=eX2T>8nUbpUKwjI=gSI^N1XqbIP}%yKkVhs&al%+7++xH?&kYS5;hCwYsi%aL1Yh zx8Ew=|KnKYu4w90{o5ZoQdc*dd=_V?VcRzd+n!)>3q`mvn02n2v#M#TY{lW0U`oh8 zoGzw^$z+RX2d{4APn#s>U}4w+XIACH3!q~(mw2K>?&!>0e;|)?H-az%Q;0yT$ z=@*C+s!<1DR`p)1wG2Zdk@)T8c>;M`XT%n?!C55W+_uE99B^I1oajvYNJCBHlT zUHqrAN3Y()53q9>J)hJskdhrz*88Os{Zc$PHhNBU3!dG~-sey7Tk&j)sVu8;^SiWA zr)o?`80h2j)9uO7X5Rh&@UUp}lPJ7jl-q8g77RI_5AlK0X3^0!9738C5ZG9(3W7n*jWL27k z-BbCbq(SS+)^T*EgQq!vt@Qm--XUH1s01A%JJSd|^D69&i-lMXqO<}6{)`p_4&W$U zlSu?Xqs}QUi2iZs$Q+ZUt;uO-SPlarbl!2vq?hi7>F`WyVaH{&S~Dq4xIN(-8tz>4 zg!QUu@gS@%x7rv6G1KH2j?50HNepR!uA0kUo@(K8N1(HXr&C_|vPd=0=V+KWXpi={ zw)WF%{Ru}+q$(NkIFd1Jxb)WiXG%YLX8!zVc=a=-Cw`ZzXgIhh`K4(|Y_dQ}knMb| z4nwv!L^-0J1vA-D6EL0!8^e@BX>C)Q)$(rHB|{YjCbQZwF3hO1iCh5V!tleNb^>d@ zFMa(R$B#?B{8RT0Ua3b}Fcthc$Tb9iFOVi_ld##Ei)0$ks(_l_94Q18%h;&F9QseQ zL)7-H7QtY&n-zb7Go_3C5yydQ=~7)V??ISF9Qj}eJ25Ph?IfT2bjoUL@5qxOym+y6 z|GoRB*Vk;UU%hwp;Af@L(JxG{%4C~r$9i^dD^eZN_vayxDz=gpywvYO)X_x!4oA(^ zcvg)}X)Z`2;-Zllse~k|Q7IRBK8u;E6eMGzbg7b3u(;qUQ5}x)nGD%Nq84O>fkN^* z0FL?$Z|AAE`RAT>uGzS6e|}DDZ%<3pjJ`(cHdL-4?b>N_FKl4$;|i1ujvAInWdyqg}}iq-4oyiauPr z=Kj-wuCSIC3!I!+^Exj>aaqCQ@she0tYRz1j%M|tk#01tP8gp+Ude|Vl(a3xPaggC z+oyW}LAv+UsZ*o;)zXa7QFir;AQzx-knc;7ZQ^km|>xD>A2tSMlL}bki`P0Y)^3ftRl3dIm#n@53O2H}twxCm7 zh#p|URap`E28J9e5elYLdQXs=*wTR{K<)QyTmJ0rmCJi)=iB0mRQ0fv_g}Q|mjl22 zb$YD%rUz%F_!FZrZxU-pTV8`cM_DasyMnuHB}8i&T4SwoQ)>`GaJ4S0%2QejU17?p zDOsyRT>&?=dTgsws57&=gH&gSqJ<+=;~H22O$HWIt%_>uQkh@H<)EU5Nui+Bd0nZY zPUPw5!X5z3nuJzC=K%wFLr1e!YHr`Me&@awec9aL%?lQH?P^F?HPqLoq&pYyNDqDf z3x~QMx$mpbEe{^4zVhL$4QukVmaLr%(}1x6Kr8yn!Dc`QNYlvplJ62;+A>8#FPMc# zGD{c-Rh>>1fJy>;*R_7095+<(iiWJ9xb=d`BfHF9UFvH8jayKg%qs=c1y-Aba1gXVnXu(Y_hMR%j1l?u5sm-d6DXj_( zt&)XnG37KFt)=j$%7NCBvZzU=tUpX+kO6drv*8g2+6KPHV#-01t^kuGTO-=2J)bRYl^vKcAAL=~$dD5A&YKhNW zwZ7~4ve{_YY3R!aX%Upf#=5R^3B*Y-!Bt@I>|*OWY=*8 z=oaYrYSi|C;g1k-5zw)b*1_3;bs!v3bK5I3MGRnrBezakH0HYO1(bN<(rNvIMK$A! z1y@XTMVe$2T(Ve&kN-A>SHz;y5&ap^gIhwDP+fZ+e@PG*`}s*ebyhk%`s3q2rnctT z5q_S(CS+MrMqdQHEZ6HsZG%^-!;<4COL)bR;o+a}+EpIAFMq6Uc+dcGpV&5w(KfRi zEim2KHij!Uw2jjhYMTTGfm*`6SXk2?;d#9*XH=m+bjh>azF2VqWtzsSEnavqv&n ztS-0LNA1@C_$Qwh(V7GCvKr`8?KA|L7C@w2V0OThE;XX4A+p~XcQ&tNOT%t=&Xw9{ zq;!nJp{V@TSgaye5jT&es^g(R;OT8!_iWu$`oU>wUhRU~n(DemwQZl8UK^{J7QCr_ ztg-LPL7iWt`1l_o+Z1bt6(~5#uAtWoKEsk0!}U%d>`E9Wrm9KoR*|?{vZ`C4a0-P1 zwPL{bX`N0;%fz1)1Nu=wF4pL5OHEeGq7Tw=Q3dAoQNtR6cB)``g~_SzQUi)+w~-&S zICam9fYpYuR|uv_DY#=My1B})Ro4iJ1Op`JbDbe;I-!tp3WpT3O}eFu7)DZ-F|!3Z7quz%$r-Akg`>BC}?-r`=q;%JW~2?^+=2#I{(dG z1Eud&)ouIqfgLelMMLR>r5XQY)1pnfU9mtXe<|V%7i-c{uVf)T>$E(cp_)`I0qP^G~u2w z^^6BSQ%OAoYg1&-a3zWn?hY0|Dj+6M95hy=_>%$+Gda4rVfxJ=Y6_lkB}Ayjk(kjE zNs_e(tc@D&Qk{w#B*Y+2t2RZAcd3dgA~Xd?#>pf=I4B~ zX0+rKPcW8m&CmPr{aZF|+4g#OzH2pqX!uSEUkQMypb_)D#hXJz7s+F1{tXPm(Yr@i6h=7B~kGjj`w+hTfDuud|9stx3 zoGI%@_2=&C?dj=UzT{NbBIjS3{B{X-aDq=*%?duM1q#>11#ZYk< zkMrFZU+2q9-$F5GMyPEu$o)0QJ<3K6sS|fzM#B_-N2u?~{J5MxLdGKO1F%PDh;#zN zJamEwsM78sfNw{zB2c|RbBsEsOZAiivIs#uU78C9Ml&HC6tEaLjf@2N5T$HMph3K2 z-JnY~oHbNJN5pLYJkNNJ#vANt+|l!)vBXULbsM^PWmV+9lX zh^zsH#fYwoR&GLMtYdogkZFoCAc&%fP6hr&prtvX(FQq_hP)6N;a{51Jw85u{KN@e zWTkg_RG0@tC(f32f|E`VC+y6Lz>bCr_+dc`p)kC=;53nJoD5oku+HS9BNNwSIlbIz za3cyuoG6{2Ej_+(AK$%i-w6NJ$ViE12cV7Ut0z#V%;p-{$BDj@Ne_KALX@oP5z0{T zh*;6%Lr?f=m^vxowsxsLGUt%E5(J!VXeTc~;3N096$-%kU& z$A?9+O{xxAbxywU*UfK#Uq9=XRW_+P9d<$lPK2<`=7ihk##Rqu9d6MQvg3L;ftd`X zCnb;;N56Rb%qgR%-r!B8XG)mJKyurR6^&mDc?!yw2@ZoueXd%Gzn}qB;AZL*PArKH zGNW-r1N80JOJ9XZzJifS?}EC)Utd5Zf86joUR@I4{zdq%b1r0~d>9sBuQel7pZvye z{#+nZ2e6rQQZxH56K0#YRzGb))=99{TqYpIzDW?&=`wK3x9Nyd`Ua5E5vk@NDu=up zPb0S`Bm%!iin~s#AFP)icxIL~>#1Y>S0xgN8+kndPQmLCj(!>KaIppdX1tX3mIet% z2&7RS9-56PBMWi`OfwU!&8))Y8zs|_`Hpn_u_Mw$4-<)i@@DW?Q6BPphJCj|a%=U- zl!8*7or7B~%g%=~ePUFKL=b^S9~!Ay7@VewG96s-H6Daf0E;%spxeSSau%{b*C7LF z$e;UQXy}8X!tR!q-7V5vUn_0<+SmA3O09c&)84%$Oobt=&O{7L{Pj9L+oM}O4CA85 zrjVr*)zaM#qBqr?Q)S)rkg*V+hn%=acpiy*!YM+1-RHnp3s>DKh8lEL_?*?dK{3z`KyMHF?6%32U2gJCY11l?jHKR_Hy6m^BFfQ!(a9#~`(=r{{{4?XGk zpcz&qX_22O_+)~3t!+pHg=E4Nku=elACv8thFRuEe3`ntu8a5wrK>BY@a~Savpz0q zY76PwPX)e+v&Rf(*6M);q0|p0af|MtO@YAO)EER3U=H9EMOY>T%*Di^-4sUurcXUzT%2dnVb(@FNXhRweAr4>6Vi2q) z+01KPB?x96dz4v9K%5&`N`o38fs$9_-Nzr{XQf?Nz9j7$0rbH8b9DLoF@ouGNy3TWn-#YVR=;ErFmfv(2X$FW<(q?KEW`#Gi>?om$sdVuZxd6_uUWU zH)F?~IXhsG-1m!eeL^3pT}j;^hy<_7VZe0)0lGvElMHJoWxh=Lz?Ch>pFI8K$t}au zzAN?c2VX?}%kS~AKV=06VGeh`;Dv}(tL_V+$A&$#A|M0Rkp*L7xPy7${ZPceA2<6i zOwQ3yThy|fP{>XE-?#(KM;tb=l})EjndXI&)LQ|kK>x@|P;;IZ-obZI^Pi-o)R&qc zJjb6aEtRUS)KiWZJ$~KKd64NBQK@Rl3$hFIKR6|1;oX?#CKSgIF~VEY>k(YxU%-_A zy|nz1`;R`pTw4Ccqxb(2pW^1y;{dtd(g*wi-+hDZ9I(WKQx?-a#LIzctzu}1PPY)c z=dk`j_tY*C!%H6_ost!N^I{-jnPsp51FpvjiNcgqAG7BW~0w#j*NCUjbAAIk<(r2X|5^$OqD-@6R zjUvDK1aeb0U^Uf}ElOrKjdEVuqE+k(PR%0b|Ikz#TaNOr$b->@AUeTvxnM=CCqwp6rK34!K2$)70SdrYN1hYZ$eK-8i zTZJdkX)ulXF9TKrHVURobeo{O%55UeM9}|x>5jV}DL!(y^l<4IKVLF<^G3Aq)vIR_ z`NxU5qX`L^Ic01__Eb-}MqtV?6XMyvKE0ne^PfR3)A5|1tHpEZzH%=>?l>~iqg43j zbAzL%=^|OH$GqnyKdV44;`4fBsk@34sVdDgL3%}H6n|B~N&2hYi2I6uQ8SU8@J(qo zFpo7drW9gINv>=xjl3JBDQXZAYpen;uNL%;3A{5HE<^#t)l@v%bvBl61u;^f5SI$$sWWU{_s&lE+I1We{Bn!rJ18Q>J)AceSXBcrot zFIsx=@aV|GMRWMmr=O}CjveLRqp@MZi%@({IGtp+UH6iD3ND0dQ0P~1Q(d4RLS{%i z_@NPgStMOabb@mwnMFX=6ijX%@`X71UINlnD-_kyrMfXI2=q;BTN0grBZG%nlw$Ka zBt8D}{gM>#O!scxvVLKkbgcA`nRIXO>YnB_r1roH9w<#;wG48jzSe!aAN7tR{?b_! zV(QCGQo%#jCR%~{?H*u1L8F0I2ne592>1x+1~9ckpjTf2mA6{-^fBJ**NAO`d!`Up zmuNf4CM9UA%M)C+e#|6gdl0hE~Z_$f)`d(j(y=oI(PGCLAH}T?h!69Z(R;+jE6rfT|rt zm`@#m3?}4E@qG4QwTo9S?ri^ZQwsXBV#NdZ9(w?ztYrIjY$Um;_r0E;qog%t z`zbCX9!Ft|bPECg#+cRW7n~DCVq8RGG{2M#0-Jmf)PW97jP8? zVc(f8y3DMG%)D1jvYU@!*$IL*dKKIs{EjUFI--$>J3=r5kft~ca0YV^V zrb&&%?+=zvj1Bglmh7eNd-w9(e;*q|i7U|WL#U5}85rP2g;x+vQGs@QGo|l-Jp5s3;l5iN zG7Ubr6g(Z|+TJT~En1nAhq%L85tp7um5e?jKFC?dZh&nC8`&Z!M8s8B8Nd+-1S$yp z6KNbxQACJh3#1!}<5D{LrRSgj>gSIgdqA>(So+`+URk>Jhlb6i`5ZocPIJw22w<&; zCE+RVkk|y{mOP-_Ynxr@`$QTgg5@H7$`@v27_m zQTtQ}#uBwo_*pMm3ivF&Q8cK~ASVqbw1QX!g~)v*qLG*og9_n=@EN4K<;tPn#<+rS zXzN{Lj4XRk?~MaX5;=w`$eQNZqF0HbC6*MSqduqv=cH#AD1Snn6GoLm$@&v=q9fNq zB?YS~R8jkCYx`;?|CP7)E}UGraFT2X`J7sCI^=UI@g+z>rZNaxn5oI6nglH{(NTCx zodnh_VW10;T!b#bIS6ziQG5xhL&Gf?+x)Sc`*)qSVV_-o|i$xRmQ zRCl;|Ob-%u$1D!R%Tu1o9f55}oGI!qqt7PnQmBGVI_O>(>Mo}G($p(*_DGL<{5XxV zLO4XYBi)Xtl^g8${N^R(=5_OZ?8~~N?c0jSg8$wBeD)hII=?54dxsUe*iDQU;0WYo2kpq-nMGb9&pD)e>zkoFL_1OssQ^kx- zF*Vaibrv)AZeVSQV&R*l_`#lIbyCd(J%{5`!{8_g{onDOr6+(JK<-mpbl%Pm1T*Ib z?uLe>&fU;Q35dpN-VNm_C@no9Ssfl>=srg2U>Xj*HD$|5YKtE}a^&%Dsr!pZjy%TK zJYV{#^idHJGD2R;Bi15jx8oDpn{||;+VbE%R5K)p+4*oQ#I?-+mw&$72-#Ir3sIkD zFHK#MHLLeBQ>`FdXx5uhYrzu~OHl6tS_|4Crc$VLKrRr@?^aRSEj}^ux zybJgq;^M?NKoZ#iBQZ<9gz7M3_#ap5e2-J6uLCUJ%c>cC59Y)fd{22#Q~`*E=u4gM z3Gl${{J`t4mrlISpBx%0y&(+^am+}dIB_F?4(P0oeVPFP7416T6UY{W`d&@8SY~Q zW+}RI?*3(!TbFNqY);2*9djPrxO{8nvi);c3faDhzMWa-I2c@zPBCF9fQ_LML8Od9 zk6_@wc=)2(`uh*{ewhuqoG;6zDqD=}(g4-Z{V{#8O$@yyas19VKd403;{#6_PjS!b>o2#Ry&JVgn_*I9vMqm(9A6+m-XXC$NDB5m&`-LvEh9ydvxQpZFn zVOo*qru2}`z=mm>;xz_VpTki8kO9s^=VR|57#kZqj%DC}otJ%V>-??5!&vbl(T4w* zZxsH2J)6UK73alw6_N7HKHad;^ga=K(6l~G=@TDQkUx1J%piS-@$cR5otQsJSU84ruNmKM zRuKcOGR%X}zuT0c1cq}Y>qcZRmOpxSY_RkJR`gn$-zeTwjiagS@A-u9Kg&F|$dlmf z&L+I#6qf5>cTydfa<2*B8_5k!x%zePr7imqTN_iPCEUyC9{4TO52OpY*2;f{A4#y% zY-WrzEaoSV25a8j>YM#*R%3bxXFmR00hX&3rXS$TL=OKW(N+B6In$=A75Khi+;94U zc$0ojUmxcCkO87wS7AYkSk7SS!4kyMiN%SvdhhGRNU_fXk%p58-c z(K*_d-&?K|y_Xicm$pJLnv}llEy_e!g5L)s5;y@29$~F!t$~P$c3Ps|DPT=N$5 znE3@ut7WIFsAGDvff8?lg>~@Bo1?Nv(eXb{5@3>R$jqVrR zA9$KPyFIUXe&Jo`9rwQOOZgs>C3#T(qWnYoSIRc!QRTc}^3U+!?mz9n;Qvh^7&sny zJ6Ina3;rlHJ@l2(o8kKK{_yGW8<9nk@yLtOis)$cxmY5$KlZKIg^KQq&sMxp@nPle z$_FcdRn>xjC#%l>fq$=7{VXoUE8;Wb3*tND8(~vOt z0ULa8t^dA-9g!#Y%nsbS2#dZ?V~Xa7(|HN|D~){I+faA<8J2_Bu3rDym4EMtT82=YeZXuZ&?owlmu9?4 z|B06ksNEi%Ph5L*f*rzFP;_P&N*u;=0LKTh9mKh9XjKA7yKzjl*K3nN{qMy4_u$?G zxUvt|mSB7R={shtRVT^m7dIuS9>u5hvB47qCf6qY{a~|sk%3gpTScHD)K`WNBW$2R?(1=y&sWs@Owdkky=%JhO z<2ajGAL|GA|0%YG-GWGVE4z&ifbKcPO^6vR+{$g-&K=yzUEIw*+{=AjM)q!keT#jY z71=l0UvP!{*>T&ahxfF$&Tlogi)fo`Z57AZwi(AcW1Ba&GmLG!vF$LnoyK;ivF$Rp z^Yv|;@!mG$y}2I!d^=`=KF6;Mx?W_(2e diff --git a/doc/jsdoc/css/fonts/mplus-1m-bold-webfont.svg b/doc/jsdoc/css/fonts/mplus-1m-bold-webfont.svg deleted file mode 100644 index 5129512..0000000 --- a/doc/jsdoc/css/fonts/mplus-1m-bold-webfont.svg +++ /dev/null @@ -1,134 +0,0 @@ - - - - -This is a custom SVG webfont generated by Font Squirrel. -Foundry URL : http://mplus-fonts.sourceforge.jp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/doc/jsdoc/css/fonts/mplus-1m-bold-webfont.ttf b/doc/jsdoc/css/fonts/mplus-1m-bold-webfont.ttf deleted file mode 100644 index 0cf54cbbef86edd4a4ed0f9749baa373503e6854..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18428 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%0AC(?{gh&L` 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.{ zVmBk|B^IAJF{~8BLODUdfvJbn3D3ctPSqn^qeZHSb#c@ot^xZ7t>3<-GrFLCU+;>h zmd3`GrWL*W+80DSd9xHc>th9T3vd2?f{9|x8>Jw8_FutgcQTk~T6qo5Xwqhq?HK}&IN=nM z!P8)UIOQIkB8x@&EH3<9pq*#{#MdH(ZKzLUEn??_C2i@p*~VU)y)T`s%hQh-i!$dN z!I!QgD^v&rcw=H0eX=Jk784hJx@4WXVjw84ne!AS5MO5nj*U{9SXBVcVV#kTc8j#V zn{>~TD|p-_aY`K%p@d~cnw!!?Is+S~Ws27sSbYsc`9lUc51o&FU~qhV`~#M$G5hs7#zAB9HY|+9E8Ps=oQ~t*h{-Ke zZq_^2>rWF2})o%N3w22_G0^k=f;Oh@8gGxrS*-XoNAm+ z-zeu}zW*%q)FMxUuREJi#A$3dzV4(pF6UkozBiH^m~!oF+)I1*0robgNXxjF(KGN{ zrXNTbaj%vC68}hol~yxjo?$aTbu3u(<88jVzhX6}w{hj8|5kwIT7~Hc_%e~h|44Kf ze|XQd~FSZJ7 zIc#ItwqknDxOp*z`^BrtdHq}Y8r*>@Re~59*;=H_v#bf^! z8xdi&?Zoypwr24TwVAeZTd-aR^Fgnt8Y914Jd5{n4E;jvssFc&J<0d;A4w0HHkl5Y z9y1k9|6op-=bH!2T^BmdfT0HZ+5@ve&5sN+2eV|^Kk0}@Yl7E)} zPX8JIMgOk@!N7^YTfzF^c<@J|nV~O-ejKh39}J%fzY$pynTUKRS`i(KJ|9cO4#vJ2 zyI9d(@#%^eD?X^)Q~6NkFRNPc->Ir|zvsVKt9}}n;uZ1P@kQ}n@rn4C#D8B!&uJbV zVJ%n%6NOcxe@{cg+6V0Ly|w=DTi6kK;>hg4lS{Da$26yCeK=j0aJ>jM%-ph6)NwxW@4a|89n}hY=^N__{z`B957hwdJU>thT zi{)$u#$**VVhu)W9Y$$A#%Uu)=vKCwZDD<^AKd>Z*Z{i?k?b~h2O9+4bDEnFGg!El z+qj)OxRblMn|rvI`?!qk-6Z=a`xYy*Z?He(3iq=Uwoi`iZEaoHYV4QLKG)hR&arPZ z&U3~-Z|r9o`*vgBVeC7N{cL03W$YK~`!=K8Hly5JkAA%!t3aRU*B(^)=h-UN-rJ{f sezITdp??!ZmGKXX1UKN|GyQS=10Dl?$dM+Ns;0~mu3Geiel?i+S6FInOaK4? diff --git a/doc/jsdoc/css/fonts/mplus-1m-bold-webfont.woff b/doc/jsdoc/css/fonts/mplus-1m-bold-webfont.woff deleted file mode 100644 index f90475d890f59f3dc11bd651aac3859e148d3499..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11772 zcmY*bHn}h<zL%07-#XlSi(_pLpD^Xu=rplCF1*U-g@5C8x<{nmc|2e3l$ zHWNEjYXAWBdnUlT?>1w^M*31yeaG)yu)*&>aQ_2P0HmpvyUDjU3jmOA0svg{a|uCl zX2$wP003p>cORB-u-&EgxSD;7-`egs$NvT?WB{nInYEJ}06_Ik0Sn*b+?9E`tnY5&XR{|`Fj9qw-HhI)E>Mt}fAwR@9*Q&jxr6@3eg3ho{3 zCQ|(Mk+aX5e0vcFU%e3f$-FS1@!DKULMCD zM3fDp6-AVsurH_@aO#Av%I1O~OJ{@so7V>@K%|eXz-SLGL1~Vq!RZbzLS~Gn!s-k! zLu-wv!{ZGqL}G}l#Ow$wMQw?r#pMYpMq!Gf#_ozJM{i4@%lGBio3|S`TYD2WT6UVY z+WH(M46!f3nw1?>HxPA!e*8S3khY0zxpuG7oqCEbUa;$BQ z)y&46;c7=j%$EjXW>FQ*zmWT@$b&b=0NUZjsuG^Oq>^t;*iN5GXGxisx!c7q_k!lv zYLTSlE)bzsB_|;Cpb$Fvo;I9GN+>9Bm5NbtkTg_KmeaMKk5ZmDA&Aj7VSc(*zsleK zkd>iqY5})<(nM)PE0nx#>?OVuy2_K0Ap8?tzw;jFxHK*x3sIm=9ux88JP>25gaeWsM02lz|>k9ztwm#(P z>4dwKe$v&_Uh%r6@?j&frRaKY+)|X%LB<-rvzl@Xsx>^k8dF!txH_1^fUc3GCscqL zq@jNi=LTiOlmkXkzm2E3^mj7EXn*O~nlbrE2Ns8h%<}D+zfK4|5h+b(Dzwe@)0Wm! zf@#7UkLf3-w3>>V^VW!K&&c(gw^~p<3y~AAXO6fq8G9m3KB<~BN7zn0^P*SsKWYn( zJBal1Uq<`>ZwOOK=G9cUwk46r;@1HMIm=uT9&9o?eBKW#kMB)y^Hw-SQCWeH?DZ3! z9|DT@dT;fCL3nL2o2W8eCUA;n6-?&-%jWtKm;5LWlwf{>eTo_ zC0D*^y;a5&$!Bj|>O;|TxPV&uf=RZ=% z+tD!1?ucE}9+ikiSYHNzUU_qg9k(>!N5R28&XsC4Z#wijU+Y)dGvRz9o^heu_Jm$? zT|`Th-XG}N(NcMT$azmlf`#mNf8x9{KcY|03JH=z{Cd_>oSUmaK~MzzNe}@2!)Pyq zHI_bk8?#4)Dg8(Ed8F)&Ab^#^lb~)R>%tfzrDj!&D? z3xoWGK?yf>1FW`+qMhcT%8O>}7k+ML1v&-rJO7|NT3I}u#;IaH=9W))&mi)TlIGKX zyW4b}LPfEPyKT|q(+(?v&1wB-0<~Bo7ItNu^FHRS?NpB6vzN}6nWYAAjD2rORlpML z5L5m$=OWh~4iPhh0^DU~Iu_5ZvR6(k$HJZJ&+~&`8_3hHQDbWKG1JRa1OZ7MDfu*Gum=vhO8O`$} z?Pg005)`aT|JE;7Tz8?2x~|qq8RUb3H47Io9X4OrorkJ>k#J;;@Bjk46Zr8$08P}{ zo-LdiXmLToQ2piGe-N~H4Jj;l`RV_~Fg-<#0QXL;K-HM7dEC+`AE3m5+L zpQ2}!e}I}*U5K=`vSz@MS$?(Ii3^NDImKB~Lfhx_!sXt0h95l*lVUX~1{Ttn@?4U5 z#jC#D`)*8ci_INu*6o%XN^2Br^s)~Kt})ea&wFTv*#ljIY~b@U^z|%mK^xEzoaJWi zy{G2+AU>GfDN6Q7RCE--+qvnGGB8T@T477zUd3V1(%%F$0&*#tepAV+P2WS0paaF= zeBiSj`E)oK8F?A|=6CR3=-y+!V|9F!@QE-!N8A09vL2i%``VT1qhfV-CqS;R2(K4T z&gk6Oh2Rp{%MbA0cPGe^p@g!%JNWR{1X8>BnEH3Tfe0J!Js;>6z=nIminOldLck`- zrCCgtbA1MNfUVD7e=zK->f>wdsU>cq6)A4AAJ|Jr)C^z?AI;1ks)Yh}L#Oqv6uMC- zl*k++6Qaj-*4!ju*)cQVw>FE^nPt;;>>SYLr4aiR=`~&UhB>u&#!WnkB~dOh0>+RH z)erQila0mCfRxU?9L9lK-ffU}!~4c5@C9JbfFM*cu6F6hCnjh zLtol1ySg@RYhQ}~a4shyyl9_+W&QNDe35GUx}E=bL_fDE)pX*UYJTc=`gxCWQoNUh zc;~E%5L!s6mApxHtYM#rm<%|0*)?iYjG2@c@fkrF%ZtEGq@-F61`VOnhaybk@(C*? z>&>`s=y`rUB*iHpc)Rbmyqv{og?W{Uvjp4c5z8o(*)+|>PclyulJV_Rq&YVVg01x_ zK^4B7%w#-WJev(fle}jdCV|m~YqN6e?F#Lq?Qa3V6@ZzdoP8@Y;jzC^-Xbmy;uj_)jv&26X?T;{q=tm`xg0QkC zxRbCMdhnw#B1#f3LnVm!<#A)a7(pUXMokOS<4D(x;)f+M;KDqn$CM%S!rb@y2}Xbe za4$L6<(O?3X0lvuH$6`6?Cq~-_2krcnq^(s;i~%|cb>*bx=-DndiOIohL82M*rDS_ zB!c%MC|eC;07?K>j>wXMTZGUBZ0xW-%CsNCrRV_bT|de^N;i1=bkMj2Z3gH3+9R?r z$5?swHn9-G6ZVg*KY6W1#Bc9q)o8)FZI@}10P?fo@+SKeRI0y2;-NVzB=?JhH9Ne_ z_pTRp%%;;(b5c#+b&L)l*r>e5oTE=%44)kCQOZB4Qo2z@Uxopf3^LGftz}ajn=AVq zva~_6jPdOK%uAS0=gI16uzWD6Vdf-n%RoFCBrvdHXpx!Zws{a7xZr1dDrb2pbk_{N9g?ampNAT9elX~;Y3``koV20qW z`ppAvl%R&>5$sWhE@vhzAtW{s^m-NyszP({+v zYIp)Eoj1F^l<1-0KkT%~mf(IVHOZ0p{s?&``FBIBLxq*xfr2$0Zo&=>sbS3wlw63? zVrfb6A+HN$uY-ZEJ~k(F>tYxG)Gt$;Y8F%)6`t3BjM{}5wxcuUMkPc*7Nr4a@s%n&v~E!dMIAo z=3UIBnS4>HX4hEEWI#i$awE&<&tuoGsba5kA7C|P>l4mo!PhJbDDSgk>@s)gvr^EA zYP2~=ltwZF{0h(neVxY@-jX=gPVA*ehmh0&f(UprQ2tZ00VS$t6iKsu^QCmoU$)xu z*vXIHaB!|Nx6w(((&(n=`gOY&DpkrG`HMNn;J##oEtO)0Ccr%#+{%**)Zj8k!1Xuz1~onKg?h$=p`E{6|V*;LjH1UM9%O#}m}=ql|OaOvemH z703{h;Wm&#*40z@Ube^zKbthA-3XiN9h|%-5>@VmS?A-uOV?T%D`-5!yDeXD)ES^M z)Zuue70QeXAAh)Qm%S=?96Tg<{9bsF+$u|YfwU@E*2w)h5%phfj@VY2n9=y=PqtS) zS#8{s($mR_i=#Srik-nW^if8S`0nA8b-hA*u;2eKR%sTOAaX%?f@N@Vu-t9Gd^TKk zyYy}9({MgW922YBI6E0Y&9640xE1!GA2c0>Aog;zw8{v`S9X?l_X{;eP3=?->6z0o z3;=_w&S!l+gLC1?^vr;rx#2 zXGDW2O9qf;qqY9}L*%OnuOS?$YK?9s<+wdLfNg}z!RQL0ScWz$rHoM9bx<@WDaw>Z z!>hhPkH!Otw+*bURy8Xp53Vr7HXtg-`*8 zffY<{tK;~1j20-=6wCXu%0pn=-eI~#E0x;VTA`sDAH-|6yAEvo;W|$0(fqu_^=dNUZKIc3s@WsWlWznLa|Zb! zbQDGrdj0P3c`aNx)#N7!Jlza~i7$r&bAZ7EIOh=1{*NFx5Ft~@>x=| zFtE7k&rFiq{=bF2YgN?3a5-+Jx1X#jy$^%$m+&!^1xBFdU}dM;yG+oYF-P#(C(PnM zP=v1;!Z?1R9j1Zm|0rfAlyw6%>m^_9egr9-{mT_L;!GrIhH%E8F0iDE9IezkpKe32eBkWgQBdOJG5m>i zHi+H&4*;%;U)NQD2q1_92w02BiRtt?8sBJ2yocKGw7Gv^1Za85gjDkC7^NpO-aG)@ z6jY!Sy*QC?Hq+>Dj0DOlV3{7pbm%fApwBc;Av!vkBoMXTv#YB<$ebK)e!NL6-rl5< zIU6Hj58rczSjJwB93T)f9h>V0&_mEu@Ml0q?t&_x-P@ahC7{Lp<;)-fUI}=!@gGx$ z)mVA-_N67*a3SxJ)_;g>J(A`LIPE?rPoT4lK6ZDx%Uu@wezf(8wA4e2O>^HtKkY;> zKRV5a_OOFXlG@o)#45CkN=b;+cLGa>;&fEds5q^xjzv(wsR`pmh_Ydr0)!`=0+}=p zrO^*n4!`Q1#txO_WOBGEg;n1uqaC00&ITu%W#ujG`>#OcF5EU<&@ZO*E+e!A*IL72 zJ^zT?ypt=$PlWrN2w=`J9t3TlO*EY#;1xh3;9(c{VB=M}58>)p<%IIG)(`eW+Dx|8 z4gh3jW^j0`;m`OI%<)AW@tIFF{$Tl z0^X$O6+_Fiz7>TS1xbLaUBB3otXwebIA!4%{2}&&dJh zxu~jHdi1%pyq{>=4s1N%?OR6#SEW$(icQ!MX%cheVK}IeTbf&VF&T&nsq54;BmUQV zIT|RiIYNRskZgCStUHJc^}QYrvy1$^+{acNNDF~;pZkeo_!ePuSF0c8kY~0dhptDN zsyu8|D?S6CTD!Hq?0e?~C#;n4+;>7?aM&T}VD2vgoAvQX`vsAj+v=H&2MoilCLzJ6 zR4Aodq^U>I2iR(8n0aT9{$eQsXjIhP9SEg;DCtO|9u?BSJKhM2^cGz{uU{~;eenD+o zlA(NJMNx|J%BY%}( z0qZ02H+uWYezA7_qoaC9;5EIvw`1<)IV3tkHYp@+Zu!P)yhcM5Y#yPd$>=;~S^?z< zk;N-0Zc^wyl~Px{Xi?f`UqmA5i^th1=*OsvEHLJz2y1tcbXqu0obeEfCZ)2cCeV=t zN#TsW#VTW^<8S_@?G?^?r{Riq=oPoalQ+)l{Ps)LpTsT_*Y4kG>TTBEB`3R=T%z@( zdjrD154i89&>`a6CR$o0OQU(LcJsG;6*brBV15*0>#(_F6CZzC>KeU?iJjkGpga{z zRbfWp_c4y7OFEnWO?NIS0m&K3GhVpfqk_-oAUpt^pvD+*1Tud-<9N!E+sg4C@jBsV z>F#tzV(h>ojCp1~;q1PK-AP8e^`02d8t_Pj0&F;!6~nGIp>#GlU;5WDWG`{`L#vyF zxS!v%TtE(I#D_#)YN>s!B#{T6RzA{+se0VSrV${edftd;d~KcHb~1j`*i1Yy{^PO4F;pM&E)NFpdLmlbiH!UlC z#P!qmy#)0L!cQaN!f-Q~ro3B>W}lAqH^cUtGZubIvU93g<-~mi_Xz&5dUHRsZNpK-jtzuYzD&ceO@ZQ8Xt+xghT#-Uw*Xv49zx(LDEc>3I|t^;n*7@8}&XL_^zhE(9=%O%%-EX zIQ$%SQp07j$82C7-7i4k{@RL|6u6DFOam?={897#1%a@l0@9Rwo+#4-{0eAm2lN{q zS`4@#_YNuWYumFWGbx(uT=f>{L>dVpMAfdjda$Zi+ijjdwIrEbvYM?ivB!@AmEA2@ zx2UnXqb`VwBk2oQ3zn4}pG=hsaWojb_yf8_GbVS2cq^eRsY0V;w^PpgPB94g-BfvS zTSgJ$PWGUXD8zu$${((Mr>g}b)VAKIr>mzC$&qJ~rakK{32Aws;e${oA}F0#ghnp0 zVF?9b7&*NfqJcK8<00&3 zub>>mEHt0m5Qq*6+K)p&d0zk84<{5~%wA<@s?q3CSny37hla4hxtI!A#MTt%ufK0B z`)yinb%Qx90DG=#)lrT9T9cRW8-jGHO3a=$n6m)tiSU`J^8x!|aU+5?{z!1Y<3(OD zHQ_Vxc{fo?Y6S~EH0$z0mzs(DRgUPFy8XMSv{VUv4##yH);lQ7nRw{$bW;xn+U0ot z?aMe_^vv@^H*Tz=JzL5y!brCRHxZx>gH`DrsQBb}!LM(k`e0i3MsF~vh!7ft+F_Zu zB{_n2`s0odK#;=p@<8c+uh^%!XBYXV;7iRLfH9Yfys=sLnCCV9soG07m7NXWy8OR z`Wd64qS4o`X1m(p*uYTt#9pP@Q?d9}Tn%?R(e50}=dy2KTc7cIK4|7~G}{pvh+4)v zxQ|U|@2yM84R%<#T)nKvgIdUq>ZpMLoNJIe@WhVmOs&f*(F(S?f@qani1(MBx7q`n z@O?=MAJn@7YkA%pvDhh1Z|ZWj@kBg|>f8`{?eQw#7^1`=FE{yxm3O6;@E=f(zJEQ1!W~Rh(cKd(RRRmX^tw?F zm$nH9J_Bu}Sc#I(Mq7eEXf|}!_j~_sWs(qxs^YFM#h*jDX*^q{WkA++H92?-;FQq0 z3MF(w31tjGwpm|5)K(P~&^s_||BQv-jRXDX@F`K({4)SmS!fO6u=O6r`yg4Z``;QW z1-|Jtq9s8mP-fZXqw2_!-a&hd>ztFLwwf6{2kYJv4Y4oX-HQ(4kG`yRmiUiPzyiWA zq)B#H=dJtR3dX;!wM_ZA38_1BzIJiv88`@hpqb;uPh;-3`$3f~LFCDPfpglG9`4x_ zaWGj2h|{|+%ND{(I`{1e`{V|s5cTK_HDYd@D^3P=>_Cmobnx6@Psk}GQd^~XGo=Jn z4D+s7TX?~bM*4_4V#Gm4j8q%&P!F@zvlHN(&1gYe zcSs6@l+r3NH#D_cn(B9(S`ez!e%BdfsJm4pKl#^vA4Zz7HQF&qu_9{%#1G;XZ?sBq zY3+uYesWmhQ>K%GxXR}`Snh$*&r+~h*8J#)(_OOzlLr*ukGa^LTG*Yp8=S9mJlVD+dJ-bp%HrYA zS8T>(jts)hHqq9+91Ja3rk*%%UX*(euIrBrZ<<2y5j03?XwR^J@$y`t#O&}Hg28s; zqS7go_ULE>a>G-7rb0*}#CnlsdXcfmL{0FH4IBauFHTM^EwQTu*LBIal z>(SUOBY>`4yXy(5;=%OtlHF6|AU@Kcj}>9mcI%BgRm*a=grEg~3ivhg0h3x3^*E%# z$yfE3+?efQ#{}tIC*A`}uB`64F&}Q`F%{mIf0NP z;OOT+Ty(It*qw%GxoEW!xvM;S-8Z~WE*#h_B*z@|OTsItyj#YW9(5W`tviM`nMor1 zlInl^!Fw1RB1^L>Yj(1}malB*-Psv`?f4jI<0-{uy_b36jHtXDHjwP7`L0F}wU|Nc zyOeAZECU-MyAsI=u({`kGYAN{GmP-whEK~adkUYHav(SD(sGEMx2K_@Om1o0aVMNWy{F zyKH7MY3;_@Xm=ziSJrXKbw4fQoyg^sc2u)=$ygS3Q=nfc-tf?M#EfB*+@)CkQCoW_0%48@qRhRKG`fGpBLru|>A*5Ym5wu&`|$df06mZhtd(AG$BJI& zUw!$kIy~9gJUW&k2#@s9sb=hvHM$ONG6z>pTDdyhcHdV%rY+T5Tdl`82@l%MzTlRg ziBtA*?^(3F*#;xFrr8H!{(GNGbJPe&PXrOp8ek4>W)sDfx-u~4L3b)T+MIVPE0x;w z%z&ngp2%A?s#_LGVuXaUqL=P@Cset{R_%RrDY`w;8k zXP~|QButs`gs(gU`@$6;c^Zdm4>bUwOjuB$3@A3w)6g(Y+w{ zGX7>~MDPO*)nmi{XMWnHKNlh8#RVO$P8(szF8TSS&95}tMzmWyP**$>F%gwA6tqrr z*1VSjFJ^mILeg_OWg&f^8HGU_;5DV6;ek3io0H$ML2O-W>SdSB@2KkMPM0%G=wh&a zSlw*@=#UepS_8zuk5IT9WUq@`o`Zvf#G5ro?VI|UtKZ$8Mqmg|&$%D$Fkgz-=(}5y z?^~;U99<_Ki0nPo@`!29^Mo@!VxxnBZWA1t?t5-GS@G5yk=>F{J}AX zM|P8q4_}>`5HQ5ZYC@V+*f)CX>_D!%Og^?uP?=^SD2X2`zqeyY7m|O=H+R8z2X7Vx zy}-<&kLUnbKU?O8%Xj~tuf~nKul5Gm3=YuTwVta%#%;-uc?}PVbHdk$o;)A!M8v&H zlD^PmQx z5zo)0_68#mH#gX;fsCj0fYX} zcPKN*2-DB-WB4{{e?OsE3J+$!SPH4$>1@6jinz7aXjw*EJ4=TN&D!izc$^Vj))QtT}vtGBH%m14Nvo;)&3o!L_YUg|gD@LQef0C$dtY9-H(DYq>_ z%e~#tQR?zFhZC902wU4wESupX*h|C4R{?@H1A008fowmH2?@G;%J~`%gtqn?=NHJy z_n@=?@k;73`1P}dXhd;Fv8S!438h7*Q83!-`wSNJ8jPR}%n#N_F8Q%WJ450?YC&vp zx^O*$JgVX9<67gMb9~y3+nLyf+gtB@4C3|iM81K?qR3&+(B;T={_4c)q;T801;2H^ z)!A3uzedtS5l2oVwiDQm)JxbU?GqA|79==9!7ne{Lzlc+gqlw!jcb6I$sF1WsU8FyQJ7YVeXY%0Z5HP_* za1%XFrb(AP9S8_`LwD{@sYgWWcQ5F5X;W{B(_sMAgSCI4@V60L@& zd@TLe;DlEWH_mP{eka^%D*uGDWiyQ-<+}CBc`W@?nMZ$gb1)*nly~f~yk_2=n$`RP z@*%?&H8VyOFO3CG!?A_(S^g4It;f08CRIyreJoreQ9hls4o-<;nYkmgvG_z#4ZT^{ zeYlg8ucbwmvQqoqQEfX=_amQ`_Is_Zr<`HK5fb$ahoO+j24Gv17v?}< zn-`>`Ynm5kBm6om$i(+JE6fE#U>T$#i((mOLBpvYaY;n5VAUUvGLQXOm}HRh=Zu(a z;13rWr>UES`BPap4UuV8H-*q~Q8xn&#kHS=F3qx^22a(tpNi&iLoaO|q{Y9Dkb6go z%L^iBz{Kfw9{o++y|7 zuKd%tp8Dj+&*qO@U0c~o7Gce7KMuLsO>8II%|5_xVB4_GSeRXpBR8>|*leMxVt)|(*YDWB?chVtpE{5I2eEu*$KgW}@sx2fV}?GQFWYr+_kK?%{x$4RK@K~2 zZ@c**GcXHdrWbJDx%-9>?t1Hv54?>1*BI-1eb3HqQ~&junNr63GC1G52L~)S8$OJE zw24*j*?;Khn_n+aGS=_K^L}^3jXSn|;ETH;gylHR-rm3M=t2G^{%P#LgZ;>XZTokY z6)$OEY%q-LPaVAR=0nea^%w7FY{g^L-h(&oJhB}7Lsv>ZM85I!L{InbQH#ZNI4c20=z;Mhrh&Cj!DF08hzT5vnWVYToG zu91VjvMv(Avm?<8!^SIz*m}cS_J)22SI{4nMJ{2zb?gD`QES3@_U&@*#StgFjXlV| z%Dx$~N0dk)QWPnTR7c{GEzycAS8!D%ca}xG5q~5U312;X<=?KHz4FYJZ=K(He(U)y z=Qo~Te}4S@(D{;oS(kevzW%5GIO#_26eo43<=Q`-G#E{0i`8a#I9+a!SMm7+!Ggk2 zQE^GQw5%Mxj#XAw*VHapSXbZB7;kD$BwJFgZHw9$FX`y)TH4*yy9`>md~n6k@W{$l zqhr^Nubxo;uNw0XB_t<1q?OxZQ8tdt+(OC4@^!k8LK}-pqS19FC*#g&ac%yiTqdxMo?2fZO5?3vC8z&=?<*|Wn`y!K(sqOkL=sFiY8IO*fh%7%b zuq}2Xav~-l7gO2zq}q)u(LZ{u+P#x@@Ex~&Qs-Ey0S%dLjAl@yRsi?Xn%cX&&KNsgWIO(ax}JDef4oS8)__!3T^S{R!9v zf%$I0R+KTmP~4Ag3tP<6n5cCbqmc!Tb*d$v;c|S2rXm4uvCk-)6Dj9r!%0A{fAkNLr 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 - - - -This is a custom SVG webfont generated by Font Squirrel. -Foundry URL : http://mplus-fonts.sourceforge.jp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/doc/jsdoc/css/fonts/mplus-1m-regular-webfont.ttf b/doc/jsdoc/css/fonts/mplus-1m-regular-webfont.ttf deleted file mode 100644 index 684abfd19f9d3fb00e02c8accb576edd2798383d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19344 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 diff --git a/doc/jsdoc/css/handheld.css b/doc/jsdoc/css/handheld.css deleted file mode 100644 index 073c0d1..0000000 --- a/doc/jsdoc/css/handheld.css +++ /dev/null @@ -1,217 +0,0 @@ -/* - * TABLE OF CONTENTS: - * - Browser reset - * - HTML elements - * - JsDoc styling - * - Media query check - */ - - - - - - -/* - * HTML ELEMENTS - */ - -body { - padding: 1% 4% 1% 4%; -} - -/* - * HTML ELEMENTS - */ - - - - - -/* - * BEGIN JSDOC - */ - -/* Start menu */ -div.index div.menu { - position: fixed; - top: 0; - right: 0; - -moz-border-radius-bottomleft: 15px; - -webkit-border-bottom-left-radius: 15px; - -border-bottom-left-radius: 15px; - padding: 4px 5px 8px 10px; - -moz-box-shadow: 0px 0px 10px #c4c4c4; - -webkit-box-shadow: 0px 0px 10px #c4c4c4; - box-shadow: 0px 0px 10px #c4c4c4; - background-color: rgba(255, 255, 255, 0.9); -} - -div.index input.classFilter { - display: none; -} - -div.index div.indexLinks a { - float: right; - clear: both; - font-size: 1.1em; -} - -div.index *.heading1 { - display:none; -} - -div.index ul.classList { - display:none; -} - -div.index div.fineprint { - display:none; -} - -div.indexStatic { - display: none; -} -/* End menu */ - - - -/* Start content */ -div.content *.classTitle { - margin-right: 60px; - margin-bottom: 15px; -} - -div.content div.intro { - margin: 15px 0 35px; -} - -div.content p.description.summary { - margin-bottom: 0.2em; -} - -div.content div.props { - margin: 1.5em -2% 0 -2%; - padding: 2%; -} - -table.summaryTable { - position: relative; - left: -10px; - width: 100%; - border-collapse: collapse; - box-sizing: content-box; - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; - -ms-box-sizing: content-box; - -o-box-sizing: content-box; - -icab-box-sizing: content-box; - -khtml-box-sizing: content-box; -} - -*.sectionTitle { - padding: 0 10px 10px 0; -} -caption.sectionTitle { - padding-left: 10px; -} - -table.summaryTable td, -table.summaryTable th { - padding: 0px 10px 10px 10px; -} -table.summaryTable tr:last-child td { - padding-bottom: 0; -} - -table.summaryTable td.attributes { - width: 35%; -} - -table.summaryTable td.nameDescription { - width: 65% -} - - - -dl.detailList { - margin-top: 0.5em; -} - -dl.detailList.nomargin + dl.detailList.nomargin { - margin-top: 0; -} - -dl.detailList dt { - display: inline; - margin-right: 5px; -} - -dl.detailList dt:before { - display: block; - content: ""; -} - -dl.detailList dd { - display: inline; -} - -dl.detailList.params dt { - display: block; -} -dl.detailList.params dd { - display: block; - padding-left: 2em; - padding-bottom: 0.4em; -} - - - - -ul.fileList li { - margin-bottom: 1.5em; -} - - - -.fixedFont.heading { - margin-bottom: 0.5em; -} - -pre.code { - margin: 10px 0 10px 0; - padding: 10px; - border: 1px solid #ccc; - -moz-border-radius: 2px; - -webkit-border-radius: 2px; - border-radius: 2px; -} -/* End content */ - -/* - * END JSDOC - */ - - - - - - - -/* - * START MEDIA QUERY CHECK - */ - -.cssLoadCheck { - position: absolute; - top: -99999px; - left: -99999px; - border: 0; - width: 100px; - padding: 0; - overflow: hidden; -} - -/* - * END MEDIA QUERY CHECK - */ - diff --git a/doc/jsdoc/css/screen.css b/doc/jsdoc/css/screen.css deleted file mode 100644 index 8cb4bba..0000000 --- a/doc/jsdoc/css/screen.css +++ /dev/null @@ -1,297 +0,0 @@ -/* - * TABLE OF CONTENTS: - * - JsDoc styling - * - Media query check - */ - - - - - - -/* - * BEGIN JSDOC - */ - -/* Start menu */ -div.index { - position: fixed; - top: 0; - bottom: 0; - float: left; - width: 30%; - min-width: 100px; - max-width: 300px; - padding: 0 0 10px 0; - overflow: auto; -} - -div.index *.heading1 { - padding: 8px 0 0 0; -} - -div.index div.menu { - margin: 0 15px 0 -15px; - -moz-border-radius-bottomright: 15px; - -webkit-border-bottom-right-radius: 15px; - -border-bottom-right-radius: 15px; - padding: 15px 15px 15px 30px; - -moz-box-shadow: 0px 0px 10px #c4c4c4; - -webkit-box-shadow: 0px 0px 10px #c4c4c4; - box-shadow: 0px 0px 10px #c4c4c4; - background-color: rgba(255, 255, 255, 0.5); -} - -div.index div.indexLinks { - margin-top: 13px; - position: absolute; - right: 30px; -} - -div.index div.indexLinks a { - color: #999999; - text-transform: lowercase; -} - -div.index div.indexLinks a:first-child { - margin-right: 3px; - border-right: 1px solid #999999; - padding-right: 5px; -} - -div.index input.classFilter { - margin-bottom: 4px; - width: 100%; - border-width: 1px; - border-style: solid; - border-color: #CCCCCC #999999 #999999 #CCCCCC; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - -border-radius: 3px; -} - -div.index ul.classList a { - line-height: 1.3em; -} - -div.index ul.classList a + a { - margin-left: 0.5em; -} - -div.index div.fineprint { - margin: 1em 0 0 15px; - color: #777; - font-size: 0.9em; -} - -div.index div.fineprint a { - color: #777; -} - -div.indexStatic { - position: static; - min-height: 1em; -} -/* End menu */ - - -/* Start content */ -div.content { - float: left; - width: 70%; - min-width: 300px; - max-width: 600px; -} -div.innerContent { - padding: 0 0 0 2.5em; -} - -div.content ul, -div.content ol { - margin-bottom: 3em; -} - -div.content ul.methodDetail { - margin-bottom: 0; -} - -div.content *.classTitle { - position: relative; - left: -10px; - margin: -30px 0 15px 0; - -moz-border-radius: 15px; - -webkit-border-radius: 15px; - border-radius: 15px; - padding: 25px 15px 15px 15px; - background-color: #FFFFFF; - background-color: rgba(255, 255, 255, 0.5); - -moz-box-shadow: 0px 0px 10px #c4c4c4; - -webkit-box-shadow: 0px 0px 10px #c4c4c4; - box-shadow: 0px 0px 10px #c4c4c4; -} - -div.content div.intro { - margin: 15px 0 45px -} - -div.content p.summary { - margin-bottom: 0.5em; -} - -div.content ul.summary { - margin-bottom: 1.5em; -} - -div.content ul *.classname a, -div.content ul *.filename a { - font-family: Consolas, "Courier New", Courier, monospace; - text-decoration: none; - font-weight: bold; -} -div.content ul *.classname a:hover, -div.content ul *.filename a:hover { - text-decoration: underline; -} - -div.content div.props { - position: relative; - left: -10px; - margin-bottom: 2.5em; - padding: 10px 15px 15px 15px; - overflow: hidden; -} - -div.content div.hr { - margin: 0 10px 0 0; - height: 4em; -} - - - -table.summaryTable { - position: relative; - left: -10px; - width: 100%; - border-collapse: collapse; - box-sizing: content-box; - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; - -ms-box-sizing: content-box; - -o-box-sizing: content-box; - -icab-box-sizing: content-box; - -khtml-box-sizing: content-box; -} - -*.sectionTitle { - padding: 0 10px 10px 0; -} -caption.sectionTitle { - padding-left: 10px; -} - -table.summaryTable td, -table.summaryTable th { - padding: 0px 10px 10px 10px; -} -table.summaryTable tr:last-child td { - padding-bottom: 0; -} - -table.summaryTable td.attributes { - width: 35%; -} - -table.summaryTable td.nameDescription { - width: 65% -} - - - -dl.detailList { - margin-top: 0.5em; -} - -dl.detailList.nomargin + dl.detailList.nomargin { - margin-top: 0; -} - -dl.detailList dt { - display: inline; - margin-right: 5px; -} - -dl.detailList dt:before { - display: block; - content: ""; -} - -dl.detailList dd { - display: inline; -} - -dl.detailList.params dt { - display: block; -} -dl.detailList.params dd { - display: block; - padding-left: 2em; - padding-bottom: 0.4em; -} - - - - -ul.fileList li { - margin-bottom: 1.5em; -} - - - -.fixedFont.heading { - margin-bottom: 0.5em; -} - -pre.code { - margin: 10px 0 10px 0; - padding: 10px; - border: 1px solid #ccc; - -moz-border-radius: 2px; - -webkit-border-radius: 2px; - border-radius: 2px; -} -/* End content */ - -.clear { - clear: both; - width: 100%; - min-height: 0; -} - -/* - * END JSDOC - */ - - - - - - - -/* - * START MEDIA QUERY CHECK - */ - -.cssLoadCheck { - position: absolute; - top: -99999px; - left: -99999px; - border: 0; - width: 100px; - padding: 0; - overflow: hidden; -} - -/* - * END MEDIA QUERY CHECK - */ - diff --git a/doc/jsdoc/files.html b/doc/jsdoc/files.html index 14b58a0..7a68641 100644 --- a/doc/jsdoc/files.html +++ b/doc/jsdoc/files.html @@ -206,6 +206,30 @@

Classes

File Index

+
+
+ +
+

../flotype/now/lib/function.js

+ +
+ + + + +
+
+
+ +
+ +

@@ -226,6 +262,66 @@

../flotype/now/lib/now.js< + + +
+ +
+
+ +
+

../flotype/now/lib/proxy.js

+ +
+ + + + +
+
+
+ + +
+ +
+

../flotype/now/lib/server.js

+ +
+ + + + +
+
+
+ +
@@ -246,7 +342,7 @@

../flotype/now/lib/user.j
- Documentation generated by JsDoc Toolkit 2.4.0 on Mon Jul 25 2011 14:03:02 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Aug 16 2011 17:09:04 GMT-0700 (PDT)
\ No newline at end of file diff --git a/doc/jsdoc/index.html b/doc/jsdoc/index.html index 9b031ed..a608a43 100644 --- a/doc/jsdoc/index.html +++ b/doc/jsdoc/index.html @@ -256,7 +256,7 @@

User#user

- Documentation generated by JsDoc Toolkit 2.4.0 on Mon Jul 25 2011 14:03:02 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Aug 16 2011 17:09:04 GMT-0700 (PDT)
\ No newline at end of file diff --git a/doc/jsdoc/javascript/all.js b/doc/jsdoc/javascript/all.js deleted file mode 100644 index a325163..0000000 --- a/doc/jsdoc/javascript/all.js +++ /dev/null @@ -1,326 +0,0 @@ -/** - * @fileOverview Contains standard code in the namespace 'wbos' and code specifically written for Codeview in the namespace 'codeview' - * @author Wouter Bos (www.thebrightlines.com) - * @since 1.0 - 2010-09-10 - * @version 1.0 - 2010-09-10 - */ - - - - - - -if (typeof(wbos) == "undefined") { - /** - * @namespace Standard code of Wouter Bos (wbos) - */ - wbos = {} -} -if (typeof(wbos.CssTools) == "undefined") { - /** - * @namespace Namespace for CSS-related functionality - */ - wbos.CssTools = {} -} - - - - -/** - * @namespace Fallback for CSS advanced media query - * @class - * @since 1.0 - 2010-09-10 - * @version 1.0 - 2010-09-10 - */ -wbos.CssTools.MediaQueryFallBack = ( function() { - var config = { - cssScreen: "/css/screen.css", - cssHandheld: "/css/handheld.css", - mobileMaxWidth: 660, - testDivClass: "cssLoadCheck", - dynamicCssLinkId: "DynCssLink", - resizeDelay: 30 - } - var noMediaQuery = false; - var delay; - var currentCssMediaType; - - // Adding events to elements in the DOM without overwriting it - function addEvent(element, newFunction, eventType) { - var oldEvent = eval("element." + eventType); - var eventContentType = eval("typeof element." + eventType) - - if ( eventContentType != 'function' ) { - eval("element." + eventType + " = newFunction") - } else { - eval("element." + eventType + " = function(e) { oldEvent(e); newFunction(e); }") - } - } - - // Get the the inner width of the browser window - function getWindowWidth() { - if (window.innerWidth) { - return window.innerWidth; - } else if (document.documentElement.clientWidth) { - return document.documentElement.clientWidth; - } else if (document.body.clientWidth) { - return document.body.clientWidth; - } else{ - return 0; - } - } - - function addCssLink(cssHref) { - var cssNode = document.createElement('link'); - var windowWidth; - cssNode.type = 'text/css'; - cssNode.rel = 'stylesheet'; - cssNode.media = 'screen, handheld, fallback'; - cssNode.href = cssHref; - document.getElementsByTagName("head")[0].appendChild(cssNode); - } - - - - /* Start public */ - return { - /** - * Adds link to CSS in the head if no CSS is loaded - * - * @since 1.0 - 2010-08-21 - * @version 1.0 - 2010-08-21 - * @param {String|Object} cssScreen URL to CSS file for larger screens - * @param {String|Object} cssHandheld URL to CSS file for smaller screens - * @param {Number} mobileMaxWidth Maximum width for handheld devices - * @example - * wbos.CssTools.MediaQueryFallBack.LoadCss(['screen.css', 'screen2.css'], 'mobile.css', 480) - */ - LoadCss: function(cssScreen, cssHandheld, mobileMaxWidth) { - // Set config values - if (typeof(cssScreen) != "undefined") { - config.cssScreen = cssScreen; - } - if (typeof(cssHandheld) != "undefined") { - config.cssHandheld = cssHandheld; - } - if (typeof(mobileMaxWidth) != "undefined") { - config.mobileMaxWidth = mobileMaxWidth; - } - - // Check if CSS is loaded - var cssloadCheckNode = document.createElement('div'); - cssloadCheckNode.className = config.testDivClass; - document.getElementsByTagName("body")[0].appendChild(cssloadCheckNode); - if (cssloadCheckNode.offsetWidth != 100 && noMediaQuery == false) { - noMediaQuery = true; - } - cssloadCheckNode.parentNode.removeChild(cssloadCheckNode) - - if (noMediaQuery == true) { - // Browser does not support Media Queries, so JavaScript will supply a fallback - var cssHref = ""; - - // Determines what CSS file to load - if (getWindowWidth() <= config.mobileMaxWidth) { - cssHref = config.cssHandheld; - newCssMediaType = "handheld"; - } else { - cssHref = config.cssScreen; - newCssMediaType = "screen"; - } - - // Add CSS link to of page - if (cssHref != "" && currentCssMediaType != newCssMediaType) { - var currentCssLinks = document.styleSheets - for (var i = 0; i < currentCssLinks.length; i++) { - for (var ii = 0; ii < currentCssLinks[i].media.length; ii++) { - if (typeof(currentCssLinks[i].media) == "object") { - if (currentCssLinks[i].media.item(ii) == "fallback") { - currentCssLinks[i].ownerNode.parentNode.removeChild(currentCssLinks[i].ownerNode) - i-- - break; - } - } else { - if (currentCssLinks[i].media.indexOf("fallback") >= 0) { - currentCssLinks[i].owningElement.parentNode.removeChild(currentCssLinks[i].owningElement) - i-- - break; - } - } - } - } - if (typeof(cssHref) == "object") { - for (var i = 0; i < cssHref.length; i++) { - addCssLink(cssHref[i]) - } - } else { - addCssLink(cssHref) - } - - currentCssMediaType = newCssMediaType; - } - - - // Check screen size again if user resizes window - addEvent(window, wbos.CssTools.MediaQueryFallBack.LoadCssDelayed, 'onresize') - } - }, - - /** - * Runs LoadCSS after a short delay - * - * @since 1.0 - 2010-08-21 - * @version 1.0 - 2010-08-21 - * @example - * wbos.CssTools.MediaQueryFallBack.LoadCssDelayed() - */ - LoadCssDelayed: function() { - clearTimeout(delay); - delay = setTimeout( "wbos.CssTools.MediaQueryFallBack.LoadCss()", config.resizeDelay) - } - - } - /* End public */ -})(); - - - - - - -/** - * @namespace Adds a function to an event of a single element. Use this if - * you don't want to use jQuery - * @class - * @since 1.0 - 2010-02-23 - * @version 1.0 - 2010-02-23 - */ -wbos.Events = ( function() { - /* Start public */ - return { - /** - * Adds a function to an event of a single element - * - * @since 1.0 - 2010-02-23 - * @version 1.0 - 2010-02-23 - * @param {Object} element The element on which the event is placed - * @param {Function} newFunction The function that has to be linked to the event - * @param {String} eventType Name of the event - * @example - * wbos.Events.AddEvent( document.getElementById('elementId'), functionName, "onclick" ) - */ - AddEvent: function( element, newFunction, eventType ) { - var oldEvent = eval("element." + eventType); - var eventContentType = eval("typeof element." + eventType) - - if ( eventContentType != 'function' ) { - eval("element." + eventType + " = newFunction") - } else { - eval("element." + eventType + " = function(e) { oldEvent(e); newFunction(e); }") - } - } - } - /* End public */ -})(); - - - - - - -if (typeof(codeview) == "undefined") { - /** - * @namespace Code written for the Codeview template - */ - codeview = {} -} - - - - - - - -/** - * @namespace Enables filtering in class lists - * @class - * @since 1.0 - 2010-11-08 - * @version 1.0 - 2010-11-08 - */ -codeview.classFilter = ( function() { - function onkeyup_ClassFilter() { - var listItems - var search = document.getElementById('ClassFilter').value - search = search.toLowerCase() - if (document.getElementById('ClassList')) { - listItems = document.getElementById('ClassList').getElementsByTagName('li') - filterList(listItems, search) - } - if (document.getElementById('ClassList2')) { - listItems = document.getElementById('ClassList2').getElementsByTagName('li') - filterList(listItems, search) - } - if (document.getElementById('FileList')) { - listItems = document.getElementById('FileList').getElementsByTagName('li') - filterList(listItems, search) - } - if (document.getElementById('MethodsListInherited')) { - var links = document.getElementById('MethodsListInherited').getElementsByTagName('a') - var linksSelected = new Array() - for (var i=0; i < links.length; i++) { - if (links[i].parentNode.parentNode.tagName == "DD") { - linksSelected.push(links[i]) - } - } - filterList(linksSelected, search) - } - if (document.getElementById('MethodsList')) { - listItems = document.getElementById('MethodsList').getElementsByTagName('tbody')[0].getElementsByTagName('tr') - filterList(listItems, search, document.getElementById('MethodDetail').getElementsByTagName('li')) - } - } - - function filterList(listItems, search, relatedElements) { - var itemContent = "" - for (var i=0; i < listItems.length; i++) { - itemContent = listItems[i].textContent||listItems[i].innerText - if (itemContent != undefined) { - itemContent = itemContent.toLowerCase() - itemContent = itemContent.replace(/\s/g, "") - if (itemContent.indexOf(search) >= 0 || itemContent == "") { - listItems[i].style.display = "" - } else { - listItems[i].style.display = "none" - } - if (relatedElements != null) { - filterRelatedList(listItems[i], search, relatedElements) - } - } - } - } - - function filterRelatedList(listItem, search, relatedElements) { - var itemIndex = parseInt(listItem.className.replace('item', '')) - if (itemIndex <= relatedElements.length) { - if (relatedElements[itemIndex].className == "item"+ itemIndex) { - relatedElements[itemIndex].style.display = listItem.style.display - } - } - } - - - - - - /* Start public */ - return { - Init: function() { - wbos.Events.AddEvent( - document.getElementById('ClassFilter'), - onkeyup_ClassFilter, - "onkeyup" - ) - } - } - /* End public */ -})(); diff --git a/doc/jsdoc/javascript/html5.js b/doc/jsdoc/javascript/html5.js deleted file mode 100644 index 289ba45..0000000 --- a/doc/jsdoc/javascript/html5.js +++ /dev/null @@ -1,6 +0,0 @@ -// html5shiv MIT @rem remysharp.com/html5-enabling-script -// iepp v1.6.2 MIT @jon_neal iecss.com/print-protector -/*@cc_on(function(m,c){var z="abbr|article|aside|audio|canvas|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video";function n(d){for(var a=-1;++ai";if(g.childNodes.length!==1){var i=z.split("|"),o=i.length,s=RegExp("(^|\\s)("+z+")", -"gi"),t=RegExp("<(/*)("+z+")","gi"),u=RegExp("(^|[^\\n]*?\\s)("+z+")([^\\n]*)({[\\n\\w\\W]*?})","gi"),r=c.createDocumentFragment(),k=c.documentElement;g=k.firstChild;var h=c.createElement("body"),l=c.createElement("style"),f;n(c);n(r);g.insertBefore(l, -g.firstChild);l.media="print";m.attachEvent("onbeforeprint",function(){var d=-1,a=p(c.styleSheets,"all"),e=[],b;for(f=f||c.body;(b=u.exec(a))!=null;)e.push((b[1]+b[2]+b[3]).replace(s,"$1.iepp_$2")+b[4]);for(l.styleSheet.cssText=e.join("\n");++d
- Documentation generated by JsDoc Toolkit 2.4.0 on Mon Jul 25 2011 14:03:02 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Aug 16 2011 17:09:04 GMT-0700 (PDT)
diff --git a/doc/jsdoc/symbols/Group.html b/doc/jsdoc/symbols/Group.html index 35fc372..2da5eaf 100644 --- a/doc/jsdoc/symbols/Group.html +++ b/doc/jsdoc/symbols/Group.html @@ -1016,7 +1016,7 @@

- Documentation generated by JsDoc Toolkit 2.4.0 on Mon Jul 25 2011 14:03:02 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Aug 16 2011 17:09:04 GMT-0700 (PDT)
diff --git a/doc/jsdoc/symbols/User#now.html b/doc/jsdoc/symbols/User#now.html index 9420e9c..c7085b3 100644 --- a/doc/jsdoc/symbols/User#now.html +++ b/doc/jsdoc/symbols/User#now.html @@ -324,7 +324,7 @@

- Documentation generated by JsDoc Toolkit 2.4.0 on Mon Jul 25 2011 14:03:02 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Aug 16 2011 17:09:04 GMT-0700 (PDT)
diff --git a/doc/jsdoc/symbols/User#user.html b/doc/jsdoc/symbols/User#user.html index 0d8d892..9158f18 100644 --- a/doc/jsdoc/symbols/User#user.html +++ b/doc/jsdoc/symbols/User#user.html @@ -278,6 +278,17 @@

+ +   + +
+ cookie +
+
The user's cookie, as determined by +Socket.IO.
+ + + @@ -354,6 +365,29 @@

+
+ + +
+ + {String} + cookie + +
+
+ The user's cookie, as determined by +Socket.IO. + + +
+ + + + + + + + @@ -371,7 +405,7 @@

- Documentation generated by JsDoc Toolkit 2.4.0 on Mon Jul 25 2011 14:03:02 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Aug 16 2011 17:09:04 GMT-0700 (PDT)
diff --git a/doc/jsdoc/symbols/User.html b/doc/jsdoc/symbols/User.html index a6e4ec6..7581ea4 100644 --- a/doc/jsdoc/symbols/User.html +++ b/doc/jsdoc/symbols/User.html @@ -458,7 +458,7 @@

- Documentation generated by JsDoc Toolkit 2.4.0 on Mon Jul 25 2011 14:03:02 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Aug 16 2011 17:09:04 GMT-0700 (PDT)
diff --git a/doc/jsdoc/symbols/_global_.html b/doc/jsdoc/symbols/_global_.html index 56ac6bf..e39c228 100644 --- a/doc/jsdoc/symbols/_global_.html +++ b/doc/jsdoc/symbols/_global_.html @@ -230,9 +230,102 @@

+ + + + + + + + + + + + + + + + + + +
Field Summary
Field AttributesField Name and Description
  +
+ Proxy +
+
wrap.js + +Wrap provides the proxy object that is exposed to the server.
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Method Summary
Method AttributesMethod Name and Description
  +
generateClientLibs(hostServer, hostPort, callback) +
+
+
  +
handleResponse(request, response) +
+
+
  +
Now() +
+
+
  +
ScopeTable(data) +
+
+
  +
serveFile(filename, request, response, options) +
+
+
+ + + + @@ -241,9 +334,268 @@

+
+ Field Detail +
+ + +
+ + + Proxy + +
+
+ wrap.js + +Wrap provides the proxy object that is exposed to the server. +Changes/additions to the object's properties and nested objects +trigger the store function to be called. + +
+ Defined in: proxy.js. + + +
+ + + + + + + + + + + +
+ Method Detail +
+ + +
+ + + generateClientLibs(hostServer, hostPort, callback) + +
+
+ + +
+ Defined in: fileServer.js. + + +
+ + + + +
+
Parameters:
+ +
+ hostServer + +
+
+ +
+ hostPort + +
+
+ +
+ callback + +
+
+ +
+ + + + + + + + +
+ + +
+ + + handleResponse(request, response) + +
+
+ + +
+ Defined in: fileServer.js. + + +
+ + + + +
+
Parameters:
+ +
+ request + +
+
+ +
+ response + +
+
+ +
+ + + + + + + + +
+ + +
+ + + Now() + +
+
+ + +
+ Defined in: now.js. + + +
+ + + + + + + + + + + +
+ + +
+ + + ScopeTable(data) + +
+
+ + +
+ Defined in: scopeTable.js. + + +
+ + + + +
+
Parameters:
+ +
+ data + +
+
+ +
+ + + + + + + + +
+ + +
+ + + serveFile(filename, request, response, options) + +
+
+ + +
+ Defined in: fileServer.js. + + +
+ + + + +
+
Parameters:
+ +
+ filename + +
+
+ +
+ request + +
+
+ +
+ response + +
+
+ +
+ options + +
+
+ +
+ + + + + + + + + + + @@ -255,7 +607,7 @@

- Documentation generated by JsDoc Toolkit 2.4.0 on Mon Jul 25 2011 14:03:02 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Aug 16 2011 17:09:04 GMT-0700 (PDT)
diff --git a/doc/jsdoc/symbols/nowjs.html b/doc/jsdoc/symbols/nowjs.html index 9aa9292..13d27ed 100644 --- a/doc/jsdoc/symbols/nowjs.html +++ b/doc/jsdoc/symbols/nowjs.html @@ -288,6 +288,17 @@

+ +   + +
getGroups(callback) +
+
Retrieves a list (represented in Javascript as an +array) of all groups that have been created and passes it in to the +supplied callback.
+ + + <static>   @@ -501,6 +512,54 @@

+
+ + +
+ + + getGroups(callback) + +
+
+ Retrieves a list (represented in Javascript as an +array) of all groups that have been created and passes it in to the +supplied callback. + + +
+ + + +
nowjs.on('connect', function () {
+  var self = this;
+  getGroups(function (groups) {
+    nowjs.getGroup(groups[Math.floor(groups.length * Math.random())]).addUser(self);
+  });
+});
+ + + + +
+
Parameters:
+ +
+ {Function} callback + +
+
Takes one argument, an array of all +groups that have been created.
+ +
+ + + + + + + +
@@ -774,7 +833,7 @@

- Documentation generated by JsDoc Toolkit 2.4.0 on Mon Jul 25 2011 14:03:02 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.4.0 on Tue Aug 16 2011 17:09:04 GMT-0700 (PDT)
diff --git a/doc/jsdoc/symbols/src/flotype_now_lib_fileServer.js.html b/doc/jsdoc/symbols/src/flotype_now_lib_fileServer.js.html new file mode 100644 index 0000000..f77043b --- /dev/null +++ b/doc/jsdoc/symbols/src/flotype_now_lib_fileServer.js.html @@ -0,0 +1,121 @@ +
  1 var fs = require('fs');
+  2 var nowUtil = require('./nowUtil').nowUtil;
+  3 
+  4 var fileCache = {};
+  5 var nowFileCache = {};
+  6 
+  7 var defaultListeners;
+  8 var server;
+  9 var options;
+ 10 
+ 11 var handleResponse, serveFile, generateClientLibs;
+ 12 
+ 13 exports.wrapServer = function (httpServer, serverOptions) {
+ 14   server = httpServer;
+ 15   options = serverOptions || {client: {}};
+ 16   options.client = JSON.stringify(options.client);
+ 17 
+ 18   defaultListeners = server.listeners('request');
+ 19   if (serverOptions.autoHost) {
+ 20     server.removeAllListeners('request');
+ 21     server.on('request', handleResponse);
+ 22   }
+ 23 };
+ 24 
+ 25 // Called upon http server request
+ 26 handleResponse = function (request, response) {
+ 27   // Handle only GET requests for /nowjs/* files. Pass all other requests through
+ 28   var i;
+ 29   if (request.method === 'GET') {
+ 30 
+ 31     // Detect if request involves the now.js file
+ 32     if (request.url.split('?')[0] === '/nowjs/now.js') {
+ 33       serveFile(__dirname + '/client/now.js', request, response, options);
+ 34     } else {
+ 35       // Make sure default listeners are still handled
+ 36       for (i in defaultListeners) {
+ 37         if (nowUtil.hasProperty(defaultListeners, i)) {
+ 38           defaultListeners[i].call(server, request, response);
+ 39         }
+ 40       }
+ 41     }
+ 42   } else {
+ 43     for (i in defaultListeners) {
+ 44       // Make sure default listeners are still handled
+ 45       if (nowUtil.hasProperty(defaultListeners, i)) {
+ 46         defaultListeners[i].call(server, request, response);
+ 47       }
+ 48     }
+ 49   }
+ 50 };
+ 51 
+ 52 // Actually serve the file
+ 53 serveFile = function (filename, request, response, options) {
+ 54   // Write file from cache if possible
+ 55   if (nowUtil.hasProperty(fileCache, filename)) {
+ 56     response.writeHead(200);
+ 57     response.write(fileCache[filename]);
+ 58     response.end();
+ 59   } else {
+ 60     if (filename.indexOf('/now.js') !== -1) {
+ 61 
+ 62       // Write file from cache if possible
+ 63       if (nowUtil.hasProperty(nowFileCache, request.headers.host)) {
+ 64 
+ 65         // Write file from cache
+ 66         response.writeHead(200, {'Content-Type': 'text/javascript'});
+ 67         response.write(nowFileCache[request.headers.host].now);
+ 68         response.end();
+ 69       } else {
+ 70         // Determine hostname / port if not given in options
+ 71         var host = request.headers.host.split(':');
+ 72         var hostServer = options['host'] || host[0];
+ 73         var hostPort =  options['port'] || host[1] || '80';
+ 74 
+ 75         // Call generate client libs, which takes the desired host/port and executes callback with two parts of now.js as parameters
+ 76         generateClientLibs(hostServer, hostPort, function (nowText) {
+ 77 
+ 78           // Write to client
+ 79           response.writeHead(200, {'Content-Type': 'text/javascript'});
+ 80           response.write(nowText);
+ 81           response.end();
+ 82 
+ 83           // Add to cache
+ 84           nowFileCache[request.headers.host] = {now: nowText};
+ 85         });
+ 86       }
+ 87     } else {
+ 88       // For any other filename, read file and server (not cached)
+ 89       fs.readFile(filename, function (err, data) {
+ 90         var text = data.toString();
+ 91         response.writeHead(200);
+ 92         response.write(text);
+ 93         response.end();
+ 94         fileCache[filename] = text;
+ 95       });
+ 96     }
+ 97   }
+ 98 };
+ 99 
+100 // Takes host and port and call callback with now.js as parameter
+101 generateClientLibs = function (hostServer, hostPort, callback) {
+102   fs.readFile(__dirname + '/client/now.js', function (err, data) {
+103     var nowText = data.toString();
+104     var initString = options.scope + '.now = nowInitialize("' +
+105           (options.protocol !==  undefined ? options.protocol + ':' : '') +
+106           '//' + hostServer + ':' + hostPort + '", ' + options.client + ');\n';
+107     nowText += initString;
+108 
+109     callback(nowText);
+110   });
+111 };
+112 
+113 exports.generateClientLibs = generateClientLibs;
+114 
\ No newline at end of file diff --git a/doc/jsdoc/symbols/src/flotype_now_lib_function.js.html b/doc/jsdoc/symbols/src/flotype_now_lib_function.js.html new file mode 100644 index 0000000..7299254 --- /dev/null +++ b/doc/jsdoc/symbols/src/flotype_now_lib_function.js.html @@ -0,0 +1,59 @@ +
  1 var nowUtil = require('./nowUtil').nowUtil;
+  2 
+  3 exports.init = function (nowjs) {
+  4   return {
+  5     multicall: function () {
+  6       var args = nowUtil.clone(Array.prototype, arguments);
+  7       nowjs.emit('multicall', this, args);
+  8     },
+  9 
+ 10     remotecall: function () {
+ 11       // Coerce arguments to an array.
+ 12       var args = nowUtil.clone(Array.prototype, arguments);
+ 13       // Find functions in the args, and store functions in
+ 14       // closure table and serialize functions.
+ 15       var closureId;
+ 16       for (var i = 0, ii = args.length; i < ii; i++) {
+ 17         if (typeof args[i] === 'function') {
+ 18           closureId = 'closure_' + args[i].name + '_' + nowUtil.generateRandomString();
+ 19           nowjs.closures[closureId] = args[i];
+ 20           args[i] = {fqn: closureId};
+ 21           setTimeout(function () {
+ 22             nowjs.closures[closureId] = nowUtil.noop;
+ 23           }, nowjs.options.closureTimeout);
+ 24         }
+ 25       }
+ 26       // On the next tick, send the remoteCall request
+ 27       this.socket.emit('rfc', {fqn: this.fqn, args: args});
+ 28     },
+ 29     closurecall: function (){
+ 30     // Coerce arguments to an array.
+ 31       var args = [];
+ 32       for (var i = 0, ii = arguments.length; i < ii; i++) {
+ 33         args[i] = arguments[i];
+ 34       }
+ 35       // Find functions in the args, and store functions usin
+ 36       // closure table and serialize functions.
+ 37       var closureId;
+ 38       for (i = 0, ii = args.length; i < ii; i++) {
+ 39         if (typeof args[i] === 'function') {
+ 40           closureId = 'closure_' + args[i].name + '_' + nowUtil.generateRandomString();
+ 41           nowjs.closures[closureId] = args[i];
+ 42           args[i] = {fqn: closureId};
+ 43           setTimeout(function () {
+ 44             nowjs.closures[closureId] = nowUtil.noop;
+ 45           }, nowjs.options.closureTimeout);
+ 46         }
+ 47       }
+ 48       this.socket.write(JSON.stringify({type:'closurecall', fqn: this.fqn, args: args}));
+ 49     }
+ 50   };
+ 51 };
+ 52 
\ No newline at end of file diff --git a/doc/jsdoc/symbols/src/flotype_now_lib_group.js.html b/doc/jsdoc/symbols/src/flotype_now_lib_group.js.html index 0a35480..7cb8b5c 100644 --- a/doc/jsdoc/symbols/src/flotype_now_lib_group.js.html +++ b/doc/jsdoc/symbols/src/flotype_now_lib_group.js.html @@ -24,304 +24,319 @@ 17 * @see Group#now 18 */ 19 var Group = function (groupName) { - 20 //all users in the group - 21 22 this.users = {}; - 23 - 24 25 this.groupName = groupName; - 26 - 27 this.excludes = {}; - 28 /** - 29 * @name Group#now - 30 * @namespace The now namespace for this particular group. Actions - 31 * to this namespace affect all users that are members of the - 32 * group. All functions that are called will be called in the - 33 * context of each individual user in the group. - 34 - 35 * @example everyone.now.prop = 42; - 36 * @example everyone.now.func = function () { - 37 * console.log('hello!'); - 38 * }; - 39 */ - 40 this.now = Proxy.wrap(this); - 41 //group scope table - 42 this.scopeTable = new ScopeTable(); - 43 }; + 20 // all users in the group + 21 this.users = {}; + 22 23 + this.groupName = groupName; + 24 + 25 this.excludes = {}; + 26 /** + 27 * @name Group#now + 28 * @namespace The now namespace for this particular group. Actions + 29 * to this namespace affect all users that are members of the + 30 * group. All functions that are called will be called in the + 31 * context of each individual user in the group. + 32 + 33 * @example everyone.now.prop = 42; + 34 * @example everyone.now.func = function () { + 35 * console.log('hello!'); + 36 * }; + 37 */ + 38 this.now = Proxy.wrap(this); + 39 // group scope table + 40 this.scopeTable = new ScopeTable(); + 41 }; + 42 + 43 Group.prototype.__proto__ = EventEmitter.prototype; 44 - 45 Group.prototype.__proto__ = EventEmitter.prototype; - 46 - 47 /** - 48 * @name count - 49 * @function - 50 * @memberOf Group# - 51 - 52 * @description Used to find the cardinality of the group (how - 53 * many users it contains). - 54 - 55 * @param {Function} callback Called with a Number corresponding to - 56 * the group's user count. - 57 - 58 * @example everyone.count(function (ct) { - 59 * console.log(ct); - 60 * }); - 61 */ - 62 Group.prototype.count = function (callback) { - 63 callback(Object.keys(this.users).length); - 64 }; - 65 - 66 /** - 67 * @name getUsers - 68 * @function - 69 * @memberOf Group# - 70 - 71 * @description Used to retrieve a list of the client IDs - 72 * corresponding to all users in the group. - 73 - 74 * @param {Function} callback Called with an Array of Strings - 75 * corresponding to the client IDs of all users in the group. - 76 - 77 * @example everyone.getUsers(function (users) { - 78 * for (var i = 0; i < users.length; i++) console.log(users[i]); - 79 * }); - 80 - 81 * @see nowjs#getClient - 82 */ - 83 Group.prototype.getUsers = function (callback) { - 84 callback(Object.keys(this.users)); - 85 }; - 86 - 87 /** - 88 * @name connected - 89 * @function - 90 * @memberOf Group# - 91 * @deprecated As of 0.7.0. Use nowjs:connect instead. - 92 */ - 93 Group.prototype.connected = function (callback) { - 94 nowjs.on('connect', callback); - 95 }; - 96 - 97 /** - 98 * @name disconnected - 99 * @function -100 * @memberOf Group# -101 * @deprecated As of 0.7.0. Use nowjs:disconnect instead. -102 */ -103 Group.prototype.disconnected = function (callback) { -104 nowjs.on('disconnect', callback); -105 }; -106 -107 /** -108 * @name addUser -109 * @function -110 * @memberOf Group# -111 * @description Adds the user identified by clientId to this group. -112 -113 * @param {String} clientId The client ID associated with the target -114 * user. -115 -116 * @example everyone.addUser('1234567890'); -117 */ -118 Group.prototype.addUser = function (clientId) { -119 var self = this; -120 this.hasClient(clientId, function (hasClient) { -121 if (hasClient) { -122 return; -123 } -124 nowjs.getClient(clientId, function () { -125 // Scoping note: `self` refers to the group, `this` refers to -126 // the new client. -127 self.users[this.user.clientId] = this; -128 this.groups[self.groupName] = self; -129 -130 // Send the client any new variables that it does not already have -131 var toSend = {}; -132 var keys = Object.keys(self.scopeTable.data); -133 var key, val; -134 for (var i = 0, ll = keys.length; i < ll; i++) { -135 key = keys[i]; -136 val = self.scopeTable.get(key); -137 if (val !== nowUtil.noop && !Array.isArray(val) && -138 !nowUtil.hasProperty(this.scopeTable.data, key)) { -139 toSend[key] = nowUtil.getValOrFqn(val, key); -140 } -141 } -142 -143 if (self.isSuperGroup || !nowUtil.isEmptyObj(toSend)) { -144 this.socket.emit('rv', toSend); -145 } -146 var user = nowUtil.clone(this, {'_events': self._events}); -147 -148 /** -149 * @name Group#join -150 * @event -151 * @description Called in the context of a user who has just been -152 * added to the group. -153 -154 * @example everyone.on('join', function () { -155 * otherGroup.addUser(this.user.clientId); -156 * }); -157 */ -158 self.emit.apply(user, ['join']); -159 }); -160 }); -161 }; -162 -163 /** -164 * @name removeUser -165 * @function -166 * @memberOf Group# -167 * @version 0.7.0 -168 * @description Removes the user identified by clientId from this group. -169 -170 * @param {String} clientId The client ID associated with the target -171 * user. -172 -173 * @example otherGroup.removeUser('1234567890'); -174 */ -175 Group.prototype.removeUser = function (clientId) { -176 var self = this; -177 this.hasClient(clientId, function (hasClient) { -178 if (!hasClient) { -179 return; -180 } -181 var user = nowUtil.clone(self.users[clientId], {'_events': self._events}); -182 -183 /** -184 * @name Group#leave -185 * @event -186 * @version 0.7.0 -187 * @description Called in the context of a user who has just been -188 * removed from the group. -189 -190 * @example otherGroup.on('leave', function () { -191 * // Store the context, i.e. the user who has just left. -192 * var self = this; -193 * // Check that the user is still connected to the server. -194 * everyone.hasClient(this.user.clientId, function (bool) { -195 * if (bool) { -196 * // Send parting words to the client. -197 * this.now.receive('SERVER', 'Goodbye. I'll miss you dearly.'); -198 * } -199 * }); -200 * }); -201 */ -202 self.emit.apply(user, ['leave']); -203 // Delete all remote functions that are part of this group from -204 // the user. -205 var fqns = Object.keys(self.scopeTable.data); -206 for (var i = 0; i < fqns.length; i++) { -207 if (typeof self.scopeTable.data[fqns[i]] === 'function' && -208 self.scopeTable.data[fqns[i]] !== nowUtil.noop && -209 user.scopeTable.data[fqns[i]] === undefined) { -210 // Tell the user to delete his function. -211 user.deleteVar(fqns[i]); -212 } -213 } -214 delete self.users[clientId]; -215 delete user.groups[self.groupName]; -216 }); -217 }; -218 -219 /** -220 * @memberOf Group# -221 * @function -222 * @name exclude -223 * @version 0.7.0 -224 -225 * @description Returns a new Group that is identical to the calling -226 * group, except with the specified clients excluded. The returned -227 * group automatically updates to accommodate any changes made to -228 * its parent group. -229 -230 * @param {Array} clientIds A list of client IDs corresponding to -231 * clients to exclude. -232 -233 * @example everyone.now.distribute = function (msg) { -234 * everyone.exclude([this.user.clientId]).now.receive(this.now.name, msg); -235 * }; -236 * @example factionOne.now.distribute = function (msg) { -237 * factionTwo.getUsers(function (users) { -238 * factionOne.exclude(users).now.receive(this.user.clientId, msg); -239 * }); -240 * }; -241 -242 * @type Group -243 */ -244 Group.prototype.exclude = function (clientIds) { -245 var excludes = {}; -246 for (var i = 0; i < clientIds.length; i++) { -247 excludes[clientIds[i]] = true; -248 } -249 var group = nowUtil.clone(this, {excludes: nowUtil.clone(this.excludes, excludes)}); -250 group.now = Proxy.wrap(group); -251 return group; -252 }; -253 -254 /** -255 * @memberOf Group# -256 * @function -257 * @name hasClient -258 -259 * @description Used to determine a given user's membership in the -260 * group. -261 -262 * @param {String} clientId The client ID associated with the target -263 * user. + 45 /** + 46 * @name count + 47 * @function + 48 * @memberOf Group# + 49 + 50 * @description Used to find the cardinality of the group (how + 51 * many users it contains). + 52 + 53 * @param {Function} callback Called with a Number corresponding to + 54 * the group's user count. + 55 + 56 * @example everyone.count(function (ct) { + 57 * console.log(ct); + 58 * }); + 59 */ + 60 Group.prototype.count = function (callback) { + 61 callback(Object.keys(this.users).length); + 62 }; + 63 + 64 /** + 65 * @name getUsers + 66 * @function + 67 * @memberOf Group# + 68 + 69 * @description Used to retrieve a list of the client IDs + 70 * corresponding to all users in the group. + 71 + 72 * @param {Function} callback Called with an Array of Strings + 73 * corresponding to the client IDs of all users in the group. + 74 + 75 * @example everyone.getUsers(function (users) { + 76 * for (var i = 0; i < users.length; i++) console.log(users[i]); + 77 * }); + 78 + 79 * @see nowjs#getClient + 80 */ + 81 Group.prototype.getUsers = function (callback) { + 82 callback(Object.keys(this.users)); + 83 }; + 84 + 85 /** + 86 * @name connected + 87 * @function + 88 * @memberOf Group# + 89 * @deprecated As of 0.7.0. Use nowjs:connect instead. + 90 */ + 91 Group.prototype.connected = function (callback) { + 92 nowjs.on('connect', callback); + 93 }; + 94 + 95 /** + 96 * @name disconnected + 97 * @function + 98 * @memberOf Group# + 99 * @deprecated As of 0.7.0. Use nowjs:disconnect instead. +100 */ +101 Group.prototype.disconnected = function (callback) { +102 nowjs.on('disconnect', callback); +103 }; +104 +105 /** +106 * @name addUser +107 * @function +108 * @memberOf Group# +109 * @description Adds the user identified by clientId to this group. +110 +111 * @param {String} clientId The client ID associated with the target +112 * user. +113 +114 * @example everyone.addUser('1234567890'); +115 */ +116 Group.prototype.addUser = function (clientId) { +117 var self = this; +118 this.hasClient(clientId, function (hasClient) { +119 if (hasClient) { +120 return; +121 } +122 if (self.excludes[clientId]) { +123 self.excludes[clientId] = false; +124 } +125 nowjs.getClient(clientId, function () { +126 // Scoping note: `self` refers to the group, `this` refers to +127 // the new client. +128 self.users[this.user.clientId] = this; +129 this.groups[self.groupName] = self; +130 +131 // Send the client any new variables that it does not already have +132 var toSend = {}; +133 var keys = Object.keys(self.scopeTable.data); +134 var key, val; +135 for (var i = 0, ll = keys.length; i < ll; i++) { +136 key = keys[i]; +137 val = self.scopeTable.get(key); +138 if (val !== nowUtil.noop && !Array.isArray(val) && +139 !nowUtil.hasProperty(this.scopeTable.data, key)) { +140 toSend[key] = nowUtil.getValOrFqn(val, key); +141 } +142 } +143 +144 if (self.isSuperGroup || !nowUtil.isEmptyObj(toSend)) { +145 this.socket.emit('rv', toSend); +146 } +147 var user = nowUtil.clone(this, {'_events': self._events}); +148 +149 /** +150 151 * @name Group#join +152 * @event +153 * @description Called in the context of a user who has just been +154 * added to the group. +155 +156 * @example everyone.on('join', function () { +157 * otherGroup.addUser(this.user.clientId); +158 * }); +159 */ +160 self.emit.call(user, 'join'); +161 }); +162 }); +163 }; +164 +165 /** +166 * @name removeUser +167 * @function +168 * @memberOf Group# +169 * @version 0.7.0 +170 * @description Removes the user identified by clientId from this group. +171 +172 * @param {String} clientId The client ID associated with the target +173 * user. +174 +175 * @example otherGroup.removeUser('1234567890'); +176 */ +177 Group.prototype.removeUser = function (clientId) { +178 var self = this; +179 this.hasClient(clientId, function (hasClient) { +180 if (!hasClient) { +181 return; +182 } +183 var user = nowUtil.clone(self.users[clientId], {'_events': self._events}); +184 +185 /** +186 * @name Group#leave +187 * @event +188 * @version 0.7.0 +189 * @description Called in the context of a user who has just been +190 * removed from the group. +191 +192 * @example otherGroup.on('leave', function () { +193 * // Store the context, i.e. the user who has just left. +194 * var self = this; +195 * // Check that the user is still connected to the server. +196 * everyone.hasClient(this.user.clientId, function (bool) { +197 * if (bool) { +198 * // Send parting words to the client. +199 * this.now.receive('SERVER', 'Goodbye. I'll miss you dearly.'); +200 * } +201 * }); +202 * }); +203 */ +204 self.emit.call(user, 'leave'); +205 // Delete all remote functions that are part of this group from +206 // the user. +207 var fqns = Object.keys(self.scopeTable.data); +208 for (var i = 0; i < fqns.length; i++) { +209 if (typeof self.scopeTable.data[fqns[i]] === 'function' && +210 self.scopeTable.data[fqns[i]] !== nowUtil.noop && +211 user.scopeTable.data[fqns[i]] === undefined) { +212 // Tell the user to delete his function. +213 user.deleteVar(fqns[i]); +214 } +215 } +216 delete self.users[clientId]; +217 delete user.groups[self.groupName]; +218 }); +219 }; +220 +221 /** +222 * @memberOf Group# +223 * @function +224 * @name exclude +225 * @version 0.7.0 +226 +227 * @description Returns a new Group that is identical to the calling +228 * group, except with the specified clients excluded. The returned +229 * group automatically updates to accommodate any changes made to +230 * its parent group. +231 +232 * @param {Array} clientIds A list of client IDs corresponding to +233 * clients to exclude. +234 +235 * @example everyone.now.distribute = function (msg) { +236 * everyone.exclude([this.user.clientId]).now.receive(this.now.name, msg); +237 * }; +238 * @example factionOne.now.distribute = function (msg) { +239 * factionTwo.getUsers(function (users) { +240 * factionOne.exclude(users).now.receive(this.user.clientId, msg); +241 * }); +242 * }; +243 +244 * @type Group +245 */ +246 Group.prototype.exclude = function (clientIds) { +247 var excludes = {}; +248 if(typeof clientIds === 'string') { +249 return this.exclude([clientIds]); +250 } else { +251 for (var i = 0; i < clientIds.length; i++) { +252 excludes[clientIds[i]] = true; +253 } +254 } +255 var group = nowUtil.clone(this, {excludes: nowUtil.clone(this.excludes, excludes)}); +256 group.now = Proxy.wrap(group); +257 return group; +258 }; +259 +260 /** +261 * @memberOf Group# +262 * @function +263 * @name hasClient 264 -265 * @param {Function} callback Called with a Boolean indicating the -266 * user's membership in the group. -267 -268 * @example group.hasClient('1234567890', function (bool) { -269 * if (bool) { -270 * console.log('User is a member of `group`.'); -271 * } -272 * }); -273 */ -274 //returns boolean whether or not user is in a group -275 Group.prototype.hasClient = function (clientId, callback) { -276 callback(this.users[clientId] !== undefined); -277 }; -278 -279 Group.prototype.get = function (fqn) { -280 var value = this.scopeTable.get(fqn); -281 // If this is a regular group, look in `everyone` for the value -282 if (value === undefined && !this.isSuperGroup) { -283 value = nowjs.getGroup('everyone').scopeTable.get(fqn); -284 } +265 * @description Used to determine a given user's membership in the +266 267 * group. +268 +269 * @param {String} clientId The client ID associated with the target +270 * user. +271 +272 * @param {Function} callback Called with a Boolean indicating the +273 * user's membership in the group. +274 +275 * @example group.hasClient('1234567890', function (bool) { +276 * if (bool) { +277 * console.log('User is a member of `group`.'); +278 * } +279 * }); +280 */ +281 Group.prototype.hasClient = function (clientId, callback) { +282 callback(this.users[clientId] !== undefined); +283 284 }; 285 -286 // If this is a function, return a multicaller. -287 if (typeof value === 'function') { -288 var group = nowUtil.clone(this, {fqn: fqn}); -289 value = fn.multicall.bind(group); -290 } -291 return value; -292 }; -293 -294 Group.prototype.deleteVar = function (fqn) { -295 var obj = nowUtil.clone(this, {fqn: fqn}); -296 nowjs.emit('groupdel', obj); -297 }; -298 -299 Group.prototype.set = function (fqn, val) { -300 var obj = nowUtil.clone(this, {fqn: fqn, val: val}); -301 nowjs.emit('grouprv', obj); +286 /** +287 * @private +288 */ +289 Group.prototype.get = function (fqn) { +290 var value = this.scopeTable.get(fqn); +291 // If this is a regular group, look in `everyone` for the value +292 if (value === undefined && !this.isSuperGroup) { +293 value = nowjs.getGroup('everyone').scopeTable.get(fqn); +294 } +295 +296 // If this is a function, return a multicaller. +297 if (typeof value === 'function') { +298 var group = nowUtil.clone(this, {fqn: fqn}); +299 value = fn.multicall.bind(group); +300 } +301 return value; 302 }; 303 -304 return Group; -305 }; -306 -307 /** -308 * @name Group#connect -309 * @event -310 * @deprecated As of 0.7.0. Use nowjs#connect instead. -311 * @description Called in the context of a user when the server -312 * first receives a message from the given user. -313 */ -314 -315 /** -316 * @name Group#disconnect -317 * @event -318 * @deprecated As of 0.7.0. Use nowjs#disconnect instead. -319 * @description Called in the context of a user who has just -320 * disconnected from the server. -321 */ -322 \ No newline at end of file +304 /** +305 * @private +306 */ +307 Group.prototype.deleteVar = function (fqn) { +308 var obj = nowUtil.clone(this, {fqn: fqn}); +309 nowjs.emit('groupdel', obj); +310 }; +311 +312 /** +313 * @private +314 */ +315 Group.prototype.set = function (fqn, val) { +316 var obj = nowUtil.clone(this, {fqn: fqn, val: val}); +317 nowjs.emit('grouprv', obj); +318 }; +319 +320 return Group; +321 }; +322 +323 /** +324 * @name Group#connect +325 * @event +326 * @deprecated As of 0.7.0. Use nowjs#connect instead. +327 * @description Called in the context of a user when the server +328 * first receives a message from the given user. +329 */ +330 +331 /** +332 * @name Group#disconnect +333 * @event +334 * @deprecated As of 0.7.0. Use nowjs#disconnect instead. +335 * @description Called in the context of a user who has just +336 * disconnected from the server. +337 */ +338 \ No newline at end of file diff --git a/doc/jsdoc/symbols/src/flotype_now_lib_handlers.js.html b/doc/jsdoc/symbols/src/flotype_now_lib_handlers.js.html new file mode 100644 index 0000000..6c60ce0 --- /dev/null +++ b/doc/jsdoc/symbols/src/flotype_now_lib_handlers.js.html @@ -0,0 +1,148 @@ +
  1 var nowUtil = require('./nowUtil').nowUtil;
+  2 
+  3 exports.initialize = function (nowjs) {
+  4   function multicall(group, fqn, args) {
+  5     var user, func;
+  6     for (var i = 0, k = Object.keys(group.users), l = k.length; i < l; i++) {
+  7       user = group.users[k[i]];
+  8       if (group.excludes[user.user.clientId]) {
+  9         continue;
+ 10       }
+ 11       func = user.get(fqn);
+ 12       user = nowUtil.clone(user, {fqn: fqn});
+ 13 
+ 14       // Call the function with group.now and group.user
+ 15       if (typeof func === 'function') {
+ 16         func.apply(user, args);
+ 17       } else {
+ 18         // err
+ 19       }
+ 20     }
+ 21   }
+ 22 
+ 23   function replaceVar(group, fqn, val) {
+ 24     var exclusive = false;
+ 25     for (var j in group.excludes) {
+ 26       if (group.excludes[j]) {
+ 27         exclusive = true;
+ 28         break;
+ 29       }
+ 30     }
+ 31     var users = Object.keys(group.users);
+ 32     var i = 0, ll = users.length;
+ 33     var toSend = {},
+ 34     flattenedVal = {},
+ 35     fqns,
+ 36     user;
+ 37 
+ 38     // Setup: generate flattenedVal and toSend.
+ 39     if (val && typeof val === 'object') {
+ 40       flattenedVal = nowUtil.flatten(val, fqn);
+ 41       fqns = Object.keys(flattenedVal);
+ 42       // Iterate through all leaves.
+ 43       for (i = 0, ll = fqns.length; i < ll; i++) {
+ 44         toSend[fqns[i]] = nowUtil.getValOrFqn(flattenedVal[fqns[i]], fqns[i]);
+ 45       }
+ 46     } else {
+ 47       // val is not an object.
+ 48       fqns = [fqn];
+ 49       toSend[fqn] = nowUtil.getValOrFqn(val, fqn);
+ 50       flattenedVal[fqn] = val;
+ 51     }
+ 52 
+ 53     var ff = fqns.length, k;
+ 54     if (exclusive) {
+ 55       for (i = 0, ll = users.length; i < ll; i++) {
+ 56         user = group.users[users[i]];
+ 57         if (group.excludes[user.user.clientId]) {
+ 58           continue;
+ 59         }
+ 60         // Clear the user's scopeTable entry before setting the new
+ 61         // value.
+ 62         user.deleteVar(fqn);
+ 63         user.socket.emit('rv', toSend);
+ 64 
+ 65         if (ff === 0) {
+ 66           group.scopeTable.set(fqn, []);
+ 67         }
+ 68 
+ 69         for (k = 0; k < ff; k++) {
+ 70           // Set values for individual users.
+ 71           user.scopeTable.set(fqns[k], flattenedVal[fqns[k]]);
+ 72         }
+ 73       }
+ 74       return;
+ 75     } else {
+ 76       // Not an exclusive group.
+ 77       group.deleteVar(fqn);
+ 78       for (k = 0; k < ff; k++) {
+ 79         // Set values for the group.
+ 80         group.scopeTable.set(fqns[k], flattenedVal[fqns[k]]);
+ 81       }
+ 82       if (ff === 0) {
+ 83         group.scopeTable.set(fqn, []);
+ 84         toSend[fqn] = {};
+ 85       }
+ 86       // Invalidate the value in the group's users' scopeTables
+ 87       for (i = 0, ll = users.length; i < ll; i++) {
+ 88         user = group.users[users[i]];
+ 89         user.scopeTable.deleteVar(fqn);
+ 90         user.socket.emit('rv', toSend);
+ 91       }
+ 92     }
+ 93 
+ 94     // If e is `everyone`, invalidate the values in the lesser groups
+ 95     if (group.isSuperGroup) {
+ 96       var groups = Object.keys(nowjs.groups);
+ 97       if (groups[0] === 'everyone') {
+ 98         for (i = 1, ll = groups.length; i < ll; i++) {
+ 99           // everyone is guaranteed to be the first group in keys.
+100           group = nowjs.groups[groups[i]];
+101           group.scopeTable.deleteVar(fqn);
+102         }
+103       } else {
+104         // stupid people, using numbers as group names...
+105         for (i = 0, ll = groups.length; i < ll; i++) {
+106           if (groups[i] !== 'everyone') {
+107             group = nowjs.groups[groups[i]];
+108             group.scopeTable.deleteVar(fqn);
+109           }
+110         }
+111       }
+112     }
+113   }
+114 
+115   function deleteVar(group, fqn) {
+116     var keys = Object.keys(group.users);
+117     var user;
+118     for (var i = 0, ll = keys.length; i < ll; i++) {
+119       user = group.users[keys[i]];
+120       // Only send to users who haven't overwritten the value at the
+121       // provided fqn.
+122       if (user.scopeTable[fqn] === undefined) {
+123         user.socket.emit('del', fqn);
+124       }
+125     }
+126     group.scopeTable.deleteVar(fqn);
+127   }
+128 
+129 
+130   nowjs.on('multicall', function (e, args) {
+131     multicall(e, e.fqn, args);
+132   });
+133 
+134   nowjs.on('grouprv', function (e) {
+135     replaceVar(e, e.fqn, e.val);
+136   });
+137 
+138   nowjs.on('groupdel', function (e) {
+139     deleteVar(e, e.fqn);
+140   });
+141 };
\ No newline at end of file diff --git a/doc/jsdoc/symbols/src/flotype_now_lib_now.js.html b/doc/jsdoc/symbols/src/flotype_now_lib_now.js.html index a76cf93..d0760c3 100644 --- a/doc/jsdoc/symbols/src/flotype_now_lib_now.js.html +++ b/doc/jsdoc/symbols/src/flotype_now_lib_now.js.html @@ -22,7 +22,7 @@ 15 this.options = { 16 clientWrite: true, 17 autoHost: true, - 18 socketio: {}, + 18 socketio: {"log level" : 2}, 19 client: {}, 20 scope: 'window', 21 closureTimeout: 30000 @@ -71,169 +71,198 @@ 64 /** 65 * @memberOf nowjs# 66 * @function - 67 * @name getGroup - 68 * @description Retrieves and returns a group from its name, creating it if - 69 * necessary. - 70 * @param {String} name The name of the group to be retrieved. - 71 * @type Group - 72 * @example var new_group = nowjs.getGroup('a new group'); - 73 */ - 74 Now.prototype.getGroup = function (name) { - 75 if (!nowUtil.hasProperty(this.groups, name)) { - 76 this.groups[name] = new this.Group(name); - 77 /** - 78 * @name nowjs#newgroup - 79 * @event - 80 * @param {Group} group The group created by {@link nowjs#getGroup}. - 81 * @description Called when a new group is created. - 82 * @example nowjs.on('newgroup', function (name) { - 83 * console.log('You have successfully created the group `' + name + '`'); - 84 * }); - 85 */ + 67 * @name getGroups + 68 + 69 * @description Retrieves a list (represented in Javascript as an + 70 * array) of all groups that have been created and passes it in to the + 71 * supplied callback. + 72 + 73 * @param {Function} callback Takes one argument, an array of all + 74 * groups that have been created. + 75 + 76 * @example nowjs.on('connect', function () { + 77 * var self = this; + 78 * getGroups(function (groups) { + 79 * nowjs.getGroup(groups[Math.floor(groups.length * Math.random())]).addUser(self); + 80 * }); + 81 * }); + 82 */ + 83 Now.prototype.getGroups = function (callback) { + 84 callback(Object.keys(this.groups)); + 85 }; 86 - 87 this.emit('newgroup', this.groups[name]); - 88 } - 89 return this.groups[name]; - 90 }; - 91 - 92 /** - 93 * @static - 94 * @memberOf nowjs - 95 * @function - 96 * @name initialize - 97 - 98 * @description Returns a reference to the `everyone` object. The - 99 * options object, if supplied, will be automatically merged with the -100 * default values. -101 -102 * @param {httpServer} server A Node.js http server (such as the one -103 * available in the http module or a module like Express) on which to -104 * run Now. -105 -106 * @param {Object} [options={"clientWrite" : true, "autoHost" : true, -107 "host" : undefined, "port" : undefined, "socketio" : {}, -108 "closureTimeout : 30000, "client : {}, "scope" : "window"}] + 87 /** + 88 * @memberOf nowjs# + 89 * @function + 90 * @name getGroup + 91 * @description Retrieves and returns a group from its name, creating it if + 92 * necessary. + 93 * @param {String} name The name of the group to be retrieved. + 94 * @type Group + 95 * @example var new_group = nowjs.getGroup('a new group'); + 96 */ + 97 Now.prototype.getGroup = function (name) { + 98 if (!nowUtil.hasProperty(this.groups, name)) { + 99 this.groups[name] = new this.Group(name); +100 /** +101 * @name nowjs#newgroup +102 * @event +103 * @param {Group} group The group created by {@link nowjs#getGroup}. +104 * @description Called when a new group is created. +105 * @example nowjs.on('newgroup', function (name) { +106 * console.log('You have successfully created the group `' + name + '`'); +107 * }); +108 */ 109 -110 * @type Group -111 -112 * @example nowjs.initialize(server, {clientWrite: false, socketio: {'log level': 2}); -113 */ -114 Now.prototype.initialize = function (server, options) { -115 // Merge options -116 if (typeof options === 'object') { -117 nowUtil.extend(this.options, options); -118 } else { -119 options = this._readConfigFile(options); -120 if (options) { -121 nowUtil.extend(this.options, options); -122 } -123 } +110 this.emit('newgroup', this.groups[name]); +111 } +112 return this.groups[name]; +113 }; +114 +115 /** +116 * @static +117 * @memberOf nowjs +118 * @function +119 * @name initialize +120 +121 * @description Returns a reference to the `everyone` object. The +122 * options object, if supplied, will be automatically merged with the +123 * default values. 124 -125 this.Group = require('./group').initialize(this); -126 this.User = require('./user').initialize(this); -127 this.Handlers = require('./handlers').initialize(this); +125 * @param {httpServer} server A Node.js http server (such as the one +126 * available in the http module or a module like Express) on which to +127 * run Now. 128 -129 var self = this; -130 -131 fileServer.wrapServer(server, this.options); -132 this.server = io.listen(server); -133 for (var i in this.options.socketio) { -134 this.server.set(i, this.options.socketio[i]); -135 } -136 -137 // Need this to be separate from clientsMap. -138 this.server.sockets.on('connection', function (socket) { -139 var user = new self.User(socket); -140 socket.user = self.users[socket.id] = user; -141 self.getGroup('everyone').addUser(socket.id); -142 socket.emit('rd'); -143 }); -144 -145 var everyone = this.getGroup('everyone'); -146 everyone.isSuperGroup = true; +129 * @param {Object} [options={"clientWrite" : true, "autoHost" : true, +130 "host" : undefined, "port" : undefined, "socketio" : {}, +131 "closureTimeout : 30000, "client : {}, "scope" : "window"}] +132 +133 * @type Group +134 +135 * @example nowjs.initialize(server, {clientWrite: false, socketio: {'log level': 2}); +136 */ +137 Now.prototype.initialize = function (server, options) { +138 // Merge options +139 if (typeof options === 'object') { +140 nowUtil.extend(this.options, options); +141 } else { +142 options = this._readConfigFile(options); +143 if (options) { +144 nowUtil.extend(this.options, options); +145 } +146 } 147 -148 // Shim for backwards compatibility. -149 this.on('connect', function () { -150 var user = nowUtil.clone(this); -151 user._events = everyone._events; -152 everyone.emit.apply(user, ['connect']); -153 }); +148 this.Group = require('./group').initialize(this); +149 this.User = require('./user').initialize(this); +150 this.Handlers = require('./handlers').initialize(this); +151 this.Support = require('./support').initialize(this); +152 +153 var self = this; 154 -155 this.on('disconnect', function () { -156 var user = nowUtil.clone(this); -157 user._events = everyone._events; -158 everyone.emit.apply(user, ['disconnect']); -159 }); +155 fileServer.wrapServer(server, this.options); +156 this.server = io.listen(server); +157 for (var i in this.options.socketio) { +158 this.server.set(i, this.options.socketio[i]); +159 } 160 -161 return everyone; -162 }; -163 -164 exports.Now = Now; -165 -166 /** -167 * @name nowjs#connect -168 * @event -169 * @version 0.7.0 -170 -171 * @description Called in the context of a user when the server first -172 * receives a message from the given user. -173 -174 * @example nowjs.on('connect', function () { -175 * this.now.receiveMessage('SERVER', 'Welcome to NowJS.'); -176 * }); -177 */ +161 // Need this to be separate from clientsMap. +162 this.server.sockets.on('connection', function (socket) { +163 var user = new self.User(socket); +164 socket.user = self.users[socket.id] = user; +165 self.getGroup('everyone').addUser(socket.id); +166 socket.emit('rd'); +167 }); +168 +169 var everyone = this.getGroup('everyone'); +170 everyone.isSuperGroup = true; +171 +172 // Shim for backwards compatibility. +173 this.on('connect', function () { +174 var user = nowUtil.clone(this); +175 user._events = everyone._events; +176 everyone.emit.apply(user, ['connect']); +177 }); 178 -179 /** -180 * @name nowjs#disconnect -181 * @event -182 * @version 0.7.0 -183 -184 * @description Called in the context of a user who has just -185 * disconnected from the server. -186 -187 * @example nowjs.on('disconnect, function () { -188 * delete myArray[this.user.clientId]; -189 * }); -190 */ -191 -192 /** -193 * @name nowjs#groupdel -194 * @event -195 * @version 0.7.0 -196 -197 * @param {Group} group Actually not quite a group; this parameter -198 * refers to a clone of the group in question that also carries the -199 * fully qualified name (fqn) of the variable to delete. Access the -200 * fqn via `group.fqn`. -201 -202 * @description Called when deleting a variable from all members of -203 * the group specified by this function's argument. -204 -205 * @example nowjs.on('groupdel', function (group) { -206 * if (group.groupName === 'everyone') { -207 * console.log('Everyone now no longer possesses ' + group.fqn); -208 * } -209 * }); -210 */ -211 -212 /** -213 * @name nowjs#grouprv -214 * @event -215 * @version 0.7.0 -216 -217 * @param {Group} group Similar to {@link nowjs#groupdel}, this is also -218 * a clone of the actual group. In addition to the fully qualified -219 * name, this clone also possesses a serialized form of its target -220 * value, accessible via `group.val`. -221 -222 * @description Called when replacing the value of a variable for all -223 * members of the group specified by this function's argument. -224 -225 * @example nowjs.on('grouprv', function (group) { -226 * if (group.groupName === 'everyone') { -227 * console.log('Everyone now sees ' + group.fqn + ' as ' + group.val); -228 * } -229 * }); -230 */ -231 -232 \ No newline at end of file +179 this.on('disconnect', function () { +180 var user = nowUtil.clone(this); +181 user._events = everyone._events; +182 everyone.emit.apply(user, ['disconnect']); +183 }); +184 +185 return everyone; +186 }; +187 +188 Now.prototype.addSupportServer = function(host, port){ +189 var server = new this.Support(host, port); +190 return server; +191 } +192 +193 exports.Now = Now; +194 +195 /** +196 * @name nowjs#connect +197 * @event +198 * @version 0.7.0 +199 +200 * @description Called in the context of a user when the server first +201 * receives a message from the given user. +202 +203 * @example nowjs.on('connect', function () { +204 * this.now.receiveMessage('SERVER', 'Welcome to NowJS.'); +205 * }); +206 */ +207 +208 /** +209 * @name nowjs#disconnect +210 * @event +211 * @version 0.7.0 +212 +213 * @description Called in the context of a user who has just +214 * disconnected from the server. +215 +216 * @example nowjs.on('disconnect, function () { +217 * delete myArray[this.user.clientId]; +218 * }); +219 */ +220 +221 /** +222 * @name nowjs#groupdel +223 * @event +224 * @version 0.7.0 +225 +226 * @param {Group} group Actually not quite a group; this parameter +227 * refers to a clone of the group in question that also carries the +228 * fully qualified name (fqn) of the variable to delete. Access the +229 * fqn via `group.fqn`. +230 +231 * @description Called when deleting a variable from all members of +232 * the group specified by this function's argument. +233 +234 * @example nowjs.on('groupdel', function (group) { +235 * if (group.groupName === 'everyone') { +236 * console.log('Everyone now no longer possesses ' + group.fqn); +237 * } +238 * }); +239 */ +240 +241 /** +242 * @name nowjs#grouprv +243 * @event +244 * @version 0.7.0 +245 +246 * @param {Group} group Similar to {@link nowjs#groupdel}, this is also +247 * a clone of the actual group. In addition to the fully qualified +248 * name, this clone also possesses a serialized form of its target +249 * value, accessible via `group.val`. +250 +251 * @description Called when replacing the value of a variable for all +252 * members of the group specified by this function's argument. +253 +254 * @example nowjs.on('grouprv', function (group) { +255 * if (group.groupName === 'everyone') { +256 * console.log('Everyone now sees ' + group.fqn + ' as ' + group.val); +257 * } +258 * }); +259 */ +260 +261 \ No newline at end of file diff --git a/doc/jsdoc/symbols/src/flotype_now_lib_nowUtil.js.html b/doc/jsdoc/symbols/src/flotype_now_lib_nowUtil.js.html new file mode 100644 index 0000000..721b721 --- /dev/null +++ b/doc/jsdoc/symbols/src/flotype_now_lib_nowUtil.js.html @@ -0,0 +1,172 @@ +
  1 /**
+  2  * NowUtil: an assorted collection of general-purpose functions used
+  3  * in NowJS.
+  4  */
+  5 
+  6 Object.defineProperty(Array.prototype,
+  7                       'toJSON',
+  8                       { enumerable: false,
+  9                         value: function () {
+ 10                           if (Array.isArray(this)) {
+ 11                             return this;
+ 12                           }
+ 13                           var toReturn = [];
+ 14  15                           for (var i = 0, ll = this.length; i < ll; i++) {
+ 16                             toReturn[i] = this[i];
+ 17                           }
+ 18                           return toReturn;
+ 19                         }
+ 20                       });
+ 21 
+ 22 var util = {
+ 23   parseCookie: function (cookie) {
+ 24     if (typeof cookie !== 'string') {
+ 25       return {};
+ 26     }
+ 27     var regex = /(.+?)(;|$)\s*/g;
+ 28     var match = cookie.match(regex);
+ 29     if (!match) {
+ 30       return {};
+ 31     }
+ 32     var jsonCookie = {};
+ 33     var m, end, index;
+ 34     for (var i = 0; i < match.length; i++) {
+ 35       m = match[i];
+ 36       index = m.indexOf('=');
+ 37       end = m.lastIndexOf(';');
+ 38       if (index === -1) {
+ 39         jsonCookie[m.substr(index + 1,
+ 40                             end + 1 ?
+ 41                             end - index - 1:
+ 42                             undefined)] = true;
+ 43       } else {
+ 44         jsonCookie[m.substr(0, index)] = m.substr(index + 1,
+ 45                                                   (end + 1 ?
+ 46                                                    end - index - 1 :
+ 47                                                    undefined));
+ 48       }
+ 49     }
+ 50     return jsonCookie;
+ 51   },
+ 52 
+ 53   hasProperty: function (obj, prop) {
+ 54     return Object.prototype.hasOwnProperty.call(Object(obj), prop);
+ 55   },
+ 56 
+ 57   noop: function () {
+ 58   },
+ 59 
+ 60   clone: function (proto, obj) {
+ 61     // note regarding speed and C++ bindings: evidently it's slightly
+ 62     // faster to provide a wrapper function than adding an additional
+ 63     // level of lookup.
+ 64     if (!(obj && typeof obj === 'object')) {
+ 65       obj = {};
+ 66     }
+ 67     obj.__proto__ = proto;
+ 68     return obj;
+ 69   },
+ 70 
+ 71   generateRandomString: function () {
+ 72     return ("" + Math.random()).substring(2);
+ 73   },
+ 74 
+ 75   error: function (err) {
+ 76     console.log(err);
+ 77     if (util.hasProperty(err, 'stack')) {
+ 78       console.log(err.stack);
+ 79     }
+ 80   },
+ 81 
+ 82   getAllChildFqns: function (parentObj, parentFqn) {
+ 83     var fqns = [];
+ 84     var prop;
+ 85     function getAllChildFqnsHelper(parentObj, parentFqn) {
+ 86       for (var i = 0, keys = Object.keys(parentObj), ll = keys.length; i < ll; i++ ) {
+ 87         prop = keys[i];
+ 88         if (parentObj[prop] && typeof parentObj[prop] === 'object') {
+ 89           getAllChildFqnsHelper(parentObj[prop], parentFqn + '.' + prop);
+ 90         } else {
+ 91           fqns.push(parentFqn + '.' + prop);
+ 92         }
+ 93       }
+ 94       if (ll == 0) {
+ 95         fqns.push(parentFqn);
+ 96       }
+ 97     }
+ 98     getAllChildFqnsHelper(parentObj, parentFqn);
+ 99     return fqns;
+100   },
+101 
+102   extend: function (target, obj) {
+103     for (var i = 0, keys = Object.keys(obj), ii = keys.length; i < ii; i++) {
+104       var key = keys[i];
+105       if (obj[key] && typeof obj[key] === 'object') {
+106         if(Array.isArray(obj[key])) {
+107           target[key] = target[key] || [];
+108         } else {
+109           target[key] = target[key] || {};
+110         }
+111         util.extend(target[key], obj[key]);
+112       } else {
+113         target[key] = obj[key];
+114       }
+115     }
+116   },
+117 
+118   getVarFromFqn: function (fqn, scope) {
+119     var path = fqn.split('.');
+120     path.shift();
+121     var currVar = scope;
+122     var prop;
+123     while (path.length > 0) {
+124       prop = path.shift();
+125       if (util.hasProperty(currVar, prop)) {
+126         currVar = currVar[prop];
+127       } else {
+128         return false;
+129       }
+130     }
+131     return currVar;
+132   },
+133 
+134   stringify: JSON.stringify,
+135 
+136   parse: JSON.parse,
+137 
+138   flatten: function (val, fqn) {
+139     var vals = {};
+140     var fqns = util.getAllChildFqns(val, '');
+141     var m;
+142     for (var i = 0, ii = fqns.length; i < ii; i++) {
+143       m = util.getVarFromFqn(fqns[i], val);
+144       vals[fqn + fqns[i]] = m;
+145     }
+146     return vals;
+147   },
+148 
+149   getValOrFqn: function (val, fqn) {
+150     if (typeof val === 'function') {
+151       return {fqn: fqn};
+152     } else {
+153       return val;
+154     }
+155   },
+156 
+157   isEmptyObj: function (obj) {
+158     for (var i in obj) {
+159       return false;
+160     }
+161     return true;
+162   }
+163 };
+164 
+165 exports.nowUtil = util;
+166 
\ No newline at end of file diff --git a/doc/jsdoc/symbols/src/flotype_now_lib_proxy.js.html b/doc/jsdoc/symbols/src/flotype_now_lib_proxy.js.html new file mode 100644 index 0000000..f6c0ad8 --- /dev/null +++ b/doc/jsdoc/symbols/src/flotype_now_lib_proxy.js.html @@ -0,0 +1,81 @@ +
  1 /**
+  2  * wrap.js
+  3  *
+  4  * Wrap provides the proxy object that is exposed to the server.
+  5  * Changes/additions to the object's properties and nested objects
+  6  * trigger the store function to be called.
+  7  *
+  8  */
+  9 
+ 10 var Proxy = require('node-proxy');
+ 11 
+ 12 exports.wrap = function (entity) {
+ 13   function wrapRoot(path, proto) {
+ 14     return Proxy.create({
+ 15       get : function (receiver, name) {
+ 16         if (Array.isArray(proto) && name === 'length') {
+ 17           var arr = entity.scopeTable.get(path);
+ 18           return entity.scopeTable.flagAsArray(path, arr.length && (1 + 1 * arr[arr.length - 1]));
+ 19         }
+ 20         var fqn = path + '.' + name;
+ 21         var returnObj = entity.get(fqn);
+ 22         if (returnObj && typeof returnObj === 'object') {
+ 23           var p = (entity.scopeTable.arrays[fqn] === undefined) ? Object.prototype : Array.prototype;
+ 24           if (p === Array.prototype) {
+ 25             entity.scopeTable.flagAsArray(fqn, returnObj[returnObj.length - 1] || 0);
+ 26           }
+ 27           return wrapRoot(fqn, p);
+ 28         }
+ 29         if (returnObj === undefined && proto[name]) {
+ 30           return proto[name];
+ 31         }
+ 32         return returnObj;
+ 33       },
+ 34       set : function (receiver, name, value) {
+ 35         var fqn = path + '.' + name;
+ 36         if (proto === Array.prototype) {
+ 37           var len = 1 * entity.scopeTable.arrays[path] || 0;
+ 38           if (name === 'length') {
+ 39             return entity.scopeTable.flagAsArray(path, value);
+ 40           }
+ 41           if (name > len) {
+ 42             entity.scopeTable.flagAsArray(path, 1 + name);
+ 43             while (len <= name) {
+ 44               receiver[len++] = undefined;
+ 45             }
+ 46           }
+ 47         }
+ 48         entity.set(fqn, value);
+ 49         if (!value || typeof value !== 'object') {
+ 50           return value;
+ 51         }
+ 52         if (Array.isArray(value)) {
+ 53           entity.scopeTable.flagAsArray(fqn, value.length);
+ 54         }
+ 55         return wrapRoot(fqn, value.constructor.prototype);
+ 56       },
+ 57       enumerate : function () {
+ 58         return entity.scopeTable.get(path);
+ 59       },
+ 60       hasOwn : function (name) {
+ 61         return entity.scopeTable.get(path + '.' + name) !== undefined;
+ 62       },
+ 63       delete : function (name) {
+ 64         var fqn = path + '.' + name;
+ 65         entity.deleteVar(fqn);
+ 66       },
+ 67       fix : function () {
+ 68         return undefined;
+ 69       }
+ 70     }, proto);
+ 71   }
+ 72   return wrapRoot('now', Object.prototype);
+ 73 };
+ 74 
\ No newline at end of file diff --git a/doc/jsdoc/symbols/src/flotype_now_lib_scopeTable.js.html b/doc/jsdoc/symbols/src/flotype_now_lib_scopeTable.js.html new file mode 100644 index 0000000..db1ccbe --- /dev/null +++ b/doc/jsdoc/symbols/src/flotype_now_lib_scopeTable.js.html @@ -0,0 +1,71 @@ +
  1 var nowUtil = require('./nowUtil').nowUtil;
+  2 var ScopeTable = function (data) {
+  3   this.data = data || {};
+  4   this.arrays = {};
+  5 };
+  6 
+  7 ScopeTable.prototype.get = function (fqn) {
+  8   // does not reconstruct objects. :P
+  9   return this.data[fqn];
+ 10 };
+ 11 
+ 12 ScopeTable.prototype.set = function (fqn, val) {
+ 13   if (this.data[fqn] !== undefined) {
+ 14     this.deleteChildren(fqn);
+ 15   } else {
+ 16     var lastIndex = fqn.lastIndexOf('.');
+ 17     var parent = fqn.substring(0, lastIndex);
+ 18     this.addParent(parent, fqn.substring(lastIndex + 1));
+ 19   }
+ 20   delete this.arrays[fqn];
+ 21   return (this.data[fqn] = val);
+ 22 };
+ 23 
+ 24 ScopeTable.prototype.addParent = function (parent, key) {
+ 25   if (parent) {
+ 26     if (!Array.isArray(this.data[parent])) {
+ 27       this.set(parent, []); // Handle changing a non-object to an object.
+ 28     }
+ 29     this.data[parent].push(key);
+ 30   }
+ 31 };
+ 32 
+ 33 ScopeTable.prototype.deleteChildren = function (fqn) {
+ 34   var keys = this.data[fqn];
+ 35   if (Array.isArray(this.data[fqn])) {
+ 36     // Deleting a child will remove it via splice.
+ 37     for (var i = 0; keys.length;) {
+ 38       // Recursive delete all children.
+ 39       this.deleteVar(fqn + '.' + keys[i]);
+ 40     }
+ 41   }
+ 42 };
+ 43 
+ 44 ScopeTable.prototype.deleteVar = function (fqn) {
+ 45   var lastIndex = fqn.lastIndexOf('.');
+ 46   var parent = fqn.substring(0, lastIndex);
+ 47 
+ 48   if (nowUtil.hasProperty(this.data, fqn)) {
+ 49     // Remove from its parent.
+ 50     var index = this.data[parent].indexOf(fqn.substring(lastIndex + 1));
+ 51     if (index > -1) {
+ 52       this.data[parent].splice(index, 1);
+ 53     }
+ 54     this.deleteChildren(fqn);
+ 55     delete this.data[fqn];
+ 56     delete this.arrays[fqn];
+ 57   }
+ 58 };
+ 59 
+ 60 ScopeTable.prototype.flagAsArray = function (fqn, len) {
+ 61   return (this.arrays[fqn] = len);
+ 62 };
+ 63 
+ 64 exports.ScopeTable = ScopeTable;
\ No newline at end of file diff --git a/doc/jsdoc/symbols/src/flotype_now_lib_server.js.html b/doc/jsdoc/symbols/src/flotype_now_lib_server.js.html new file mode 100644 index 0000000..97f4deb --- /dev/null +++ b/doc/jsdoc/symbols/src/flotype_now_lib_server.js.html @@ -0,0 +1,15 @@ +
  1 var nowUtil = require('./nowUtil').nowUtil;
+  2 var Now = require('./now').Now;
+  3 
+  4 process.on('uncaughtException', function (err) {
+  5   nowUtil.error(err);
+  6 });
+  7 
+  8 module.exports = new Now();
\ No newline at end of file diff --git a/doc/jsdoc/symbols/src/flotype_now_lib_support.js.html b/doc/jsdoc/symbols/src/flotype_now_lib_support.js.html new file mode 100644 index 0000000..e6d3556 --- /dev/null +++ b/doc/jsdoc/symbols/src/flotype_now_lib_support.js.html @@ -0,0 +1,110 @@ +
  1 var net = require('net');
+  2 var nowUtil = require('./nowUtil').nowUtil;
+  3 
+  4 exports.initialize = function(nowjs){
+  5   var fn = require('./function').init(nowjs);
+  6 
+  7   function Support(host, port){
+  8     this.socket = net.createConnection(port, host);
+  9     this._attachListeners();
+ 10     this.socket.setNoDelay();
+ 11     this.availableFunctions = {};
+ 12   }
+ 13 
+ 14   Support.prototype._startHandshake = function(){
+ 15     this.socket.write(JSON.stringify({type:'new'}));
+ 16   };
+ 17 
+ 18   Support.prototype._attachListeners = function(){
+ 19     var self = this;
+ 20     this.socket.on('connect', function(){self._startHandshake();});
+ 21     this.socket.on('data', function(message){self._handleMessage(message);});
+ 22   };
+ 23 
+ 24   Support.prototype.getRemoteFunction = function(fn) {
+ 25     var self = this;
+ 26     if(this.availableFunctions[fn] == undefined){throw new Error("No such function: " + fn);};
+ 27     return function(){
+ 28       var args = [];
+ 29       for (var i = 0, ii = arguments.length; i < ii; i++) {
+ 30         args[i] = arguments[i];
+ 31       }
+ 32       for (i = 0, ii = args.length; i < ii; i++) {
+ 33         if (typeof args[i] === 'function') {
+ 34           closureId = 'closure_' + args[i].name + '_' + nowUtil.generateRandomString();
+ 35           nowjs.closures[closureId] = args[i];
+ 36           args[i] = {fqn: closureId};
+ 37           setTimeout(function () {
+ 38             nowjs.closures[closureId] = nowUtil.noop;
+ 39           }, nowjs.options.closureTimeout);
+ 40         }
+ 41       }
+ 42 
+ 43       self.socket.write(JSON.stringify({type: 'rfc',fqn:fn, args:args}));
+ 44     };
+ 45   };
+ 46 
+ 47   Support.prototype._handleMessage = function(message){
+ 48     message = JSON.parse(message.toString());
+ 49     switch(message.type){
+ 50     case "usercall":
+ 51       var user = nowjs.users[message.id];
+ 52       if (user && message.serverId !== nowjs.serverId) {
+ 53         args = message.args;
+ 54         // Convert any remote function stubs into remote functions
+ 55         for (i = 0, ll = args.length; i < ll; i++) {
+ 56           if (nowUtil.hasProperty(args[i], 'fqn')) {
+ 57             obj = {host: message.host, port:message.port, fqn: args[i].fqn};
+ 58             args[i] = fn.closurecall.bind(obj);
+ 59           }
+ 60         }
+ 61         theFunction = user.get(message.fqn);
+ 62         theFunction.apply({}, args);
+ 63       } 
+ 64       break;
+ 65     case "multicall":
+ 66       group = nowjs.getGroup(message.groupName);
+ 67       //group = nowUtil.clone(group, {excludes: message.excludes});
+ 68       if (group) {
+ 69         args = message.args;
+ 70         // Convert any remote function stubs into remote functions
+ 71         for (i = 0, ll = args.length; i < ll; i++) {
+ 72           if (nowUtil.hasProperty(args[i], 'fqn')) {
+ 73             obj = {socket: this.socket, host: message.host, port:message.port, fqn: args[i].fqn};
+ 74             args[i] = fn.closurecall.bind(obj);
+ 75           }
+ 76         }
+ 77         group = nowUtil.clone(group, {fqn: message.fqn});
+ 78         nowjs.emit('multicall', group, args);
+ 79       }
+ 80       break;
+ 81     case 'closurecall':
+ 82       var args = message.args;
+ 83       // Convert any remote function stubs into remote functions
+ 84       for (i = 0, ll = args.length; i < ll; i++) {
+ 85         if (nowUtil.hasProperty(args[i], 'fqn')) {
+ 86           obj = {socket: this.socket, host: message.host, port:message.port, fqn: args[i].fqn};
+ 87           args[i] = fn.closurecall.bind(obj);
+ 88         }
+ 89       }
+ 90       theFunction = nowjs.closures[message.fqn];
+ 91       theFunction.apply({}, args);
+ 92       break;
+ 93     case 'functionList':
+ 94       var funcs = message.functions;
+ 95       for(var i = 0, ll = funcs.length; i < ll; i++){
+ 96         this.availableFunctions[funcs[i]] = true;
+ 97       }
+ 98     }
+ 99   };
+100 
+101 
+102   return Support;
+103 }
\ No newline at end of file diff --git a/doc/jsdoc/symbols/src/flotype_now_lib_user.js.html b/doc/jsdoc/symbols/src/flotype_now_lib_user.js.html index eb56d75..a39e12e 100644 --- a/doc/jsdoc/symbols/src/flotype_now_lib_user.js.html +++ b/doc/jsdoc/symbols/src/flotype_now_lib_user.js.html @@ -53,189 +53,197 @@ 46 47 * @property {String} clientId The user's ID, as created by 48 * Socket.IO. - 49 */ - 50 this.user = { clientId: socket.id }; - 51 - 52 // set to true upon first replaceVar and emit connect event - 53 /** - 54 * @private - 55 */ - 56 this.ready = false; - 57 - 58 /** - 59 * @name User#now - 60 * @namespace Synchronized with the connected user's local now - 61 * namespace; function calls with respect to this namespace will - 62 * only be executed for the current user. - 63 * @see User - 64 * @see User#user - 65 - 66 * @example everyone.now.prop = 42; - 67 * @example everyone.now.func = function () { - 68 * console.log('hello!'); - 69 * }; - 70 */ - 71 this.now = Proxy.wrap(this); - 72 - 73 // Remote function call handler - 74 socket.on('rfc', function rfcHandler(data) { - 75 var theFunction; - 76 if (data.fqn.split('_')[0] === 'closure') { - 77 theFunction = nowjs.closures[data.fqn]; - 78 } else { - 79 theFunction = self.get(data.fqn); - 80 } - 81 var args = data.args; - 82 // Convert any remote function stubs into remote functions - 83 var user; - 84 for (var i = 0, ll = args.length; i < ll; i++) { - 85 if (nowUtil.hasProperty(args[i], 'fqn')) { - 86 user = nowUtil.clone(self, {fqn: args[i].fqn}); - 87 args[i] = fn.remotecall.bind(user); - 88 } - 89 } - 90 theFunction.apply(self, args); - 91 }); - 92 - 93 // Replace var handler - 94 if (nowjs.options.clientWrite) { - 95 socket.on('rv', function rvHandler(data) { - 96 var keys = Object.keys(data); - 97 var everyone = nowjs.getGroup('everyone'); - 98 var fqn, user, value; - 99 for (var i = 0, ll = keys.length; i < ll ; i++) { -100 fqn = keys[i]; -101 value = data[fqn]; -102 user = nowUtil.clone(self); -103 user.fqn = fqn; -104 if (nowUtil.hasProperty(value, 'fqn')) { -105 value = fn.remotecall.bind(user); -106 } -107 // Set directly in scope table to avoid extra processing and -108 // socket firing. -109 self.scopeTable.set(fqn, value); -110 if (typeof value === 'function' && -111 everyone.scopeTable.get(fqn) === undefined) { -112 everyone.scopeTable.set(fqn, nowUtil.noop); -113 } -114 } -115 }); -116 -117 // Called after initial scope sent. Ready handler -118 socket.on('rd', function rdHandler() { -119 var user = nowUtil.clone(self, {'_events': nowjs._events}); -120 nowjs.emit.apply(user, ['connect']); -121 }); -122 -123 // Variable deletion handler -124 socket.on('del', function rfcHandler(data) { -125 // Takes an array of fqns to delete. -126 // Note: Does not handle deleting something that's a group -127 // property (would need to override somehow). -128 for (var i = 0; i < data.length; i++) { -129 // delete straight from scopeTable to bypass emitting 'del'. -130 self.scopeTable.deleteVar(data[i]); -131 } -132 }); -133 } -134 -135 socket.on('disconnect', function () { -136 var user = nowUtil.clone(self, {'_events': nowjs._events}); -137 -138 // trigger 'disconnect' in all groups. -139 for (var g = Object.keys(self.groups), ll = g.length; ll--;) { -140 self.groups[g[ll]].removeUser(self.user.clientId); -141 } -142 nowjs.emit.apply(user, ['disconnect']); -143 -144 delete nowjs.users[self.user.clientId]; -145 }); -146 }; -147 -148 /** -149 * @memberOf User# -150 * @function -151 * @name getGroups + 49 * @property {String} cookie The user's cookie, as determined by + 50 * Socket.IO. + 51 */ + 52 this.user = { clientId: socket.id, cookie: nowUtil.parseCookie(socket.handshake.headers.cookie) }; + 53 + 54 // set to true upon first replaceVar and emit connect event + 55 /** + 56 * @private + 57 */ + 58 this.ready = false; + 59 + 60 /** + 61 * @name User#now + 62 * @namespace Synchronized with the connected user's local now + 63 * namespace; function calls with respect to this namespace will + 64 * only be executed for the current user. + 65 * @see User + 66 * @see User#user + 67 + 68 * @example everyone.now.prop = 42; + 69 * @example everyone.now.func = function () { + 70 * console.log('hello!'); + 71 * }; + 72 */ + 73 this.now = Proxy.wrap(this); + 74 + 75 // Remote function call handler + 76 socket.on('rfc', function rfcHandler(data) { + 77 var theFunction; + 78 if (data.fqn.split('_')[0] === 'closure') { + 79 theFunction = nowjs.closures[data.fqn]; + 80 } else { + 81 theFunction = self.get(data.fqn); + 82 } + 83 var args = data.args; + 84 // Convert any remote function stubs into remote functions + 85 var user; + 86 for (var i = 0, ll = args.length; i < ll; i++) { + 87 if (nowUtil.hasProperty(args[i], 'fqn')) { + 88 user = nowUtil.clone(self, {fqn: args[i].fqn}); + 89 args[i] = fn.remotecall.bind(user); + 90 } + 91 } + 92 theFunction.apply(self, args); + 93 }); + 94 + 95 // Replace var handler + 96 if (nowjs.options.clientWrite) { + 97 socket.on('rv', function rvHandler(data) { + 98 var keys = Object.keys(data); + 99 var everyone = nowjs.getGroup('everyone'); +100 var fqn, user, value; +101 for (var i = 0, ll = keys.length; i < ll ; i++) { +102 fqn = keys[i]; +103 value = data[fqn]; +104 user = nowUtil.clone(self); +105 user.fqn = fqn; +106 if (nowUtil.hasProperty(value, 'fqn')) { +107 value = fn.remotecall.bind(user); +108 } +109 // Set directly in scope table to avoid extra processing and +110 // socket firing. +111 self.scopeTable.set(fqn, (value && typeof value === 'object') ? [] : value); +112 if (typeof value === 'function' && +113 everyone.scopeTable.get(fqn) === undefined) { +114 everyone.scopeTable.set(fqn, nowUtil.noop); +115 } +116 if (Array.isArray(value)) { +117 self.scopeTable.flagAsArray(fqn, 0); +118 } +119 } +120 }); +121 +122 // Called after initial scope sent. Ready handler +123 socket.on('rd', function rdHandler() { +124 var user = nowUtil.clone(self, {'_events': nowjs._events}); +125 nowjs.emit.call(user, 'connect'); +126 }); +127 +128 // Variable deletion handler +129 socket.on('del', function rfcHandler(data) { +130 // Takes an array of fqns to delete. +131 // Note: Does not handle deleting something that's a group +132 // property (would need to override somehow). +133 for (var i = 0; i < data.length; i++) { +134 // delete straight from scopeTable to bypass emitting 'del'. +135 self.scopeTable.deleteVar(data[i]); +136 } +137 }); +138 } +139 +140 socket.on('disconnect', function () { +141 var user = nowUtil.clone(self, {'_events': nowjs._events}); +142 +143 // trigger 'disconnect' in all groups. +144 for (var g = Object.keys(self.groups), ll = g.length; ll--;) { +145 self.groups[g[ll]].removeUser(self.user.clientId); +146 } +147 nowjs.emit.call(user, 'disconnect'); +148 +149 delete nowjs.users[self.user.clientId]; +150 }); +151 }; 152 -153 * @description Used to retrieve a list of the group names -154 * corresponding to all groups the user is in. -155 -156 * @param {Function} callback Called with an Array of Strings -157 * corresponding to the various group names. -158 -159 * @example everyone.now.broadcast = function (message) { -160 * var name = this.now.name; -161 * this.getGroups(function (groups) { -162 * for (var i = groups.length; i--;) { -163 * if (groups[i] !== 'everyone') { -164 * nowjs.getGroup(groups[i]).now.receive(name, message); -165 * } -166 * } -167 * }); -168 */ -169 User.prototype.getGroups = function (callback) { -170 callback(Object.keys(this.groups)); -171 }; -172 -173 /** @private */ -174 User.prototype.get = function (fqn) { -175 // First look in this user's scopeTable -176 var value = this.scopeTable.get(fqn); -177 if (value !== undefined) { -178 return value; -179 } else { -180 // Look through all the groups for the value -181 var i = 0; -182 var keys = Object.keys(this.groups); -183 var ll = keys.length; -184 while (value === undefined && i < ll) { -185 // Look in the scopeTable directly, rather than using Group.get -186 // method. This resolves functions to the real functions -187 // rather than a multicaller. -188 value = this.groups[keys[i++]].scopeTable.get(fqn); -189 } -190 // If this is a function, bind to the current user -191 if (typeof value === 'function') { -192 var userClone = nowUtil.clone(this); -193 userClone.fqn = fqn; -194 value = value.bind(userClone); -195 } -196 -197 // Cache it in this user's scopeTable for quicker access. -198 this.scopeTable[fqn] = value; -199 return value; -200 } -201 }; -202 -203 /** @private */ -204 User.prototype.deleteVar = function (fqn) { -205 this.scopeTable.deleteVar(fqn); -206 this.socket.emit('del', fqn); -207 }; -208 -209 /** @private */ -210 User.prototype.set = function (fqn, val) { -211 var everyone = nowjs.getGroup('everyone'); -212 if (typeof val === 'function' && -213 everyone.scopeTable.get(fqn) === undefined) { -214 everyone.scopeTable.set(fqn, nowUtil.noop); -215 } -216 if (typeof val === 'object') { -217 this.scopeTable.set(fqn, Object.keys(val)); -218 var flattenedVal = nowUtil.flatten(val, fqn); -219 for (var i = 0, key = Object.keys(flattenedVal), ll = key.length; i < ll; i++) { -220 this.scopeTable.set(key[i], flattenedVal[key[i]]); -221 flattenedVal[key[i]] = nowUtil.getValOrFqn(flattenedVal[key[i]], key[i]); -222 } -223 this.socket.emit('rv', flattenedVal); -224 } else { -225 this.scopeTable.set(fqn, val); -226 var toSend = {}; -227 toSend[fqn] = nowUtil.getValOrFqn(val, fqn); -228 this.socket.emit('rv', toSend); -229 } -230 }; -231 -232 return User; -233 }; -234 \ No newline at end of file +153 /** +154 * @memberOf User# +155 * @function +156 * @name getGroups +157 +158 * @description Used to retrieve a list of the group names +159 * corresponding to all groups the user is in. +160 +161 * @param {Function} callback Called with an Array of Strings +162 * corresponding to the various group names. +163 +164 * @example everyone.now.broadcast = function (message) { +165 * var name = this.now.name; +166 * this.getGroups(function (groups) { +167 * for (var i = groups.length; i--;) { +168 * if (groups[i] !== 'everyone') { +169 * nowjs.getGroup(groups[i]).now.receive(name, message); +170 * } +171 * } +172 * }); +173 */ +174 User.prototype.getGroups = function (callback) { +175 callback(Object.keys(this.groups)); +176 }; +177 +178 /** @private */ +179 User.prototype.get = function (fqn) { +180 // First look in this user's scopeTable +181 var value = this.scopeTable.get(fqn); +182 if (value !== undefined) { +183 return value; +184 } else { +185 // Look through all the groups for the value +186 var i = 0; +187 var keys = Object.keys(this.groups); +188 var ll = keys.length; +189 while (value === undefined && i < ll) { +190 // Look in the scopeTable directly, rather than using Group.get +191 // method. This resolves functions to the real functions +192 // rather than a multicaller. +193 value = this.groups[keys[i++]].scopeTable.get(fqn); +194 } +195 // If this is a function, bind to the current user +196 if (typeof value === 'function') { +197 var userClone = nowUtil.clone(this); +198 userClone.fqn = fqn; +199 value = value.bind(userClone); +200 } +201 +202 // Cache it in this user's scopeTable for quicker access. +203 this.scopeTable[fqn] = value; +204 return value; +205 } +206 }; +207 +208 /** @private */ +209 User.prototype.deleteVar = function (fqn) { +210 this.scopeTable.deleteVar(fqn); +211 this.socket.emit('del', fqn); +212 }; +213 +214 /** @private */ +215 User.prototype.set = function (fqn, val) { +216 var everyone = nowjs.getGroup('everyone'); +217 if (typeof val === 'function' && +218 everyone.scopeTable.get(fqn) === undefined) { +219 everyone.scopeTable.set(fqn, nowUtil.noop); +220 } +221 if (typeof val === 'object') { +222 this.scopeTable.set(fqn, Object.keys(val)); +223 var flattenedVal = nowUtil.flatten(val, fqn); +224 for (var i = 0, key = Object.keys(flattenedVal), ll = key.length; i < ll; i++) { +225 this.scopeTable.set(key[i], flattenedVal[key[i]]); +226 flattenedVal[key[i]] = nowUtil.getValOrFqn(flattenedVal[key[i]], key[i]); +227 if (flattenedVal[key[i]] instanceof Array) { +228 this.scopeTable.flagAsArray(key[i], 0); +229 } +230 } +231 this.socket.emit('rv', flattenedVal); +232 } else { +233 this.scopeTable.set(fqn, val); +234 var toSend = {}; +235 toSend[fqn] = nowUtil.getValOrFqn(val, fqn); +236 this.socket.emit('rv', toSend); +237 } +238 }; +239 +240 return User; +241 }; +242 \ No newline at end of file diff --git a/lib/client/now.js b/lib/client/now.js index ed634ea..41110e4 100644 --- a/lib/client/now.js +++ b/lib/client/now.js @@ -19,7 +19,7 @@ try { Object.defineProperty({}, '', {}); return false; - } catch (err) { + } catch (err) { if (Object.prototype.__defineGetter__ && Object.prototype.__defineSetter__) { return false; } else { @@ -27,7 +27,7 @@ } } }()); - + var fqnMap = { data: {}, arrays: {}, @@ -211,7 +211,7 @@ fqnMap.deleteVar(fqn); socket.emit('del', [fqn]); val = newVal; - lib.processScope(obj, fqn.substring(0, fqn.lastIndexOf('.'))); + lib.processScope(obj, fqn.substring(0, fqn.lastIndexOf('.'))); return newVal; } if (newVal && typeof newVal === 'object') { @@ -243,19 +243,19 @@ } } }, - - unwatch: function(obj, label) { + + unwatch: function (obj, label) { //try { - if (Object.defineProperty) { - Object.defineProperty(obj, label, {get: undefined, set: undefined}); - } else { - if (obj.__defineSetter__) { - obj.__defineSetter__(label, undefined); - } - if (obj.__defineGetter__) { - obj.__defineGetter__(label, undefined); - } + if (Object.defineProperty) { + Object.defineProperty(obj, label, {get: undefined, set: undefined}); + } else { + if (obj.__defineSetter__) { + obj.__defineSetter__(label, undefined); + } + if (obj.__defineGetter__) { + obj.__defineGetter__(label, undefined); } + } //} catch (e) {} } }; @@ -349,9 +349,9 @@ constructRemoteFunction: function (fqn) { var remoteFn = function () { - + lib.processNowScope(); - + var args = []; for (var i = 0, ii = arguments.length; i < ii; i++) { args[i] = arguments[i]; @@ -434,19 +434,19 @@ } }, traverseScope: function (obj, path, data) { - + if (obj && typeof obj === 'object') { var objIsArray = util.isArray(obj); var keys = fqnMap.get(path); for (var key in obj) { var fqn = path + '.' + key; - + if (fqn === 'now.core' || fqn === 'now.ready') { continue; } - + if (util.hasProperty(obj, key)) { - + var val = obj[key]; var mapVal = fqnMap.get(fqn); var wasArray = fqnMap.arrays[fqn]; @@ -481,22 +481,22 @@ } } else if (mapVal === undefined) { util.watch(obj, key, fqn); - + if (valIsObj) { if (valIsArray) { // Value is array fqnMap.set(fqn, []); fqnMap.flagAsArray(fqn); - data[fqn] = []; + data[fqn] = []; } else { // Value is object fqnMap.set(fqn, []); - data[fqn] = {}; + data[fqn] = {}; } } else { // Value is primitive / func fqnMap.set(fqn, val); - data[fqn] = util.getValOrFqn(val, fqn); + data[fqn] = util.getValOrFqn(val, fqn); } } if (valIsObj) { @@ -504,7 +504,7 @@ } } } - + if (keys && typeof keys === 'object') { var toDelete = []; // Scan for deleted keys. @@ -521,13 +521,13 @@ } } } - + }, - + traverseScopeIE: function (obj, path, data) { } - - + + }; var dependencies = [ @@ -540,7 +540,7 @@ if (dependenciesLoaded !== dependencies.length) { return; } - socket = io.connect(uri+'/', now.core.options.socketio || {}); + socket = io.connect(uri + '/', now.core.options.socketio || {}); now.core.socketio = socket; socket.on('connect', function () { now.core.clientId = socket.socket.sessionid; @@ -596,7 +596,6 @@ } document.getElementsByTagName('head')[0].appendChild(fileref); } - return (nowObjects[uri] = now); }; window.nowInitialize = noConflict; diff --git a/lib/group.js b/lib/group.js index d9f9b3e..70e8dbe 100644 --- a/lib/group.js +++ b/lib/group.js @@ -280,6 +280,9 @@ exports.initialize = function (nowjs) { callback(this.users[clientId] !== undefined); }; + /** + * @private + */ Group.prototype.get = function (fqn) { var value = this.scopeTable.get(fqn); // If this is a regular group, look in `everyone` for the value @@ -295,11 +298,17 @@ exports.initialize = function (nowjs) { return value; }; + /** + * @private + */ Group.prototype.deleteVar = function (fqn) { var obj = nowUtil.clone(this, {fqn: fqn}); nowjs.emit('groupdel', obj); }; + /** + * @private + */ Group.prototype.set = function (fqn, val) { var obj = nowUtil.clone(this, {fqn: fqn, val: val}); nowjs.emit('grouprv', obj);