update @option example to use a keypath and a literal

# /api/App Components/Batman.View

`Batman.View`s connect a batman.js app to the DOM. This includes rendering HTML, handling DOM events, and maintaining view bindings. `Batman.View` extends `Batman.Object`. When subclassing `Batman.View`, you can create reusable UI components by defining attributes of the new view:

- [`::source`](/docs/api/batman.view.html#prototype_accessor_source) or [`::html`](/docs/api/batman.view.html#prototype_accessor_html) define the view's HTML.
- [`@option`](/docs/api/batman.view.html#class_function_option) adds context-based initialization options.
- [`@filter`](/docs/api/batman.view.html#class_function_filter) adds custom view filters.
- [Lifecycle hooks](/docs/views.html) fire when the view is loaded, rendered, or destroyed.

For more information about views, see [the guide](/docs/views.html).

## Accessors and Event Handlers

[View bindings](/docs/api/batman.view_bindings.html) have access to the views they're rendered by, so custom views are a great place to define view-specific accessors and event handlers. Then, you can connect them to your HTML with view bindings. For example, define a view:

```coffeescript
class CoffeeView extends Batman.View
  @accessor 'coffeeOfTheDay', -> "Guatemalan"
  drinkCoffee: -> alert("Yum!!")
```

then apply it to some HTML:

```html
<div data-view='CoffeeView'>
  <span data-bind='coffeeOfTheDay'></span>
  <button data-event-click='drinkCoffee'> Take a sip! </button>
<div>
```

Data bindings look for keys on their closest views first, so these bindings will be handled by `CoffeeView`.

## ::constructor(options = {}) : Batman.View

Returns a new `Batman.View`. Since `Batman.View` extends `Batman.Object`, all `options` are mixed in to the new instance. Use this to override `html`, `node`, `superview`, `parentNode`, and/or your custom data.

## ::lookupKeypath(keypath : String)

Traverses up the view tree searching for `keypath` and returns the first
result or `undefined` if no match is found. The path it takes is:

current view → chain of superviews → layout view → active controller → app →
window

    test 'lookupKeypath returns the value if defined on the view or on an ancestor', ->
      superview = new Batman.View(cat: 'Meowie')
      subview = new Batman.View(superview: superview, dog: 'Fido')
      equal 'Fido', subview.lookupKeypath('dog'), "finds an accessor on itself"
      equal 'Meowie', subview.lookupKeypath('cat'), "finds an accessor on its superview"
      equal undefined, subview.lookupKeypath('bogusKeypath'), "returns undefined if the keypath isn't defined"

If used in an accessor, `keypath` is registered as source and will be correctly bound. `lookupKeypath` is used by [view bindings](/docs/api/batman.view_bindings.html) to get data.

## ::setKeypath(keypath, value)

Traverses the view tree searching for the specified keypath and sets the value
on the nearest ancestor which defines it. If no ancestor view defines the given
keypath, it will be set on the nearest ancestor which is not a
backing view.

`setKeypath` is used by [view bindings](/docs/api/batman.view_bindings.html) to set data.

    test 'setKeypath sets the value if defined on the view or on an ancestor', ->
      superview = new Batman.View(cat: 'Meowie')
      subview = new Batman.View(superview: superview, dog: 'Fido')
      subview.setKeypath('cat', 'Mittens')
      equal 'Mittens', superview.get('cat'), "updates an accessor on its superview"
      subview.setKeypath('dog', 'Lassie')
      equal 'Lassie', subview.get('dog'), "updates an accessor on itself"

    test 'setKeypath sets the value on the nearest non-backing view when not defined anywhere', ->
      superview = new Batman.View()
      view = new Batman.View(superview: superview)
      backingView = new Batman.BackingView(superview: view)

      backingView.setKeypath('animal', 'cat')
      equal 'cat', view.get('animal')

## ::%node : Node

Returns the DOM node that this view encapsulates.

Accessing `node` will load and parse the template if it isn't already
loaded.

    test 'node parses the template', ->
      view = new Batman.View(html: '
cat
')

      node = view.get('node')
      equal 'cat', node.firstChild.innerHTML

You can also access a view's `node` in its methods, for example, activating jQuery plugins:

```
class App.SearchBarView extends Batman.View
  viewDidAppear: ->
    $node = $(@get('node'))
    $node.typeahead() # <= whatever jQuery plugin you want!
```
## ::%source : String

This string will be used to fetch a view's HTML, relative to [`Batman.config.pathToHTML`](/docs/configuration.html).
You don't need to add `.html` to this string -- it will be added automatically.

Inside a controller action, batman.js provides a default source based on the
contoller's [`routingKey`](/docs/api/batman.controller.html#routingkey_and_minification) and the [controller action](/docs/api/batman.controller.html#actions).

You can set `source` in the class definition:

```
class App.HeaderNavigationView extends Batman.View
  source: 'layout/_header'
```

Or when calling `@render()` inside a controller action:

```
class App.PostsController extends Batman.Controller
  show: ->
    @set('post', new App.Post)
    if @get('post.isAlternative')
      @render(source: "posts/alternative_new")
    else
      @render() # defaults to 'posts/new'
```

## ::%html : String

The HTML source for the view's template. Setting this will parse the template
and build bindings automatically, but it will not be inserted into the DOM
until the view is added to a superview. You can specify a view's HTML when you define the class:

```
class App.SearchBarView extends Batman.View
  html: "<input type='text' placeholder='Enter a search term' />"
```

If you don't explicitly set `html` but you do set `source`, then getting `html`
will automatically fetch the template source from the local template store.

    test 'setting a source loads the correct template', ->
      Batman.View.store.set('/animals', '
cat
')
      view = new Batman.View(source: '/animals')

      node = view.get('node')
      equal 'cat', node.firstChild.innerHTML

## @filter(label : string, filter : function)

Defines a custom [view filter](/docs/api/batman.view_filters.html) for use within the `View`.

`filter` will be invoked with the pre-filter `value` and any arguments passed to the view filter. For example:

```coffeescript
class App.MultiplierView extends Batman.View
  @filter 'multiplyBy', (value, multiplier) -> value * multiplier
```

would handle:

```html
<div data-view='MultiplierView' data-context-amount='100'>
  <span data-bind='amount | multiplyBy 6'>
    <!-- would render to "600" -->
  </span>
</div>
```

_Note_: If the `View`'s HTML is loaded before the view is instantiated, this filter won't have been defined yet and batman.js will throw an error. Avoid this by defining your custom filter at app-level or by defining the `View`'s HTML with [`::source`](/docs/api/batman.view.html#prototype_accessor_source) or [`::html`](/docs/api/batman.view.html#prototype_accessor_html).

## @option(keys...)

Defines a custom option for the `View`. `@option` allows you to initialize your view with data from its context. For example, you can define some options:

```coffeescript
class App.MultiplierView extends Batman.View
  @option 'amount', 'multiplier'
  @accessor 'finalAmount', -> @get('amount') * @get('multiplier')
```

then pass in keypaths or [keypath literals](/docs/api/batman.view_bindings.html#keypath_literals):

```html
<div data-context-ten='10'> <!-- sets 10 on keypath "ten" -->
  <div data-view='MultiplierView' data-view-amount='ten' data-view-multiplier='8'>
    <span data-bind='finalAmount'>
      <!-- would render to 80 !-->
    </span>
  </div>
</div>
```

## ::.superview : Batman.View

Returns the view's superview. Every view except an app's `LayoutView` has a superview.

## ::.subviews : Batman.Set

The set of direct children of this `View`. Since it's a [`Batman.Set`](/docs/api/batman.set.html), you can operate directly on this set and batman.js will automatically keep the DOM in sync.

Adding to a view's subviews will automatically update the tree and parse
the template and bindings. If the superview is in the DOM, this will
insert the current view's node into the DOM.

    test 'adding to a superview parses bindings', ->
      superview = new Batman.View()
      view = new Batman.View(html: '

', animal: 'cat')

      superview.subviews.add(view)
      equal 'cat', view.get('node').firstChild.innerHTML

Removing from a view's subviews will automatically remove the subview from
the DOM.

    test 'removing from the current superview removes the node from the DOM', ->
      superview = new Batman.View(html: '', parentNode: document.body)
      superview.get('node')
      view = new Batman.View(html: '', superview: superview)

      ok Batman.DOM.containsNode(superview.get('node'), view.get('node'))

      superview.subviews.remove(view)
      ok not Batman.DOM.containsNode(superview.get('node'), view.get('node'))

## ::removeFromSuperview()

Removes this view from its parent (and from the DOM), without killing it.

    test 'removing from the current superview removes the node from the DOM', ->
      superview = new Batman.View()
      view = new Batman.View(superview: superview)

      view.removeFromSuperview()
      ok not superview.subviews.has(view)

## ::die()

Kills this view, which renders it to forever unusable. This has the
following implications:

- The view is removed from its superview
- The view's node is removed from the DOM
- The view's bindings are destroyed
- The view's current subviews are killed

      test 'die kills the view', ->
        superview = new Batman.View()
        view = new Batman.View(superview: superview)

        view.die()
        equal true, view.isDead
        equal 0, superview.subviews.length

## ::.isDead : boolean

True if the view has been killed, false otherwise.

## ::destroySubviews()

Kills every subview of this view.

    test 'destroySubviews kills all subviews', ->
      superview = new Batman.View()
      one = new Batman.View(superview: superview)
      two = new Batman.View(superview: superview)

      superview.destroySubviews()
      ok one.isDead
      ok two.isDead

## ::propagateToSubviews(eventOrKey : string, value : Object)

If `value` is defined, set `eventOrKey` to `value` on the entire subtree.
Otherwise, fire `eventOrKey` on the entire subtree.

    test 'propagateToSubviews propagates events', ->
      superview = new Batman.View()
      one = new Batman.View(superview: superview)
      two = new Batman.View(superview: one)

      superview.on 'eventName', superSpy = createSpy()
      one.on 'eventName', oneSpy = createSpy()
      two.on 'eventName', twoSpy = createSpy()

      superview.propagateToSubviews('eventName')

      equal 1, superSpy.callCount
      equal 1, oneSpy.callCount
      equal 1, twoSpy.callCount

    test 'propagateToSubviews propagates keys', ->
      superview = new Batman.View()
      one = new Batman.View(superview: superview)
      two = new Batman.View(superview: one)

      superview.propagateToSubviews('key', 'value')

      equal superview.get('key'), 'value'
      equal one.get('key'), 'value'
      equal two.get('key'), 'value'

## @viewForNode(node, climbTree = true) : Batman.View

Finds the view acting as the current context for a node — i.e. perform the
reverse mapping of the view tree to the DOM. If you pass `false` for
`climbTree`, it won't traverse up the DOM, and will return `undefined` unless
the node is the view's root.

# /api/App Components/Batman.View

`Batman.View`s connect a batman.js app to the DOM. This includes rendering HTML, handling DOM events, and maintaining view bindings. `Batman.View` extends `Batman.Object`. When subclassing `Batman.View`, you can create reusable UI components by defining attributes of the new view:

- [`::source`](/docs/api/batman.view.html#prototype_accessor_source) or [`::html`](/docs/api/batman.view.html#prototype_accessor_html) define the view's HTML.
- [`@option`](/docs/api/batman.view.html#class_function_option) adds context-based initialization options.
- [`@filter`](/docs/api/batman.view.html#class_function_filter) adds custom view filters.
- [Lifecycle hooks](/docs/views.html) fire when the view is loaded, rendered, or destroyed.

For more information about views, see [the guide](/docs/views.html).

## Accessors and Event Handlers

[View bindings](/docs/api/batman.view_bindings.html) have access to the views they're rendered by, so custom views are a great place to define view-specific accessors and event handlers. Then, you can connect them to your HTML with view bindings. For example, define a view:

```coffeescript
class CoffeeView extends Batman.View
  @accessor 'coffeeOfTheDay', -> "Guatemalan"
  drinkCoffee: -> alert("Yum!!")
```

then apply it to some HTML:

```html
<div data-view='CoffeeView'>
  <span data-bind='coffeeOfTheDay'></span>
  <button data-event-click='drinkCoffee'> Take a sip! </button>
<div>
```

Data bindings look for keys on their closest views first, so these bindings will be handled by `CoffeeView`.

## ::constructor(options = {}) : Batman.View

Returns a new `Batman.View`. Since `Batman.View` extends `Batman.Object`, all `options` are mixed in to the new instance. Use this to override `html`, `node`, `superview`, `parentNode`, and/or your custom data.

## ::lookupKeypath(keypath : String)

Traverses up the view tree searching for `keypath` and returns the first
result or `undefined` if no match is found. The path it takes is:

current view → chain of superviews → layout view → active controller → app →
window

    test 'lookupKeypath returns the value if defined on the view or on an ancestor', ->
      superview = new Batman.View(cat: 'Meowie')
      subview = new Batman.View(superview: superview, dog: 'Fido')
      equal 'Fido', subview.lookupKeypath('dog'), "finds an accessor on itself"
      equal 'Meowie', subview.lookupKeypath('cat'), "finds an accessor on its superview"
      equal undefined, subview.lookupKeypath('bogusKeypath'), "returns undefined if the keypath isn't defined"

If used in an accessor, `keypath` is registered as source and will be correctly bound. `lookupKeypath` is used by [view bindings](/docs/api/batman.view_bindings.html) to get data.

## ::setKeypath(keypath, value)

Traverses the view tree searching for the specified keypath and sets the value
on the nearest ancestor which defines it. If no ancestor view defines the given
keypath, it will be set on the nearest ancestor which is not a
backing view.

`setKeypath` is used by [view bindings](/docs/api/batman.view_bindings.html) to set data.

    test 'setKeypath sets the value if defined on the view or on an ancestor', ->
      superview = new Batman.View(cat: 'Meowie')
      subview = new Batman.View(superview: superview, dog: 'Fido')
      subview.setKeypath('cat', 'Mittens')
      equal 'Mittens', superview.get('cat'), "updates an accessor on its superview"
      subview.setKeypath('dog', 'Lassie')
      equal 'Lassie', subview.get('dog'), "updates an accessor on itself"

    test 'setKeypath sets the value on the nearest non-backing view when not defined anywhere', ->
      superview = new Batman.View()
      view = new Batman.View(superview: superview)
      backingView = new Batman.BackingView(superview: view)

      backingView.setKeypath('animal', 'cat')
      equal 'cat', view.get('animal')

## ::%node : Node

Returns the DOM node that this view encapsulates.

Accessing `node` will load and parse the template if it isn't already
loaded.

    test 'node parses the template', ->
      view = new Batman.View(html: '
cat
')

      node = view.get('node')
      equal 'cat', node.firstChild.innerHTML

You can also access a view's `node` in its methods, for example, activating jQuery plugins:

```
class App.SearchBarView extends Batman.View
  viewDidAppear: ->
    $node = $(@get('node'))
    $node.typeahead() # <= whatever jQuery plugin you want!
```
## ::%source : String

This string will be used to fetch a view's HTML, relative to [`Batman.config.pathToHTML`](/docs/configuration.html).
You don't need to add `.html` to this string -- it will be added automatically.

Inside a controller action, batman.js provides a default source based on the
contoller's [`routingKey`](/docs/api/batman.controller.html#routingkey_and_minification) and the [controller action](/docs/api/batman.controller.html#actions).

You can set `source` in the class definition:

```
class App.HeaderNavigationView extends Batman.View
  source: 'layout/_header'
```

Or when calling `@render()` inside a controller action:

```
class App.PostsController extends Batman.Controller
  show: ->
    @set('post', new App.Post)
    if @get('post.isAlternative')
      @render(source: "posts/alternative_new")
    else
      @render() # defaults to 'posts/new'
```

## ::%html : String

The HTML source for the view's template. Setting this will parse the template
and build bindings automatically, but it will not be inserted into the DOM
until the view is added to a superview. You can specify a view's HTML when you define the class:

```
class App.SearchBarView extends Batman.View
  html: "<input type='text' placeholder='Enter a search term' />"
```

If you don't explicitly set `html` but you do set `source`, then getting `html`
will automatically fetch the template source from the local template store.

    test 'setting a source loads the correct template', ->
      Batman.View.store.set('/animals', '
cat
')
      view = new Batman.View(source: '/animals')

      node = view.get('node')
      equal 'cat', node.firstChild.innerHTML

## @filter(label : string, filter : function)

Defines a custom [view filter](/docs/api/batman.view_filters.html) for use within the `View`.

`filter` will be invoked with the pre-filter `value` and any arguments passed to the view filter. For example:

```coffeescript
class App.MultiplierView extends Batman.View
  @filter 'multiplyBy', (value, multiplier) -> value * multiplier
```

would handle:

```html
<div data-view='MultiplierView' data-context-amount='100'>
  <span data-bind='amount | multiplyBy 6'>
    <!-- would render to "600" -->
  </span>
</div>
```

_Note_: If the `View`'s HTML is loaded before the view is instantiated, this filter won't have been defined yet and batman.js will throw an error. Avoid this by defining your custom filter at app-level or by defining the `View`'s HTML with [`::source`](/docs/api/batman.view.html#prototype_accessor_source) or [`::html`](/docs/api/batman.view.html#prototype_accessor_html).

## @option(keys...)

Defines a custom option for the `View`. `@option` allows you to initialize your view with data from its context. For example:

```coffeescript
class App.MultiplierView extends Batman.View
  @option 'amount', 'multiplier'
  @accessor 'finalAmount', -> @get('amount') * @get('multiplier')
```

```html
<div data-view='MultiplierView' data-view-amount='10' data-view-multiplier='8'>
  <span data-bind='finalAmount'>
    <!-- would render to "80" !-->
  </span>
</div>
```

Options passed with `data-view-#{option}` may also be keypaths. Keypath changes will be tracked by the view.

## ::.superview : Batman.View

Returns the view's superview. Every view except an app's `LayoutView` has a superview.

## ::.subviews : Batman.Set

The set of direct children of this `View`. Since it's a [`Batman.Set`](/docs/api/batman.set.html), you can operate directly on this set and batman.js will automatically keep the DOM in sync.

Adding to a view's subviews will automatically update the tree and parse
the template and bindings. If the superview is in the DOM, this will
insert the current view's node into the DOM.

    test 'adding to a superview parses bindings', ->
      superview = new Batman.View()
      view = new Batman.View(html: '

', animal: 'cat')

      superview.subviews.add(view)
      equal 'cat', view.get('node').firstChild.innerHTML

Removing from a view's subviews will automatically remove the subview from
the DOM.

    test 'removing from the current superview removes the node from the DOM', ->
      superview = new Batman.View(html: '', parentNode: document.body)
      superview.get('node')
      view = new Batman.View(html: '', superview: superview)

      ok Batman.DOM.containsNode(superview.get('node'), view.get('node'))

      superview.subviews.remove(view)
      ok not Batman.DOM.containsNode(superview.get('node'), view.get('node'))

## ::removeFromSuperview()

Removes this view from its parent (and from the DOM), without killing it.

    test 'removing from the current superview removes the node from the DOM', ->
      superview = new Batman.View()
      view = new Batman.View(superview: superview)

      view.removeFromSuperview()
      ok not superview.subviews.has(view)

## ::die()

Kills this view, which renders it to forever unusable. This has the
following implications:

- The view is removed from its superview
- The view's node is removed from the DOM
- The view's bindings are destroyed
- The view's current subviews are killed

      test 'die kills the view', ->
        superview = new Batman.View()
        view = new Batman.View(superview: superview)

        view.die()
        equal true, view.isDead
        equal 0, superview.subviews.length

## ::.isDead : boolean

True if the view has been killed, false otherwise.

## ::destroySubviews()

Kills every subview of this view.

    test 'destroySubviews kills all subviews', ->
      superview = new Batman.View()
      one = new Batman.View(superview: superview)
      two = new Batman.View(superview: superview)

      superview.destroySubviews()
      ok one.isDead
      ok two.isDead

## ::propagateToSubviews(eventOrKey : string, value : Object)

If `value` is defined, set `eventOrKey` to `value` on the entire subtree.
Otherwise, fire `eventOrKey` on the entire subtree.

    test 'propagateToSubviews propagates events', ->
      superview = new Batman.View()
      one = new Batman.View(superview: superview)
      two = new Batman.View(superview: one)

      superview.on 'eventName', superSpy = createSpy()
      one.on 'eventName', oneSpy = createSpy()
      two.on 'eventName', twoSpy = createSpy()

      superview.propagateToSubviews('eventName')

      equal 1, superSpy.callCount
      equal 1, oneSpy.callCount
      equal 1, twoSpy.callCount

    test 'propagateToSubviews propagates keys', ->
      superview = new Batman.View()
      one = new Batman.View(superview: superview)
      two = new Batman.View(superview: one)

      superview.propagateToSubviews('key', 'value')

      equal superview.get('key'), 'value'
      equal one.get('key'), 'value'
      equal two.get('key'), 'value'

## @viewForNode(node, climbTree = true) : Batman.View

Finds the view acting as the current context for a node — i.e. perform the
reverse mapping of the view tree to the DOM. If you pass `false` for
`climbTree`, it won't traverse up the DOM, and will return `undefined` unless
the node is the view's root.


proper superclass

proper superclass

# CLASS: Component
* Extends: [Element][Element]
* Parent: [Index][Parent]

---

    module.exports = class Component extends require './element'

## CONSTRUCTOR

### new Component()

Creates Component instance.

      constructor: -> super

#### PARAMETERS
* **args** - named arguments

---

## PROPERTIES

---

## METHODS

[Parent]: ./index.litcoffee
[Element]: ./element.litcoffee

# CLASS: Component
* Extends: [Element][Element]
* Parent: [Index][Parent]

---

    module.exports = class Component extends require 'ecl/dist/evented'

## CONSTRUCTOR

### new Component()

Creates Component instance.

      constructor: (args) ->

#### PARAMETERS
* **args** - named arguments

---

## PROPERTIES

---

## METHODS

[Parent]: ./index.litcoffee
[Element]: ./element.litcoffee


fixed indentation

fixed indentation

# CLASS: Event
* Extends: [Base][Base]
* Parent: [lib][lib]

This class provides a data transport between instances of [Evented][Evented].
Any instance of this class must have at least the **type** property set
so that [Evented][Evented] methods will not drop it. This class does not provide
any functionality and mostly saves as the envelope for data.

      module.exports = class Event extends require './base'

## CONSTRUCTOR

### new Event(type)
### new Event(callback)
### new Event(args, callback)
### new Event(type, callback)

* Returns: [Event][Event]

Create the event. All the key-value pairs from **args** will be copied
to the event instance. If **callback** is provided in the **args**, it
will override the **callback** provided as the second argument.

Upon instance creation, the event will log it's creation timestamp. This
can be disabled by passing `timestamp:null` to constructor.

Any Event instance at its minimum will have **timestamp** property. This
is the only mandatory property.

Create Event instance, accepting arguments in multiple forms.

        constructor: (args = {}, callback) ->

Set the event type to the value of the first argument if it is a [String][String]

          if typeof args is 'string' then args = type:args

Otherwise, set the `args` to empty [Object][Object] and `callback` to the value of the
first argument if it is a [Function][Function].

          else if (arguments.length < 2) and typeof args is 'function'
            callback = args
            args = {}

Copy contents of args into this instance

          this[key] = value for key, value of args

Overwrite the **#callback** only if it is not set.

          @callback = callback if callback and not @callback

Calculate and set the event creation timestamp if it was not disabled or set from **args**

          if (args.timestamp is true) or not args.hasOwnProperty 'timestamp'
            date = Date.now()
            perf = performance?.now() or 0
            @timestamp = 1000 * date + Math.floor 1000 * (perf - Math.floor perf)

### PARAMETERS
**args**
* Type: [Object][Object] - event data

**args.type**
* Type: [String][String] - event type

**args.callback**
* Type: [Function][Function] - event completion callback
* Optional
* Overrides the **callback** parameter

**args.timestamp**
* Type: [Boolean][Boolean] - set to `false` to disable the timestamp calculation
* Type: [Number][Number] - event timestamp

**type**
* Type: [String][String] - event type

**callback**
* Type: [Function][Function] - event completion callback
* Optional

---

## PROPERTIES

### #type
* Type: [String][String] - event type

### #phase
* Type: [Number][Number] - event phase (1..3)

### #timestamp
* Type: [Number][Number] - event creation timestamp

### #callback
* Type: [Function][Function] - event completion callback

---

## FLAGS

### #started
* Type: [Boolean][Boolean] - event **started** flag

### #stopped
* Type: [Boolean][Boolean] - event **stopped** flag

### #canceled
* Type: [Boolean][Boolean] - event **canceled** flag

### #aborted
* Type: [Boolean][Boolean] - event **aborted** flag

### #done
* Type: [Boolean][Boolean] - event **done** flag

---

## METHODS

### #start()
* Returns: [Event][Event]

**started** flag setter

        start: -> (@started = yes) and this

---

### #stop()
* Returns: [Event][Event]

**stopped** flag setter

        stop: -> (@stopped = yes) and this

---

### #cancel()
* Returns: [Event][Event]

**canceled** flag setter

        cancel: -> (@canceled = yes) and this

---

### #abort()
* Returns: [Event][Event]

**aborted** flag setter

        abort: -> (@aborted = yes) and this

---

### #finish()
* Returns: [Event][Event]

**done** flag setter

        finish: -> (@done = yes) and this

[lib]: ./index.litcoffee
[Evented]: ./evented.litcoffee
[Base]: ./base.litcoffee
[Event]: ./event.litcoffee
[Object]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
[String]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
[Function]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function
[Boolean]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean
[Number]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number

# CLASS: Event
* Extends: [Base][Base]
* Parent: [lib][lib]

This class provides a data transport between instances of [Evented][Evented].
Any instance of this class must have at least the **type** property set
so that [Evented][Evented] methods will not drop it. This class does not provide
any functionality and mostly saves as the envelope for data.

      module.exports = class Event extends require './base'

## CONSTRUCTOR

### new Event(type)
### new Event(callback)
### new Event(args, callback)
### new Event(type, callback)

* Returns: [Event][Event]

Create the event. All the key-value pairs from **args** will be copied
to the event instance. If **callback** is provided in the **args**, it
will override the **callback** provided as the second argument.

Upon instance creation, the event will log it's creation timestamp. This
can be disabled by passing `timestamp:null` to constructor.

Any Event instance at its minimum will have **timestamp** property. This
is the only mandatory property.

Create Event instance, accepting arguments in multiple forms.

      constructor: (args = {}, callback) ->

Set the event type to the value of the first argument if it is a [String][String]

        if typeof args is 'string' then args = type:args

Otherwise, set the `args` to empty [Object][Object] and `callback` to the value of the
first argument if it is a [Function][Function].

        else if (arguments.length < 2) and typeof args is 'function'
            callback = args
            args = {}

Copy contents of args into this instance

        this[key] = value for key, value of args

Overwrite the **#callback** only if it is not set.

        @callback = callback if callback and not @callback

Calculate and set the event creation timestamp if it was not disabled or set from **args**

        if (args.timestamp is true) or not args.hasOwnProperty 'timestamp'
          date = Date.now()
          perf = performance?.now() or 0
          @timestamp = 1000 * date + Math.floor 1000 * (perf - Math.floor perf)

### PARAMETERS
**args**
* Type: [Object][Object] - event data

**args.type**
* Type: [String][String] - event type

**args.callback**
* Type: [Function][Function] - event completion callback
* Optional
* Overrides the **callback** parameter

**args.timestamp**
* Type: [Boolean][Boolean] - set to `false` to disable the timestamp calculation
* Type: [Number][Number] - event timestamp

**type**
* Type: [String][String] - event type

**callback**
* Type: [Function][Function] - event completion callback
* Optional

---

## PROPERTIES

### #type
* Type: [String][String] - event type

### #phase
* Type: [Number][Number] - event phase (1..3)

### #timestamp
* Type: [Number][Number] - event creation timestamp

### #callback
* Type: [Function][Function] - event completion callback

---

## FLAGS

### #started
* Type: [Boolean][Boolean] - event **started** flag

### #stopped
* Type: [Boolean][Boolean] - event **stopped** flag

### #canceled
* Type: [Boolean][Boolean] - event **canceled** flag

### #aborted
* Type: [Boolean][Boolean] - event **aborted** flag

### #done
* Type: [Boolean][Boolean] - event **done** flag

---

## METHODS

### #start()
* Returns [Event][Event]

**started** flag setter

      start: -> (@started = yes) and this

---

### #stop()
* Returns [Event][Event]

**stopped** flag setter

      stop: -> (@stopped = yes) and this

---

### #cancel()
* Returns [Event][Event]

**canceled** flag setter

      cancel: -> (@canceled = yes) and this

---

### #abort()
* Returns [Event][Event]

**aborted** flag setter

      abort: -> (@aborted = yes) and this

---

### finish()
* Returns [Event][Event]

**done** flag setter

      finish: -> (@done = yes) and this

[lib]: ./index.litcoffee
[Evented]: ./evented.litcoffee
[Base]: ./base.litcoffee
[Event]: ./event.litcoffee
[Object]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
[String]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
[Function]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function
[Boolean]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean
[Number]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number


Preliminary date functionality - just so it exists

#Includes

	moment = require 'moment'

#Date

	module.exports =
		scope:
			getDate: (result) ->
				if result.relativeDay?
					return moment({hour: 0}).add(result.relativeDay, 'd').toDate()
				else
					return moment().toDate()
		schema: [
			name: 'dayOfTheWeek'
			root:
				type: 'choice'
				id: '@value'
				children: [
					type: 'Sunday'
					value: 0
				,
					type: 'Monday'
					value: 1
				,
					type: 'Tuesday'
					value: 2
				,
					type: 'Wednesday'
					value: 3
				,
					type: 'Thursday'
					value: 4
				,
					type: 'Friday'
					value: 5
				,
					type: 'Saturday'
					value: 6
				]
		,
			name: 'date'
			evaluate: 'getDate'
			root:
				type: 'choice'
				children: [
					type: 'literal'
					id: 'relativeDay'
					display: 'today'
					value: 0
				,
					type: 'literal'
					id: 'relativeDay'
					display: 'tomorrow'
					value: 1
				,
					type: 'literal'
					id: 'relativeDay'
					display: 'the day after tomorrow'
					value: 2
				,
					type: 'sequence'
					children: [
						'in'
					,
						type: 'integer'
						id: 'relativeDay'
						min: 1
					,
						'days'
					]
				]
		]

#Includes

	moment = require 'moment'

#Date

	module.exports =
		scope:
			getDate: (result) ->
				if result.relativeDate?
					return moment({hour: 0}).add(result.relativeDate, 'd').toDate()
				else
					return moment().toDate()
		schema: [
			name: 'dayOfTheWeek'
			root:
				type: 'choice'
				id: '@value'
				children: [
					type: 'Sunday'
					value: 0
				,
					type: 'Monday'
					value: 1
				,
					type: 'Tuesday'
					value: 2
				,
					type: 'Wednesday'
					value: 3
				,
					type: 'Thursday'
					value: 4
				,
					type: 'Friday'
					value: 5
				,
					type: 'Saturday'
					value: 6
				]
		,
			name: 'date'
			evaluate: 'getDate'
			root:
				type: 'choice'
				children: [
					type: 'literal'
					id: 'relativeDate'
					display: 'today'
					value: 0
				,
					type: 'literal'
					id: 'relativeDate'
					display: 'tomorrow'
					value: 1
				,
					type: 'literal'
					id: 'relativeDate'
					display: 'the day after tomorrow'
					value: 2
				,
					type: 'sequence'
					children: [
						'in'
					,
						type: 'integer'
						id: 'relativeDate'
					,
						'days'
					]
				]
		]


Fix heading for ComponentQuery

Fix heading for ComponentQuery

# ComponentQuery

When we first start out, we are likely to have only a single
component.  This monad is used for querying that component
and getting a list of nodes that we will filter later.

## Example

```
componentQuery.contains
              .tags("div")
              .result()
```

This will take a component in the componentFilter
and generate a ComponentFilter with the DOM nodes
that have the tag "div".  In this particular example,
it will return a matching result if there are any
such nodes.

## Requirements

In order to make sure that the user can use whatever version of React
they want, we assume that the variable `React` already points to
the React package (FIXME: I wonder if there is a better way).  Just
to save typing, we will use the following alias:

    Utils = React.addons.TestUtils

The [JasmineMonad](./JasmineMonad.litcoffee)is a "maybe" monad that
allows us to chain our matcher functions in a fluent way.

    JasmineMonad = require("./JasmineMonad.litcoffee")

The [ComponentFilter](./ComponentFilter.litcoffee) is a JasmineMonad
that allows you to filter and match collections of React components.

    ComponentFilter = require("./ComponentFilter.litcoffee")

## A monad for making queries of single Components

    class ComponentQuery extends JasmineMonad

      constructor: (@value, @util, @testers, @messages) ->
        super(@value, @util, @testers, @messages)
        @contains = this

Most of the methods on `ComponentQuery` will actually want to
return a ComponentFilter so the user can filter the collection of returned
nodes.  If we were using a language with strong typing the compiler
would be able to construct the correct the correct Monad based
on the types.  However, we are using Coffeescript, so we have to
give it a helping hand by making a different `return` method.

      returnMany: (nodes, messages) ->
        new ComponentFilter(nodes, @util, @testers, messages)

#### Testing for DOM tags

One of the most common kinds of tests is to determine whether or not
a component contains a DOM "tag" (eg "h1", "div", etc). This matcher
passes if there is at least one.

      tags: (tag) ->
        @bind (component) =>
          nodes = Utils.scryRenderedDOMComponentsWithTag(component, tag)
          messages = [
            "Expected to find DOM tag #{tag}, but it was not there."
            "Expected not to find DOM tag #{tag}, but there #{@was(nodes.length)}."
          ]
          if nodes.length > 0
            @returnMany(nodes, messages)
          else
            @return(null, messages)

Export our matchers from this file.

    module.exports = ComponentQuery

# Component Query

When we first start out, we are likely to have only a single
component.  This monad is used for querying that component
and getting a list of nodes that we will filter later.

## Example

```
componentQuery.contains
              .tags("div")
              .result()
```

This will take a component in the componentFilter
and generate a ComponentFilter with the DOM nodes
that have the tag "div".  In this particular example,
it will return a matching result if there are any
such nodes.

## Requirements

In order to make sure that the user can use whatever version of React
they want, we assume that the variable `React` already points to
the React package (FIXME: I wonder if there is a better way).  Just
to save typing, we will use the following alias:

    Utils = React.addons.TestUtils

The [JasmineMonad](./JasmineMonad.litcoffee)is a "maybe" monad that
allows us to chain our matcher functions in a fluent way.

    JasmineMonad = require("./JasmineMonad.litcoffee")

The [ComponentFilter](./ComponentFilter.litcoffee) is a JasmineMonad
that allows you to filter and match collections of React components.

    ComponentFilter = require("./ComponentFilter.litcoffee")

## A monad for making queries of single Components

    class ComponentQuery extends JasmineMonad

      constructor: (@value, @util, @testers, @messages) ->
        super(@value, @util, @testers, @messages)
        @contains = this

Most of the methods on `ComponentQuery` will actually want to
return a ComponentFilter so the user can filter the collection of returned
nodes.  If we were using a language with strong typing the compiler
would be able to construct the correct the correct Monad based
on the types.  However, we are using Coffeescript, so we have to
give it a helping hand by making a different `return` method.

      returnMany: (nodes, messages) ->
        new ComponentFilter(nodes, @util, @testers, messages)

#### Testing for DOM tags

One of the most common kinds of tests is to determine whether or not
a component contains a DOM "tag" (eg "h1", "div", etc). This matcher
passes if there is at least one.

      tags: (tag) ->
        @bind (component) =>
          nodes = Utils.scryRenderedDOMComponentsWithTag(component, tag)
          messages = [
            "Expected to find DOM tag #{tag}, but it was not there."
            "Expected not to find DOM tag #{tag}, but there #{@was(nodes.length)}."
          ]
          if nodes.length > 0
            @returnMany(nodes, messages)
          else
            @return(null, messages)

Export our matchers from this file.

    module.exports = ComponentQuery


weya example lint

weya example lint

Create a sample div

    class Student
     constructor: (name, age) ->
      @name = name
      @age = age

     template: ->
      @div "#name.col-md-6", ->
       @span "Name"
       @span @$.name
      @div "#age.col-md-6", style: {background: "red"}, ->
       @span "Age"
       @span "#{@$.age}"
       @input "#ageInput", type: "text", null

     render: ->
      console.log Weya.markup context: this, @template
      Weya elem: document.body, context: this, @template

    student = new Student "Varuna", 26
    student.render()

Create a sample div

    class Student
     constructor: (name, age) ->
      @name = name
      @age = age

     template: ->
      @div "#name.col-md-6", ->
       @span "Name"
       @span @$.name
      @div "#age.col-md-6", style: {background: "red"}, ->
       @span "Age"
       @span "#{@$.age}"
       @input "#ageInput", type: "text", null

     render: ->
      console.log Weya.markup context: @, @template
      Weya elem: document.body, context: @, @template

    student = new Student "Varuna", 26
    student.render()


gzip over deflate

gzip over deflate

    _self = this

    if console?.log?
     LOG = console.log.bind console
    else
     LOG = -> null

    if console?.error?
     ERROR_LOG = console.error.bind console
    else
     ERROR_LOG = -> null

    POLL_TYPE =
     progress: true

##Response class

    class Response
     constructor: (data, port, options) ->
      @id = data.id
      @port = port
      @options = options
      @queue = []
      @fresh = true

     progress: (progress, data, callback) ->
      @queue.push
       method: 'progress'
       data: data
       options: {progress: progress}
       callback: callback
      @_handleQueue()

     success: (data) ->
      @queue.push method: 'success', data: data, options: {}
      @_handleQueue()

     fail: (data) ->
      @queue.push method: 'fail', data: data, options: {}
      @_handleQueue()

     setOptions: (options) ->
      @options = options
      @fresh = true
      @_handleQueue()

     _multipleResponse: ->
      responseList = []
      callbacks = []
      for d in @queue
       responseList.push
        status: d.method
        data: d.data
        options: d.options
       if d.callback?
        callbacks.push d.callback

      done = ->
       for callback in callbacks
        callback()

      if @port.isStreaming
       @port.respondMultiple this, responseList, @options, done
      else if @fresh
       @port.respondMultiple this, responseList, @options, done
       @fresh = false

      @queue = []

     _handleQueue: ->
      return unless @queue.length > 0
      return if not @queue.isStreaming and not @fresh

      if @queue.length > 1
       return @_multipleResponse()

      d = @queue[0]

      if @port.isStreaming
       @port.respond this, d.method, d.data, d.options, @options, d.callback
      else if @fresh
       @port.respond this, d.method, d.data, d.options, @options, d.callback
       @fresh = false

      @queue = []

##Call class

    class Call
     constructor: (@id, @method, @data, @callbacks, @options) -> null

     handle: (data, options) ->
      if not @callbacks[options.status]?
       return if options.status is 'progress'
       #Handled by caller
       throw new Error "No callback registered #{@method} #{options.status}"
      self = this
      setTimeout (-> self.callbacks[options.status] data, options), 0

      if POLL_TYPE[options.status]?
       return false
      else
       return true

##Port base class

    class Port
     constructor: ->
      @handlers = {}
      @callsCache = {}
      @callsCounter = 0
      @id = parseInt Math.random() * 1000
      @responses = {}
      @wrappers =
       send: []
       respond: []
       handleCall: []
       handleResponse: []

     isStreaming: true

     onCallError: (msg, options) ->
      callsCache = @callsCache
      @callsCache = {}
      for id, call of callsCache
       if not call.callbacks.fail?
        ERROR_LOG 'fail callback not registered', call.method, call.data
       else
        call.callbacks.fail error: 'connectionError', msg: msg, options: options, {}

      @errorCallback msg, options

     onHandleError: (msg, data, options) ->
      @errorCallback msg, data
      response = new Response data, this, options
      response.fail msg

     errorCallback: (msg, options) ->
      ERROR_LOG msg, options

     wrap: (wrapper) ->
      for key, f of wrapper
       if @wrappers[key]?
        @wrappers[key].push f
       else
        this[key] = f

###Send RPC call

     send: (method, data, callbacks, options = {}) ->
      if (typeof callbacks) is 'function'
       callbacks =
        success: callbacks

      for f in @wrappers.send
       return unless f.apply this, [method, data, callbacks, options]

      params = @_createCall method, data, callbacks, options
      @_send params, callbacks

###Respond to a RPC call

     respond: (response, status, data, options = {}, portOptions = {}, callback = null) ->
      if not POLL_TYPE[status]?
       delete @responses[response.id]

      for f in @wrappers.respond
       return unless f.apply this, [response, status, data, options, portOptions]

      @_respond (@_createResponse response, status, data, options), portOptions, callback

     respondMultiple: (response, list, portOptions = {}, callback = null) ->
      for d in list
       if not POLL_TYPE[d.status]?
        delete @responses[response.id]
        break

      data = []
      for d in list
       cancel = false
       d.options ?= {}
       for f in @wrappers.respond
        r = f.apply this, [response, d.status, d.data, d.options, portOptions]
        if not r
         cancel = true
         break

        continue if cancel

       data.push @_createResponse response, d.status, d.data, d.options

      return if data.length is 0

      data =
       type: 'list'
       list: data

      @_respond data, portOptions, callback

###Create Call object
This is a private function

     _createCall: (method, data, callbacks, options) ->
      call = new Call "#{@id}-#{@callsCounter}", method, data, callbacks, options
      @callsCounter++
      @callsCache[call.id] = call

      params =
       type: 'call'
       id: call.id
       method: call.method
       data: call.data

      params[k] = v for k, v of options
      return params

###Create Response object

     _createResponse: (response, status, data, options) ->
      params =
       type: 'response'
       id: response.id
       status: status
       data: data

      params[k] = v for k, v of options

      return params

###Add handler

     on: (method, callback) ->
      @handlers[method] = callback

###Handle incoming message

     _handleMessage: (data, options, last = true) ->
      switch data.type
       when 'list'
        for d, i in data.list
         @_handleMessage d, options, (last and i + 1 is data.list.length)
       when 'response'
        @_handleResponse data, options, last
       when 'call'
        @_handleCall data, options, last
       when 'poll'
        @_handlePoll data, options, last

     _handleCall: (data, options) ->
      for f in @wrappers.handleCall
       return unless f.apply this, arguments
      if not @handlers[data.method]?
       @onHandleError "Unknown method: #{data.method}", data, options
       return
      @responses[data.id] = new Response data, this, options
      @handlers[data.method] data.data, data, @responses[data.id]

     _handleResponse: (data, options) ->
      for f in @wrappers.handleResponse
       return unless f.apply this, arguments
      if not @callsCache[data.id]?
       #Cannot reply
       @errorCallback "Response without call: #{data.id}", data
       return
      try
       if @callsCache[data.id].handle data.data, data
        delete @callsCache[data.id]
      catch e
       @errorCallback e.message, data
       delete @callsCache[data.id]

     _handlePoll: (data, options) ->
      @onHandleError "Poll not implemented", data, options

##WorkerPort class
Used for browser and worker

    class WorkerPort extends Port
     constructor: (worker) ->
      super()
      @worker = worker
      @worker.onmessage = @_onMessage.bind this
      #@worker.onerror = @onCallError.bind this

     _send: (data) ->
      @worker.postMessage data

     _respond: (data, options, callback) ->
      @worker.postMessage data
      callback?()

     _onMessage: (e) ->
      data = e.data
      @_handleMessage data

##SocketPort class

    class SocketPort extends Port
     constructor: (socket) ->
      super()
      @socket = socket
      @socket.on 'message', @_onMessage.bind this

     _send: (data) ->  @socket.emit 'message', data
     _respond: (data, options, callback) ->
      @worker.emit 'message', data
      callback?()

     _onMessage: (e) ->
      data = e.data
      @_handleMessage data

##ServerSocketPort class

    class ServerSocketPort extends Port
     constructor: (server) ->
      super()
      @server = server
      @server.on 'connection', @_onConnection.bind this

     _onConnection: (socket) ->
      new SocketPort handlers: @handlers, socket

##AJAX class

    class AjaxHttpPort extends Port
     constructor: (options) ->
      super()
      @protocol = options.protocol
      @host = options.host
      @port = options.port
      @path = options.path ? '/'
      @url = @path
      if @protocol?
       if @host? and not @port?
        @url = "#{@protocol}://#{@host}#{@path}"
       else if @host? and @port?
        @url = "#{@protocol}://#{@host}:#{@port}#{@path}"
      else
       if @host? and not @port?
        @url = "//#{@host}#{@path}"
       else if @host? and @port?
        @url = "//#{@host}:#{@port}#{@path}"

     isStreaming: false

     _onRequest: (xhr) ->
      return unless xhr.readyState is 4
      status = xhr.status
      if ((not status and xhr.responseText? and xhr.responseText != '') or
          (status >= 200 and status < 300) or
          (status is 304))
       try
        jsonData = JSON.parse xhr.responseText
       catch e
        @onCallError 'ParseError', e
        return

       @_handleMessage jsonData, xhr: xhr
      else
       @onCallError 'Cannot connect to server'

     _respond: (data, options, callback) ->
      @errorCallback 'AJAX cannot respond', data
      callback?()

     _send: (data) ->
      data = JSON.stringify data
      xhr = new XMLHttpRequest
      xhr.open 'POST', @url
      xhr.onreadystatechange = =>
       @_onRequest xhr
      xhr.setRequestHeader 'Accept', 'application/json'
      #xhr.setRequestHeader 'Content-Type', 'application/json'
      xhr.send data

     _handleResponse: (data, options, last = true) ->
      for f in @wrappers.handleResponse
       return unless f.apply this, arguments
      if not @callsCache[data.id]?
       @errorCallback "Response without call: #{data.id}", data
       return
      call = @callsCache[data.id]
      try
       if call.handle data.data, data
        delete @callsCache[data.id]
       else if last
        params =
         type: 'poll'
         id: call.id
        params[k] = v for k, v of call.options
        @_send params
      catch e
       @errorCallback e.message, data
       delete @callsCache[data.id]

##NodeHttpPort class

    class NodeHttpPort extends Port
     constructor: (options, http) ->
      super()
      @host = options.host ? 'localhost'
      @port = options.port ? 80
      @path = options.path ? '/'
      @http = http
      @_createHttpOptions()

     isStreaming: false

     _createHttpOptions: ->
      @httpOptions =
       hostname: @host
       port: @port
       path: @path
       method: 'POST'
       agent: false
       headers:
        accept: 'application/json'
       'content-type': 'application/json'

     _onRequest: (res) ->
      data = ''
      #LOG 'STATUS: ' + res.statusCode
      #LOG 'HEADERS: ' + JSON.stringify res.headers
      res.setEncoding 'utf8'
      res.on 'data', (chunk) ->
       data += chunk
      #LOG 'result', res
      res.on 'end', =>
       try
        jsonData = JSON.parse data
       catch e
        @onCallError 'ParseError', e
        return

       @_handleMessage jsonData, response: res

     _respond: (data, options, callback) ->
      data = JSON.stringify data
      res = options.response
      res.setHeader 'content-length', Buffer.byteLength data, 'utf8'
      if callback?
       res.once 'finish', ->
        callback()
       res.once 'close', ->
        callback()

      res.write data
      res.end()

     _send: (data, callbacks) ->
      data = JSON.stringify data
      options = @httpOptions
      options.headers['content-length'] = Buffer.byteLength data, 'utf8'

      req = @http.request options, @_onRequest.bind this
      delete options.headers['content-length']
      req.on 'error', (e) ->
       callbacks.fail? e

      req.write data
      req.end()

     _handleResponse: (data, options, last = true) ->
      for f in @wrappers.handleResponse
       return unless f.apply this, arguments
      if not @callsCache[data.id]?
       @errorCallback "Response without call: #{data.id}", data
       return
      call = @callsCache[data.id]
      if not call.handle data.data, data
       return if not last
       params =
        type: 'poll'
        id: call.id
       params[k] = v for k, v of call.options
       @_send params, call.callbacks

##NodeHttpServerPort class

    class NodeHttpServerPort extends Port
     constructor: (options, http, zlib = null) ->
      super()
      @port = options.port
      @http = http
      @zlib = zlib
      @allowOrigin = options.allowOrigin

     isStreaming: false

     _onRequest: (req, res) ->
      data = ''
      res.setHeader 'content-type', 'application/json'

      req.on 'data', (chunk) ->
       data += chunk
      req.on 'end', =>
       try
        jsonData = JSON.parse data
       catch e
        @errorCallback 'ParseError', e
        return

       @_handleMessage jsonData, response: res, request: req

     _respond: (data, options, callback) ->
      if @allowOrigin?
       options.response.setHeader 'Access-Control-Allow-Origin', @allowOrigin

      accept = options.request.headers['accept-encoding']
      accept ?= ''
      if not @zlib?
       accept = ''

      data = JSON.stringify data
      buffer = new Buffer data, 'utf8'
      if accept.match /\bgzip\b/
       options.response.setHeader 'content-encoding', 'gzip'
       @zlib.gzip buffer, (err, result) =>
        if err?
         return @errorCallback 'GZipeError', e
        @_sendBuffer result, options.response, callback
      else if accept.match /\bdeflate\b/
       options.response.setHeader 'content-encoding', 'deflate'
       @zlib.deflate buffer, (err, result) =>
        if err?
         return @errorCallback 'DeflateError', e
        @_sendBuffer result, options.response, callback
      else
       @_sendBuffer buffer, options.response, callback

     _sendBuffer: (buf, res, callback) ->
       res.setHeader 'content-length', buf.length
       if callback?
        res.once 'finish', ->
         callback()
        res.once 'close', ->
         callback()

       res.write buf
       res.end()

     listen: ->
      @server = @http.createServer @_onRequest.bind this
      @server.listen @port

     _handlePoll: (data, options) ->
      for f in @wrappers.handleCall
       return unless f.apply this, arguments
      if not @responses[data.id]?
       @onHandleError "Poll without response: #{data.id}", data, options
       return
      @responses[data.id].setOptions options

##NodeHttpsServerPort class

    class NodeHttpsServerPort extends NodeHttpServerPort
     constructor: (options, http) ->
      super options, http
      @_key = options.key
      @_cert = options.cert

     listen: ->
      options =
       key: @_key
       cert: @_cert

      @server = @http.createServer options, @_onRequest.bind this
      @server.listen @port

#IO Module

    IO =
     addPort: (name, port) ->
      IO[name] = port

     ports:
      WorkerPort: WorkerPort
      SocketPort: SocketPort
      AjaxHttpPort: AjaxHttpPort
      NodeHttpPort: NodeHttpPort
      NodeHttpServerPort: NodeHttpServerPort
      NodeHttpsServerPort: NodeHttpsServerPort
      ServerSocketPort: ServerSocketPort

     Helpers:
      progress: (from, to, func) ->
       (progress, data) ->
        func? progress * (to - from) + from, data

     setup_____: (options) ->
      options.workers ?= []
      switch options.platform
       when 'ui'
        for worker in options.workers
         IO.addPort worker.name, new WorkerPort worker.js
        for socket in options.sockets
         IO.addPort socket.name, new SocketPort socket.url
       when 'node'
        for socket in options.listenSockets
         IO.addPort socket.name, new SocketListenPort socket.port
        for socket in options.sockets
         IO.addPort socket.name, new SocketPort socket.url
       when 'worker'
        IO.addPort 'UI', new WorkerListenPort _self

    if exports?
     module.exports = IO
    else
     _self.IO = IO

    _self = this

    if console?.log?
     LOG = console.log.bind console
    else
     LOG = -> null

    if console?.error?
     ERROR_LOG = console.error.bind console
    else
     ERROR_LOG = -> null

    POLL_TYPE =
     progress: true

##Response class

    class Response
     constructor: (data, port, options) ->
      @id = data.id
      @port = port
      @options = options
      @queue = []
      @fresh = true

     progress: (progress, data, callback) ->
      @queue.push
       method: 'progress'
       data: data
       options: {progress: progress}
       callback: callback
      @_handleQueue()

     success: (data) ->
      @queue.push method: 'success', data: data, options: {}
      @_handleQueue()

     fail: (data) ->
      @queue.push method: 'fail', data: data, options: {}
      @_handleQueue()

     setOptions: (options) ->
      @options = options
      @fresh = true
      @_handleQueue()

     _multipleResponse: ->
      responseList = []
      callbacks = []
      for d in @queue
       responseList.push
        status: d.method
        data: d.data
        options: d.options
       if d.callback?
        callbacks.push d.callback

      done = ->
       for callback in callbacks
        callback()

      if @port.isStreaming
       @port.respondMultiple this, responseList, @options, done
      else if @fresh
       @port.respondMultiple this, responseList, @options, done
       @fresh = false

      @queue = []

     _handleQueue: ->
      return unless @queue.length > 0
      return if not @queue.isStreaming and not @fresh

      if @queue.length > 1
       return @_multipleResponse()

      d = @queue[0]

      if @port.isStreaming
       @port.respond this, d.method, d.data, d.options, @options, d.callback
      else if @fresh
       @port.respond this, d.method, d.data, d.options, @options, d.callback
       @fresh = false

      @queue = []

##Call class

    class Call
     constructor: (@id, @method, @data, @callbacks, @options) -> null

     handle: (data, options) ->
      if not @callbacks[options.status]?
       return if options.status is 'progress'
       #Handled by caller
       throw new Error "No callback registered #{@method} #{options.status}"
      self = this
      setTimeout (-> self.callbacks[options.status] data, options), 0

      if POLL_TYPE[options.status]?
       return false
      else
       return true

##Port base class

    class Port
     constructor: ->
      @handlers = {}
      @callsCache = {}
      @callsCounter = 0
      @id = parseInt Math.random() * 1000
      @responses = {}
      @wrappers =
       send: []
       respond: []
       handleCall: []
       handleResponse: []

     isStreaming: true

     onCallError: (msg, options) ->
      callsCache = @callsCache
      @callsCache = {}
      for id, call of callsCache
       if not call.callbacks.fail?
        ERROR_LOG 'fail callback not registered', call.method, call.data
       else
        call.callbacks.fail error: 'connectionError', msg: msg, options: options, {}

      @errorCallback msg, options

     onHandleError: (msg, data, options) ->
      @errorCallback msg, data
      response = new Response data, this, options
      response.fail msg

     errorCallback: (msg, options) ->
      ERROR_LOG msg, options

     wrap: (wrapper) ->
      for key, f of wrapper
       if @wrappers[key]?
        @wrappers[key].push f
       else
        this[key] = f

###Send RPC call

     send: (method, data, callbacks, options = {}) ->
      if (typeof callbacks) is 'function'
       callbacks =
        success: callbacks

      for f in @wrappers.send
       return unless f.apply this, [method, data, callbacks, options]

      params = @_createCall method, data, callbacks, options
      @_send params, callbacks

###Respond to a RPC call

     respond: (response, status, data, options = {}, portOptions = {}, callback = null) ->
      if not POLL_TYPE[status]?
       delete @responses[response.id]

      for f in @wrappers.respond
       return unless f.apply this, [response, status, data, options, portOptions]

      @_respond (@_createResponse response, status, data, options), portOptions, callback

     respondMultiple: (response, list, portOptions = {}, callback = null) ->
      for d in list
       if not POLL_TYPE[d.status]?
        delete @responses[response.id]
        break

      data = []
      for d in list
       cancel = false
       d.options ?= {}
       for f in @wrappers.respond
        r = f.apply this, [response, d.status, d.data, d.options, portOptions]
        if not r
         cancel = true
         break

        continue if cancel

       data.push @_createResponse response, d.status, d.data, d.options

      return if data.length is 0

      data =
       type: 'list'
       list: data

      @_respond data, portOptions, callback

###Create Call object
This is a private function

     _createCall: (method, data, callbacks, options) ->
      call = new Call "#{@id}-#{@callsCounter}", method, data, callbacks, options
      @callsCounter++
      @callsCache[call.id] = call

      params =
       type: 'call'
       id: call.id
       method: call.method
       data: call.data

      params[k] = v for k, v of options
      return params

###Create Response object

     _createResponse: (response, status, data, options) ->
      params =
       type: 'response'
       id: response.id
       status: status
       data: data

      params[k] = v for k, v of options

      return params

###Add handler

     on: (method, callback) ->
      @handlers[method] = callback

###Handle incoming message

     _handleMessage: (data, options, last = true) ->
      switch data.type
       when 'list'
        for d, i in data.list
         @_handleMessage d, options, (last and i + 1 is data.list.length)
       when 'response'
        @_handleResponse data, options, last
       when 'call'
        @_handleCall data, options, last
       when 'poll'
        @_handlePoll data, options, last

     _handleCall: (data, options) ->
      for f in @wrappers.handleCall
       return unless f.apply this, arguments
      if not @handlers[data.method]?
       @onHandleError "Unknown method: #{data.method}", data, options
       return
      @responses[data.id] = new Response data, this, options
      @handlers[data.method] data.data, data, @responses[data.id]

     _handleResponse: (data, options) ->
      for f in @wrappers.handleResponse
       return unless f.apply this, arguments
      if not @callsCache[data.id]?
       #Cannot reply
       @errorCallback "Response without call: #{data.id}", data
       return
      try
       if @callsCache[data.id].handle data.data, data
        delete @callsCache[data.id]
      catch e
       @errorCallback e.message, data
       delete @callsCache[data.id]

     _handlePoll: (data, options) ->
      @onHandleError "Poll not implemented", data, options

##WorkerPort class
Used for browser and worker

    class WorkerPort extends Port
     constructor: (worker) ->
      super()
      @worker = worker
      @worker.onmessage = @_onMessage.bind this
      #@worker.onerror = @onCallError.bind this

     _send: (data) ->
      @worker.postMessage data

     _respond: (data, options, callback) ->
      @worker.postMessage data
      callback?()

     _onMessage: (e) ->
      data = e.data
      @_handleMessage data

##SocketPort class

    class SocketPort extends Port
     constructor: (socket) ->
      super()
      @socket = socket
      @socket.on 'message', @_onMessage.bind this

     _send: (data) ->  @socket.emit 'message', data
     _respond: (data, options, callback) ->
      @worker.emit 'message', data
      callback?()

     _onMessage: (e) ->
      data = e.data
      @_handleMessage data

##ServerSocketPort class

    class ServerSocketPort extends Port
     constructor: (server) ->
      super()
      @server = server
      @server.on 'connection', @_onConnection.bind this

     _onConnection: (socket) ->
      new SocketPort handlers: @handlers, socket

##AJAX class

    class AjaxHttpPort extends Port
     constructor: (options) ->
      super()
      @protocol = options.protocol
      @host = options.host
      @port = options.port
      @path = options.path ? '/'
      @url = @path
      if @protocol?
       if @host? and not @port?
        @url = "#{@protocol}://#{@host}#{@path}"
       else if @host? and @port?
        @url = "#{@protocol}://#{@host}:#{@port}#{@path}"
      else
       if @host? and not @port?
        @url = "//#{@host}#{@path}"
       else if @host? and @port?
        @url = "//#{@host}:#{@port}#{@path}"

     isStreaming: false

     _onRequest: (xhr) ->
      return unless xhr.readyState is 4
      status = xhr.status
      if ((not status and xhr.responseText? and xhr.responseText != '') or
          (status >= 200 and status < 300) or
          (status is 304))
       try
        jsonData = JSON.parse xhr.responseText
       catch e
        @onCallError 'ParseError', e
        return

       @_handleMessage jsonData, xhr: xhr
      else
       @onCallError 'Cannot connect to server'

     _respond: (data, options, callback) ->
      @errorCallback 'AJAX cannot respond', data
      callback?()

     _send: (data) ->
      data = JSON.stringify data
      xhr = new XMLHttpRequest
      xhr.open 'POST', @url
      xhr.onreadystatechange = =>
       @_onRequest xhr
      xhr.setRequestHeader 'Accept', 'application/json'
      #xhr.setRequestHeader 'Content-Type', 'application/json'
      xhr.send data

     _handleResponse: (data, options, last = true) ->
      for f in @wrappers.handleResponse
       return unless f.apply this, arguments
      if not @callsCache[data.id]?
       @errorCallback "Response without call: #{data.id}", data
       return
      call = @callsCache[data.id]
      try
       if call.handle data.data, data
        delete @callsCache[data.id]
       else if last
        params =
         type: 'poll'
         id: call.id
        params[k] = v for k, v of call.options
        @_send params
      catch e
       @errorCallback e.message, data
       delete @callsCache[data.id]

##NodeHttpPort class

    class NodeHttpPort extends Port
     constructor: (options, http) ->
      super()
      @host = options.host ? 'localhost'
      @port = options.port ? 80
      @path = options.path ? '/'
      @http = http
      @_createHttpOptions()

     isStreaming: false

     _createHttpOptions: ->
      @httpOptions =
       hostname: @host
       port: @port
       path: @path
       method: 'POST'
       agent: false
       headers:
        accept: 'application/json'
       'content-type': 'application/json'

     _onRequest: (res) ->
      data = ''
      #LOG 'STATUS: ' + res.statusCode
      #LOG 'HEADERS: ' + JSON.stringify res.headers
      res.setEncoding 'utf8'
      res.on 'data', (chunk) ->
       data += chunk
      #LOG 'result', res
      res.on 'end', =>
       try
        jsonData = JSON.parse data
       catch e
        @onCallError 'ParseError', e
        return

       @_handleMessage jsonData, response: res

     _respond: (data, options, callback) ->
      data = JSON.stringify data
      res = options.response
      res.setHeader 'content-length', Buffer.byteLength data, 'utf8'
      if callback?
       res.once 'finish', ->
        callback()
       res.once 'close', ->
        callback()

      res.write data
      res.end()

     _send: (data, callbacks) ->
      data = JSON.stringify data
      options = @httpOptions
      options.headers['content-length'] = Buffer.byteLength data, 'utf8'

      req = @http.request options, @_onRequest.bind this
      delete options.headers['content-length']
      req.on 'error', (e) ->
       callbacks.fail? e

      req.write data
      req.end()

     _handleResponse: (data, options, last = true) ->
      for f in @wrappers.handleResponse
       return unless f.apply this, arguments
      if not @callsCache[data.id]?
       @errorCallback "Response without call: #{data.id}", data
       return
      call = @callsCache[data.id]
      if not call.handle data.data, data
       return if not last
       params =
        type: 'poll'
        id: call.id
       params[k] = v for k, v of call.options
       @_send params, call.callbacks

##NodeHttpServerPort class

    class NodeHttpServerPort extends Port
     constructor: (options, http, zlib = null) ->
      super()
      @port = options.port
      @http = http
      @zlib = zlib
      @allowOrigin = options.allowOrigin

     isStreaming: false

     _onRequest: (req, res) ->
      data = ''
      res.setHeader 'content-type', 'application/json'

      req.on 'data', (chunk) ->
       data += chunk
      req.on 'end', =>
       try
        jsonData = JSON.parse data
       catch e
        @errorCallback 'ParseError', e
        return

       @_handleMessage jsonData, response: res, request: req

     _respond: (data, options, callback) ->
      if @allowOrigin?
       options.response.setHeader 'Access-Control-Allow-Origin', @allowOrigin

      accept = options.request.headers['accept-encoding']
      accept ?= ''
      if not @zlib?
       accept = ''

      data = JSON.stringify data
      buffer = new Buffer data, 'utf8'
      if accept.match /\bdeflate\b/
       options.response.setHeader 'content-encoding', 'deflate'
       @zlib.deflate buffer, (err, result) =>
        if err?
         return @errorCallback 'DeflateError', e
        @_sendBuffer result, options.response, callback
      else if accept.match /\bgzip\b/
       options.response.setHeader 'content-encoding', 'gzip'
       @zlib.gzip buffer, (err, result) =>
        if err?
         return @errorCallback 'GZipeError', e
        @_sendBuffer result, options.response, callback
      else
       @_sendBuffer buffer, options.response, callback

     _sendBuffer: (buf, res, callback) ->
       res.setHeader 'content-length', buf.length
       if callback?
        res.once 'finish', ->
         callback()
        res.once 'close', ->
         callback()

       res.write buf
       res.end()

     listen: ->
      @server = @http.createServer @_onRequest.bind this
      @server.listen @port

     _handlePoll: (data, options) ->
      for f in @wrappers.handleCall
       return unless f.apply this, arguments
      if not @responses[data.id]?
       @onHandleError "Poll without response: #{data.id}", data, options
       return
      @responses[data.id].setOptions options

##NodeHttpsServerPort class

    class NodeHttpsServerPort extends NodeHttpServerPort
     constructor: (options, http) ->
      super options, http
      @_key = options.key
      @_cert = options.cert

     listen: ->
      options =
       key: @_key
       cert: @_cert

      @server = @http.createServer options, @_onRequest.bind this
      @server.listen @port

#IO Module

    IO =
     addPort: (name, port) ->
      IO[name] = port

     ports:
      WorkerPort: WorkerPort
      SocketPort: SocketPort
      AjaxHttpPort: AjaxHttpPort
      NodeHttpPort: NodeHttpPort
      NodeHttpServerPort: NodeHttpServerPort
      NodeHttpsServerPort: NodeHttpsServerPort
      ServerSocketPort: ServerSocketPort

     Helpers:
      progress: (from, to, func) ->
       (progress, data) ->
        func? progress * (to - from) + from, data

     setup_____: (options) ->
      options.workers ?= []
      switch options.platform
       when 'ui'
        for worker in options.workers
         IO.addPort worker.name, new WorkerPort worker.js
        for socket in options.sockets
         IO.addPort socket.name, new SocketPort socket.url
       when 'node'
        for socket in options.listenSockets
         IO.addPort socket.name, new SocketListenPort socket.port
        for socket in options.sockets
         IO.addPort socket.name, new SocketPort socket.url
       when 'worker'
        IO.addPort 'UI', new WorkerListenPort _self

    if exports?
     module.exports = IO
    else
     _self.IO = IO


undebug

undebug

# Application Routes

The purpose of a route is to connect URL resources with underlying code.  I
also do explicit data normalization (input -> dictionary to pass to method/dict
from method -> view) at this stage.

To configure routes, the only object we need access to is `app`.  This module
can be called with `require("./lib/routes")(app)` as long as `app` is an
already initialized ExpressJS application.

    module.exports = (app) ->

## GET /

Render the main index page.

      app.get '/', (req, res) ->
        res.render 'index', {
          title: 'Welcome'
        }

## GET /

Render the main index page.

      app.get '/game', (req, res) ->
        title = 'Gift Exchange'
        request = require '../../node_modules/request'
        request {
          url: 'https://docs.google.com/spreadsheet/pub?key=0ArrqhUPPrcPCdG5iV1hkRHdsVjJnTm84NW1RVnQ4WlE&single=true&gid=0&output=csv',
        }, (err, rres, body) ->
          if err
            res.render 'page', {
              title: title,
              body: 'Error #1: '+err
            }
          else
            presents = []
            gravatar = require '../../node_modules/gravatar'
            csv = require '../../node_modules/csv'
            csv().from.string(body).on('record', (row, index) ->
              return if index == 0
              presents.push {
                id: row[0],
                img: if row[4] then row[3] else row[2],
                detail: if row[4] then "#{row[1]} - #{row[5]}",
                ownerurl:
                  if row[6]
                    gravatar.url("#{row[6]}@zerolag.com",{s: '256', d: 'monsterid'})
                  else
                    "http://placehold.it/256x256&text=available"
                ,
                owner: if row[6] then "#{row[6]}@zerolag.com" else "nobody@zerolag.com"
              })
            res.render 'game', {
              title: title,
              presents: presents,
              debug: if 0 then JSON.stringify presents
            }

## GET /page/:name

Render static pages at /view/page/name.html

      app.get '/page/:name', (req, res) ->
        res.render 'page/'+req.params.name

## Copying

This software is released under the ISC License.

Copyright (c) 2013, Cameron King <cking@ecc12.com>

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

<!-- vim: ts=2 sts=2 sw=2 expandtab
     CoffeeScript-friendly tabstops in vim. -->

# Application Routes

The purpose of a route is to connect URL resources with underlying code.  I
also do explicit data normalization (input -> dictionary to pass to method/dict
from method -> view) at this stage.

To configure routes, the only object we need access to is `app`.  This module
can be called with `require("./lib/routes")(app)` as long as `app` is an
already initialized ExpressJS application.

    module.exports = (app) ->

## GET /

Render the main index page.

      app.get '/', (req, res) ->
        res.render 'index', {
          title: 'Welcome'
        }

## GET /

Render the main index page.

      app.get '/game', (req, res) ->
        title = 'Gift Exchange'
        request = require '../../node_modules/request'
        request {
          url: 'https://docs.google.com/spreadsheet/pub?key=0ArrqhUPPrcPCdG5iV1hkRHdsVjJnTm84NW1RVnQ4WlE&single=true&gid=0&output=csv',
        }, (err, rres, body) ->
          if err
            res.render 'page', {
              title: title,
              body: 'Error #1: '+err
            }
          else
            presents = []
            gravatar = require '../../node_modules/gravatar'
            csv = require '../../node_modules/csv'
            csv().from.string(body).on('record', (row, index) ->
              return if index == 0
              presents.push {
                id: row[0],
                img: if row[4] then row[3] else row[2],
                detail: if row[4] then "#{row[1]} - #{row[5]}",
                ownerurl:
                  if row[6]
                    gravatar.url("#{row[6]}@zerolag.com",{s: '256', d: 'monsterid'})
                  else
                    "http://placehold.it/256x256&text=available"
                ,
                owner: if row[6] then "#{row[6]}@zerolag.com" else "nobody@zerolag.com"
              })
            res.render 'game', {
              title: title,
              presents: presents,
              debug: if 1 then JSON.stringify presents
            }

## GET /page/:name

Render static pages at /view/page/name.html

      app.get '/page/:name', (req, res) ->
        res.render 'page/'+req.params.name

## Copying

This software is released under the ISC License.

Copyright (c) 2013, Cameron King <cking@ecc12.com>

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

<!-- vim: ts=2 sts=2 sw=2 expandtab
     CoffeeScript-friendly tabstops in vim. -->


modify README

modify README

# loopback-with-domain

run loopback server with "domain"

domain is in this context business logic, the same as Domain-Driven Design (DDD).

connection with [base-domain](https://github.com/CureApp/base-domain)

# install

```
npm install loopback-with-domain
```

# run

    lbWithDomain = require 'loopback-with-domain'

    domain = require('base-domain').createInstance(dirname: 'domain')

    config =
        admin:
            accessToken: 'Your Secret Value Here'
        server:
            port: 4000

    lbWithDomain.runWithDomain(domain, config).then ->
        # loopback started

# configs

## server

 config name | meaning       | default
-------------|---------------|----------------
 restApiRoot | REST api root | /api
 port        | port number   | 3000

## admin

 config name | meaning               | default
-------------|-----------------------|----------------------------
 accessToken | accessToken for admin | (you must set access token)

# loopback-with-domain

run loopback server with "domain"

domain is in this context business logic, the same as Domain-Driven Design (DDD).

connection with [base-domain](https://github.com/CureApp/base-domain)

# install

```
npm install loopback-with-domain
```

# run

    lbWithDomain = require 'loopback-with-domain'

    domain = require('base-domain').createInstance(dirname: 'domain')

    config =
        server:
            port: 4000

    lbWithDomain.runWithDomain(domain, config).then ->
        # loopback started

# configs

## server

 config name | meaning       | default
-------------|---------------|----------------
 restApiRoot | REST api root | /api
 port        | port number   | 3000

## admin

 config name | meaning               | default
-------------|-----------------------|----------------------------
 accessToken | accessToken for admin | (you must set access token)


comments

comments

List of SVG elements

    Tags =
     svg: 'a altGlyph altGlyphDef altGlyphItem animate animateColor animateMotion
      animateTransform circle clipPath color-profile cursor defs desc ellipse
      feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix
      feDiffuseLighting feDisplacementMap feDistantLight feFlood feFuncA feFuncB
      feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology
      feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence
      filter font font-face font-face-format font-face-name font-face-src
      font-face-uri foreignObject g glyph glyphRef hkern image line linearGradient
      marker mask metadata missing-glyph mpath path pattern polygon polyline
      radialGradient rect script set stop style svg symbol text textPath
      title tref tspan use view vkern'

List of HTML elements

     html: 'a abbr address article aside audio b bdi bdo blockquote body button
      canvas caption cite code colgroup datalist dd del details dfn div dl dt em
      fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head header hgroup
      html i iframe ins kbd label legend li main map mark menu meter nav noscript object
      ol optgroup option output p pre progress q rp rt ruby s samp script section
      select small span strong style sub summary sup table tbody td textarea tfoot
      th thead time title tr u ul video'

     htmlVoid: 'area base br col command embed hr img input keygen link meta param
      source track wbr'

Wrapper for browser API

    Api =
     document: @document

#Weya DOM

    weyaDomCreate = ->

Weya object to be passed as `this`

     weya =
      _elem: null

Manipulating dom objects

     setStyles = (elem, styles) ->
      for k, v of styles
       if v?
        elem.style.setProperty k, v
       else
        elem.style.removeProperty k

     setEvents = (elem, events) ->
      for k, v of events
       elem.addEventListener k, v, false

     setAttributes = (elem, attrs) ->
      for k, v of attrs
       switch k
        when 'style' then setStyles elem, v
        when 'on' then setEvents elem, v
        else
         if v?
          elem.setAttribute k, v
         else
          elem.removeAttribute k

Parse id and class string

     parseIdClass = (str) ->
      res =
       id: null
       class: null

      for c, i in str.split "."
       if c.indexOf("#") is 0
        res.id = c.substr 1
       else if c isnt ""
        if not res.class?
         res.class = c
        else
         res.class += " #{c}"

      return res

Append a child element

     append = (ns, name, args) ->
      idClass = null
      contentText = null
      attrs = null
      contentFunction = null

      for arg, i in args
       switch typeof arg
        when 'function' then contentFunction = arg
        when 'object' then attrs = arg
        when 'string'
         if args.length is 1
          contentText = arg
         else
          c = arg.charAt 0

          if i is 0 and (c is '#' or c is '.')
           idClass = arg
          else
           contentText = arg

Keep a reference to parent element

      pElem = @_elem

Keep a reference of `elem` to return at the end of the function

      if ns?
       elem = @_elem = Api.document.createElementNS ns, name
      else
       elem = @_elem = Api.document.createElement name

      if idClass?
       idClass = parseIdClass idClass
       if idClass.id?
        elem.id = idClass.id
       if idClass.class?
        elem.className = idClass.class

      if attrs?
       setAttributes elem, attrs

      if pElem?
       pElem.appendChild elem

      if contentFunction?
       contentFunction.call @
      else if contentText?
       elem.textContent = contentText

      @_elem = pElem
      return elem

Wrap `append`

     wrapAppend = (ns, name) ->
      ->
       append.call @, ns, name, arguments

Initialize

     for name in Tags.svg.split ' '
      weya[name] = wrapAppend "http://www.w3.org/2000/svg", name

     for name in Tags.html.split ' '
      weya[name] = wrapAppend null, name

     for name in Tags.htmlVoid.split ' '
      weya[name] = wrapAppend null, name

     return weya

#Weya Markup

    weyaMarkupCreate = ->

Weya object to be passed as `this`

     weya =
      _buf: null
      _indent: 0

Render components

     setStyles = (buf, styles) ->
      buf.push " style=\""
      for k, v of styles
       buf.push "#{k}:#{v};"
      buf.push "\""

     setEvents = (buf, events) ->
      for k, v of events
       buf.push " on#{k}=\"#{v}\""

     setAttributes = (buf, attrs) ->
      for k, v of attrs
       switch k
        when 'style' then setStyles buf, v
        when 'on' then setEvents buf, v
        else
         buf.push " #{k}=\"#{v}\""

     setIndent = (buf, indent) ->
      for i in [0...indent]
       buf.push " "

Parse id and class string

     parseIdClass = (str) ->
      res =
       id: null
       class: null

      for c, i in str.split "."
       if c.indexOf("#") is 0
        res.id = c.substr 1
       else if c isnt ""
        if not res.class?
         res.class = c
        else
         res.class += " #{c}"

      return res

Append a child element

     append = (ns, name, args) ->
      idClass = null
      contentText = null
      attrs = null
      contentFunction = null

      for arg, i in args
       switch typeof arg
        when 'function' then contentFunction = arg
        when 'object' then attrs = arg
        when 'string'
         if args.length is 1
          contentText = arg
         else
          c = arg.charAt 0

          if i is 0 and (c is '#' or c is '.')
           idClass = arg
          else
           contentText = arg

      buf = @_buf

      setIndent buf, @_indent

      buf.push "<#{name}"

      if idClass?
       idClass = parseIdClass idClass
       if idClass.id?
        buf.push " id=\"#{idClass.id}\""
       if idClass.class?
        buf.push " class=\"#{idClass.class}\""

      if attrs?
       setAttributes buf, attrs

Can close void elements (element that self close) with a `/>`

      buf.push ">\n"
      @_indent++

      if contentFunction?
       contentFunction.call @
      else if contentText?
       setIndent buf, @_indent
       buf.push contentText
       buf.push "\n"

      @_indent--
      setIndent buf, @_indent
      buf.push "</#{name}>\n"

Wrap `append`

     wrapAppend = (ns, name) ->
      ->
       append.call @, ns, name, arguments

Initialize

     for name in Tags.svg.split ' '
      weya[name] = wrapAppend "http://www.w3.org/2000/svg", name

     for name in Tags.html.split ' '
      weya[name] = wrapAppend null, name

     for name in Tags.htmlVoid.split ' '
      weya[name] = wrapAppend null, name

     return weya

#Weya API

    weyaDom = weyaDomCreate()
    weyaMarkup = weyaMarkupCreate()

Create and append to `options.elem`. If `options.context` is provied it can be accessed via `@$`.
If `options.elem` is `null`, the element is created but not appended.

    @Weya = Weya = (options, func) ->
     weya = weyaDom
     pContext = weya.$
     weya.$ = options.context
     pElem = weya._elem
     weya._elem = options.elem
     r = func?.call weya
     weya._elem = pElem
     weya.$ = pContext
     return r

    Weya.markup = (options, func) ->
     weya = weyaMarkup
     pContext = weya.$
     weya.$ = options.context
     pBuf = weya._buf
     weya._buf = []
     r = func?.call weya
     buf = weya._buf
     weya._buf = pBuf
     weya.$ = pContext
     return buf.join ''

List of SVG elements

    Tags =
     svg: 'a altGlyph altGlyphDef altGlyphItem animate animateColor animateMotion
      animateTransform circle clipPath color-profile cursor defs desc ellipse
      feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix
      feDiffuseLighting feDisplacementMap feDistantLight feFlood feFuncA feFuncB
      feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology
      feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence
      filter font font-face font-face-format font-face-name font-face-src
      font-face-uri foreignObject g glyph glyphRef hkern image line linearGradient
      marker mask metadata missing-glyph mpath path pattern polygon polyline
      radialGradient rect script set stop style svg symbol text textPath
      title tref tspan use view vkern'

List of HTML elements

     html: 'a abbr address article aside audio b bdi bdo blockquote body button
      canvas caption cite code colgroup datalist dd del details dfn div dl dt em
      fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head header hgroup
      html i iframe ins kbd label legend li main map mark menu meter nav noscript object
      ol optgroup option output p pre progress q rp rt ruby s samp script section
      select small span strong style sub summary sup table tbody td textarea tfoot
      th thead time title tr u ul video'

     htmlVoid: 'area base br col command embed hr img input keygen link meta param
      source track wbr'

#Weya DOM

    weyaDomCreate = ->

Weya object to be passed as `this`

     weya =
      _elem: null

Wrapper for browser API

     Api =
      document: @document

Manipulating dom objects

     setStyles = (elem, styles) ->
      for k, v of styles
       if v?
        elem.style.setProperty k, v
       else
        elem.style.removeProperty k

     setEvents = (elem, events) ->
      for k, v of events
       elem.addEventListener k, v, false

     setAttributes = (elem, attrs) ->
      for k, v of attrs
       switch k
        when 'style' then setStyles elem, v
        when 'on' then setEvents elem, v
        else
         if v?
          elem.setAttribute k, v
         else
          elem.removeAttribute k

Parse id and class string

     parseIdClass = (str) ->
      res =
       id: null
       class: null

      for c, i in str.split "."
       if c.indexOf("#") is 0
        res.id = c.substr 1
       else if c isnt ""
        if not res.class?
         res.class = c
        else
         res.class += " #{c}"

      return res

Append a child element

     append = (ns, name, args) ->
      idClass = null
      contentText = null
      attrs = null
      contentFunction = null

      for arg, i in args
       switch typeof arg
        when 'function' then contentFunction = arg
        when 'object' then attrs = arg
        when 'string'
         if args.length is 1
          contentText = arg
         else
          c = arg.charAt 0

          if i is 0 and (c is '#' or c is '.')
           idClass = arg
          else
           contentText = arg

Keep a reference to parent element

      pElem = @_elem

Keep a reference of `elem` to return at the end of the function

      if ns?
       elem = @_elem = Api.document.createElementNS ns, name
      else
       elem = @_elem = Api.document.createElement name

      if idClass?
       idClass = parseIdClass idClass
       if idClass.id?
        elem.id = idClass.id
       if idClass.class?
        elem.className = idClass.class

      if attrs?
       setAttributes elem, attrs

      if pElem?
       pElem.appendChild elem

      if contentFunction?
       contentFunction.call @
      else if contentText?
       elem.textContent = contentText

      @_elem = pElem
      return elem

Wrap `append`

     wrapAppend = (ns, name) ->
      ->
       append.call @, ns, name, arguments

Initialize

     for name in Tags.svg.split ' '
      weya[name] = wrapAppend "http://www.w3.org/2000/svg", name

     for name in Tags.html.split ' '
      weya[name] = wrapAppend null, name

     for name in Tags.htmlVoid.split ' '
      weya[name] = wrapAppend null, name

     return weya

#Weya Markup

    weyaMarkupCreate = ->

Weya object to be passed as `this`

     weya =
      _buf: null
      _indent: 0

Render components

     setStyles = (buf, styles) ->
      buf.push " style=\""
      for k, v of styles
       buf.push "#{k}:#{v};"
      buf.push "\""

     setEvents = (buf, events) ->
      for k, v of events
       buf.push " on#{k}=\"#{v}\""

     setAttributes = (buf, attrs) ->
      for k, v of attrs
       switch k
        when 'style' then setStyles buf, v
        when 'on' then setEvents buf, v
        else
         buf.push " #{k}=\"#{v}\""

     setIndent = (buf, indent) ->
      for i in [0...indent]
       buf.push " "

Parse id and class string

     parseIdClass = (str) ->
      res =
       id: null
       class: null

      for c, i in str.split "."
       if c.indexOf("#") is 0
        res.id = c.substr 1
       else if c isnt ""
        if not res.class?
         res.class = c
        else
         res.class += " #{c}"

      return res

Append a child element

     append = (ns, name, args) ->
      idClass = null
      contentText = null
      attrs = null
      contentFunction = null

      for arg, i in args
       switch typeof arg
        when 'function' then contentFunction = arg
        when 'object' then attrs = arg
        when 'string'
         if args.length is 1
          contentText = arg
         else
          c = arg.charAt 0

          if i is 0 and (c is '#' or c is '.')
           idClass = arg
          else
           contentText = arg

      buf = @_buf

      setIndent buf, @_indent

      buf.push "<#{name}"

      if idClass?
       idClass = parseIdClass idClass
       if idClass.id?
        buf.push " id=\"#{idClass.id}\""
       if idClass.class?
        buf.push " class=\"#{idClass.class}\""

      if attrs?
       setAttributes buf, attrs

      buf.push ">\n"
      @_indent++

      if contentFunction?
       contentFunction.call @
      else if contentText?
       setIndent buf, @_indent
       buf.push contentText
       buf.push "\n"

      @_indent--
      setIndent buf, @_indent
      buf.push "</#{name}>\n"

Wrap `append`

     wrapAppend = (ns, name) ->
      ->
       append.call @, ns, name, arguments

Initialize

     for name in Tags.svg.split ' '
      weya[name] = wrapAppend "http://www.w3.org/2000/svg", name

     for name in Tags.html.split ' '
      weya[name] = wrapAppend null, name

     for name in Tags.htmlVoid.split ' '
      weya[name] = wrapAppend null, name

     return weya

#Weya

    weyaDom = weyaDomCreate()
    weyaMarkup = weyaMarkupCreate()

Create and append to `options.elem`. If `options.context` is provied it can be accessed via `@$`.

If `options.elem` is `null`, the element is created but not appended.

    @Weya = Weya = (options, func) ->
     weya = weyaDom
     pContext = weya.$
     weya.$ = options.context
     pElem = weya._elem
     weya._elem = options.elem
     r = func?.call weya
     weya._elem = pElem
     weya.$ = pContext
     return r

    Weya.markup = (options, func) ->
     weya = weyaMarkup
     pContext = weya.$
     weya.$ = options.context
     pBuf = weya._buf
     weya._buf = []
     r = func?.call weya
     buf = weya._buf
     weya._buf = pBuf
     weya.$ = pContext
     return buf.join ''