additional fixes to revert state

additional fixes to revert state

# Property - controller of Object properties

The `Property` class is the *secretive shadowy* element that governs
`Object` behavior and are bound to the `Object` via
`Object.defineProperty`. It acts like a shadow `Proxy/Reflector` to
the `Object` instance and provides tight control via the
`Getter/Setter` interfaces.

Below are list of properties available to every instance of `Property`:

property | type | mapping | description
--- | --- | --- | ---
name   | string | direct | name of the property
schema | object | direct | a schema instance (usually [Yang](./src/yang.listcoffee))
state  | object | direct | *private* object holding internal state
configurable | boolean | getter(state) | defines whether this property can be redefined
enumerable   | boolean | getter(state) | defines whether this property is enumerable
content | any | computed | getter/setter for `state.value`
context | object | computed | dynamically generated using [context](./src/context.coffee)
root  | [Property](./src/property.litcoffee) | computed | dynamically returns the root Property instance
path  | [XPath](./src/xpath.coffee) | computed | dynamically generate XPath for this Property from root

## Class Property

    debug    = require('debug')('yang:property')
    delegate = require 'delegates'
    context  = require './context'
    Yang     = require './yang'
    XPath    = require './xpath'

    class Property
      @property: (prop, desc) ->
        Object.defineProperty @prototype, prop, desc

      constructor: (spec={}) ->
        # NOTE: ES6/CS2 does not support below
        # unless this instanceof Property then return new Property arguments...

        # 1. parse if spec is YANG definition (string)
        spec = Yang.parse spec if typeof spec is 'string'

        # 2. assign if spec is an instance of Yang schema
        schema = spec if spec instanceof Yang

        # 3. destructure spec as an object if not schema as instance
        { name, schema } = spec unless schema?

        # 4. parse if schema is YANG definition (string)
        schema = Yang.parse schema if typeof schema is 'string'
        schema ?= kind: 'anydata'

        # 5. initialize property instance
        @name = name ? schema.datakey
        @schema = schema
        @state =
          parent:    null
          strict:    false
          private:   false
          mutable:   `schema.config != false`
          attached:  false
          changed:   false
          prior:     undefined
          value:     undefined

        # 6. soft freeze this instance
        Object.preventExtensions this

      delegate @prototype, 'state'
        .access 'parent'
        .access 'strict'
        .getter 'private'
        .getter 'mutable'
        .getter 'attached'
        .getter 'changed'
        .getter 'prior'
        .getter 'value'

      delegate @prototype, 'schema'
        .getter 'tag'
        .getter 'kind'
        .getter 'type'
        .getter 'default'
        .getter 'external'
        .getter 'binding'
        .method 'locate'
        .method 'lookup'

### Computed Properties

      @property 'value',
        get: -> @state.value

      @property 'data',
        set: (value) -> @set value, { force: true, suppress: true }
        get: -> switch
          when @binding?.get? then @binding.get @context
          else @value

      @property 'enumerable',
        get: -> not @private and (@value? or @binding?)

      @property 'active',
        get: -> @enumerable and @value?

      @property 'change',
        get: -> switch
          when @changed and not @active then null
          when @changed then @data

      @property 'context',
        get: ->
          ctx = Object.create(context)
          ctx.opts = {}
          ctx.node = this
          Object.preventExtensions ctx
          return ctx

      @property 'root',
        get: ->
          return this if @kind is 'module'
          root = switch
            when @parent is this then this
            when @parent instanceof Property then @parent.root
            else this
          @state.path = undefined unless @state.root is root
          return @state.root = root

      @property 'path',
        get: ->
          if this is @root
            entity = switch
              when @kind is 'module' then '/'
              else '.'
            return XPath.parse entity, @schema
          @state.path ?= @parent.path.clone().append @name
          return @state.path

      @property 'uri',
        get: -> @schema.datapath ? @schema.uri

## Instance-level methods

      clone: (state = {}) ->
        throw @error 'must clone with state typeof object' unless typeof state is 'object'
        copy = new @constructor this
        copy.state = Object.assign(Object.create(@state), state, origin: this)
        return copy

      debug: -> debug @uri, arguments...

      equals: (a, b) -> switch @kind
        when 'leaf-list'
          return false unless a and b
          a = Array.from(new Set([].concat(a)))
          b = Array.from(new Set([].concat(b)))
          return false unless a.length is b.length
          a.every (x) => b.some (y) => x is y
        else a is b

### get (key)

