├── .sailsrc ├── templates ├── routes │ ├── user.js │ └── index.js ├── app.js ├── views │ ├── layout.jade │ └── index.jade ├── README.md └── public │ └── javascripts │ └── sails.io.js ├── .gitignore ├── .editorconfig ├── package.json ├── CONTRIBUTING.md ├── LICENSE ├── .jshintrc ├── index.js ├── README.md └── FAQ.md /.sailsrc: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "generators": { 4 | "modules": { 5 | "new": "./index" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /templates/routes/user.js: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * GET users listing. 4 | */ 5 | 6 | exports.list = function(req, res){ 7 | res.send('respond with a resource'); 8 | }; 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | lib-cov 2 | *.seed 3 | *.log 4 | *.csv 5 | *.dat 6 | *.out 7 | *.pid 8 | *.gz 9 | 10 | pids 11 | logs 12 | results 13 | 14 | npm-debug.log 15 | node_modules 16 | -------------------------------------------------------------------------------- /templates/routes/index.js: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * GET home page. 4 | */ 5 | 6 | exports.index = function(req, res){ 7 | res.render('index', { title: 'Sails (but like Express)' }); 8 | }; 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true -------------------------------------------------------------------------------- /templates/app.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies 3 | */ 4 | 5 | var Sails = require('sails').constructor; 6 | 7 | 8 | // Load logic from `routes` directory 9 | var routes = require('./routes'); 10 | var user = require('./routes/user'); 11 | 12 | 13 | // Configure and lift app 14 | var app = new Sails(); 15 | app.lift({ 16 | port: 1337, 17 | views: { engine: 'jade', layout: false }, 18 | hooks: { grunt: false }, 19 | globals: false, 20 | routes: { 21 | 'get /': routes.index, 22 | 'get /users': user.list 23 | } 24 | }); 25 | -------------------------------------------------------------------------------- /templates/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | title= title 5 | 6 | // Viewport mobile tag for sensible mobile support 7 | meta(name="viewport",content="width=device-width, initial-scale=1, maximum-scale=1") 8 | 9 | block styles 10 | 11 | body 12 | block body 13 | 14 | // A few key dependencies, linked in order 15 | 16 | // Bring in the socket.io client 17 | script(type="text/javascript", src="/js/socket.io.js") 18 | 19 | // then beef it up with some convenience logic for talking to Sails.js' 20 | script(type="text/javascript", src="/js/sails.io.js") 21 | 22 | // listen on socket.io for incoming messages 23 | script(type="text/javascript", src="/js/app.js") 24 | -------------------------------------------------------------------------------- /templates/README.md: -------------------------------------------------------------------------------- 1 | # Templates 2 | 3 | 4 | This is directory is where the templates for the generator live (i.e. source files specified in `{template: './foo'}` objects in the generator.) Currently, they're run through `ejs` templating, though that will likely change to lodash in the future (in the interest of reducing the weight of Sails in general) 5 | 6 | 7 | 8 | To use these templates: 9 | 10 | ```javascript 11 | // In `lib/index.js` 12 | { 13 | targets: { 14 | 15 | // ... 16 | 17 | // Create file at `scope.rootPath` using template at `templates/foo.bar` 18 | '.': { template: 'foo.bar' }, 19 | 20 | // Create file at `scope.rootPath/foo.js` 21 | './foo.js': { template: 'bar.baz' }, 22 | 23 | // ... 24 | } 25 | } 26 | ``` 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sails-generate-new-but-like-express", 3 | "version": "0.10.1", 4 | "description": "Generate a new for Sails.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "mocha" 8 | }, 9 | "keywords": [ 10 | "new", 11 | "generator", 12 | "sails", 13 | "generate", 14 | "plugin" 15 | ], 16 | "author": "balderdashy", 17 | "license": "MIT", 18 | "dependencies": { 19 | "lodash": ">=2.4.x", 20 | "merge-defaults": ">=0.1.0" 21 | }, 22 | "devDependencies": { 23 | "sails-generate": "*", 24 | "reportback": "*", 25 | "fs-extra": "*" 26 | }, 27 | "sailsGenerator": { 28 | "type": "new", 29 | "behavior": "overrides `sails generate new`", 30 | "sailsVersion": "~0.10.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to sails-generate-new-but-like-express 2 | 3 | 4 | ## Opening Issues 5 | 6 | Please observe the same conventions as you would opening issues in the main Sails repo. 7 | 8 | See [Opening Issues](https://github.com/balderdashy/sails/blob/master/CONTRIBUTING.md#opening-issues) for more information. 9 | 10 | 11 | 12 | ## Submitting Pull Requests 13 | 14 | Please observe the same conventions as you would submitting pull requests to the Sails core. 15 | 16 | See [Submitting Pull Requests](https://github.com/balderdashy/sails/blob/master/CONTRIBUTING.md#submitting-pull-requests). 17 | 18 | 19 | 20 | ## Need more help? 21 | 22 | Please see the [contribution guide](https://github.com/balderdashy/sails/blob/v0.10/CONTRIBUTING.md#contributing-to-a-generator) in the Sails repo for more general guidelines. 23 | 24 | 25 | [![githalytics.com alpha](https://cruel-carlota.pagodabox.com/8acf2fc2ca0aca8a3018e355ad776ed7 "githalytics.com")](http://githalytics.com/balderdashy/sails-generate-new-but-like-express/CONTRIBUTING.md) 26 | 27 | 28 | # Overriding a generator 29 | 30 | 31 | # Authoring custom generators 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 balderdashy & contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | // To fix column positions for JSHint errors you may want to add `"indent": 1` to your 3 | // **User** "jshint_options". This issue affects users with tabs for indentation. 4 | // This fix was reverted due to a conflict with using the `"white": true` option. 5 | // "indent": 1, 6 | "evil": true, 7 | "regexdash": true, 8 | "browser": true, 9 | "wsh": true, 10 | "sub": true, 11 | 12 | // Suppress warnings about mixed tabs and spaces 13 | "smarttabs": true, 14 | 15 | // Suppress warnings about trailing whitespace 16 | "trailing": false, 17 | 18 | // Suppress warnings about the use of expressions where fn calls or assignments are expected 19 | "expr": true, 20 | 21 | // Suppress warnings about using functions inside loops (useful for inifinityCounters) 22 | "loopfunc": true, 23 | 24 | // Suppress warnings about using assignments where conditionals are expected 25 | "boss": true, 26 | 27 | // Suppress warnings about "weird constructions" 28 | // i.e. allow code like: 29 | // (new (function OneTimeUsePrototype () { } )) 30 | "supernew": true, 31 | 32 | // Allow backwards, node-dependency-style commas 33 | "laxcomma": true 34 | } 35 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module dependencies 3 | */ 4 | 5 | var _ = require('lodash'); 6 | 7 | 8 | 9 | /** 10 | * sails-generate-new-but-like-express 11 | * 12 | * Usage: 13 | * `nodeg new foo --like express` 14 | * 15 | * @type {Object} 16 | */ 17 | 18 | module.exports = { 19 | 20 | targets: { 21 | 22 | './:appPath/app.js': { copy: 'app.js' }, 23 | './:appPath/public/javascripts': { folder: {} }, 24 | './:appPath/public/javascripts/sails.io.js': { copy: 'public/javascripts/sails.io.js' }, 25 | './:appPath/public/stylesheets': { folder: {} }, 26 | './:appPath/public/images': { folder: {} }, 27 | './:appPath/routes': { folder: {} }, 28 | './:appPath/routes/index.js': { template: 'routes/index.js' }, 29 | './:appPath/routes/user.js': { template: 'routes/user.js' }, 30 | './:appPath/views': { folder: {} }, 31 | './:appPath/views/index.jade': { template: 'views/index.jade' }, 32 | './:appPath/views/layout.jade': { template: 'views/layout.jade' }, 33 | './:appPath/package.json': { jsonfile: function (scope) { 34 | return { 35 | name: scope.appName, 36 | 'private': true, 37 | version: '0.0.0', 38 | description: 'a Sails application (but like Express)', 39 | dependencies: { 40 | 'sails' : '~0.10.0', 41 | 'sails-disk' : '~0.10.0', 42 | 'jade' : '*' 43 | }, 44 | scripts: { 45 | // TODO: Include this later when we have "sails test" ready. 46 | // test: './node_modules/mocha/bin/mocha -b', 47 | start: 'node app.js', 48 | debug: 'node debug app.js' 49 | }, 50 | main: 'app.js', 51 | repository: '', 52 | author: scope.author, 53 | license: '' 54 | }; 55 | } } 56 | }, 57 | 58 | 59 | before: function(scope, cb) { 60 | 61 | // Validate custom scope variables which 62 | // are required by this generator. 63 | if (!scope.rootPath) { 64 | return cb(new Error( 65 | 'Missing scope variable: `rootPath`\n' + 66 | 'Please make sure it is specified and try again.' 67 | )); 68 | } 69 | // Determine default values based on the 70 | // available generator scope. 71 | _.defaults(scope, { 72 | author: 'a Node.js/Sails.js Contributor', 73 | year: (new Date()).getFullYear(), 74 | appName: (scope.args[0] === '.' || !scope.args[0]) ? path.basename(process.cwd()) : scope.args[0], 75 | }); 76 | scope.appPath = scope.args[0] || '.'; 77 | 78 | // Trigger callback with no error to proceed. 79 | cb(); 80 | }, 81 | 82 | templatesDirectory: require('path').resolve('./templates') 83 | }; 84 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![image_squidhome@2x.png](http://i.imgur.com/RIvu9.png) 2 | 3 | # sails-generate-new-but-like-express 4 | 5 | 6 | A `new` generator for use with the Sails command-line interface. 7 | 8 | 9 | ### Installation 10 | 11 | Certain generators are installed by default in Sails, but they can be overridden. Check the [Sails docs](http://sailsjs.org/#!documentation) for information on installing generator overrides / custom generators. 12 | 13 | 18 | 19 | 20 | ### Production Usage 21 | 22 | ##### On the command line 23 | 24 | ```sh 25 | $ sails generate new 26 | ``` 27 | 28 | ##### In a node script 29 | 30 | ```javascript 31 | var path = require('path'); 32 | var sailsgen = require('sails-generate'); 33 | var scope = { 34 | rootPath: path.resolve(__dirname) 35 | }; 36 | sailsgen(require('sails-generate-new-but-like-express'), scope, function (err) { 37 | if (err) throw err; 38 | 39 | // It worked. 40 | }); 41 | ``` 42 | 43 | 44 | ### Development 45 | 46 | To get started quickly and see this generator in action, run the `bin/index.js` script: 47 | 48 | ```sh 49 | $ git clone YOUR_FORK_OF_THIS_REPO sails-generate-new-but-like-express-fork 50 | $ cd sails-generate-new-but-like-express-fork 51 | $ npm install 52 | $ node ./bin 53 | ``` 54 | 55 | `bin/index.js` is a simple script, bundled only for convenience, that runs the generator with hard-coded scope variables. Please feel free to modify that file however you like! Also see `CONTRIBUTING.md` for more information on overriding/enhancing generators. 56 | 57 | 58 | 59 | ### Questions? 60 | 61 | See `FAQ.md`. 62 | 63 | 64 | 65 | ### More Resources 66 | 67 | - [Stackoverflow](http://stackoverflow.com/questions/tagged/sails.js) 68 | - [#sailsjs on Freenode](http://webchat.freenode.net/) (IRC channel) 69 | - [Twitter](https://twitter.com/sailsjs) 70 | - [Professional/enterprise](https://github.com/balderdashy/sails-docs/blob/master/FAQ.md#are-there-professional-support-options) 71 | - [Tutorials](https://github.com/balderdashy/sails-docs/blob/master/FAQ.md#where-do-i-get-help) 72 | - Sails.js logo (small) 73 | 74 | 75 | ### License 76 | 77 | **[MIT](./LICENSE)** 78 | © 2014 [balderdashy](http://github.com/balderdashy) & [contributors] 79 | [Mike McNeil](http://michaelmcneil.com), [Balderdash](http://balderdash.co) & contributors 80 | 81 | [Sails](http://sailsjs.org) is free and open-source under the [MIT License](http://sails.mit-license.org/). 82 | 83 | -------------------------------------------------------------------------------- /FAQ.md: -------------------------------------------------------------------------------- 1 | # FAQ (Frequently Asked Questions) 2 | 3 | 4 | ### Which version should I use? 5 | 6 | The latest stable version in npm is always a safe bet. 7 | 8 | ```sh 9 | $ npm install sails-generate-new-but-like-express 10 | ``` 11 | 12 | [![NPM](https://nodei.co/npm/sails-generate-new-but-like-express.png?downloads=true&stars=true)](https://nodei.co/npm/sails-generate-new-but-like-express/) 13 | 14 | 15 | 16 | ### Where is the documentation? 17 | + Documentation for this module is in the README.md file. 18 | + [Docs for the latest stable npm release of Sails are on the website](http://sailsjs.org/#!documentation) 19 | 20 | 21 | 22 | ### What is a generator? 23 | 24 | A generator is one of the three main types of Sails plugins. It allows you to extend or override a generator in the Sails command-line interface (i.e. when a user runs `sails new` and/or `sails generate`. 25 | 26 | Out of all the types of plugins, generators involve the fewest lines of code, and are probably the best way to get your hands dirty without getting buried. 27 | 28 | 29 | ### What kind of things can I do in a generator? 30 | 31 | Generators are mainly about creating files. There are built-in helpers for: 32 | 33 | + creating folders 34 | + copying files 35 | + EJS template 36 | + running other generators 37 | 38 | 39 | 40 | ### How do I get involved? 41 | 42 | + [Contributing to this module](./CONTRIBUTING.md) 43 | + If you find a bug with this module, please submit an issue to the tracker in this repository. Better yet, send a pull request :) 44 | 45 | 46 | ### Where do I get help? 47 | 48 | + [Ask a question on StackOverflow](http://stackoverflow.com/questions/tagged/sailsjs?sort=newest&days=30) 49 | + Get help from the [Google Group](https://groups.google.com/forum/#!forum/sailsjs) 50 | + Get help on IRC ([#sailsjs on freenode](http://irc.netsplit.de/channels/details.php?room=%23sailsjs&net=freenode)) 51 | + [Tweet @sailsjs](http://twitter.com/sailsjs) 52 | 53 | 54 | ### Why haven't I gotten a response to my feature request? 55 | 56 | When people see something working in practice, they're usually a lot more down to get on board with it! That's even more true in the open-source community, since most of us are not getting paid to do this (myself included). The best feature request is a pull request-- even if you can't do the whole thing yourself, if you blueprint your thoughts, it'll help everyone understand what's going on. 57 | 58 | ### I want to make a sweeping change / add a major feature 59 | It's always a good idea to contact the maintainer(s) of a module before doing a bunch of work. This is even more true when it affects how things work / breaks backwards compatibility. 60 | 61 | ### The maintainer of this module won't merge my pull request. 62 | 63 | Most of the time, when PRs don't get merged, a scarcity of time is to blame. I can almost guarantee you it's nothing personal :) And I can only speak for myself here, but in most cases, when someone follows up on a PR that's been sitting for a little while on Twitter, I don't mind the reminder at all. 64 | 65 | The best thing about maintaining lots of small modules is that it's trivial to override any one of them on their own. If you need some changes merged, please feel empowered to fork this model and release your own version. 66 | 67 | If you feel that yours is the better approach, and should be the default, share it with the community via IRC, Twitter, Google Groups, etc. Also, feel free to let the core Sails/Waterline team know and we'll take it into consideration. 68 | 69 | 70 | 71 | ### More questions? 72 | 73 | > If you have an unanswered question that isn't covered here, and that you feel would add value for the community, please feel free to send a PR adding it to this section. 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | [![githalytics.com alpha](https://cruel-carlota.pagodabox.com/8acf2fc2ca0aca8a3018e355ad776ed7 "githalytics.com")](http://githalytics.com/balderdashy/sails-generate-new-but-like-express/FAQ.md) 82 | -------------------------------------------------------------------------------- /templates/views/index.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block styles 4 | // Default home page 5 | // 6 | link(href='http://sailsjs.org/styles/fonts.css', rel='stylesheet') 7 | style. 8 | /* Styles included inline since you'll probably be deleting this page anyway */ 9 | html,body{text-align:left;font-size:1em}html,body,img,form,textarea,input,fieldset,div,p,div,ul,li,ol,dl,dt,dd,h1,h2,h3,h4,h5,h6,pre,code{margin:0;padding:0}ul,li{list-style:none}img{display:block}a img{border:0}a{text-decoration:none;font-weight:normal;font-family:inherit}*:active,*:focus{outline:0;-moz-outline-style:none}h1,h2,h3,h4,h5,h6{font-weight:normal}div.clear{clear:both}.clearfix:after{clear:both;content:".";display:block;font-size:0;height:0;line-height:0;visibility:hidden}body{font-family:"Open Sans",Arial,sans-serif;font-weight:300;font-size:15px}h1{color:#0c8da0;font-size:2em;font-weight:300}h2{font-size:1.5em;font-weight:300;margin-top:4%}h3{font-size:1.25em;font-weight:300;font-style:italic;margin-bottom:5px}h4{color:#0c8da0;font-weight:300;font-size:1.5em}span{font-weight:700}ul{margin-top:5%;margin-bottom:5%}a{text-decoration:none;color:inherit}p{margin-bottom:7px;font-size:.9em}.container{max-width:997px;margin:0 auto;padding:0 4%}.sprite{font-weight:normal;background:url(http://sailsjs.org/images/newapp.sprite.png) no-repeat}.top-bar{position:relative;padding-top:10px;background-color:#001c20;height:55px}.main{float:left;max-width:610px;height:555px;margin-top:50px}.steps{height:250px}.getting-started p{ margin-bottom: 30px; line-height: 26px; }.getting-started div{float:left;width:540px}.getting-started li{clear:both;height:60px;margin-top:20px;margin-bottom:20px}.getting-started .sprite{margin-left:10px;padding-left:60px;height:42px;width:0}.getting-started .one{background-position:0 0}.getting-started .two{background-position:0 -42px}.getting-started .three{background-position:0 -83px}.delete{margin-top:5%;height:52px;background:#e3f0f1;border:1px solid #118798;color:#118798;clear:both}.delete .sprite{margin-top:10px;margin-bottom:10px;margin-left:9%;padding-left:42px;padding-top:7px;height:25px;background-position:0 -126px}.delete a{color:#0c8da0;font-weight:bold;padding-left:1%}.side-bar{max-width:327px;height:555px;float:left;border-left:1px solid #0c8da0;margin-left:25px;margin-top:50px;padding-left:25px}.side-bar ul{margin-bottom:10%}.side-bar ul li{margin-top:5px;margin-bottom:.25em}.side-bar ul li a{margin-bottom:.25em}.side-bar .sprite{padding-left:25px}.side-bar .single_page{background-position:0 -199px}.side-bar .traditional{background-position:0 -219px}.side-bar .realtime{background-position:0 -179px}.side-bar .api{background-position:0 -158px}.boxy{font-family:Courier,"Courier New",sans-serif;background-color:#e4edec;border:1px solid #d0d6d6;padding-left:5px;padding-right:5px;padding-top:2px;padding-bottom:2px;font-weight:100}.sixteen{margin-right:10px}.nineteen{margin-right:7px} 10 | 11 | //if IE 7 12 | style. 13 | .getting-started li{overflow:visible;clear:both}.delete{width:690px} 14 | 15 | block body 16 | .top-bar 17 | .container.clearfix 18 | img.logo(src="http://sailsjs.org/images/sails-logo.jpg") 19 | 20 | .container.clearfix 21 | .main 22 | h1#main-title Welcome 23 | h2 Getting started 24 | p Don't worry, we've got your back. 25 | .steps 26 | ul.getting-started 27 | li 28 | .sprite.one 29 | div 30 | h3 Get your API going. 31 | p 32 | | Run 33 | span.boxy sails generate foo 34 | | . This will create a model 35 | span.boxy Foo 36 | | and controller 37 | span.boxy FooController 38 | li 39 | .sprite.two 40 | div 41 | h3 Lift your app. 42 | p 43 | | Run 44 | span.boxy sails lift 45 | | to start up your app. If you visit 46 | span.boxy http://localhost:1337/foo 47 | | in your browser, you'll see a socket.io-compatible REST API was generated for your 'Foo' model. 48 | li 49 | .sprite.three 50 | div 51 | h3 Dive in and start building. 52 | p From here, you can modify your models, create custom controller methods as Express middleware, and create custom routes (routes are set up in 53 | span.boxy config/routes.js 54 | | ). Visit 55 | a(href="http://sailsjs.org") the Sails website 56 | | for more information on next steps. 57 | .delete 58 | .sprite You're looking at: 59 | span.boxy views/home/index.jade 60 | .side-bar 61 | h4#new New to Sails? 62 | ul 63 | li 64 | a(href="http://sailsjs.org") Visit sailsjs.org 65 | li 66 | a(href="http://sailsjs.org/#!documentation") Documentation 67 | h4 Next Steps 68 | ul 69 | li.sprite.single_page 70 | a(target="_blank", href="http://sailsjs.org") Build a single page app 71 | li.sprite.traditional 72 | a(target="_blank", href="http://sailsjs.org") Build a traditional webapp 73 | li.sprite.realtime 74 | a(target="_blank", href="http://sailsjs.org") Build a realtime app 75 | li.sprite.api 76 | a(target="_blank", href="http://sailsjs.org") Build an API 77 | -------------------------------------------------------------------------------- /templates/public/javascripts/sails.io.js: -------------------------------------------------------------------------------- 1 | /*! Socket.IO.min.js build:0.9.16, production. Copyright(c) 2011 LearnBoost MIT Licensed */ 2 | var io="undefined"==typeof module?{}:module.exports;(function(){(function(a,b){var c=a;c.version="0.9.16",c.protocol=1,c.transports=[],c.j=[],c.sockets={},c.connect=function(a,d){var e=c.util.parseUri(a),f,g;b&&b.location&&(e.protocol=e.protocol||b.location.protocol.slice(0,-1),e.host=e.host||(b.document?b.document.domain:b.location.hostname),e.port=e.port||b.location.port),f=c.util.uniqueUri(e);var h={host:e.host,secure:"https"==e.protocol,port:e.port||("https"==e.protocol?443:80),query:e.query||""};c.util.merge(h,d);if(h["force new connection"]||!c.sockets[f])g=new c.Socket(h);return!h["force new connection"]&&g&&(c.sockets[f]=g),g=g||c.sockets[f],g.of(e.path.length>1?e.path:"")}})("object"==typeof module?module.exports:this.io={},this),function(a,b){var c=a.util={},d=/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,e=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];c.parseUri=function(a){var b=d.exec(a||""),c={},f=14;while(f--)c[e[f]]=b[f]||"";return c},c.uniqueUri=function(a){var c=a.protocol,d=a.host,e=a.port;return"document"in b?(d=d||document.domain,e=e||(c=="https"&&document.location.protocol!=="https:"?443:document.location.port)):(d=d||"localhost",!e&&c=="https"&&(e=443)),(c||"http")+"://"+d+":"+(e||80)},c.query=function(a,b){var d=c.chunkQuery(a||""),e=[];c.merge(d,c.chunkQuery(b||""));for(var f in d)d.hasOwnProperty(f)&&e.push(f+"="+d[f]);return e.length?"?"+e.join("&"):""},c.chunkQuery=function(a){var b={},c=a.split("&"),d=0,e=c.length,f;for(;db.length?a:b,f=a.length>b.length?b:a;for(var g=0,h=f.length;g0&&a.splice(0,1)[0]!=c.transport.name);a.length?h(a):c.publish("connect_failed")}}},c.options["connect timeout"]))})}c.sessionid=d,c.closeTimeout=f*1e3,c.heartbeatTimeout=e*1e3,c.transports||(c.transports=c.origTransports=g?b.util.intersect(g.split(","),c.options.transports):c.options.transports),c.setHeartbeatTimeout(),h(c.transports),c.once("connect",function(){clearTimeout(c.connectTimeoutTimer),a&&typeof a=="function"&&a()})}),this},d.prototype.setHeartbeatTimeout=function(){clearTimeout(this.heartbeatTimeoutTimer);if(this.transport&&!this.transport.heartbeats())return;var a=this;this.heartbeatTimeoutTimer=setTimeout(function(){a.transport.onClose()},this.heartbeatTimeout)},d.prototype.packet=function(a){return this.connected&&!this.doBuffer?this.transport.packet(a):this.buffer.push(a),this},d.prototype.setBuffer=function(a){this.doBuffer=a,!a&&this.connected&&this.buffer.length&&(this.options.manualFlush||this.flushBuffer())},d.prototype.flushBuffer=function(){this.transport.payload(this.buffer),this.buffer=[]},d.prototype.disconnect=function(){if(this.connected||this.connecting)this.open&&this.of("").packet({type:"disconnect"}),this.onDisconnect("booted");return this},d.prototype.disconnectSync=function(){var a=b.util.request(),c=["http"+(this.options.secure?"s":"")+":/",this.options.host+":"+this.options.port,this.options.resource,b.protocol,"",this.sessionid].join("/")+"/?disconnect=1";a.open("GET",c,!1),a.send(null),this.onDisconnect("booted")},d.prototype.isXDomain=function(){var a=c.location.port||("https:"==c.location.protocol?443:80);return this.options.host!==c.location.hostname||this.options.port!=a},d.prototype.onConnect=function(){this.connected||(this.connected=!0,this.connecting=!1,this.doBuffer||this.setBuffer(!1),this.emit("connect"))},d.prototype.onOpen=function(){this.open=!0},d.prototype.onClose=function(){this.open=!1,clearTimeout(this.heartbeatTimeoutTimer)},d.prototype.onPacket=function(a){this.of(a.endpoint).onPacket(a)},d.prototype.onError=function(a){a&&a.advice&&a.advice==="reconnect"&&(this.connected||this.connecting)&&(this.disconnect(),this.options.reconnect&&this.reconnect()),this.publish("error",a&&a.reason?a.reason:a)},d.prototype.onDisconnect=function(a){var b=this.connected,c=this.connecting;this.connected=!1,this.connecting=!1,this.open=!1;if(b||c)this.transport.close(),this.transport.clearTimeouts(),b&&(this.publish("disconnect",a),"booted"!=a&&this.options.reconnect&&!this.reconnecting&&this.reconnect())},d.prototype.reconnect=function(){function e(){if(a.connected){for(var b in a.namespaces)a.namespaces.hasOwnProperty(b)&&""!==b&&a.namespaces[b].packet({type:"connect"});a.publish("reconnect",a.transport.name,a.reconnectionAttempts)}clearTimeout(a.reconnectionTimer),a.removeListener("connect_failed",f),a.removeListener("connect",f),a.reconnecting=!1,delete a.reconnectionAttempts,delete a.reconnectionDelay,delete a.reconnectionTimer,delete a.redoTransports,a.options["try multiple transports"]=c}function f(){if(!a.reconnecting)return;if(a.connected)return e();if(a.connecting&&a.reconnecting)return a.reconnectionTimer=setTimeout(f,1e3);a.reconnectionAttempts++>=b?a.redoTransports?(a.publish("reconnect_failed"),e()):(a.on("connect_failed",f),a.options["try multiple transports"]=!0,a.transports=a.origTransports,a.transport=a.getTransport(),a.redoTransports=!0,a.connect()):(a.reconnectionDelay=10:!1},c.xdomainCheck=function(){return!0},typeof window!="undefined"&&(WEB_SOCKET_DISABLE_AUTO_INITIALIZATION=!0),b.transports.push("flashsocket")}("undefined"!=typeof io?io.Transport:module.exports,"undefined"!=typeof io?io:module.parent.exports);if("undefined"!=typeof window)var swfobject=function(){function A(){if(t)return;try{var a=i.getElementsByTagName("body")[0].appendChild(Q("span"));a.parentNode.removeChild(a)}catch(b){return}t=!0;var c=l.length;for(var d=0;d0)for(var c=0;c0){var g=P(d);if(g)if(S(m[c].swfVersion)&&!(y.wk&&y.wk<312))U(d,!0),e&&(f.success=!0,f.ref=G(d),e(f));else if(m[c].expressInstall&&H()){var h={};h.data=m[c].expressInstall,h.width=g.getAttribute("width")||"0",h.height=g.getAttribute("height")||"0",g.getAttribute("class")&&(h.styleclass=g.getAttribute("class")),g.getAttribute("align")&&(h.align=g.getAttribute("align"));var i={},j=g.getElementsByTagName("param"),k=j.length;for(var l=0;l');h.outerHTML='"+k+"",n[n.length]=c.id,g=P(c.id)}else{var m=Q(b);m.setAttribute("type",e);for(var o in c)c[o]!=Object.prototype[o]&&(o.toLowerCase()=="styleclass"?m.setAttribute("class",c[o]):o.toLowerCase()!="classid"&&m.setAttribute(o,c[o]));for(var p in d)d[p]!=Object.prototype[p]&&p.toLowerCase()!="movie"&&M(m,p,d[p]);h.parentNode.replaceChild(m,h),g=m}}return g}function M(a,b,c){var d=Q("param");d.setAttribute("name",b),d.setAttribute("value",c),a.appendChild(d)}function N(a){var b=P(a);b&&b.nodeName=="OBJECT"&&(y.ie&&y.win?(b.style.display="none",function(){b.readyState==4?O(a):setTimeout(arguments.callee,10)}()):b.parentNode.removeChild(b))}function O(a){var b=P(a);if(b){for(var c in b)typeof b[c]=="function"&&(b[c]=null);b.parentNode.removeChild(b)}}function P(a){var b=null;try{b=i.getElementById(a)}catch(c){}return b}function Q(a){return i.createElement(a)}function R(a,b,c){a.attachEvent(b,c),o[o.length]=[a,b,c]}function S(a){var b=y.pv,c=a.split(".");return c[0]=parseInt(c[0],10),c[1]=parseInt(c[1],10)||0,c[2]=parseInt(c[2],10)||0,b[0]>c[0]||b[0]==c[0]&&b[1]>c[1]||b[0]==c[0]&&b[1]==c[1]&&b[2]>=c[2]?!0:!1}function T(c,d,e,f){if(y.ie&&y.mac)return;var g=i.getElementsByTagName("head")[0];if(!g)return;var h=e&&typeof e=="string"?e:"screen";f&&(v=null,w=null);if(!v||w!=h){var j=Q("style");j.setAttribute("type","text/css"),j.setAttribute("media",h),v=g.appendChild(j),y.ie&&y.win&&typeof i.styleSheets!=a&&i.styleSheets.length>0&&(v=i.styleSheets[i.styleSheets.length-1]),w=h}y.ie&&y.win?v&&typeof v.addRule==b&&v.addRule(c,d):v&&typeof i.createTextNode!=a&&v.appendChild(i.createTextNode(c+" {"+d+"}"))}function U(a,b){if(!x)return;var c=b?"visible":"hidden";t&&P(a)?P(a).style.visibility=c:T("#"+a,"visibility:"+c)}function V(b){var c=/[\\\"<>\.;]/,d=c.exec(b)!=null;return d&&typeof encodeURIComponent!=a?encodeURIComponent(b):b}var a="undefined",b="object",c="Shockwave Flash",d="ShockwaveFlash.ShockwaveFlash",e="application/x-shockwave-flash",f="SWFObjectExprInst",g="onreadystatechange",h=window,i=document,j=navigator,k=!1,l=[D],m=[],n=[],o=[],p,q,r,s,t=!1,u=!1,v,w,x=!0,y=function(){var f=typeof i.getElementById!=a&&typeof i.getElementsByTagName!=a&&typeof i.createElement!=a,g=j.userAgent.toLowerCase(),l=j.platform.toLowerCase(),m=l?/win/.test(l):/win/.test(g),n=l?/mac/.test(l):/mac/.test(g),o=/webkit/.test(g)?parseFloat(g.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):!1,p=!1,q=[0,0,0],r=null;if(typeof j.plugins!=a&&typeof j.plugins[c]==b)r=j.plugins[c].description,r&&(typeof j.mimeTypes==a||!j.mimeTypes[e]||!!j.mimeTypes[e].enabledPlugin)&&(k=!0,p=!1,r=r.replace(/^.*\s+(\S+\s+\S+$)/,"$1"),q[0]=parseInt(r.replace(/^(.*)\..*$/,"$1"),10),q[1]=parseInt(r.replace(/^.*\.(.*)\s.*$/,"$1"),10),q[2]=/[a-zA-Z]/.test(r)?parseInt(r.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0);else if(typeof h[["Active"].concat("Object").join("X")]!=a)try{var s=new(window[["Active"].concat("Object").join("X")])(d);s&&(r=s.GetVariable("$version"),r&&(p=!0,r=r.split(" ")[1].split(","),q=[parseInt(r[0],10),parseInt(r[1],10),parseInt(r[2],10)]))}catch(t){}return{w3:f,pv:q,wk:o,ie:p,win:m,mac:n}}(),z=function(){if(!y.w3)return;(typeof i.readyState!=a&&i.readyState=="complete"||typeof i.readyState==a&&(i.getElementsByTagName("body")[0]||i.body))&&A(),t||(typeof i.addEventListener!=a&&i.addEventListener("DOMContentLoaded",A,!1),y.ie&&y.win&&(i.attachEvent(g,function(){i.readyState=="complete"&&(i.detachEvent(g,arguments.callee),A())}),h==top&&function(){if(t)return;try{i.documentElement.doScroll("left")}catch(a){setTimeout(arguments.callee,0);return}A()}()),y.wk&&function(){if(t)return;if(!/loaded|complete/.test(i.readyState)){setTimeout(arguments.callee,0);return}A()}(),C(A))}(),W=function(){y.ie&&y.win&&window.attachEvent("onunload",function(){var a=o.length;for(var b=0;b= 10.0.0 is required.");return}location.protocol=="file:"&&a.error("WARNING: web-socket-js doesn't work in file:///... URL unless you set Flash Security Settings properly. Open the page via Web server i.e. http://..."),WebSocket=function(a,b,c,d,e){var f=this;f.__id=WebSocket.__nextId++,WebSocket.__instances[f.__id]=f,f.readyState=WebSocket.CONNECTING,f.bufferedAmount=0,f.__events={},b?typeof b=="string"&&(b=[b]):b=[],setTimeout(function(){WebSocket.__addTask(function(){WebSocket.__flash.create(f.__id,a,b,c||null,d||0,e||null)})},0)},WebSocket.prototype.send=function(a){if(this.readyState==WebSocket.CONNECTING)throw"INVALID_STATE_ERR: Web Socket connection has not been established";var b=WebSocket.__flash.send(this.__id,encodeURIComponent(a));return b<0?!0:(this.bufferedAmount+=b,!1)},WebSocket.prototype.close=function(){if(this.readyState==WebSocket.CLOSED||this.readyState==WebSocket.CLOSING)return;this.readyState=WebSocket.CLOSING,WebSocket.__flash.close(this.__id)},WebSocket.prototype.addEventListener=function(a,b,c){a in this.__events||(this.__events[a]=[]),this.__events[a].push(b)},WebSocket.prototype.removeEventListener=function(a,b,c){if(!(a in this.__events))return;var d=this.__events[a];for(var e=d.length-1;e>=0;--e)if(d[e]===b){d.splice(e,1);break}},WebSocket.prototype.dispatchEvent=function(a){var b=this.__events[a.type]||[];for(var c=0;c"),this.doc.close(),this.doc.parentWindow.s=this;var a=this.doc.createElement("div");a.className="socketio",this.doc.body.appendChild(a),this.iframe=this.doc.createElement("iframe"),a.appendChild(this.iframe);var c=this,d=b.util.query(this.socket.options.query,"t="+ +(new Date));this.iframe.src=this.prepareUrl()+d,b.util.on(window,"unload",function(){c.destroy()})},c.prototype._=function(a,b){a=a.replace(/\\\//g,"/"),this.onData(a);try{var c=b.getElementsByTagName("script")[0];c.parentNode.removeChild(c)}catch(d){}},c.prototype.destroy=function(){if(this.iframe){try{this.iframe.src="about:blank"}catch(a){}this.doc=null,this.iframe.parentNode.removeChild(this.iframe),this.iframe=null,CollectGarbage()}},c.prototype.close=function(){return this.destroy(),b.Transport.XHR.prototype.close.call(this)},c.check=function(a){if(typeof window!="undefined"&&["Active"].concat("Object").join("X")in window)try{var c=new(window[["Active"].concat("Object").join("X")])("htmlfile");return c&&b.Transport.XHR.check(a)}catch(d){}return!1},c.xdomainCheck=function(){return!1},b.transports.push("htmlfile")}("undefined"!=typeof io?io.Transport:module.exports,"undefined"!=typeof io?io:module.parent.exports),function(a,b,c){function d(){b.Transport.XHR.apply(this,arguments)}function e(){}a["xhr-polling"]=d,b.util.inherit(d,b.Transport.XHR),b.util.merge(d,b.Transport.XHR),d.prototype.name="xhr-polling",d.prototype.heartbeats=function(){return!1},d.prototype.open=function(){var a=this;return b.Transport.XHR.prototype.open.call(a),!1},d.prototype.get=function(){function b(){this.readyState==4&&(this.onreadystatechange=e,this.status==200?(a.onData(this.responseText),a.get()):a.onClose())}function d(){this.onload=e,this.onerror=e,a.retryCounter=1,a.onData(this.responseText),a.get()}function f(){a.retryCounter++,!a.retryCounter||a.retryCounter>3?a.onClose():a.get()}if(!this.isOpen)return;var a=this;this.xhr=this.request(),c.XDomainRequest&&this.xhr instanceof XDomainRequest?(this.xhr.onload=d,this.xhr.onerror=f):this.xhr.onreadystatechange=b,this.xhr.send(null)},d.prototype.onClose=function(){b.Transport.XHR.prototype.onClose.call(this);if(this.xhr){this.xhr.onreadystatechange=this.xhr.onload=this.xhr.onerror=e;try{this.xhr.abort()}catch(a){}this.xhr=null}},d.prototype.ready=function(a,c){var d=this;b.util.defer(function(){c.call(d)})},b.transports.push("xhr-polling")}("undefined"!=typeof io?io.Transport:module.exports,"undefined"!=typeof io?io:module.parent.exports,this),function(a,b,c){function e(a){b.Transport["xhr-polling"].apply(this,arguments),this.index=b.j.length;var c=this;b.j.push(function(a){c._(a)})}var d=c.document&&"MozAppearance"in c.document.documentElement.style;a["jsonp-polling"]=e,b.util.inherit(e,b.Transport["xhr-polling"]),e.prototype.name="jsonp-polling",e.prototype.post=function(a){function i(){j(),c.socket.setBuffer(!1)}function j(){c.iframe&&c.form.removeChild(c.iframe);try{h=document.createElement('