Skip to content
Browse files

Overhaul.

  • Loading branch information...
1 parent 40f33e4 commit f746449aa8c8677d5f98a907be374d9d0ee8c615 @majek majek committed Sep 15, 2011
Showing with 641 additions and 4,389 deletions.
  1. +4 −0 .gitignore
  2. +0 −8 .hgignore
  3. +4 −0 Makefile
  4. +51 −0 README.md
  5. +0 −35 README.txt
  6. +0 −44 channels.conf
  7. 0 channels/__init__.py
  8. +0 −2 channels/config_local.py
  9. +0 −231 channels/index.html
  10. +0 −55 channels/site.py
  11. BIN channels/static/images/ui-bg_flat_0_aaaaaa_40x100.png
  12. BIN channels/static/images/ui-bg_flat_75_ffffff_40x100.png
  13. BIN channels/static/images/ui-bg_glass_55_fbf9ee_1x400.png
  14. BIN channels/static/images/ui-bg_glass_65_ffffff_1x400.png
  15. BIN channels/static/images/ui-bg_glass_75_dadada_1x400.png
  16. BIN channels/static/images/ui-bg_glass_75_e6e6e6_1x400.png
  17. BIN channels/static/images/ui-bg_glass_95_fef1ec_1x400.png
  18. BIN channels/static/images/ui-bg_highlight-soft_75_cccccc_1x100.png
  19. BIN channels/static/images/ui-icons_222222_256x240.png
  20. BIN channels/static/images/ui-icons_2e83ff_256x240.png
  21. BIN channels/static/images/ui-icons_454545_256x240.png
  22. BIN channels/static/images/ui-icons_888888_256x240.png
  23. BIN channels/static/images/ui-icons_cd0a0a_256x240.png
  24. +0 −578 channels/static/jquery-ui-1.8.12.custom.css
  25. +0 −480 channels/static/json2.js
  26. BIN channels/static/routing.png
  27. BIN channels/static/routing2.png
  28. +0 −61 channels/static/screen.css
  29. +0 −1 crontab
  30. +0 −186 cursors/index.html
  31. +0 −34 cursors/site.py
  32. +0 −87 fabfile.py
  33. +11 −0 gateway/config.js
  34. +10 −0 gateway/package.json
  35. +78 −0 gateway/server.js
  36. +1 −0 gateway/static/index.html
  37. +0 −49 mud.conf
  38. +2 −2 mud/core/__init__.py
  39. +22 −4 mud/core/fs.py
  40. +131 −0 mud/core/models.py.orig
  41. +87 −0 mud/core/puk.py
  42. +0 −215 mud/core/rooms.json
  43. +0 −19 mud/core/signals.py
  44. +5 −12 mud/core/templates/index.html
  45. +4 −20 mud/core/views.py
  46. +213 −0 mud/initial_data.json
  47. +6 −5 mud/{settings_local_devel.py → settings_local.py}
  48. +0 −303 mud/static/flyingsquirrel-client-0.0.0.js
  49. +11 −13 mud/static/main.js
  50. +0 −1,918 mud/static/socket.io.js
  51. +1 −0 requirements.txt
  52. +0 −27 run.py