This is the main `Getter` for the target object's property value. When
called with optional `key` it will perform an internal
[find](#find-xpath) operation to traverse/locate that value being
requested instead of returning its own `@data`.

It also provides special handling based on different types of
`@data` currently held.

      get: (key) -> switch
        when key?
          try match = @find key
          return unless match? and match.length
          switch
            when match.length is 1 then match[0].data
            when match.length > 1  then match.map (x) -> x.data
            else undefined
        else @data

### set (value)

This is the main `Setter` for the target object's property value.  It
utilizes internal `@schema` attribute if available to enforce schema
validations.

      set: (value, opts={}) ->
        opts.origin ?= this

        # @debug "[set] enter..."
        unless @mutable or not value? or opts.force
          throw @error "cannot set data on read-only (config false) element"

        if not opts.force and @binding?.set?
          try value = @binding.set @context.with(opts), value
          catch e
            throw @error "failed executing set() binding: #{e.message}", e

        return this if value? and @equals value, @value # return if same value

        bypass = opts.bypass and @kind in ["leaf", "leaf-list"]
        @debug "[set] applying schema..."
        value = switch
          when @schema.apply? and not bypass
            subopts = Object.assign {}, opts, inner: true, suppress: true
            @schema.apply value, this, subopts
          else value
        @debug "[set] done applying schema...", value
        return this if value instanceof Error
        return this if value? and @equals value, @value # return if same value
        @update value, opts

### merge (value)

Performs a granular merge of `value` into existing `@value` if
available, otherwise performs [set](#set-value) operation.

      merge: (value, opts={}) ->
        opts.origin ?= this
        return @delete opts if value is null
        return @set value, opts

### delete

      delete: (opts={}) ->
        opts.origin ?= this
        return this if @state.value is null
        if not opts.force and @binding?.delete?
          try @binding.delete @context.with(opts), null
          catch e
            throw @error "failed executing delete() binding: #{e.message}", e
        @update null, opts

### update

Updates the value to the data model. Called *once* for each node that
is part of the change branch.

      update: (value, opts={}) ->
        opts.origin ?= this
        @state.prior ?= @state.value
        @state.changed = @state.changed or (@state.value isnt value)
        @state.value = value
        @parent?.update this, opts # unless opts.suppress
        return this

### commit async transaction

Commits the changes to the data model. Called *once* for each node that
is part of the change branch.

      commit: (opts={}) ->
        opts.origin ?= this
        return true unless @changed
        try
          unless opts.sync
            # 1. perform save binding
            @debug "[commit] execute binding..."
            await @binding?.commit? @context.with(opts)
            # 2. if has parent, then wait for parent commited before updating changed state
            promise = @parent?.commit? opts
              .then (ok) =>
                if ok
                  @state.prior = undefined
                  @state.changed = false
          unless promise?
            @state.prior = undefined
            @state.changed = false
        catch err
          @debug "[commit] revert due to #{err.message}"
          await @revert opts
          throw @error err
        return true

      revert: (opts={}) ->
        return unless @changed

        @debug "[revert] changing back to:", @state.prior
        unless @state.prior?
          @delete opts
        else
          @state.value = @state.prior

        @debug "[revert] execute binding..."
        try await @binding?.commit? @context.with(opts) unless opts.sync
        catch err
          @debug "[revert] failed due to #{err.message}"
          throw @error err

        @state.prior = undefined
        @state.changed = false

### attach (obj, parent, opts)

This call is the primary mechanism via which the `Property` instance
attaches itself to the provided target `obj`. It defines itself in the
target `obj` via `Object.defineProperty`.

      attach: (obj, parent, opts) ->
        return obj unless obj instanceof Object
        opts ?= { replace: false, suppress: false, force: false }
        @parent = parent

        # if joining for the first time, apply existing data unless explicit replace
        unless @attached
          # @debug "[attach] applying existing data for #{@name} (external: #{@external}) to:"
          # @debug obj
          name = switch
            when @parent?.external and @tag of obj then @tag
            when @external then @name
            when @name of obj then @name
            else "#{@root.name}:#{@name}" # should we ensure root is kind = module?

          @set obj[name], Object.assign {}, opts, inner: true, suppress: true

        unless opts.preserve
          try Object.defineProperty obj, @name,
              configurable: true
              enumerable: @enumerable
              get: (args...) => @get args...
              set: (args...) => @set args...

        @state.attached = true
        @debug "[attach] attached into #{obj.constructor.name} container"
        return obj

### find (pattern)

This helper routine can be used to allow traversal to other elements
in the data tree from the relative location of the current `Property`
instance. It returns matching `Property` instances based on the
provided `pattern` in the form of XPATH or YPATH.

It is internally used via [get](#get) and generally used inside
controller logic bound inside the [Yang expression](./yang.litcoffee)
as well as event handler listening on [Model](./model.litcoffee)
events.

It *always* returns an array (empty to denote no match) unless it
encounters an error, in which case it will throw an Error.

      find: (pattern='.', opts={}) ->
        @debug "[find] #{pattern}"
        pattern = XPath.parse pattern, @schema
        switch
          when pattern.tag is '/'  and this isnt @root then @root.find(pattern)
          when pattern.tag is '..' then @parent?.find pattern.xpath
          else pattern.apply(this) ? []

### in (pattern)

A convenience routine to locate one or more matching Property
instances based on `pattern` (XPATH or YPATH) from this Model.

      in: (pattern) ->
        try props = @find pattern
        return unless props? and props.length
        return switch
          when props.length > 1 then props
          else props[0]

### defer (value)

Optionally defer setting the value to the property until root has been updated.

      defer: (value) ->
        @debug "deferring '#{@kind}(#{@name})' until update at #{@root.name}"
        @root.once 'update', =>
          @debug "applying deferred data (#{typeof value})"
          @data = value
        return value

### error (msg)

Provides more contextual error message pertaining to the Property instance.

      error: (err, ctx) ->
        err = new Error err unless err instanceof Error
        err.uri ?= @uri
        err.src ?= this
        err.ctx ?= ctx
        return err

### toJSON

This call creates a new copy of the current `Property.content`
completely detached/unbound to the underlying data schema. It's main
utility is to represent the current data state for subsequent
serialization/transmission. It accepts optional argument `tag` which
when called with `true` will tag the produced object with the current
property's `@name`.

      toJSON: (key, state = true) ->
        value = switch
          when @kind is 'anydata' then undefined
          when state isnt true and not @mutable then undefined
          else @data
        value = "#{@name}": value if key is true
        return value

### inspect

      inspect: ->
        return {
          name:    @name
          kind:    @kind
          path:    @path.toString()
          active:  @active
          private: @private
          mutable: @mutable
          changed: @changed
          schema: switch
            when @schema.uri?
              uri:      @schema.uri
              summary:  @schema.description?.tag
              datakey:  @schema.datakey
              datapath: @schema.datapath
              external: @schema.external
              children: @schema.children.map (x) -> x.uri
            else false
          value: @toJSON()
        }

## Export Property Class

    module.exports = Property

# Property - controller of Object properties

The `Property` class is the *secretive shadowy* element that governs
`Object` behavior and are bound to the `Object` via
`Object.defineProperty`. It acts like a shadow `Proxy/Reflector` to
the `Object` instance and provides tight control via the
`Getter/Setter` interfaces.

Below are list of properties available to every instance of `Property`:

property | type | mapping | description
--- | --- | --- | ---
name   | string | direct | name of the property
schema | object | direct | a schema instance (usually [Yang](./src/yang.listcoffee))
state  | object | direct | *private* object holding internal state
configurable | boolean | getter(state) | defines whether this property can be redefined
enumerable   | boolean | getter(state) | defines whether this property is enumerable
content | any | computed | getter/setter for `state.value`
context | object | computed | dynamically generated using [context](./src/context.coffee)
root  | [Property](./src/property.litcoffee) | computed | dynamically returns the root Property instance
path  | [XPath](./src/xpath.coffee) | computed | dynamically generate XPath for this Property from root

## Class Property

    debug    = require('debug')('yang:property')
    delegate = require 'delegates'
    context  = require './context'
    Yang     = require './yang'
    XPath    = require './xpath'

    class Property
      @property: (prop, desc) ->
        Object.defineProperty @prototype, prop, desc

      constructor: (spec={}) ->
        # NOTE: ES6/CS2 does not support below
        # unless this instanceof Property then return new Property arguments...

        # 1. parse if spec is YANG definition (string)
        spec = Yang.parse spec if typeof spec is 'string'

        # 2. assign if spec is an instance of Yang schema
        schema = spec if spec instanceof Yang

        # 3. destructure spec as an object if not schema as instance
        { name, schema } = spec unless schema?

        # 4. parse if schema is YANG definition (string)
        schema = Yang.parse schema if typeof schema is 'string'
        schema ?= kind: 'anydata'

        # 5. initialize property instance
        @name = name ? schema.datakey
        @schema = schema
        @state =
          parent:    null
          strict:    false
          private:   false
          mutable:   `schema.config != false`
          attached:  false
          changed:   false
          prior:     undefined
          value:     undefined

        # 6. soft freeze this instance
        Object.preventExtensions this

      delegate @prototype, 'state'
        .access 'parent'
        .access 'strict'
        .getter 'private'
        .getter 'mutable'
        .getter 'attached'
        .getter 'changed'
        .getter 'prior'
        .getter 'value'

      delegate @prototype, 'schema'
        .getter 'tag'
        .getter 'kind'
        .getter 'type'
        .getter 'default'
        .getter 'external'
        .getter 'binding'
        .method 'locate'
        .method 'lookup'

### Computed Properties

      @property 'value',
        get: -> @state.value

      @property 'data',
        set: (value) -> @set value, { force: true, suppress: true }
        get: -> switch
          when @binding?.get? then @binding.get @context
          else @value

      @property 'enumerable',
        get: -> not @private and (@value? or @binding?)

      @property 'active',
        get: -> @enumerable and @value?

      @property 'change',
        get: -> switch
          when @changed and not @active then null
          when @changed then @data

      @property 'context',
        get: ->
          ctx = Object.create(context)
          ctx.opts = {}
          ctx.node = this
          Object.preventExtensions ctx
          return ctx

      @property 'root',
        get: ->
          return this if @kind is 'module'
          root = switch
            when @parent is this then this
            when @parent instanceof Property then @parent.root
            else this
          @state.path = undefined unless @state.root is root
          return @state.root = root

      @property 'path',
        get: ->
          if this is @root
            entity = switch
              when @kind is 'module' then '/'
              else '.'
            return XPath.parse entity, @schema
          @state.path ?= @parent.path.clone().append @name
          return @state.path

      @property 'uri',
        get: -> @schema.datapath ? @schema.uri

## Instance-level methods

      clone: (state = {}) ->
        throw @error 'must clone with state typeof object' unless typeof state is 'object'
        copy = new @constructor this
        copy.state = Object.assign(Object.create(@state), state, origin: this)
        return copy

      debug: -> debug @uri, arguments...

      equals: (a, b) -> switch @kind
        when 'leaf-list'
          return false unless a and b
          a = Array.from(new Set([].concat(a)))
          b = Array.from(new Set([].concat(b)))
          return false unless a.length is b.length
          a.every (x) => b.some (y) => x is y
        else a is b

### get (key)

This is the main `Getter` for the target object's property value. When
called with optional `key` it will perform an internal
[find](#find-xpath) operation to traverse/locate that value being
requested instead of returning its own `@data`.

It also provides special handling based on different types of
`@data` currently held.

      get: (key) -> switch
        when key?
          try match = @find key
          return unless match? and match.length
          switch
            when match.length is 1 then match[0].data
            when match.length > 1  then match.map (x) -> x.data
            else undefined
        else @data

### set (value)

This is the main `Setter` for the target object's property value.  It
utilizes internal `@schema` attribute if available to enforce schema
validations.

      set: (value, opts={}) ->
        opts.origin ?= this

        # @debug "[set] enter..."
        unless @mutable or not value? or opts.force
          throw @error "cannot set data on read-only (config false) element"

        if not opts.force and @binding?.set?
          try value = @binding.set @context.with(opts), value
          catch e
            throw @error "failed executing set() binding: #{e.message}", e

        return this if value? and @equals value, @value # return if same value

        bypass = opts.bypass and @kind in ["leaf", "leaf-list"]
        @debug "[set] applying schema..."
        value = switch
          when @schema.apply? and not bypass
            subopts = Object.assign {}, opts, inner: true, suppress: true
            @schema.apply value, this, subopts
          else value
        @debug "[set] done applying schema...", value
        return this if value instanceof Error
        return this if value? and @equals value, @value # return if same value
        @update value, opts

### merge (value)

Performs a granular merge of `value` into existing `@value` if
available, otherwise performs [set](#set-value) operation.

      merge: (value, opts={}) ->
        opts.origin ?= this
        return @delete opts if value is null
        return @set value, opts

### delete

      delete: (opts={}) ->
        opts.origin ?= this
        return this if @state.value is null
        if not opts.force and @binding?.delete?
          try @binding.delete @context.with(opts), null
          catch e
            throw @error "failed executing delete() binding: #{e.message}", e
        @update null, opts

### update

Updates the value to the data model. Called *once* for each node that
is part of the change branch.

      update: (value, opts={}) ->
        opts.origin ?= this
        @state.prior ?= @state.value
        @state.changed = @state.changed or (@state.value isnt value)
        @state.value = value
        @parent?.update this, opts # unless opts.suppress
        return this

### commit async transaction

Commits the changes to the data model. Called *once* for each node that
is part of the change branch.

      commit: (opts={}) ->
        opts.origin ?= this
        return true unless @changed
        try
          unless opts.sync
            # 1. perform save binding
            @debug "[commit] execute binding..."
            await @binding?.commit? @context.with(opts)
            # 2. if has parent, then wait for parent commited before updating changed state
            promise = @parent?.commit? opts
              .then (ok) =>
                @state.changed = false if ok
          unless promise?
            @state.changed = false
        catch err
          @debug "[commit] revert due to #{err.message}"
          await @revert opts
          throw @error err
        return true

      revert: (opts={}) ->
        return unless @changed

        @debug "[revert] changing back to:", @state.prior
        # XXX - don't need the below?
        # @delete opts unless @state.prior?
        @state.value = @state.prior

        @debug "[revert] execute binding..."
        try await @binding?.commit? @context.with(opts) unless opts.sync
        catch err
          @debug "[revert] failed due to #{err.message}"
          throw @error err

        @state.changed = false

### attach (obj, parent, opts)

This call is the primary mechanism via which the `Property` instance
attaches itself to the provided target `obj`. It defines itself in the
target `obj` via `Object.defineProperty`.

      attach: (obj, parent, opts) ->
        return obj unless obj instanceof Object
        opts ?= { replace: false, suppress: false, force: false }
        @parent = parent

        # if joining for the first time, apply existing data unless explicit replace
        unless @attached
          # @debug "[attach] applying existing data for #{@name} (external: #{@external}) to:"
          # @debug obj
          name = switch
            when @parent?.external and @tag of obj then @tag
            when @external then @name
            when @name of obj then @name
            else "#{@root.name}:#{@name}" # should we ensure root is kind = module?

          @set obj[name], Object.assign {}, opts, inner: true, suppress: true

        unless opts.preserve
          try Object.defineProperty obj, @name,
              configurable: true
              enumerable: @enumerable
              get: (args...) => @get args...
              set: (args...) => @set args...

        @state.attached = true
        @debug "[attach] attached into #{obj.constructor.name} container"
        return obj

### find (pattern)

This helper routine can be used to allow traversal to other elements
in the data tree from the relative location of the current `Property`
instance. It returns matching `Property` instances based on the
provided `pattern` in the form of XPATH or YPATH.

It is internally used via [get](#get) and generally used inside
controller logic bound inside the [Yang expression](./yang.litcoffee)
as well as event handler listening on [Model](./model.litcoffee)
events.

It *always* returns an array (empty to denote no match) unless it
encounters an error, in which case it will throw an Error.

      find: (pattern='.', opts={}) ->
        @debug "[find] #{pattern}"
        pattern = XPath.parse pattern, @schema
        switch
          when pattern.tag is '/'  and this isnt @root then @root.find(pattern)
          when pattern.tag is '..' then @parent?.find pattern.xpath
          else pattern.apply(this) ? []

### in (pattern)

A convenience routine to locate one or more matching Property
instances based on `pattern` (XPATH or YPATH) from this Model.

      in: (pattern) ->
        try props = @find pattern
        return unless props? and props.length
        return switch
          when props.length > 1 then props
          else props[0]

### defer (value)

Optionally defer setting the value to the property until root has been updated.

      defer: (value) ->
        @debug "deferring '#{@kind}(#{@name})' until update at #{@root.name}"
        @root.once 'update', =>
          @debug "applying deferred data (#{typeof value})"
          @data = value
        return value

### error (msg)

Provides more contextual error message pertaining to the Property instance.

      error: (err, ctx) ->
        err = new Error err unless err instanceof Error
        err.uri ?= @uri
        err.src ?= this
        err.ctx ?= ctx
        return err

### toJSON

This call creates a new copy of the current `Property.content`
completely detached/unbound to the underlying data schema. It's main
utility is to represent the current data state for subsequent
serialization/transmission. It accepts optional argument `tag` which
when called with `true` will tag the produced object with the current
property's `@name`.

      toJSON: (key, state = true) ->
        value = switch
          when @kind is 'anydata' then undefined
          when state isnt true and not @mutable then undefined
          else @data
        value = "#{@name}": value if key is true
        return value

### inspect

      inspect: ->
        return {
          name:    @name
          kind:    @kind
          path:    @path.toString()
          active:  @active
          private: @private
          mutable: @mutable
          changed: @changed
          schema: switch
            when @schema.uri?
              uri:      @schema.uri
              summary:  @schema.description?.tag
              datakey:  @schema.datakey
              datapath: @schema.datapath
              external: @schema.external
              children: @schema.children.map (x) -> x.uri
            else false
          value: @toJSON()
        }

## Export Property Class

    module.exports = Property


Lowercase image extention before testing

    url          = require 'url'

    compression  = require 'compression'
    express      = require 'express'
    morgan       = require 'morgan'
    responseTime = require 'response-time'

    multer       = require 'multer'
    async        = require 'async'
    dms2dec      = require 'dms2dec'

    raven        = require 'raven'
    sentry       = require './sentry'

    app = express()
    app.use morgan 'combined'
    app.use compression()
    app.use responseTime()

    Upload = require 's3-uploader'
    s3 = new Upload process.env.AWS_BUCKET_NAME,
      awsBucketUrl: "https://s3-eu-west-1.amazonaws.com/#{process.env.AWS_BUCKET_NAME}/"
      awsBucketPath: process.env.AWS_BUCKET_PATH
      awsBucketAcl: 'public-read'
      awsHttpTimeout: 60000
      returnExif: true

      versions: [{
        original: true
        awsImageAcl: 'private'
      },{
        suffix: '-large'
        quality: 80
        maxHeight: 1040
        maxWidth: 1040
      },{
        suffix: '-medium'
        maxHeight: 780
        maxWidth: 780
      },{
        suffix: '-small'
        maxHeight: 320
        maxWidth: 320
      }]

    origins = process.env.ALLOW_ORIGINS?.split(',') or []

    app.all '/upload', (req, res, next) ->
      res.once 'close', -> sentry.captureResClose res

      origin = url.parse req.get('Origin') or ''

      if origin.hostname not in origins
        error = new Error "Bad Origin Header #{req.get('Origin')}"
        error.status = 403
        return next error

      res.set 'Access-Control-Allow-Origin', req.get('Origin')
      res.set 'Access-Control-Allow-Methods', 'POST'
      res.set 'Access-Control-Allow-Headers', 'X-Requested-With, Content-Type'
      res.set 'Access-Control-Expose-Headers', 'X-Response-Time'
      res.set 'Access-Control-Allow-Max-Age', 0

      return res.send 200 if req.method is 'OPTIONS'
      return next()

    app.post '/upload', multer(dest: require('os').tmpdir()), (req, res, next) ->
      console.log "Recieved #{Object.keys(req.files).length} files"

      async.mapSeries Object.keys(req.files), (key, cb) ->
        if req.files[key].extension.toLowerCase() not in ['jpg', 'jpeg', 'png', 'gif', 'tiff']
          error = new Error "Invalid Image #{req.files[key].extension}"
          error.status = 422
          return cb error

        s3.upload req.files[key].path, {}, (err, images, meta) ->
          return cb err if err

          if meta.exif['exif:GPSLatitude'] and meta.exif['exif:GPSLongitude']
            meta.geojson =
              type: 'Point'
              coordinates: dms2dec \
                meta.exif['exif:GPSLatitude'], \
                meta.exif['exif:GPSLatitudeRef'], \
                meta.exif['exif:GPSLongitude'], \
                meta.exif['exif:GPSLongitudeRef']
              .reverse()

          return cb null, versions: images.splice(1), meta: meta
      , (err, files) ->
        return next err if err
        sentry.captureHeaderSent req, files if res._headerSent
        return res.status(201).json files

    app.use (req, res, next) ->
      res.status(404).json message: 'Not Found'

    app.use raven.middleware.express sentry
    app.use (err, req, res, next) ->
      if not err.status or err.status >= 500
        sentry.captureError err

        console.error err.message
        console.error err.stack

        res.status(err.status or 500).json message: 'Internal Server Error'
      else
        sentry.captureMessage err.message, level: 'warning', req: req
        res.status(err.status).json message: err.message

    if not module.parent
      app.listen process.env.PORT_WWW
      console.log "Server listening on port #{process.env.PORT_WWW}"
    else
      module.exports = app

    url          = require 'url'

    compression  = require 'compression'
    express      = require 'express'
    morgan       = require 'morgan'
    responseTime = require 'response-time'

    multer       = require 'multer'
    async        = require 'async'
    dms2dec      = require 'dms2dec'

    raven        = require 'raven'
    sentry       = require './sentry'

    app = express()
    app.use morgan 'combined'
    app.use compression()
    app.use responseTime()

    Upload = require 's3-uploader'
    s3 = new Upload process.env.AWS_BUCKET_NAME,
      awsBucketUrl: "https://s3-eu-west-1.amazonaws.com/#{process.env.AWS_BUCKET_NAME}/"
      awsBucketPath: process.env.AWS_BUCKET_PATH
      awsBucketAcl: 'public-read'
      awsHttpTimeout: 60000
      returnExif: true

      versions: [{
        original: true
        awsImageAcl: 'private'
      },{
        suffix: '-large'
        quality: 80
        maxHeight: 1040
        maxWidth: 1040
      },{
        suffix: '-medium'
        maxHeight: 780
        maxWidth: 780
      },{
        suffix: '-small'
        maxHeight: 320
        maxWidth: 320
      }]

    origins = process.env.ALLOW_ORIGINS?.split(',') or []

    app.all '/upload', (req, res, next) ->
      res.once 'close', -> sentry.captureResClose res

      origin = url.parse req.get('Origin') or ''

      if origin.hostname not in origins
        error = new Error "Bad Origin Header #{req.get('Origin')}"
        error.status = 403
        return next error

      res.set 'Access-Control-Allow-Origin', req.get('Origin')
      res.set 'Access-Control-Allow-Methods', 'POST'
      res.set 'Access-Control-Allow-Headers', 'X-Requested-With, Content-Type'
      res.set 'Access-Control-Expose-Headers', 'X-Response-Time'
      res.set 'Access-Control-Allow-Max-Age', 0

      return res.send 200 if req.method is 'OPTIONS'
      return next()

    app.post '/upload', multer(dest: require('os').tmpdir()), (req, res, next) ->
      console.log "Recieved #{Object.keys(req.files).length} files"

      async.mapSeries Object.keys(req.files), (key, cb) ->
        if req.files[key].extension not in ['jpg', 'jpeg', 'png', 'gif', 'tiff']
          error = new Error "Invalid Image #{req.files[key].extension}"
          error.status = 422
          return cb error

        s3.upload req.files[key].path, {}, (err, images, meta) ->
          return cb err if err

          if meta.exif['exif:GPSLatitude'] and meta.exif['exif:GPSLongitude']
            meta.geojson =
              type: 'Point'
              coordinates: dms2dec \
                meta.exif['exif:GPSLatitude'], \
                meta.exif['exif:GPSLatitudeRef'], \
                meta.exif['exif:GPSLongitude'], \
                meta.exif['exif:GPSLongitudeRef']
              .reverse()

          return cb null, versions: images.splice(1), meta: meta
      , (err, files) ->
        return next err if err
        sentry.captureHeaderSent req, files if res._headerSent
        return res.status(201).json files

    app.use (req, res, next) ->
      res.status(404).json message: 'Not Found'

    app.use raven.middleware.express sentry
    app.use (err, req, res, next) ->
      if not err.status or err.status >= 500
        sentry.captureError err

        console.error err.message
        console.error err.stack

        res.status(err.status or 500).json message: 'Internal Server Error'
      else
        sentry.captureMessage err.message, level: 'warning', req: req
        res.status(err.status).json message: err.message

    if not module.parent
      app.listen process.env.PORT_WWW
      console.log "Server listening on port #{process.env.PORT_WWW}"
    else
      module.exports = app


weya lint

weya lint

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 switch foreignObject'

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: []

      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.push 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?
        if elem.classList?
         for c in idClass.class
          elem.classList.add c
        else #For older browsers; does not work with svgs
         className = ''
         for c in idClass.class
          className += ' ' if className isnt ''
          className += "#{c}"
         elem.className = className

      if attrs?
       setAttributes elem, attrs

      if pElem?
       pElem.appendChild elem

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

      @_elem = pElem
      return elem

Wrap `append`

     wrapAppend = (ns, name) ->
      ->
       append.call this, 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 "http://www.w3.org/1999/xhtml", 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 this
      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 this, 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 ''

    Weya.setApi = (api) ->
     for k, v of api
      Api[k] = v

    if module?
     module.exports = Weya

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 switch foreignObject'

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: []

      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.push 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?
        if elem.classList?
         for c in idClass.class
          elem.classList.add c
        else #For older browsers; does not work with svgs
         className = ''
         for c in idClass.class
          className += ' ' if className isnt ''
          className += "#{c}"
         elem.className = className

      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 "http://www.w3.org/1999/xhtml", 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 ''

    Weya.setApi = (api) ->
     for k, v of api
      Api[k] = v

    if module?
     module.exports = Weya


Document the file.

Document the file.

Grab the Files
=====================
I found that I we reusing a lot of the same logic to get the policies, controllers, and models, when in reality it is pretty trivial to reuse and just have a parameter.

## Libraries

    Promise = require 'bluebird'
    _ = require 'lodash'
    fs = Promise.promisifyAll require 'fs'

Note: The `promisifyAll` function simply takes a module, suffixes the functions with the word `Async`, and makes them promisable instead of callbackey.

----------

Let's start the function. Expected input is a string of the type of file you want, and the expected output is a promise'd array of objects of the imported files.

    module.exports = (type) ->

Let's read in the folder of the files.

        fs.readdirAsync './#{type}'

Once the files have been loaded, the remaining logic is pretty simple: We `map` through them and require them, and from there we can plop them into an array.

        .then (files) ->
            _.map files, (file) ->
                if ((file.match /.+\.js/g)? or (file.match /.+\.coffee/g)? or (file.match /.+\.litcoffee/g)?)
                    myObject = {}
                    name = file.replace('.js', '').replace('.coffee', '').replace('.litcoffee', '')
                    myObject[name] = require "../#{type}/#{name}"
                    myObject

Once we've put all these files into an array, we'd like to merge them into one big object.  We can utilize lodash's reduce function to handle returning back one item, and we can use lodash's extend function to handle the merging.

        .then (fileArray) ->
            _.reduce fileArray, _.extend

Grab the Files
=====================
I found that I we reusing a lot of the same logic to get the policies, controllers, and models, when in reality it is pretty trivial to reuse and just have a parameter.

    Promise = require 'bluebird'
    _ = require 'lodash'
    fs = Promise.promisifyAll require 'fs'
    module.exports = (type) ->
        fs.readdirAsync './#{type}'
        .then (files) ->
            _.map files, (file) ->
                if ((file.match /.+\.js/g)? or (file.match /.+\.coffee/g)? or (file.match /.+\.litcoffee/g)?)
                    myObject = {}
                    name = file.replace('.js', '').replace('.coffee', '').replace('.litcoffee', '')
                    myObject[name] = require "../#{type}/#{name}"
                    myObject
        .then (fileArray) ->
            _.reduce fileArray, _.extend


Disabled transparency on the render context.

Exports an object.
Call "load" early in the application to get the WebGL context.
The "context" property is the WebGL context.
The "width" and "height" properties are the dimensions of the viewport in pixels.

    handleError = require "./../handleError.litcoffee"
    matrix = require "./../matrix.litcoffee"

    module.exports =
        canvas: null
        context: null
        width: null
        height: null
        load: ->
            module.exports.canvas = (document.getElementsByTagName "canvas")[0]
            module.exports.context = module.exports.canvas.getContext "experimental-webgl",
                antialias: false
                alpha: false
            if not module.exports.context then handleError "Failed to open a WebGL context"

            resize = ->
                module.exports.width = window.innerWidth
                module.exports.height = window.innerHeight
                if not module.exports.canvas then return
                module.exports.canvas.width = module.exports.width
                module.exports.canvas.height = module.exports.height
                return

            addEventListener "resize", resize
            resize()
            return

Call the "begin" property to set up the camera and viewport.  This takes the
following arguments:

- The distance, in pixels, between the left border of the screen and the
  left border of the viewport.
- The distance, in pixels, between the bottom border of the screen and the
  bottom border of the viewport.
- The width, in pixels, of the viewport.
- The height, in pixels, of the viewport.
- A zoom factor, where 1 is 100% and 2 is 200%.
- The matrix to apply to all geometry the previous frame.
- The matrix to apply to all geometry this frame.

        postScale: [1, 1]
        transforms: [[],[]]

        begin: (left, bottom, width, height, zoom, oldTransform, newTransform) ->
            gl = module.exports.context
            gl.viewport left, bottom, width, height
            gl.enable gl.SCISSOR_TEST
            gl.scissor left, bottom, width, height
            gl.clear gl.DEPTH_BUFFER_BIT
            gl.disable gl.SCISSOR_TEST

            matrix.copy oldTransform, module.exports.transforms[0]
            matrix.copy newTransform, module.exports.transforms[1]

            if width > height
                module.exports.postScale[0] = zoom * height / width
                module.exports.postScale[1] = zoom
            else
                module.exports.postScale[0] = zoom
                module.exports.postScale[1] = zoom * width / height
            return

Specific to this implementation are the following properties:
- "postScale": An array of two numbers to multiply the X and Y of every vertex
               by in NDC.  This is used to apply zoom and aspect correction.
- "transforms": An array of two matrices; the global transform from last frame
                and this frame.

Exports an object.
Call "load" early in the application to get the WebGL context.
The "context" property is the WebGL context.
The "width" and "height" properties are the dimensions of the viewport in pixels.

    handleError = require "./../handleError.litcoffee"
    matrix = require "./../matrix.litcoffee"

    module.exports =
        canvas: null
        context: null
        width: null
        height: null
        load: ->
            module.exports.canvas = (document.getElementsByTagName "canvas")[0]
            module.exports.context = module.exports.canvas.getContext "experimental-webgl",
                antialias: false
            if not module.exports.context then handleError "Failed to open a WebGL context"

            resize = ->
                module.exports.width = window.innerWidth
                module.exports.height = window.innerHeight
                if not module.exports.canvas then return
                module.exports.canvas.width = module.exports.width
                module.exports.canvas.height = module.exports.height
                return

            addEventListener "resize", resize
            resize()
            return

Call the "begin" property to set up the camera and viewport.  This takes the
following arguments:

- The distance, in pixels, between the left border of the screen and the
  left border of the viewport.
- The distance, in pixels, between the bottom border of the screen and the
  bottom border of the viewport.
- The width, in pixels, of the viewport.
- The height, in pixels, of the viewport.
- A zoom factor, where 1 is 100% and 2 is 200%.
- The matrix to apply to all geometry the previous frame.
- The matrix to apply to all geometry this frame.

        postScale: [1, 1]
        transforms: [[],[]]

        begin: (left, bottom, width, height, zoom, oldTransform, newTransform) ->
            gl = module.exports.context
            gl.viewport left, bottom, width, height
            gl.enable gl.SCISSOR_TEST
            gl.scissor left, bottom, width, height
            gl.clear gl.DEPTH_BUFFER_BIT
            gl.disable gl.SCISSOR_TEST

            matrix.copy oldTransform, module.exports.transforms[0]
            matrix.copy newTransform, module.exports.transforms[1]

            if width > height
                module.exports.postScale[0] = zoom * height / width
                module.exports.postScale[1] = zoom
            else
                module.exports.postScale[0] = zoom
                module.exports.postScale[1] = zoom * width / height
            return

Specific to this implementation are the following properties:
- "postScale": An array of two numbers to multiply the X and Y of every vertex
               by in NDC.  This is used to apply zoom and aspect correction.
- "transforms": An array of two matrices; the global transform from last frame
                and this frame.


One more try with litcoffee

One more try with litcoffee

Load in the libraries

    _ = require 'lodash'
    Promise = require "bluebird"

Load up the user-defined policies.

    policies = require '../config/policies'

    module.exports = (routeActions, req, res) ->
        new Promise (resolve, reject) ->
            require('./getPolicies')()
            .then (actualPolicies) ->
                policyResults = _.flatten _.map routeActions, (action) ->
                        # What I'm doing here is looking for the policies file.
                        # If there is a policy defined for that action, use that, else use the * catch all.
                        tempPolicies = _.flatten [policies[action.controllerName][action.actionName] || policies[action.controllerName]['*'] ]

                        _.map tempPolicies, (policy) ->
                            # This is pretty straightforward; we'll loop up the policy in the hash
                            # table and then return back their result (which can just be a true or false
                            #
                            # We want to make sure this is properly wrapped in promisey stuff, so we can init
                            # an empty promise then run our stuff in the "then". Since our empty promise only
                            # resolves, it won't hit the catch.
                            tempPromise = new Promise (resolve, reject) -> do resolve
                            tempPromise.then -> actualPolicies[policy] req

                Promise.all policyResults
            .then (results) ->
                # Not entirely sure I like this logic, but it's pretty straightforward:
                # I want to allow synchronous or asynchronous policies.  Subsequently, we can
                # either allow the policy to reject if not permitted or to simply return false.
                unless false in results
                  resolve true
                else
                  reject "Not Authorized"

Libraries

    _ = require 'lodash'
    Promise = require "bluebird"
    policies = require '../config/policies'

    module.exports = (routeActions, req, res) ->
        new Promise (resolve, reject) ->
            require('./getPolicies')()
            .then (actualPolicies) ->
                policyResults = _.flatten _.map routeActions, (action) ->
                        # What I'm doing here is looking for the policies file.
                        # If there is a policy defined for that action, use that, else use the * catch all.
                        tempPolicies = _.flatten [policies[action.controllerName][action.actionName] || policies[action.controllerName]['*'] ]

                        _.map tempPolicies, (policy) ->
                            # This is pretty straightforward; we'll loop up the policy in the hash
                            # table and then return back their result (which can just be a true or false
                            #
                            # We want to make sure this is properly wrapped in promisey stuff, so we can init
                            # an empty promise then run our stuff in the "then". Since our empty promise only
                            # resolves, it won't hit the catch.
                            tempPromise = new Promise (resolve, reject) -> do resolve
                            tempPromise.then -> actualPolicies[policy] req

                Promise.all policyResults
            .then (results) ->
                # Not entirely sure I like this logic, but it's pretty straightforward:
                # I want to allow synchronous or asynchronous policies.  Subsequently, we can
                # either allow the policy to reject if not permitted or to simply return false.
                unless false in results
                  resolve true
                else
                  reject "Not Authorized"