View
4 .gitignore
@@ -0,0 +1,4 @@
+venv
+*.pyc
+gateway/node_modules
+
View
8 .hgignore
@@ -1,8 +0,0 @@
-~$
-.pyc$
-channels/config.py
-venv$
-distribute-0.6.10.tar.gz$
-mud/settings_local.py
-mud/settings_local_prod.py
-
View
4 Makefile
@@ -0,0 +1,4 @@
+all:
+
+clean:
+ find mud -name \*.pyc |xargs --no-run-if-empty rm
View
51 README.md
@@ -0,0 +1,51 @@
+SockJS - mud
+============
+
+This is a rough and dirty Mud game. Unlike games from early 80's this
+one uses web interface - you can play from your browser. It's
+presenting the power of
+[SockJS](https://github.com/majek/sockjs-client) and under the hood
+uses also Django.
+
+This code is derived from [flying squirrel
+demos](https://github.com/rabbitmq/flying-squirrel-demos).
+
+
+Local deployment
+----------------
+
+To run the stuff locally you need to have `node`, `npm` and local
+`Rabbitmq` server running. Additionally you need few Python
+dependencies, to install them run:
+
+ virtualenv venv
+ . venv/bin/activate
+ pip install -r requirements.txt
+
+
+To run the sockjs gateway:
+
+ cd gateway
+ npm install
+ node server.js
+
+
+To run the main part of mud - python/django server:
+
+ . venv/bin/activate
+ cd mud
+ ./manage.py syncdb --noinput
+ ./manage.py createsuperuser --username=admin --email=a@b.co.uk
+ ./manage.py runserver 0.0.0.0:3000
+
+And on the second console:
+
+ while [ 1 ]; do curl http://127.0.0.1:3000/tick; echo; sleep 10; done
+
+If you modified the rooms, you may want to save the data:
+
+ ./manage.py dumpdata \
+ --format=json \
+ --indent=4 core > /tmp/initial_data.json
+
+
View
35 README.txt
@@ -1,35 +0,0 @@
-
-To run the stuff locally:
-
- virtualenv venv
- . venv/bin/activate
- pip install -r requirements.txt
-
-
-To run mud:
-
- . venv/bin/activate
- cd mud
- ln -s settings_local_devel.py settings_local.py
- ./manage.py syncdb --noinput
- ./manage.py loaddata core/rooms.json
- ./manage.py createsuperuser --username=admin --email=a@b.co.uk
- ./manage.py runserver 0.0.0.0:8000
-
-And on the second console:
-
- while [ 1 ]; do curl http://127.0.0.1:8000/tick; echo; sleep 10; done
-
-In order to save data:
-
- ./manage.py dumpdata \
- --format=json \
- --indent=4 core > /tmp/rooms.json
-
-To run the channels:
-
- . venv/bin/activate
- cd channels
- ln -s config_local.py config.py
- python site.py
-
View
44 channels.conf
@@ -1,44 +0,0 @@
-server {
- listen 80;
- server_name channels.squirr.us;
-
- location /robots.txt {
- alias /srv/flying-squirrel-demos/channels/static/robots.txt;
- }
-
- location /favicon.ico {
- alias /srv/flying-squirrel-demos/channels/static/favicon.ico;
- }
-
- location /static/ {
- alias /srv/flying-squirrel-demos/channels/static/;
- }
-
- access_log /srv/flying-squirrel-data/channels-access.log;
- error_log /srv/flying-squirrel-data/channels-error.log;
-
- location / {
- fastcgi_pass unix:/tmp/fs-channels.sock;
- fastcgi_pass_header Authorization;
- fastcgi_intercept_errors off;
-
- fastcgi_param PATH_INFO $fastcgi_script_name;
- fastcgi_param REQUEST_METHOD $request_method;
- fastcgi_param QUERY_STRING $query_string;
- fastcgi_param CONTENT_TYPE $content_type;
- fastcgi_param CONTENT_LENGTH $content_length;
- fastcgi_param SERVER_PORT $server_port;
- fastcgi_param SERVER_PROTOCOL $server_protocol;
- fastcgi_param SERVER_NAME $server_name;
- fastcgi_param REQUEST_URI $request_uri;
- fastcgi_param DOCUMENT_URI $document_uri;
- fastcgi_param DOCUMENT_ROOT $document_root;
-
- fastcgi_param REMOTE_USER $remote_user;
- fastcgi_param REMOTE_ADDR $remote_addr;
- fastcgi_param REMOTE_PORT $remote_port;
- fastcgi_param SERVER_ADDR $server_addr;
- fastcgi_param SERVER_PORT $server_port;
- fastcgi_param SERVER_NAME $server_name;
- }
-}
View
0 channels/__init__.py
No changes.
View
2 channels/config_local.py
@@ -1,2 +0,0 @@
-SERVICE_URL='http://guest:guest@localhost:55670/socks-api/default'
-SQUIRREL_SITE_URL="http://127.0.0.1:8080/"
View
231 channels/index.html
@@ -1,231 +0,0 @@
-$def with (squirrel_url, connection_url, ticket)
-<html>
- <head>
- <title>Channels demo</title>
- <link rel="stylesheet" href="/static/screen.css"/>
- <link rel="stylesheet" href="/static/jquery-ui-1.8.12.custom.css"/>
-
- <script type="text/javascript"
- src="static/json2.js"></script>
- <script type="text/javascript"
- src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
- <script type="text/javascript"
- src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.12/jquery-ui.min.js"></script>
- <script type="text/javascript"
- src="http://cdn.socket.io/stable/socket.io.js"></script>
- <script type="text/javascript"
- src="http://cdn.squirr.us/flyingsquirrel-client-0.0.0.js"></script>
- </head>
- <body>
- <script type="text/javascript">
- var conn_url = "${connection_url}";
- var ticket = "${ticket}";
-
- (function (jq) {
- jq(function() {
-
- jq('#demos').tabs();
-
- var conn1 = new flyingsquirrel.Connection(conn_url, ticket);
- var conn2 = new flyingsquirrel.Connection(conn_url, ticket);
-
- function notify(innerhtml) {
- jq('#notifications').append(innerhtml);
- }
-
- function showMsg(out, innerhtml) {
- elem = jq(innerhtml);
- elem.hide();
- jq(out).append(elem);
- elem.show('slide', {'direction': 'up'});
- jq(out).effect('highlight');
- }
-
- conn1.on_connect = function() {notify("<p>Connected 1</p>")};
- conn2.on_connect = function() {notify("<p>Connected 2</p>")};
-
- function sender(channel, form, conn) {
- jq(form).bind('submit', function(event) {
- event.preventDefault();
- notify("<em>Sending on " + channel + " channel</em><br/>");
- conn.publish(channel, jq(form).children(':text').val());
- jq(form).children(':text').val('');
- });
- };
-
- function receiver(channel, out, conn) {
- conn.subscribe(channel, function(msg) {
- showMsg(out, '<p>' + msg + '<p>');
- });
- };
-
- // Pub/Sub -- one publisher, and two subscribers
- sender('pub', '#pubform', conn1);
- receiver('sub', '#pubsub1', conn1);
- receiver('sub', '#pubsub2', conn2);
-
- // Push/Pull -- one er, pusher, and two, erm, pullers
- sender('push', '#pushform', conn1);
-
- receiver('pull', '#pushpull1', conn1);
- receiver('pull', '#pushpull2', conn2);
-
- // Req/Rep -- two requesters and one replier,
- // each sends and receives
-
- function requester(channel, form, out, conn) {
- jq(form).bind('submit', function(event) {
- event.preventDefault();
- var question = jq(form).children(':text').val();
- jq(form).children(':text').val('');
- jq(out).children().remove();
- showMsg(out, '<p>Q:' + question + '</p>');
- conn.request(channel, question, function(answer) {
- showMsg(out, '<p>A: ' + answer + '</p>');
- });
- });
- }
-
- function replier(channel, form, out, conn) {
- var answerer = null;
- initial(form);
- conn.serve(channel, function(question, _ch, _obj, reply) {
- disableExcept(form);
- jq(out).children().remove();
- showMsg(out, '<p>Q: ' + question + '</p>');
- answerer = reply;
- });
- jq(form).bind('submit', function(event) {
- event.preventDefault();
- if (answerer) {
- initial();
- var answer = jq(form).children(':text').val();
- jq(form).children(':text').val('');
- showMsg(out, '<p>A: ' + answer + '</p>');
- answerer(answer);
- answerer = null;
- }
- else {
- console.log('Answer to an unasked question ...');
- }
- });
- }
-
- function initial() {
- jq('#reqform1, #reqform2').children('input').attr('disabled', false);
- jq('#repform1, #repform2').children('input').attr('disabled', true);
- }
-
- function disableExcept(form) {
- jq(form).children('input').attr('disabled', false);
- jq(form).children('input:text').focus();
- jq('#reqreptab form').not(form).children('input').attr('disabled', true);
- }
-
- requester('req', '#reqform1', '#req1', conn1);
- requester('req', '#reqform2', '#req2', conn2);
- replier('rep', '#repform1', '#rep1', conn1);
- replier('rep', '#repform2', '#rep2', conn2);
-
- conn1.connect();
- conn2.connect();
- });
- })(jQuery);
- </script>
-
- <div id="demos">
- <ul>
- <li><a href="#pubsubtab">Publish / Subscribe</a></li>
- <li><a href="#pushpulltab">Push / Pull</a></li>
- <li><a href="#reqreptab">Request / Reply</a></li>
- </ul>
-
-
- <div id="pubsubtab">
- <h2>Publish / Subscribe</h2>
- <p>
- A <code>PUB</code> channel will send messages to all of the
- <code>SUB</code> channels wired to the same resource.
- </p>
- <form id="pubform">
- <input type="text" id="pubinput" name="pubinput"/>
- <input type="submit" id="pubbutton" value="Publish"/>
- </form>
- <img class="routing" src="/static/routing.png"/>
- <div class="out" id="pubsub1">
- </div>
- <div class="out" id="pubsub2">
- </div>
- </div>
-
- <div id="pushpulltab">
- <h2>Push / Pull</h2>
- <p>
- A <code>PUSH</code> channel will send messages to one of
- the <code>PULL</code> channels wired to the same resource.
- </p>
- <form id="pushform">
- <input type="text" id="pushinput" name="pushinput"/>
- <input type="submit" id="pushbutton" value="Push"/>
- </form>
- <img class="routing" src="/static/routing.png"/>
- <div class="out" id="pushpull1">
- </div>
- <div class="out" id="pushpull2">
- </div>
- </div>
-
- <div id="reqreptab">
- <h2>Request / Reply</h2>
- <p>
- A <code>REQ</code> channel will send messages to one of
- the <code>REP</code> channels wired to the same
- resource. The response from the <code>REP</code> channel
- is routed back to the original <code>REQ</code> channel.
- </p>
-
- <div class="req">
- <form id="reqform1">
- <input type="text" id="reqinput1" name="reqinput"/>
- <input type="submit" id="reqbutton1" value="Request"/>
- </form>
- <div class="out" id="req1">
- </div>
- </div>
-
- <div class="req">
- <form id="reqform2">
- <input type="text" id="reqinput2" name="reqinput"/>
- <input type="submit" id="reqbutton2" value="Request"/>
- </form>
- <div class="out" id="req2">
- </div>
- </div>
-
- <img class="routing" src="/static/routing2.png"/>
-
- <div class="req">
- <div class="out" id="rep1">
- </div>
- <form id="repform1">
- <input type="text" id="repinput1" name="repinput"/>
- <input type="submit" id="repbutton1" value="Reply"/>
- </form>
- </div>
-
- <div class="req">
- <div class="out" id="rep2">
- </div>
- <form id="repform2">
- <input type="text" id="repinput2" name="repinput"/>
- <input type="submit" id="repbutton2" value="Reply"/>
- </form>
- </div>
-
- </div>
- </div>
- <div id="notifications" class="ui-corner-all ui-widget ui-widget-content">
- <h3>Log messages</h3>
- </div>
- </body>
-</html>
View
55 channels/site.py
@@ -1,55 +0,0 @@
-#!/usr/bin/env python
-from __future__ import with_statement
-
-import os
-import web
-import random
-import string
-import flyingsquirrel as squirrel
-
-from config import SERVICE_URL, SQUIRREL_SITE_URL
-
-urls = (
- '/(index(.html)?)?', 'Channels'
-)
-app = web.application(urls, globals())
-
-render = web.template.render('.')
-
-class Channels:
- def GET(self, *_ignore):
- (conn_url, ticket) = create_endpoint()
- return render.index(SQUIRREL_SITE_URL, conn_url, ticket)
-
-def create_endpoint():
- client = squirrel.API(SERVICE_URL)
- name = ''.join([random.choice(string.letters) for i in range(10)])
- endpoint = client.create_endpoint(
- name,
- definition={'pub': ['pub', name + '_pubsub'],
- 'sub': ['sub', name + '_pubsub'],
- 'push': ['push', name + '_pushpull'],
- 'pull': ['pull', name + '_pushpull'],
- 'req': ['req', name + '_reqrep'],
- 'rep': ['rep', name + '_reqrep']})
- ticket = client.generate_ticket(name, 'anon')
- return endpoint['protocols']['socket.io'], ticket
-
-if __name__ == "__main__":
- if 'WSGI_DATA' not in os.environ:
- app.run()
- else:
- from flup.server.fcgi import WSGIServer
-
- from django.utils.daemonize import become_daemon
- become_daemon(out_log=os.environ['WSGI_DATA']+'/channels_out.log',
- err_log=os.environ['WSGI_DATA']+'/channels_err.log')
-
- with open(os.environ['WSGI_DATA'] + "/channels.pid", "w") as f:
- f.write("%d\n" % os.getpid())
-
- web.config.debug = False
-
- WSGIServer(app.wsgifunc(),
- bindAddress='/tmp/fs-channels.sock',
- umask=0000).run()
View
BIN channels/static/images/ui-bg_flat_0_aaaaaa_40x100.png
Deleted file not rendered
View
BIN channels/static/images/ui-bg_flat_75_ffffff_40x100.png
Deleted file not rendered
View
BIN channels/static/images/ui-bg_glass_55_fbf9ee_1x400.png
Deleted file not rendered
View
BIN channels/static/images/ui-bg_glass_65_ffffff_1x400.png
Deleted file not rendered
View
BIN channels/static/images/ui-bg_glass_75_dadada_1x400.png
Deleted file not rendered
View
BIN channels/static/images/ui-bg_glass_75_e6e6e6_1x400.png
Deleted file not rendered
View
BIN channels/static/images/ui-bg_glass_95_fef1ec_1x400.png
Deleted file not rendered
View
BIN channels/static/images/ui-bg_highlight-soft_75_cccccc_1x100.png
Deleted file not rendered
View
BIN channels/static/images/ui-icons_222222_256x240.png
Deleted file not rendered
View
BIN channels/static/images/ui-icons_2e83ff_256x240.png
Deleted file not rendered
View
BIN channels/static/images/ui-icons_454545_256x240.png
Deleted file not rendered
View
BIN channels/static/images/ui-icons_888888_256x240.png
Deleted file not rendered
View
BIN channels/static/images/ui-icons_cd0a0a_256x240.png
Deleted file not rendered
View
578 channels/static/jquery-ui-1.8.12.custom.css
@@ -1,578 +0,0 @@
-/*
- * jQuery UI CSS Framework 1.8.12
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Theming/API
- */
-
-/* Layout helpers
-----------------------------------*/
-.ui-helper-hidden { display: none; }
-.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
-.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
-.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
-.ui-helper-clearfix { display: inline-block; }
-/* required comment for clearfix to work in Opera \*/
-* html .ui-helper-clearfix { height:1%; }
-.ui-helper-clearfix { display:block; }
-/* end clearfix */
-.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
-
-
-/* Interaction Cues
-----------------------------------*/
-.ui-state-disabled { cursor: default !important; }
-
-
-/* Icons
-----------------------------------*/
-
-/* states and images */
-.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
-
-
-/* Misc visuals
-----------------------------------*/
-
-/* Overlays */
-.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
-
-
-/*
- * jQuery UI CSS Framework 1.8.12
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Theming/API
- *
- * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
- */
-
-
-/* Component containers
-----------------------------------*/
-.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; }
-.ui-widget .ui-widget { font-size: 1em; }
-.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; }
-.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; }
-.ui-widget-content a { color: #222222; }
-.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; }
-.ui-widget-header a { color: #222222; }
-
-/* Interaction states
-----------------------------------*/
-.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; }
-.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; }
-.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
-.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; }
-.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
-.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; }
-.ui-widget :active { outline: none; }
-
-/* Interaction Cues
-----------------------------------*/
-.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; }
-.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
-.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; }
-.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; }
-.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; }
-.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
-.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
-.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
-
-/* Icons
-----------------------------------*/
-
-/* states and images */
-.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
-.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
-.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
-.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); }
-.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
-.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
-.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); }
-.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); }
-
-/* positioning */
-.ui-icon-carat-1-n { background-position: 0 0; }
-.ui-icon-carat-1-ne { background-position: -16px 0; }
-.ui-icon-carat-1-e { background-position: -32px 0; }
-.ui-icon-carat-1-se { background-position: -48px 0; }
-.ui-icon-carat-1-s { background-position: -64px 0; }
-.ui-icon-carat-1-sw { background-position: -80px 0; }
-.ui-icon-carat-1-w { background-position: -96px 0; }
-.ui-icon-carat-1-nw { background-position: -112px 0; }
-.ui-icon-carat-2-n-s { background-position: -128px 0; }
-.ui-icon-carat-2-e-w { background-position: -144px 0; }
-.ui-icon-triangle-1-n { background-position: 0 -16px; }
-.ui-icon-triangle-1-ne { background-position: -16px -16px; }
-.ui-icon-triangle-1-e { background-position: -32px -16px; }
-.ui-icon-triangle-1-se { background-position: -48px -16px; }
-.ui-icon-triangle-1-s { background-position: -64px -16px; }
-.ui-icon-triangle-1-sw { background-position: -80px -16px; }
-.ui-icon-triangle-1-w { background-position: -96px -16px; }
-.ui-icon-triangle-1-nw { background-position: -112px -16px; }
-.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
-.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
-.ui-icon-arrow-1-n { background-position: 0 -32px; }
-.ui-icon-arrow-1-ne { background-position: -16px -32px; }
-.ui-icon-arrow-1-e { background-position: -32px -32px; }
-.ui-icon-arrow-1-se { background-position: -48px -32px; }
-.ui-icon-arrow-1-s { background-position: -64px -32px; }
-.ui-icon-arrow-1-sw { background-position: -80px -32px; }
-.ui-icon-arrow-1-w { background-position: -96px -32px; }
-.ui-icon-arrow-1-nw { background-position: -112px -32px; }
-.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
-.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
-.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
-.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
-.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
-.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
-.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
-.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
-.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
-.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
-.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
-.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
-.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
-.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
-.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
-.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
-.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
-.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
-.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
-.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
-.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
-.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
-.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
-.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
-.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
-.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
-.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
-.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
-.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
-.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
-.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
-.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
-.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
-.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
-.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
-.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
-.ui-icon-arrow-4 { background-position: 0 -80px; }
-.ui-icon-arrow-4-diag { background-position: -16px -80px; }
-.ui-icon-extlink { background-position: -32px -80px; }
-.ui-icon-newwin { background-position: -48px -80px; }
-.ui-icon-refresh { background-position: -64px -80px; }
-.ui-icon-shuffle { background-position: -80px -80px; }
-.ui-icon-transfer-e-w { background-position: -96px -80px; }
-.ui-icon-transferthick-e-w { background-position: -112px -80px; }
-.ui-icon-folder-collapsed { background-position: 0 -96px; }
-.ui-icon-folder-open { background-position: -16px -96px; }
-.ui-icon-document { background-position: -32px -96px; }
-.ui-icon-document-b { background-position: -48px -96px; }
-.ui-icon-note { background-position: -64px -96px; }
-.ui-icon-mail-closed { background-position: -80px -96px; }
-.ui-icon-mail-open { background-position: -96px -96px; }
-.ui-icon-suitcase { background-position: -112px -96px; }
-.ui-icon-comment { background-position: -128px -96px; }
-.ui-icon-person { background-position: -144px -96px; }
-.ui-icon-print { background-position: -160px -96px; }
-.ui-icon-trash { background-position: -176px -96px; }
-.ui-icon-locked { background-position: -192px -96px; }
-.ui-icon-unlocked { background-position: -208px -96px; }
-.ui-icon-bookmark { background-position: -224px -96px; }
-.ui-icon-tag { background-position: -240px -96px; }
-.ui-icon-home { background-position: 0 -112px; }
-.ui-icon-flag { background-position: -16px -112px; }
-.ui-icon-calendar { background-position: -32px -112px; }
-.ui-icon-cart { background-position: -48px -112px; }
-.ui-icon-pencil { background-position: -64px -112px; }
-.ui-icon-clock { background-position: -80px -112px; }
-.ui-icon-disk { background-position: -96px -112px; }
-.ui-icon-calculator { background-position: -112px -112px; }
-.ui-icon-zoomin { background-position: -128px -112px; }
-.ui-icon-zoomout { background-position: -144px -112px; }
-.ui-icon-search { background-position: -160px -112px; }
-.ui-icon-wrench { background-position: -176px -112px; }
-.ui-icon-gear { background-position: -192px -112px; }
-.ui-icon-heart { background-position: -208px -112px; }
-.ui-icon-star { background-position: -224px -112px; }
-.ui-icon-link { background-position: -240px -112px; }
-.ui-icon-cancel { background-position: 0 -128px; }
-.ui-icon-plus { background-position: -16px -128px; }
-.ui-icon-plusthick { background-position: -32px -128px; }
-.ui-icon-minus { background-position: -48px -128px; }
-.ui-icon-minusthick { background-position: -64px -128px; }
-.ui-icon-close { background-position: -80px -128px; }
-.ui-icon-closethick { background-position: -96px -128px; }
-.ui-icon-key { background-position: -112px -128px; }
-.ui-icon-lightbulb { background-position: -128px -128px; }
-.ui-icon-scissors { background-position: -144px -128px; }
-.ui-icon-clipboard { background-position: -160px -128px; }
-.ui-icon-copy { background-position: -176px -128px; }
-.ui-icon-contact { background-position: -192px -128px; }
-.ui-icon-image { background-position: -208px -128px; }
-.ui-icon-video { background-position: -224px -128px; }
-.ui-icon-script { background-position: -240px -128px; }
-.ui-icon-alert { background-position: 0 -144px; }
-.ui-icon-info { background-position: -16px -144px; }
-.ui-icon-notice { background-position: -32px -144px; }
-.ui-icon-help { background-position: -48px -144px; }
-.ui-icon-check { background-position: -64px -144px; }
-.ui-icon-bullet { background-position: -80px -144px; }
-.ui-icon-radio-off { background-position: -96px -144px; }
-.ui-icon-radio-on { background-position: -112px -144px; }
-.ui-icon-pin-w { background-position: -128px -144px; }
-.ui-icon-pin-s { background-position: -144px -144px; }
-.ui-icon-play { background-position: 0 -160px; }
-.ui-icon-pause { background-position: -16px -160px; }
-.ui-icon-seek-next { background-position: -32px -160px; }
-.ui-icon-seek-prev { background-position: -48px -160px; }
-.ui-icon-seek-end { background-position: -64px -160px; }
-.ui-icon-seek-start { background-position: -80px -160px; }
-/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
-.ui-icon-seek-first { background-position: -80px -160px; }
-.ui-icon-stop { background-position: -96px -160px; }
-.ui-icon-eject { background-position: -112px -160px; }
-.ui-icon-volume-off { background-position: -128px -160px; }
-.ui-icon-volume-on { background-position: -144px -160px; }
-.ui-icon-power { background-position: 0 -176px; }
-.ui-icon-signal-diag { background-position: -16px -176px; }
-.ui-icon-signal { background-position: -32px -176px; }
-.ui-icon-battery-0 { background-position: -48px -176px; }
-.ui-icon-battery-1 { background-position: -64px -176px; }
-.ui-icon-battery-2 { background-position: -80px -176px; }
-.ui-icon-battery-3 { background-position: -96px -176px; }
-.ui-icon-circle-plus { background-position: 0 -192px; }
-.ui-icon-circle-minus { background-position: -16px -192px; }
-.ui-icon-circle-close { background-position: -32px -192px; }
-.ui-icon-circle-triangle-e { background-position: -48px -192px; }
-.ui-icon-circle-triangle-s { background-position: -64px -192px; }
-.ui-icon-circle-triangle-w { background-position: -80px -192px; }
-.ui-icon-circle-triangle-n { background-position: -96px -192px; }
-.ui-icon-circle-arrow-e { background-position: -112px -192px; }
-.ui-icon-circle-arrow-s { background-position: -128px -192px; }
-.ui-icon-circle-arrow-w { background-position: -144px -192px; }
-.ui-icon-circle-arrow-n { background-position: -160px -192px; }
-.ui-icon-circle-zoomin { background-position: -176px -192px; }
-.ui-icon-circle-zoomout { background-position: -192px -192px; }
-.ui-icon-circle-check { background-position: -208px -192px; }
-.ui-icon-circlesmall-plus { background-position: 0 -208px; }
-.ui-icon-circlesmall-minus { background-position: -16px -208px; }
-.ui-icon-circlesmall-close { background-position: -32px -208px; }
-.ui-icon-squaresmall-plus { background-position: -48px -208px; }
-.ui-icon-squaresmall-minus { background-position: -64px -208px; }
-.ui-icon-squaresmall-close { background-position: -80px -208px; }
-.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
-.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
-.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
-.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
-.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
-.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
-
-
-/* Misc visuals
-----------------------------------*/
-
-/* Corner radius */
-.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; }
-.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; }
-.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
-.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
-.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; }
-.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
-.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
-.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
-.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; }
-
-/* Overlays */
-.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
-.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/*
- * jQuery UI Resizable 1.8.12
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Resizable#theming
- */
-.ui-resizable { position: relative;}
-.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;
- /* http://bugs.jqueryui.com/ticket/7233
- - Resizable: resizable handles fail to work in IE if transparent and content overlaps
- */
- background-image:url(data:);
-}
-.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
-.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
-.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
-.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
-.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
-.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
-.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
-.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
-.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*
- * jQuery UI Selectable 1.8.12
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Selectable#theming
- */
-.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }
-/*
- * jQuery UI Accordion 1.8.12
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Accordion#theming
- */
-/* IE/Win - Fix animation bug - #4615 */
-.ui-accordion { width: 100%; }
-.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
-.ui-accordion .ui-accordion-li-fix { display: inline; }
-.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
-.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; }
-.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }
-.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
-.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }
-.ui-accordion .ui-accordion-content-active { display: block; }
-/*
- * jQuery UI Autocomplete 1.8.12
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Autocomplete#theming
- */
-.ui-autocomplete { position: absolute; cursor: default; }
-
-/* workarounds */
-* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
-
-/*
- * jQuery UI Menu 1.8.12
- *
- * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Menu#theming
- */
-.ui-menu {
- list-style:none;
- padding: 2px;
- margin: 0;
- display:block;
- float: left;
-}
-.ui-menu .ui-menu {
- margin-top: -3px;
-}
-.ui-menu .ui-menu-item {
- margin:0;
- padding: 0;
- zoom: 1;
- float: left;
- clear: left;
- width: 100%;
-}
-.ui-menu .ui-menu-item a {
- text-decoration:none;
- display:block;
- padding:.2em .4em;
- line-height:1.5;
- zoom:1;
-}
-.ui-menu .ui-menu-item a.ui-state-hover,
-.ui-menu .ui-menu-item a.ui-state-active {
- font-weight: normal;
- margin: -1px;
-}
-/*
- * jQuery UI Button 1.8.12
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Button#theming
- */
-.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
-.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
-button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
-.ui-button-icons-only { width: 3.4em; }
-button.ui-button-icons-only { width: 3.7em; }
-
-/*button text element */
-.ui-button .ui-button-text { display: block; line-height: 1.4; }
-.ui-button-text-only .ui-button-text { padding: .4em 1em; }
-.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
-.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
-.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
-.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
-/* no icon support for input elements, provide padding by default */
-input.ui-button { padding: .4em 1em; }
-
-/*button icon element(s) */
-.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
-.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
-.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
-.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
-.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
-
-/*button sets*/
-.ui-buttonset { margin-right: 7px; }
-.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
-
-/* workarounds */
-button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
-/*
- * jQuery UI Dialog 1.8.12
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Dialog#theming
- */
-.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
-.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; }
-.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; }
-.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
-.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
-.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
-.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
-.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
-.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
-.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
-.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
-.ui-draggable .ui-dialog-titlebar { cursor: move; }
-/*
- * jQuery UI Slider 1.8.12
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Slider#theming
- */
-.ui-slider { position: relative; text-align: left; }
-.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
-.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
-
-.ui-slider-horizontal { height: .8em; }
-.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
-.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
-.ui-slider-horizontal .ui-slider-range-min { left: 0; }
-.ui-slider-horizontal .ui-slider-range-max { right: 0; }
-
-.ui-slider-vertical { width: .8em; height: 100px; }
-.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
-.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
-.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
-.ui-slider-vertical .ui-slider-range-max { top: 0; }/*
- * jQuery UI Tabs 1.8.12
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Tabs#theming
- */
-.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
-.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
-.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }
-.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
-.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
-.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
-.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
-.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
-.ui-tabs .ui-tabs-hide { display: none !important; }
-/*
- * jQuery UI Datepicker 1.8.12
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Datepicker#theming
- */
-.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; }
-.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
-.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
-.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
-.ui-datepicker .ui-datepicker-prev { left:2px; }
-.ui-datepicker .ui-datepicker-next { right:2px; }
-.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
-.ui-datepicker .ui-datepicker-next-hover { right:1px; }
-.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
-.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
-.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
-.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
-.ui-datepicker select.ui-datepicker-month,
-.ui-datepicker select.ui-datepicker-year { width: 49%;}
-.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
-.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
-.ui-datepicker td { border: 0; padding: 1px; }
-.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
-.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
-.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
-.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
-
-/* with multiple calendars */
-.ui-datepicker.ui-datepicker-multi { width:auto; }
-.ui-datepicker-multi .ui-datepicker-group { float:left; }
-.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
-.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
-.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
-.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
-.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
-.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
-.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
-.ui-datepicker-row-break { clear:both; width:100%; }
-
-/* RTL support */
-.ui-datepicker-rtl { direction: rtl; }
-.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
-.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
-.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
-.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
-.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
-.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
-.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
-.ui-datepicker-rtl .ui-datepicker-group { float:right; }
-.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
-.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
-
-/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
-.ui-datepicker-cover {
- display: none; /*sorry for IE5*/
- display/**/: block; /*sorry for IE5*/
- position: absolute; /*must have*/
- z-index: -1; /*must have*/
- filter: mask(); /*must have*/
- top: -4px; /*must have*/
- left: -4px; /*must have*/
- width: 200px; /*must have*/
- height: 200px; /*must have*/
-}/*
- * jQuery UI Progressbar 1.8.12
- *
- * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * http://docs.jquery.com/UI/Progressbar#theming
- */
-.ui-progressbar { height:2em; text-align: left; }
-.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
View
480 channels/static/json2.js
@@ -1,480 +0,0 @@
-/*
- http://www.JSON.org/json2.js
- 2011-02-23
-
- Public Domain.
-
- NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
-
- See http://www.JSON.org/js.html
-
-
- This code should be minified before deployment.
- See http://javascript.crockford.com/jsmin.html
-
- USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
- NOT CONTROL.
-
-
- This file creates a global JSON object containing two methods: stringify
- and parse.
-
- JSON.stringify(value, replacer, space)
- value any JavaScript value, usually an object or array.
-
- replacer an optional parameter that determines how object
- values are stringified for objects. It can be a
- function or an array of strings.
-
- space an optional parameter that specifies the indentation
- of nested structures. If it is omitted, the text will
- be packed without extra whitespace. If it is a number,
- it will specify the number of spaces to indent at each
- level. If it is a string (such as '\t' or '&nbsp;'),
- it contains the characters used to indent at each level.
-
- This method produces a JSON text from a JavaScript value.
-
- When an object value is found, if the object contains a toJSON
- method, its toJSON method will be called and the result will be
- stringified. A toJSON method does not serialize: it returns the
- value represented by the name/value pair that should be serialized,
- or undefined if nothing should be serialized. The toJSON method
- will be passed the key associated with the value, and this will be
- bound to the value
-
- For example, this would serialize Dates as ISO strings.
-
- Date.prototype.toJSON = function (key) {
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10 ? '0' + n : n;
- }
-
- return this.getUTCFullYear() + '-' +
- f(this.getUTCMonth() + 1) + '-' +
- f(this.getUTCDate()) + 'T' +
- f(this.getUTCHours()) + ':' +
- f(this.getUTCMinutes()) + ':' +
- f(this.getUTCSeconds()) + 'Z';
- };
-
- You can provide an optional replacer method. It will be passed the
- key and value of each member, with this bound to the containing
- object. The value that is returned from your method will be
- serialized. If your method returns undefined, then the member will
- be excluded from the serialization.
-
- If the replacer parameter is an array of strings, then it will be
- used to select the members to be serialized. It filters the results
- such that only members with keys listed in the replacer array are
- stringified.
-
- Values that do not have JSON representations, such as undefined or
- functions, will not be serialized. Such values in objects will be
- dropped; in arrays they will be replaced with null. You can use
- a replacer function to replace those with JSON values.
- JSON.stringify(undefined) returns undefined.
-
- The optional space parameter produces a stringification of the
- value that is filled with line breaks and indentation to make it
- easier to read.
-
- If the space parameter is a non-empty string, then that string will
- be used for indentation. If the space parameter is a number, then
- the indentation will be that many spaces.
-
- Example:
-
- text = JSON.stringify(['e', {pluribus: 'unum'}]);
- // text is '["e",{"pluribus":"unum"}]'
-
-
- text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
- // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
-
- text = JSON.stringify([new Date()], function (key, value) {
- return this[key] instanceof Date ?
- 'Date(' + this[key] + ')' : value;
- });
- // text is '["Date(---current time---)"]'
-
-
- JSON.parse(text, reviver)
- This method parses a JSON text to produce an object or array.
- It can throw a SyntaxError exception.
-
- The optional reviver parameter is a function that can filter and
- transform the results. It receives each of the keys and values,
- and its return value is used instead of the original value.
- If it returns what it received, then the structure is not modified.
- If it returns undefined then the member is deleted.
-
- Example:
-
- // Parse the text. Values that look like ISO date strings will
- // be converted to Date objects.
-
- myData = JSON.parse(text, function (key, value) {
- var a;
- if (typeof value === 'string') {
- a =
-/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
- if (a) {
- return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
- +a[5], +a[6]));
- }
- }
- return value;
- });
-
- myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
- var d;
- if (typeof value === 'string' &&
- value.slice(0, 5) === 'Date(' &&
- value.slice(-1) === ')') {
- d = new Date(value.slice(5, -1));
- if (d) {
- return d;
- }
- }
- return value;
- });
-
-
- This is a reference implementation. You are free to copy, modify, or
- redistribute.
-*/
-
-/*jslint evil: true, strict: false, regexp: false */
-
-/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
- call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
- getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
- lastIndex, length, parse, prototype, push, replace, slice, stringify,
- test, toJSON, toString, valueOf
-*/
-
-
-// Create a JSON object only if one does not already exist. We create the
-// methods in a closure to avoid creating global variables.
-
-var JSON;
-if (!JSON) {
- JSON = {};
-}
-
-(function () {
- "use strict";
-
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10 ? '0' + n : n;
- }
-
- if (typeof Date.prototype.toJSON !== 'function') {
-
- Date.prototype.toJSON = function (key) {
-
- return isFinite(this.valueOf()) ?
- this.getUTCFullYear() + '-' +
- f(this.getUTCMonth() + 1) + '-' +
- f(this.getUTCDate()) + 'T' +
- f(this.getUTCHours()) + ':' +
- f(this.getUTCMinutes()) + ':' +
- f(this.getUTCSeconds()) + 'Z' : null;
- };
-
- String.prototype.toJSON =
- Number.prototype.toJSON =
- Boolean.prototype.toJSON = function (key) {
- return this.valueOf();
- };
- }
-
- var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- gap,
- indent,
- meta = { // table of character substitutions
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '"' : '\\"',
- '\\': '\\\\'
- },
- rep;
-
-
- function quote(string) {
-
-// If the string contains no control characters, no quote characters, and no
-// backslash characters, then we can safely slap some quotes around it.
-// Otherwise we must also replace the offending characters with safe escape
-// sequences.
-
- escapable.lastIndex = 0;
- return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
- var c = meta[a];
- return typeof c === 'string' ? c :
- '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- }) + '"' : '"' + string + '"';
- }
-
-
- function str(key, holder) {
-
-// Produce a string from holder[key].
-
- var i, // The loop counter.
- k, // The member key.
- v, // The member value.
- length,
- mind = gap,
- partial,
- value = holder[key];
-
-// If the value has a toJSON method, call it to obtain a replacement value.
-
- if (value && typeof value === 'object' &&
- typeof value.toJSON === 'function') {
- value = value.toJSON(key);
- }
-
-// If we were called with a replacer function, then call the replacer to
-// obtain a replacement value.
-
- if (typeof rep === 'function') {
- value = rep.call(holder, key, value);
- }
-
-// What happens next depends on the value's type.
-
- switch (typeof value) {
- case 'string':
- return quote(value);
-
- case 'number':
-
-// JSON numbers must be finite. Encode non-finite numbers as null.
-
- return isFinite(value) ? String(value) : 'null';
-
- case 'boolean':
- case 'null':
-
-// If the value is a boolean or null, convert it to a string. Note:
-// typeof null does not produce 'null'. The case is included here in
-// the remote chance that this gets fixed someday.
-
- return String(value);
-
-// If the type is 'object', we might be dealing with an object or an array or
-// null.
-
- case 'object':
-
-// Due to a specification blunder in ECMAScript, typeof null is 'object',
-// so watch out for that case.
-
- if (!value) {
- return 'null';
- }
-
-// Make an array to hold the partial results of stringifying this object value.
-
- gap += indent;
- partial = [];
-
-// Is the value an array?
-
- if (Object.prototype.toString.apply(value) === '[object Array]') {
-
-// The value is an array. Stringify every element. Use null as a placeholder
-// for non-JSON values.
-
- length = value.length;
- for (i = 0; i < length; i += 1) {
- partial[i] = str(i, value) || 'null';
- }
-
-// Join all of the elements together, separated with commas, and wrap them in
-// brackets.
-
- v = partial.length === 0 ? '[]' : gap ?
- '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
- '[' + partial.join(',') + ']';
- gap = mind;
- return v;
- }
-
-// If the replacer is an array, use it to select the members to be stringified.
-
- if (rep && typeof rep === 'object') {
- length = rep.length;
- for (i = 0; i < length; i += 1) {
- if (typeof rep[i] === 'string') {
- k = rep[i];
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- } else {
-
-// Otherwise, iterate through all of the keys in the object.
-
- for (k in value) {
- if (Object.prototype.hasOwnProperty.call(value, k)) {
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- }
-
-// Join all of the member texts together, separated with commas,
-// and wrap them in braces.
-
- v = partial.length === 0 ? '{}' : gap ?
- '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
- '{' + partial.join(',') + '}';
- gap = mind;
- return v;
- }
- }
-
-// If the JSON object does not yet have a stringify method, give it one.
-
- if (typeof JSON.stringify !== 'function') {
- JSON.stringify = function (value, replacer, space) {
-
-// The stringify method takes a value and an optional replacer, and an optional
-// space parameter, and returns a JSON text. The replacer can be a function
-// that can replace values, or an array of strings that will select the keys.
-// A default replacer method can be provided. Use of the space parameter can
-// produce text that is more easily readable.
-
- var i;
- gap = '';
- indent = '';
-
-// If the space parameter is a number, make an indent string containing that
-// many spaces.
-
- if (typeof space === 'number') {
- for (i = 0; i < space; i += 1) {
- indent += ' ';
- }
-
-// If the space parameter is a string, it will be used as the indent string.
-
- } else if (typeof space === 'string') {
- indent = space;
- }
-
-// If there is a replacer, it must be a function or an array.
-// Otherwise, throw an error.
-
- rep = replacer;
- if (replacer && typeof replacer !== 'function' &&
- (typeof replacer !== 'object' ||
- typeof replacer.length !== 'number')) {
- throw new Error('JSON.stringify');
- }
-
-// Make a fake root object containing our value under the key of ''.
-// Return the result of stringifying the value.
-
- return str('', {'': value});
- };
- }
-
-
-// If the JSON object does not yet have a parse method, give it one.
-
- if (typeof JSON.parse !== 'function') {
- JSON.parse = function (text, reviver) {
-
-// The parse method takes a text and an optional reviver function, and returns
-// a JavaScript value if the text is a valid JSON text.
-
- var j;
-
- function walk(holder, key) {
-
-// The walk method is used to recursively walk the resulting structure so
-// that modifications can be made.
-
- var k, v, value = holder[key];
- if (value && typeof value === 'object') {
- for (k in value) {
- if (Object.prototype.hasOwnProperty.call(value, k)) {
- v = walk(value, k);
- if (v !== undefined) {
- value[k] = v;
- } else {
- delete value[k];
- }
- }
- }
- }
- return reviver.call(holder, key, value);
- }
-
-
-// Parsing happens in four stages. In the first stage, we replace certain
-// Unicode characters with escape sequences. JavaScript handles many characters
-// incorrectly, either silently deleting them, or treating them as line endings.
-
- text = String(text);
- cx.lastIndex = 0;
- if (cx.test(text)) {
- text = text.replace(cx, function (a) {
- return '\\u' +
- ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- });
- }
-
-// In the second stage, we run the text against regular expressions that look
-// for non-JSON patterns. We are especially concerned with '()' and 'new'
-// because they can cause invocation, and '=' because it can cause mutation.
-// But just to be safe, we want to reject all unexpected forms.
-
-// We split the second stage into 4 regexp operations in order to work around
-// crippling inefficiencies in IE's and Safari's regexp engines. First we
-// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
-// replace all simple value tokens with ']' characters. Third, we delete all
-// open brackets that follow a colon or comma or that begin the text. Finally,
-// we look to see that the remaining characters are only whitespace or ']' or
-// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
-
- if (/^[\],:{}\s]*$/
- .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
- .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
- .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
-
-// In the third stage we use the eval function to compile the text into a
-// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
-// in JavaScript: it can begin a block or an object literal. We wrap the text
-// in parens to eliminate the ambiguity.
-
- j = eval('(' + text + ')');
-
-// In the optional fourth stage, we recursively walk the new structure, passing
-// each name/value pair to a reviver function for possible transformation.
-
- return typeof reviver === 'function' ?
- walk({'': j}, '') : j;
- }
-
-// If the text is not JSON parseable, then a SyntaxError is thrown.
-
- throw new SyntaxError('JSON.parse');
- };
- }
-}());
View
BIN channels/static/routing.png
Deleted file not rendered
View
BIN channels/static/routing2.png
Deleted file not rendered
View
61 channels/static/screen.css
@@ -1,61 +0,0 @@
-#demos {
- float: left;
- margin-left: 20px;
- height: 100%;
- width: 720px;
-}
-
-#notifications {
- float: left;
- height: 100%;
- width: 220px;
- margin-left: 20px;
- padding: 4px;
-}
-
-.out {
- float: left;
- width: 220px;
- border: 1px solid black;
- padding: 3px;
- margin-left: 20px;
-}
-.out p, #notifications p {
- line-height: 1.1;
- padding: 2px;
- margin: 0;
-}
-
-form {
- clear: both;
- margin-bottom: 8px;
-}
-
-input[type=text] {
- width: 140px;
-}
-
-.req {
- float: left;
- width: 300px;
-}
-
-#pubform, #pushform {
- margin-left: 180px;
-}
-
-#reqform, repform {
- margin-left: 20px;
-}
-
-.req .out {
- margin-left: 0;
- height: 3.1em;
-}
-
-img.routing {
- clear: both;
- margin-left:90px;
- display: block;
- margin-bottom: 12px;
-}
View
1 crontab
@@ -1 +0,0 @@
-* * * * * curl --connect-timeout 2 --silent --fail --out /dev/null http://tales.squirr.us/tick
View
186 cursors/index.html
@@ -1,186 +0,0 @@
-$def with (username, transport_url, ticket)
-<html>
-<head>
- <title>Flying Squirrel - Cursors</title>
- <script type="text/javascript"
- src="http://code.jquery.com/jquery-1.6.min.js"></script>
- <script type="text/javascript"
- src="http://cdn.socket.io/stable/socket.io.js"></script>
-
- <script type="text/javascript"
- src="http://cdn.squirr.us/flyingsquirrel-client-0.0.0.js"></script>
-
- <script type="text/javascript"
- src="http://dygraphs.com/dygraph-combined.js"></script>
-
- <style type="text/css">
- #inbox {
- border: 1px solid black;
- width: 50em;
- height: 20em;
- padding: 4px;
- overflow: auto;
- }
- .cursor {
- height: 30px;
- width: 30px;
- position: absolute;
- border: 1px solid grey;
- }
- #cursor_${ username } {
- border: 1px solid red;
- }
-
- </style>
-</head>
-<body>
- <h1>Flying Squirrel Example - latency test</h1>
-
- <h3>Send</h3>
- <div id="send_graph" style="height:200px; width:400px;"></div>
- <h3>Recv</h3>
- <div id="recv_graph" style="height:200px; width:400px;"></div>
- <h3>Round trip time</h3>
- <div id="latency_graph" style="height:200px; width:400px;"></div>
-
-
- <div id="inbox"></div>
-
-
- <script type="text/javascript">
- function prepare_data() {
- var data = [];
- var d = new Date();
- d.setMilliseconds(0);
- var t = d.getTime() - 40*1000;
- var i;
- for (i=0; i<120; i++) {
- data.push([new Date(t+333.33333*i), 0, 0, 0]);
- }
- return data;
- }
- function add_stat(stats, value) {
- var d = new Date();
- d.setMilliseconds( Math.floor(d.getMilliseconds()/333) * 333 );
- if (Math.abs(stats[stats.length-1][0] - d) > 10) {
- stats.push([d, 0, 0, 0]);
- stats.shift();
- }
- if (value !== undefined) {
- stats[stats.length-1][1] += value;
- stats[stats.length-1][2] += value*value;
- stats[stats.length-1][3] += 1;
- }
- }
- function construct_graph(id, data, filter, user_opts) {
- var opts = {
- labels: ["Date", "X"],
- };
- var opts = $$.extend(opts, user_opts)
- var graph_data = [];
- $$(data).each(function(_, e) {
- graph_data.push(filter(e));
- });
- var graph = new Dygraph(document.getElementById(id), graph_data, opts);
- var updater = function (data) {
- var graph_data = [];
- $$(data).each(function(_, e) {
- graph_data.push(filter(e));
- });
- graph.updateOptions({'file': graph_data});
- };
- return updater;
- }
- var send_data = prepare_data();
- var send_graph = construct_graph('send_graph', send_data, function(row){return [row[0], row[1]];}, {});
-
- var recv_data = prepare_data();
- var recv_graph = construct_graph('recv_graph', recv_data, function(row){return [row[0], row[1]];}, {});
-
- var latency_data = prepare_data();
- var latency_graph = construct_graph('latency_graph', latency_data,
- function(row){
- var sum = row[1];
- var sum_sq = row[2];
- var cnt = row[3] || 1;
- var avg = sum / cnt;
- var stddev = Math.sqrt((sum_sq / cnt) - avg*avg);
- return [row[0], [avg-stddev/2, avg, avg+stddev/2]];
- },
- {errorBars: true,
- sigma: 1.0,
- customBars: true
- });
-
- setInterval(function() {
- add_stat(send_data, 0);
- send_graph(send_data);
-
- add_stat(recv_data, 0);
- recv_graph(recv_data);
-
- add_stat(latency_data, 0);
- latency_graph(latency_data);
- }, 333);
- </script>
-
-
- <script>
- var transport_url = "${ transport_url }";
- var ticket = "${ ticket }";
- var opts = {debug: true};
- var connection = new flyingsquirrel.Connection(transport_url, ticket, opts);
-
- if( 'console' in window) {
- connection.socket.on('connect', function(){console.log('on_connected');} );
- connection.socket.on('disconnect', function(){console.log('on_disconnected');} );
- connection.socket.on('connecting', function(){console.log('on_connecting');} );
- connection.socket.on('connect_failed', function () {console.log('connect_failed');} );
- connection.socket.on('reconnect', function () {console.log('reconnect');} );
- connection.socket.on('reconnecting', function () {console.log('reconnecting');} );
- connection.socket.on('reconnect_failed', function () {console.log('reconnect_failed');} );
-
- connection.on_disconnect = function () {console.log('conn:on_disconnect');}
- connection.on_connect = function () {console.log('conn:on_connect');}
-}
- connection.connect();
-
- connection.subscribe('ingress', function (msg, _channel, raw_msg) {
- var latency = undefined;
- if (raw_msg.identity === '${ username }') {
- latency = (new Date()).getTime() - msg.t;
- }
- var m = {x:msg.x, y:msg.y, latency:latency,
- identity:raw_msg.identity};
-
- var inbox = $$("#inbox");
- while (inbox.children().length > 40) {
- inbox.children().first().remove();
- }
- inbox.append($$("<code />").text(JSON.stringify(m)));
- inbox.append("<br>");
- inbox.scrollTop(inbox.scrollTop() + 100);
-
- add_stat(recv_data, 3);
-
- if (latency !== undefined) {
- add_stat(latency_data, m.latency);
- }
-
- var id = "cursor_" + raw_msg.identity;
- if ($$('#'+id).length === 0) {
- $$("body").append('<div id="'+id+'" class="cursor"></div>');
- }
- $$('#'+id).offset({top:m.y-15, left:m.x-15});
- });
-
-
- $$(document).mousemove(function(e){
- var message = {x:e.pageX, y:e.pageY, t: (new Date()).getTime()};
- add_stat(send_data, 3);
- connection.publish('egress', message);
- });
-
- </script>
-</body>
-</html>
View
34 cursors/site.py
@@ -1,34 +0,0 @@
-#!/usr/bin/env python
-
-import random
-import string
-import web
-import flyingsquirrel as squirrel
-
-from config import SERVICE_URL
-
-
-urls = (
- '/(index(.html)?)?', 'Cursors'
-)
-app = web.application(urls, globals())
-
-render = web.template.render('.')
-
-class Cursors:
- def GET(self, *_ignore):
- username, transport_url, ticket = create_endpoint()
- return render.index(username, transport_url, ticket)
-
-def create_endpoint():
- client = squirrel.API(SERVICE_URL)
- endpoint = client.create_endpoint(
- "flying_cursors",
- definition = {'egress': ['pub', 'flying_cursors'],
- 'ingress': ['sub', 'flying_cursors']})
- username = ''.join(random.choice(string.letters) for i in xrange(8))
- ticket = client.generate_ticket('flying_cursors', username)
- return (username, endpoint['protocols']['socket.io'], ticket)
-
-if __name__ == "__main__":
- app.run()
View
87 fabfile.py
@@ -1,87 +0,0 @@
-from __future__ import with_statement
-from fabric.api import *
-from fabric.contrib.project import rsync_project
-from contextlib import contextmanager as _contextmanager
-
-# The trailing folder must be 'flying-squirrel-demos'.
-PREFIX = '/srv/flying-squirrel-demos'
-DATA = '/srv/flying-squirrel-data'
-
-
-@_contextmanager
-def virtualenv():
- with prefix('source %s/venv/bin/activate' % PREFIX):
- yield
-
-
-def upload():
- for p in [PREFIX, DATA]:
- run('[ -e "%(p)s" ] || (sudo mkdir -p "%(p)s"; sudo chown ubuntu:ubuntu "%(p)s")' % {'p':p})
- run('sudo chown -R srs:srs %s' % (DATA,))
- run('sudo chmod 777 %s' % (DATA,))
-
- rsync_project(
- remote_dir=PREFIX + '/..',
- exclude=['.hg', 'venv', "*.pyc"],
- delete=True)
-
- with cd(PREFIX):
- run('[ -e "venv" ] || virtualenv venv')
- with virtualenv():
- run('pip install -r requirements.txt')
- run('python -m compileall -q .')
-
-def prerequisites():
- sudo('apt-get -y install python-dev')
-
-
-def mud_setup():
- with virtualenv():
- with cd(PREFIX + '/mud'):
- run('[ -e settings_local.py ] && rm settings_local.py || true')
- run('ln -s settings_local_prod.py settings_local.py')
- run('[ -e "'+DATA+'/mud.sqlite" ] || (./manage.py syncdb --noinput && ./manage.py loaddata core/rooms.json;)')
- run('sudo chown srs:srs %s/mud.sqlite' % (DATA,))
- with cd('/etc/nginx/sites-enabled/'):
- # run('[ -e srs ] && sudo rm srs || true')
- run('[ -e 00-mud.conf ] && sudo rm 00-mud.conf || true')
- sudo('ln -s %s/mud.conf 00-mud.conf' % (PREFIX,))
- sudo('/etc/init.d/nginx restart')
- run('sudo crontab -u srs %(p)s/crontab' % {'p':PREFIX,})
-
-def mud_stop():
- with cd(DATA):
- run("sudo -u srs kill `cat mud.pid` || true")
-
-def mud_start():
- with virtualenv():
- with cd(PREFIX + '/mud'):
- run("sudo -u srs %(p)s/venv/bin/python ./manage.py runfcgi method=prefork socket=/tmp/fs-mud.sock pidfile=%(d)s/mud.pid outlog=%(d)s/mud-out.log errlog=%(d)s/mud-err.log daemonize=true workdir=%(p)s/mud umask=0000" % {'p':PREFIX, 'd':DATA})
-
-
-def channels_setup():
- with cd('/etc/nginx/sites-enabled/'):
- # run('[ -e srs ] && sudo rm srs || true')
- run('[ -e 00-channels.conf ] && sudo rm 00-channels.conf || true')
- sudo('ln -s %s/channels.conf 00-channels.conf' % (PREFIX,))
- sudo('/etc/init.d/nginx restart')
-
-def channels_stop():
- with cd(DATA):
- run("sudo -u srs kill `cat channels.pid` || true")
-
-def channels_start():
- with virtualenv():
- with cd(PREFIX + '/channels'):
- run("sudo -u srs PYTHONPATH='%(d)s' %(p)s/venv/bin/python ../run.py %(d)s channels" % {'p': PREFIX, 'd':DATA})
-
-
-def deploy():
- upload()
- mud_setup()
- mud_stop()
- mud_start()
- channels_setup()
- channels_stop()
- channels_start()
-
View
11 gateway/config.js
@@ -0,0 +1,11 @@
+var rabbitUrl = function() {
+ if (process.env.VCAP_SERVICES) {
+ var conf = JSON.parse(process.env.VCAP_SERVICES);
+ return conf['rabbitmq-2.4'][0].credentials.url;
+ }
+ else {
+ return "amqp://localhost";
+ }
+};
+exports.amqp_url = rabbitUrl();
+exports.port = process.env.VCAP_APP_PORT || 3001;
View
10 gateway/package.json
@@ -0,0 +1,10 @@
+{
+ "name": "mud-js",
+ "author": "Marek Majkowski",
+ "version": "0.0.0-unreleasable",
+ "dependencies": {
+ "node-static": "*",
+ "amqp": "*",
+ "sockjs": "*"
+ }
+}
View
78 gateway/server.js
@@ -0,0 +1,78 @@
+var http = require('http');
+var amqp = require('amqp');
+var sockjs = require('sockjs');
+var node_static = require('node-static');
+
+var config = require('./config');
+
+
+var client_id = '' + Math.random();
+
+var conn;
+var amqpSetup = function() {
+ var queue = conn.queue('mud-' + client_id, {durable: false, exclusive: true},
+ function() {
+ queue.subscribe(
+ function(msg) {
+ got_msg(msg);
+ });
+ });
+};
+
+conn = amqp.createConnection({url: config.amqp_url});
+conn.on('ready', amqpSetup);
+
+
+var sockjs_opts = {
+ sockjs_url: "http://majek.github.com/sockjs-client/sockjs-latest.min.js"
+};
+
+
+var register = {};
+function got_msg(raw_msg) {
+ var d = JSON.parse(raw_msg.data.toString('utf-8'));
+ var id = d.id, msg=d.data;
+ if(id in register) {
+ register[id](msg);
+ }
+};
+
+var sjs = new sockjs.Server(sockjs_opts);
+sjs.on('open', function(s) {
+ var id = '' + Math.random();
+ register[id] = function(msg) {
+ s.send(msg);
+ };
+ console.log(id + " created");