Fire error event on rejected promise

Fire error event on rejected promise

    q     = require 'q'
    fs    = require 'fs'
    async = require 'async'
    uuid  = require 'uuid-1345'

    microtime = require 'microtime'

    EventEmitter2 = require('eventemitter2').EventEmitter2
    emitter       = new EventEmitter2 wildcard: true

    available   = { }
    initialized = { }
    listeners   = { }

    underscore = (value) -> value.replace /\W+/g, '_'
    strip      = (name)  -> name.toLowerCase().replace /\W+/g, ''

    SEARCH_ROOTS  = { }
    WRAPPED       = { }
    _INITIALIZERS = { }
    HYDRATED      = { }
    LOCALS        = { }

    HYRDATION_LISTENERS = { }

    INITIALIZERS = (cls, method) ->
      _INITIALIZERS[cls] = [ ] unless _INITIALIZERS[cls]?

      _INITIALIZERS[cls].push fn: method, called: false

    WRAP = (cls, method) ->
      unless WRAPPED[cls]?
        WRAPPED[cls] = [
          'constructor'
          'initialize'
          'details'
        ]

      WRAPPED[cls].indexOf(method) < 0

    class Madul

      details: =>
        name  = @.__proto__.constructor.name
        props = for own key, val of @.__proto__
          if key != 'constructor' &&
             key != 'details'     &&
             key != 'initialize'  && ((
               key[0]            == '_' &&
               @.__proto__[key]? == false
             ) || key[0] != '_')

            if typeof val == 'function'
              value = val.constructor.name
            else if Array.isArray val
              value = for v in val
                if typeof v == 'function'
                  v.constructor.name
                else if typeof v == 'object'
                  v.constructor.name
                else
                  v
              value = value.join ','
            else if typeof val == 'object'
              value = val.constructor.name
            else
              value = val

            "#{key} => #{value}"

        "\n  #{name}\n    #{props.filter((e) -> e?).join '\n    '}"

      @LISTEN: (event, callback) => emitter.on event, callback

      @FIRE: (event, args) => emitter.emit event, args

      @SEARCH_ROOT: (mod, path) =>
        Madul.FIRE '$.Madul.search_root.register', "#{mod}": path

        SEARCH_ROOTS[mod] = path.substring 0, path.lastIndexOf '/'

      @PARSE_SPEC: (value) =>
        tokens = value.split '='

        if tokens.length == 2
          initer = tokens[1].trim()
          t      = tokens[0].split '->'

          if t[0].indexOf('#') > -1
            r = t[0].split '#'

            root = r[0].trim()
            t[0] = r[1]

          if t.length == 2
            n = t[0].trim()

            if n[0] == '.'
              local = true
              name  = n.substring 1, n.length
            else
              local = false
              name  = n

            alias = t[1].trim()
          else if t.length == 1
            n = t[0].trim()

            if n[0] == '.'
              local = true
              name  = alias = n.substring 1, n.length
            else
              local = false
              name  = alias = n
          else
            return Madul.FIRE '!.Madul.dependency_spec.alias.invalid', tokens[1]

          toks = initer.split ':'

          if toks.length == 2
            initer = toks[0].trim()
            pres   = toks[1].split(',').map (p) => p.trim()
          else if toks.length == 1
            initer = toks[0].trim()
          else
            return Madul.FIRE '!.Madul.dependency_spec.initializer.invalid', tokens[1]

        else if tokens.length == 1
          t = tokens[0].split '->'

          if t[0].indexOf('#') > -1
            r = t[0].split '#'

            root = r[0].trim()
            t[0] = r[1]

          if t.length == 2
            n = t[0].trim()

            if n[0] == '.'
              local = true
              name  = n.substring 1, n.length
            else
              local = false
              name  = n

            alias = t[1].trim()
          else if t.length == 1
            n = t[0].trim()

            if n[0] == '.'
              local = true
              name  = alias = n.substring 1, n.length
            else
              local = false
              name  = alias = n
          else
            return Madul.FIRE '!.Madul.dependency_spec.alias.invalid', tokens[1]

        else
          return Madul.FIRE '!.Madul.dependency_spec.invalid', d

        { ref: alias || name, alias, name, root, initer, pres, local }

      @BUILD_SPEC: ({ search_root, name, alias, initializer, prerequisites }) =>
        unless name?
          return Madul.FIRE '!.Madul.dependency_spec.name-required', arguments[0]

        if prerequisites? && initializer? == false
          return Madul.FIRE '!.Madul.dependency_spec.prerequisites-require-initializer', arguments[0]

        "#{if search_root?   then "#{search_root}#"            else ''}\
         #{name}\
         #{if alias?         then " -> #{alias}"               else ''}\
         #{if initializer?   then " = #{initializer}"          else ''}\
         #{if prerequisites? then ":#{prerequisites.join ','}" else ''}\
        "

      listen: (event, callback) ->
        Madul.LISTEN "*.#{@constructor.name}.#{event}", callback

      fire: (event, args) ->
        Madul.FIRE "@.#{@constructor.name}.#{event}", args

      warn: (event, details) ->
        Madul.FIRE "!.#{@constructor.name}.#{event}", details

      _report: (name, method, state, id, args) =>
        if state == 'reject'
          Madul.FIRE "!.#{name}.#{method}.#{state}",
            uuid:      id
            message:   args
            timestamp: microtime.now()
        else
          Madul.FIRE "@.#{name}.#{method}.#{state}",
            uuid:      id
            args:      args
            timestamp: microtime.now()

      _respond: (proto, method, id, deferred) =>
        (state, data) =>
          process.nextTick =>
            deferred[state] data

            proto._report proto.constructor.name, method, state, id, data

      _prep_invocation: (proto, method, input, def) =>
        id  = uuid.v4fast()
        res = proto._respond proto, method, id, def

        if Array.isArray input
          input.push (out) => res 'resolve', out
          input.push (err) => res 'reject',  err
          input.push (out) => res 'notify',  out
        else if typeof input == 'object'
          input.done   = (out) => res 'resolve', out
          input.fail   = (err) => res 'reject',  err
          input.update = (out) => res 'notify',  out

          input = [ input ]
        else
          msg = "input to #{proto.constructor.name}.#{method} must be an Array of Object"
          @warn 'input.invalid', msg
          throw new Error msg

        proto._report proto.constructor.name, method, 'invoke', id, input

        input

      _do_wrap: (proto, method) =>
        if method != 'fire' && method != 'warn' && method != 'listen'
          Madul.FIRE "$.#{proto.constructor.name}.#{method}.wrap"

          if typeof proto[method] == 'function'
            proto["_#{method}"] = proto[method]

            proto[method] = =>
              def  = q.defer()
              args = if arguments[0]? then Array.prototype.slice.call arguments else [ ]

              proto["_#{method}"].apply @, proto._prep_invocation proto, method, args, def

              def.promise
          else if typeof proto[method] == 'object'

            if Array.isArray proto[method].validate
              args_format = 'ARRAY'
              decs        = for val in proto[method].validate
                @_parse_handle(val).ref

              proto[method].validate = decs
            else if typeof proto[method].validate == 'object'
              args_format = 'OBJECT'
              decs        = for own key, val of proto[method].validate
                { ref } = @_parse_handle val
                proto[method].validate[key] = ref
                ref
            else if typeof proto[method].validate == 'string'
              args_format = 'ARRAY'
              decs        = [ @_parse_handle(proto[method].validate).ref ]
            else if typeof proto[method].validate != 'undefined'
              @warn 'meta.invalid', validate: 'must be a String, Object, or Array'
              return
            else
              args_format = 'ARRAY'
              decs        = [ ]

            decs = decs.concat(proto[method].before.map (b, i) =>
              { ref } = @_parse_handle b
              proto[method].before[i] = ref
              ref
            ) if proto[method].before?

            decs = decs.concat(proto[method].after.map (a, i) =>
              { ref } = @_parse_handle a
              proto[method].after[i] = ref
              ref
            ) if proto[method].after?

            Madul.FIRE '$.Madul.decorators.hydrate', decs

            @_do_hydrate proto, decs, =>
              proto["_#{method}"] = proto[method]

              proto[method] = =>
                def = q.defer()
                me  = proto["_#{method}"]

                if args_format == 'ARRAY'
                  args = Array.prototype.slice.call arguments

                  if me.validate?
                    validators = for val, i in me.validate
                      { ref } = @_parse_handle val
                      Madul.FIRE '$.Madul.validator.execute', "#{ref}": args[i]
                      proto[ref].EXECUTE args[i]
                else if args_format == 'OBJECT'
                  args = arguments[0]

                  if me.validate?
                    validators = for own key, val of me.validate
                      { ref } = @_parse_handle val
                      Madul.FIRE '$.Madul.validator.execute', "#{ref}": args[key]
                      proto[ref].EXECUTE args[key]
                else
                  @warn 'cannot-continue', 'No arg format specified'

                  return def.reject 'No arg format specified'

                me.before = [ ] unless me.before?
                me.after  = [ ] unless me.after?

                q.all validators
                .then =>
                  q.all me.before.map (b) =>
                    Madul.FIRE '$.Madul.before_filter.execute', "#{b}": args
                    proto[b].before args
                .then =>
                  me.behavior.apply @, @_prep_invocation proto, method, args, def
                .then (result) =>
                  if me.after.length > 0
                    q.all me.after.map (b) =>
                      Madul.FIRE '$.Madul.after_filter.execute', "#{b}": result
                      b.after result
                  else
                    d = q.defer()

                    process.nextTick => d.resolve result

                    d.promise
                .then  (out) => def.resolve out
                .catch (err) => def.reject  err

                def.promise
          else
            @warn 'cannot-wrap', method

          WRAPPED[proto.constructor.name].push method

      _wrap_methods: (proto, callback) =>
        name    = proto.constructor.name
        to_wrap = [ ]

        while proto? && Object.keys(proto).length > 0 && WRAPPED[name]? == false
          to_wrap.push { proto, name, methods: [ ] }

          for own prop, body of proto
            if prop[0]                  != '_'         &&
               typeof proto["_#{prop}"] == 'undefined' &&
               WRAP(name, prop)         == true

              continue if proto.deps? && proto.deps.indexOf(prop.replace(/_/g, '-')) > -1

              if typeof body == 'function' || typeof body?.behavior == 'function'
                to_wrap[to_wrap.length - 1].methods.push prop

          proto = proto.__proto__
          name  = proto.constructor.name

        async.each to_wrap.reverse(), (wrap, completed) =>
          async.each wrap.methods, (method, next) =>
            wrap.proto._do_wrap wrap.proto, method

            INITIALIZERS wrap.name, method if method[0] == '$'

            next()
          , => @_call_initializers_for wrap.proto, wrap.name, completed
        , callback

      _make_available: (name, mod) =>
        Madul.FIRE "$.#{name}.available"

        available[strip name] = mod

      _hydrate_deps: (proto, done) =>
        protos = [ proto ]

        if proto.__proto__?
          while proto.__proto__? && Object.keys(proto.__proto__).length > 0
            protos.push proto = proto.__proto__

        async.each protos.reverse(), (p, next) =>
          name = p.constructor.name

          if p.hasOwnProperty 'deps'
            if HYDRATED[name] == undefined
              HYDRATED[name]            = false
              HYRDATION_LISTENERS[name] = [ next ]

              p._do_hydrate p, p.deps, =>
                HYDRATED[name] = true

                for listener in HYRDATION_LISTENERS[name]
                  listener()
            else if HYDRATED[name] == false
              HYRDATION_LISTENERS[name].push next
            else if HYDRATED[name] == true
              next()
          else
            next()
        , done

      _init_if_madul: (path, callback) =>
        mod      = require path
        proto    = mod
        is_madul = false

        while proto
          is_madul = true if proto.name == 'Madul'
          if is_madul                            == false      &&
             proto.constructor.name              != 'Object'   &&
             typeof proto                        == 'function' &&
             typeof proto.__super__?.constructor == 'function'
            proto = proto.__super__.constructor
          else
            proto = undefined

        if is_madul
          new mod()
            .initialize()
            .then callback
        else
          callback mod

      _load: (me, name, path, loaded) =>
        me._init_if_madul path, (mod) =>
          me._make_available name, mod
          loaded mod

      _check: (me, path, dep, ref, finished) =>
        fs.readdir path, (err, files) =>
          if err?
            me.warn 'file-not-found', err

            done type: 'ERROR', info: err
          else
            async.each files, (f, next) =>
              depth = "#{path}/#{f}"

              fs.stat depth, (e, s) =>
                if s.isDirectory() && f[0] != '.'
                  me._check me, depth, dep, ref, next
                else if s.isFile() && f.substring(0, f.length - 3) == dep
                  me._load me, ref, depth, (mod) => me._do_add me, mod, ref, next
                else
                  next()
            , finished

      _do_add: (me, mod, ref, next) =>
        Madul.FIRE "$.#{me.constructor.name}.dependency.register", ref

        me[underscore ref] = mod

        next()

      _add: (me, ref, path, next) =>
        me._init_if_madul path, (mod) =>
          me._make_available ref, mod
          me._do_add me, mod, ref, next

      _do_hydrate: (proto, deps, hydration_complete) =>
        initers = [ ]

        async.each deps, (d, next) =>
          { ref, alias, name, root, initer, pres, local } = Madul.PARSE_SPEC d

          if pres?
            insert_at = for p in pres
              index_for = (sibling) => sibling.alias == p.alias

              initers.find index_for

            insert_at.sort()

            insert_at = if insert_at.length == 0 then 0 else insert_at[insert_at.length - 1]

            initers.splice insert_at, 0, alias: alias, execute: initer

          if proto[underscore ref]? == false
            if available[strip ref]? == true
              proto._do_add proto, available[strip ref], ref, next
            else
              if root?
                Madul.FIRE '$.Madul.search_root.load', { name, alias, root }

                @_do_hydrate proto, [ root ], =>
                  if SEARCH_ROOTS[root] == undefined
                    SEARCH_ROOTS[root] = @_find_code_root root

                  proto._check proto, SEARCH_ROOTS[root], name, ref, next
              else if local
                proto._check proto, LOCALS[proto.constructor.name], name, ref, next
              else
                try
                  proto._add proto, ref, name, next
                catch e
                  cwd = process.cwd()
                  pkg = "#{cwd}/node_modules/#{name}/package.json"

                  fs.stat pkg, (err, stat) =>
                    if stat?.isFile()
                      fs.readFile pkg, 'utf8', (err, data) =>
                        json = JSON.parse data
                        main = json.main || json._main || 'index.js'
                        path = "#{cwd}/node_modules/#{name}/#{main}"

                        proto._add proto, ref, path, next
                    else
                      proto._check proto, LOCALS[proto.constructor.name], name, ref, next
          else
            next()
        , =>
          async.eachSeries initers, (initer, next) =>
            proto[initer.execute].apply(@).then next
          , hydration_complete

      _finish_up: (proto, args) =>
        name = proto.constructor.name

        if listeners[name]?
          async.each listeners[name], (listener, next) =>
            listener @
            next()
          , => @_register_initialized name
        else
          @_register_initialized name

      _register_initialized: (name) =>
        @_make_available name, @

        initialized[name] = true

        Madul.FIRE "$.#{name}.initialized"

      _call_initializers_for: (proto, name, callback) =>
        if _INITIALIZERS[name]?
          async.each _INITIALIZERS[name], (initializer, next) =>
            if initializer.called == false
              proto[initializer.fn].apply @
                .then =>
                  initializer.called = true
                  next()
            else
              next()
          , callback
        else
          callback()

      _find_code_root: (resource) =>
        file  = resource.toLowerCase()
        found = for own key, val of require.cache
          if key.replace(/_/g, '').toLowerCase().includes file
            key.substring(0, key.lastIndexOf '/').split '/'

        found
          .filter (f) => f?
          .sort((a, b) => a.length - b.length)[0]
          .join '/'

      initialize: =>
        deferred = q.defer()
        proto    = @.__proto__
        name     = proto.constructor.name

        Madul.FIRE "$.#{name}.request_instance"

        if initialized[name] == undefined
          Madul.FIRE "$.#{name}.initialize"

          initialized[name] = false
          listeners[name]   = [ deferred.resolve ]

          if LOCALS[name] == undefined
            LOCALS[name] = @_find_code_root name

          @_hydrate_deps proto, => @_wrap_methods proto, => @_finish_up proto
        else if initialized[name] == false
          listeners[name].push deferred.resolve
        else if initialized[name] == true
          process.nextTick => deferred.resolve available[strip name]

        deferred.promise

    module.exports = Madul

    q     = require 'q'
    fs    = require 'fs'
    async = require 'async'
    uuid  = require 'uuid-1345'

    microtime = require 'microtime'

    EventEmitter2 = require('eventemitter2').EventEmitter2
    emitter       = new EventEmitter2 wildcard: true

    available   = { }
    initialized = { }
    listeners   = { }

    underscore = (value) -> value.replace /\W+/g, '_'
    strip      = (name)  -> name.toLowerCase().replace /\W+/g, ''

    SEARCH_ROOTS  = { }
    WRAPPED       = { }
    _INITIALIZERS = { }
    HYDRATED      = { }
    LOCALS        = { }

    HYRDATION_LISTENERS = { }

    INITIALIZERS = (cls, method) ->
      _INITIALIZERS[cls] = [ ] unless _INITIALIZERS[cls]?

      _INITIALIZERS[cls].push fn: method, called: false

    WRAP = (cls, method) ->
      unless WRAPPED[cls]?
        WRAPPED[cls] = [
          'constructor'
          'initialize'
          'details'
        ]

      WRAPPED[cls].indexOf(method) < 0

    class Madul

      details: =>
        name  = @.__proto__.constructor.name
        props = for own key, val of @.__proto__
          if key != 'constructor' &&
             key != 'details'     &&
             key != 'initialize'  && ((
               key[0]            == '_' &&
               @.__proto__[key]? == false
             ) || key[0] != '_')

            if typeof val == 'function'
              value = val.constructor.name
            else if Array.isArray val
              value = for v in val
                if typeof v == 'function'
                  v.constructor.name
                else if typeof v == 'object'
                  v.constructor.name
                else
                  v
              value = value.join ','
            else if typeof val == 'object'
              value = val.constructor.name
            else
              value = val

            "#{key} => #{value}"

        "\n  #{name}\n    #{props.filter((e) -> e?).join '\n    '}"

      @LISTEN: (event, callback) => emitter.on event, callback

      @FIRE: (event, args) => emitter.emit event, args

      @SEARCH_ROOT: (mod, path) =>
        Madul.FIRE '$.Madul.search_root.register', "#{mod}": path

        SEARCH_ROOTS[mod] = path.substring 0, path.lastIndexOf '/'

      @PARSE_SPEC: (value) =>
        tokens = value.split '='

        if tokens.length == 2
          initer = tokens[1].trim()
          t      = tokens[0].split '->'

          if t[0].indexOf('#') > -1
            r = t[0].split '#'

            root = r[0].trim()
            t[0] = r[1]

          if t.length == 2
            n = t[0].trim()

            if n[0] == '.'
              local = true
              name  = n.substring 1, n.length
            else
              local = false
              name  = n

            alias = t[1].trim()
          else if t.length == 1
            n = t[0].trim()

            if n[0] == '.'
              local = true
              name  = alias = n.substring 1, n.length
            else
              local = false
              name  = alias = n
          else
            return Madul.FIRE '!.Madul.dependency_spec.alias.invalid', tokens[1]

          toks = initer.split ':'

          if toks.length == 2
            initer = toks[0].trim()
            pres   = toks[1].split(',').map (p) => p.trim()
          else if toks.length == 1
            initer = toks[0].trim()
          else
            return Madul.FIRE '!.Madul.dependency_spec.initializer.invalid', tokens[1]

        else if tokens.length == 1
          t = tokens[0].split '->'

          if t[0].indexOf('#') > -1
            r = t[0].split '#'

            root = r[0].trim()
            t[0] = r[1]

          if t.length == 2
            n = t[0].trim()

            if n[0] == '.'
              local = true
              name  = n.substring 1, n.length
            else
              local = false
              name  = n

            alias = t[1].trim()
          else if t.length == 1
            n = t[0].trim()

            if n[0] == '.'
              local = true
              name  = alias = n.substring 1, n.length
            else
              local = false
              name  = alias = n
          else
            return Madul.FIRE '!.Madul.dependency_spec.alias.invalid', tokens[1]

        else
          return Madul.FIRE '!.Madul.dependency_spec.invalid', d

        { ref: alias || name, alias, name, root, initer, pres, local }

      @BUILD_SPEC: ({ search_root, name, alias, initializer, prerequisites }) =>
        unless name?
          return Madul.FIRE '!.Madul.dependency_spec.name-required', arguments[0]

        if prerequisites? && initializer? == false
          return Madul.FIRE '!.Madul.dependency_spec.prerequisites-require-initializer', arguments[0]

        "#{if search_root?   then "#{search_root}#"            else ''}\
         #{name}\
         #{if alias?         then " -> #{alias}"               else ''}\
         #{if initializer?   then " = #{initializer}"          else ''}\
         #{if prerequisites? then ":#{prerequisites.join ','}" else ''}\
        "

      listen: (event, callback) ->
        Madul.LISTEN "*.#{@constructor.name}.#{event}", callback

      fire: (event, args) ->
        Madul.FIRE "@.#{@constructor.name}.#{event}", args

      warn: (event, details) ->
        Madul.FIRE "!.#{@constructor.name}.#{event}", details

      _report: (name, method, state, id, args) =>
        Madul.FIRE "@.#{name}.#{method}.#{state}",
          uuid:      id
          args:      args
          timestamp: microtime.now()

      _respond: (proto, method, id, deferred) =>
        (state, data) =>
          process.nextTick =>
            deferred[state] data

            proto._report proto.constructor.name, method, state, id, data

      _prep_invocation: (proto, method, input, def) =>
        id  = uuid.v4fast()
        res = proto._respond proto, method, id, def

        if Array.isArray input
          input.push (out) => res 'resolve', out
          input.push (err) => res 'reject',  err
          input.push (out) => res 'notify',  out
        else if typeof input == 'object'
          input.done   = (out) => res 'resolve', out
          input.fail   = (err) => res 'reject',  err
          input.update = (out) => res 'notify',  out

          input = [ input ]
        else
          msg = "input to #{proto.constructor.name}.#{method} must be an Array of Object"
          @warn 'input.invalid', msg
          throw new Error msg

        proto._report proto.constructor.name, method, 'invoke', id, input

        input

      _do_wrap: (proto, method) =>
        if method != 'fire' && method != 'warn' && method != 'listen'
          Madul.FIRE "$.#{proto.constructor.name}.#{method}.wrap"

          if typeof proto[method] == 'function'
            proto["_#{method}"] = proto[method]

            proto[method] = =>
              def  = q.defer()
              args = if arguments[0]? then Array.prototype.slice.call arguments else [ ]

              proto["_#{method}"].apply @, proto._prep_invocation proto, method, args, def

              def.promise
          else if typeof proto[method] == 'object'

            if Array.isArray proto[method].validate
              args_format = 'ARRAY'
              decs        = for val in proto[method].validate
                @_parse_handle(val).ref

              proto[method].validate = decs
            else if typeof proto[method].validate == 'object'
              args_format = 'OBJECT'
              decs        = for own key, val of proto[method].validate
                { ref } = @_parse_handle val
                proto[method].validate[key] = ref
                ref
            else if typeof proto[method].validate == 'string'
              args_format = 'ARRAY'
              decs        = [ @_parse_handle(proto[method].validate).ref ]
            else if typeof proto[method].validate != 'undefined'
              @warn 'meta.invalid', validate: 'must be a String, Object, or Array'
              return
            else
              args_format = 'ARRAY'
              decs        = [ ]

            decs = decs.concat(proto[method].before.map (b, i) =>
              { ref } = @_parse_handle b
              proto[method].before[i] = ref
              ref
            ) if proto[method].before?

            decs = decs.concat(proto[method].after.map (a, i) =>
              { ref } = @_parse_handle a
              proto[method].after[i] = ref
              ref
            ) if proto[method].after?

            Madul.FIRE '$.Madul.decorators.hydrate', decs

            @_do_hydrate proto, decs, =>
              proto["_#{method}"] = proto[method]

              proto[method] = =>
                def = q.defer()
                me  = proto["_#{method}"]

                if args_format == 'ARRAY'
                  args = Array.prototype.slice.call arguments

                  if me.validate?
                    validators = for val, i in me.validate
                      { ref } = @_parse_handle val
                      Madul.FIRE '$.Madul.validator.execute', "#{ref}": args[i]
                      proto[ref].EXECUTE args[i]
                else if args_format == 'OBJECT'
                  args = arguments[0]

                  if me.validate?
                    validators = for own key, val of me.validate
                      { ref } = @_parse_handle val
                      Madul.FIRE '$.Madul.validator.execute', "#{ref}": args[key]
                      proto[ref].EXECUTE args[key]
                else
                  @warn 'cannot-continue', 'No arg format specified'

                  return def.reject 'No arg format specified'

                me.before = [ ] unless me.before?
                me.after  = [ ] unless me.after?

                q.all validators
                .then =>
                  q.all me.before.map (b) =>
                    Madul.FIRE '$.Madul.before_filter.execute', "#{b}": args
                    proto[b].before args
                .then =>
                  me.behavior.apply @, @_prep_invocation proto, method, args, def
                .then (result) =>
                  if me.after.length > 0
                    q.all me.after.map (b) =>
                      Madul.FIRE '$.Madul.after_filter.execute', "#{b}": result
                      b.after result
                  else
                    d = q.defer()

                    process.nextTick => d.resolve result

                    d.promise
                .then  (out) => def.resolve out
                .catch (err) => def.reject  err

                def.promise
          else
            @warn 'cannot-wrap', method

          WRAPPED[proto.constructor.name].push method

      _wrap_methods: (proto, callback) =>
        name    = proto.constructor.name
        to_wrap = [ ]

        while proto? && Object.keys(proto).length > 0 && WRAPPED[name]? == false
          to_wrap.push { proto, name, methods: [ ] }

          for own prop, body of proto
            if prop[0]                  != '_'         &&
               typeof proto["_#{prop}"] == 'undefined' &&
               WRAP(name, prop)         == true

              continue if proto.deps? && proto.deps.indexOf(prop.replace(/_/g, '-')) > -1

              if typeof body == 'function' || typeof body?.behavior == 'function'
                to_wrap[to_wrap.length - 1].methods.push prop

          proto = proto.__proto__
          name  = proto.constructor.name

        async.each to_wrap.reverse(), (wrap, completed) =>
          async.each wrap.methods, (method, next) =>
            wrap.proto._do_wrap wrap.proto, method

            INITIALIZERS wrap.name, method if method[0] == '$'

            next()
          , => @_call_initializers_for wrap.proto, wrap.name, completed
        , callback

      _make_available: (name, mod) =>
        Madul.FIRE "$.#{name}.available"

        available[strip name] = mod

      _hydrate_deps: (proto, done) =>
        protos = [ proto ]

        if proto.__proto__?
          while proto.__proto__? && Object.keys(proto.__proto__).length > 0
            protos.push proto = proto.__proto__

        async.each protos.reverse(), (p, next) =>
          name = p.constructor.name

          if p.hasOwnProperty 'deps'
            if HYDRATED[name] == undefined
              HYDRATED[name]            = false
              HYRDATION_LISTENERS[name] = [ next ]

              p._do_hydrate p, p.deps, =>
                HYDRATED[name] = true

                for listener in HYRDATION_LISTENERS[name]
                  listener()
            else if HYDRATED[name] == false
              HYRDATION_LISTENERS[name].push next
            else if HYDRATED[name] == true
              next()
          else
            next()
        , done

      _init_if_madul: (path, callback) =>
        mod      = require path
        proto    = mod
        is_madul = false

        while proto
          is_madul = true if proto.name == 'Madul'
          if is_madul                            == false      &&
             proto.constructor.name              != 'Object'   &&
             typeof proto                        == 'function' &&
             typeof proto.__super__?.constructor == 'function'
            proto = proto.__super__.constructor
          else
            proto = undefined

        if is_madul
          new mod()
            .initialize()
            .then callback
        else
          callback mod

      _load: (me, name, path, loaded) =>
        me._init_if_madul path, (mod) =>
          me._make_available name, mod
          loaded mod

      _check: (me, path, dep, ref, finished) =>
        fs.readdir path, (err, files) =>
          if err?
            me.warn 'file-not-found', err

            done type: 'ERROR', info: err
          else
            async.each files, (f, next) =>
              depth = "#{path}/#{f}"

              fs.stat depth, (e, s) =>
                if s.isDirectory() && f[0] != '.'
                  me._check me, depth, dep, ref, next
                else if s.isFile() && f.substring(0, f.length - 3) == dep
                  me._load me, ref, depth, (mod) => me._do_add me, mod, ref, next
                else
                  next()
            , finished

      _do_add: (me, mod, ref, next) =>
        Madul.FIRE "$.#{me.constructor.name}.dependency.register", ref

        me[underscore ref] = mod

        next()

      _add: (me, ref, path, next) =>
        me._init_if_madul path, (mod) =>
          me._make_available ref, mod
          me._do_add me, mod, ref, next

      _do_hydrate: (proto, deps, hydration_complete) =>
        initers = [ ]

        async.each deps, (d, next) =>
          { ref, alias, name, root, initer, pres, local } = Madul.PARSE_SPEC d

          if pres?
            insert_at = for p in pres
              index_for = (sibling) => sibling.alias == p.alias

              initers.find index_for

            insert_at.sort()

            insert_at = if insert_at.length == 0 then 0 else insert_at[insert_at.length - 1]

            initers.splice insert_at, 0, alias: alias, execute: initer

          if proto[underscore ref]? == false
            if available[strip ref]? == true
              proto._do_add proto, available[strip ref], ref, next
            else
              if root?
                Madul.FIRE '$.Madul.search_root.load', { name, alias, root }

                @_do_hydrate proto, [ root ], =>
                  if SEARCH_ROOTS[root] == undefined
                    SEARCH_ROOTS[root] = @_find_code_root root

                  proto._check proto, SEARCH_ROOTS[root], name, ref, next
              else if local
                proto._check proto, LOCALS[proto.constructor.name], name, ref, next
              else
                try
                  proto._add proto, ref, name, next
                catch e
                  cwd = process.cwd()
                  pkg = "#{cwd}/node_modules/#{name}/package.json"

                  fs.stat pkg, (err, stat) =>
                    if stat?.isFile()
                      fs.readFile pkg, 'utf8', (err, data) =>
                        json = JSON.parse data
                        main = json.main || json._main || 'index.js'
                        path = "#{cwd}/node_modules/#{name}/#{main}"

                        proto._add proto, ref, path, next
                    else
                      proto._check proto, LOCALS[proto.constructor.name], name, ref, next
          else
            next()
        , =>
          async.eachSeries initers, (initer, next) =>
            proto[initer.execute].apply(@).then next
          , hydration_complete

      _finish_up: (proto, args) =>
        name = proto.constructor.name

        if listeners[name]?
          async.each listeners[name], (listener, next) =>
            listener @
            next()
          , => @_register_initialized name
        else
          @_register_initialized name

      _register_initialized: (name) =>
        @_make_available name, @

        initialized[name] = true

        Madul.FIRE "$.#{name}.initialized"

      _call_initializers_for: (proto, name, callback) =>
        if _INITIALIZERS[name]?
          async.each _INITIALIZERS[name], (initializer, next) =>
            if initializer.called == false
              proto[initializer.fn].apply @
                .then =>
                  initializer.called = true
                  next()
            else
              next()
          , callback
        else
          callback()

      _find_code_root: (resource) =>
        file  = resource.toLowerCase()
        found = for own key, val of require.cache
          if key.replace(/_/g, '').toLowerCase().includes file
            key.substring(0, key.lastIndexOf '/').split '/'

        found
          .filter (f) => f?
          .sort((a, b) => a.length - b.length)[0]
          .join '/'

      initialize: =>
        deferred = q.defer()
        proto    = @.__proto__
        name     = proto.constructor.name

        Madul.FIRE "$.#{name}.request_instance"

        if initialized[name] == undefined
          Madul.FIRE "$.#{name}.initialize"

          initialized[name] = false
          listeners[name]   = [ deferred.resolve ]

          if LOCALS[name] == undefined
            LOCALS[name] = @_find_code_root name

          @_hydrate_deps proto, => @_wrap_methods proto, => @_finish_up proto
        else if initialized[name] == false
          listeners[name].push deferred.resolve
        else if initialized[name] == true
          process.nextTick => deferred.resolve available[strip name]

        deferred.promise

    module.exports = Madul


Make the API doc headings consistent

Make the API doc headings consistent

# Batman.View Bindings

Batman's view bindings are how data gets shown and collected from the user. They center on the notion of "bindings": that the view representation and the JavaScript land value are always guaranteed to be in sync, such that when one changes, the other will reflect it.

## How to use bindings

Bindings are declared as attributes on nodes under the `data` namespace. In practice, it looks like this:

```html
<div data-bind="name"></div>
```

This instantiates a binding on the `div` node which will update the node's `innerHTML` with the value found at the `name` keypath in the current context. Whenever the `name` key changes, the div's `innerHTML` will update to the new value.

Nodes can have multiple bindings:

```html
<p data-bind="body" data-showif="isPublished"></p>
```

or attribute bindings:

```html
<p data-bind-id="currentID"></p>
```

and bindings can be on inputs which the user can change:

```html
<input type="text" data-bind="title"></input>
```

When the `title` property changes on the JavaScript object this `input` is bound to, the `input`'s value will be updated. When the user types into the `input` (and `change` or `keyup` events are triggered), the `title` property in JavaScript land will be updated.

## Binding Keypaths

A `keypath` is the value of the HTML attribute a binding references. Importantly, keypaths can have multiple segments:

```html
<p data-bind="order.customer.name"></p>
```

The keypath in the above HTML is `order.customer.name`. When you create a binding to a keypath like this (with dots separating segments), the binding will update the HTML value when _any_ of those segments change. In the above example, this means the `p` tag's `innerHTML` will be updated when:

 1. the order changes,
 2. the order's customer changes,
 3. or the order's customer's name changes.

This is important because it means you can rely on a binding to "just work" when anything it depends on changes. If say you had a `<select>` on the page which changed the `order`'s `customer` property, bindings which bind to `order.customer.name` will update each time you change that select to reflect the new customer's name.

## Binding Contexts

All bindings render in a context. Binding contexts, known internally to Batman as `RenderContext`s, are objects which emulate the notion of variable scope in JavaScript code. When a controller action renders, it passes a context to the view consisting of itself, the `App`, and an object with a `window` key pointing to the host `window` object.

## Keypath Filters

Bindings can bind to filtered keypaths:

```html
<p data-bind="post.body | truncate 100"></p>
```

The above `<p>` will have 100 characters worth of the post's body. Whenever the post's body changes, it will be retruncated and the `<p>`'s `innerHTML` will be updated.

Filter chains can be arbitrarily long:

```html
<span data-bind="knight.title | prepend 'Sir' | append ', the honourable'."></span>
```

and filter chains can use other keypaths as arguments to the filters:

```html
<span data-bind="person.name | prepend ' ' | prepend person.title"></span>
```

The above `<span>`'s `innerHTML` will be updated whenever the person's name or title changes.

#### Two Way Bindings and Filters

Note that filtered keypaths cannot propagate DOM land changes because values can't always be "unfiltered". For example, if we bind an input to the truncated version of a string:

```html
<input data-bind="post.body | truncate 100"></input>
```

The `<input>`'s value can be updated when the `post.body` property changes but if a user types into this input field, they will edit the truncated body. If Batman updated the `post.body` property with the contents of the input, all characters which had been truncated will be lost to the nether. To avoid this loss of information and inconsistency, bindings to filtered keypaths will _only update from JavaScript land to HTML_, and never vice versa.

## Keypath Literals

Keypaths also support a select few literals within them. Numbers, strings, and booleans can be passed as arguments to filters or used as the actual value of the keypath.

The following are all valid, albeit contrived, bindings:

```html
<!-- String literal used as an argument -->
<p data-bind="body | append ' ... '"></p>

<!-- Boolean literal used as an argument -->
<p data-showif="shouldShow | default true"></p>

<!-- Number literal used as an argument -->
<p data-bind="body | truncate 100"></p>

<!-- String literal used as the value -->
<p data-bind="'Hardcoded'"></p>

<!-- Boolean literal used as the value -->
<p data-showif="true"></p>
```

## data-bind

`data-bind` creates a two way binding between a property on a `Batman.Object` and an HTML element. Bindings created via `data-bind` will update the HTML element with the value of the JS land property as soon as they are created and each time the property changes after, and if the HTML element can be observed for changes, it will update the JS land property with the value from the HTML.

`data-bind` will change its behaviour depending on what kind of tag it is attached to:

 + `<input type="checkbox">`: the binding will edit the `checked` property of the checkbox and populate the keypath with a boolean.
 + `<input type="text">` and similar, `<textarea`>: the binding will edit the `value` property of the input and populate the keypath with the string found at `value`.
 + `<input type="file">`: the binding will _not_ edit the `value` property of the input, but it will update the keypath with a host `File` object or objects if the node has the `multiple` attribute.
 + `<select>`: the binding will edit the `selected` property of each `<option>` tag within the `<select>` matching the property at the keypath. If the `<select>` has the multiple attribute, the value at the keypath can be an array of selected `<option>` values. You can also use `data-bind-selected` bindings on the individual options to toggle option selectedness.
 + All other tags: the binding will edit the `innerHTML` property of the tag and will not populate the keypath.

`data-bind` can also be used to bind an attribute of a node to a JavaScript property. Since attributes can't be observed for changes, this is a one way binding which will never update the JavaScript land property. Specify which attribute to bind using the "double dash" syntax like so: `data-bind-attribute="some.keypath"`. For example, to bind the `placeholder` attribute of an input, use `data-bind-placeholder`.

```html
<input type="text" data-bind-placeholder="'Specify a subtitle for product ' | append product.name">
```

_Note_: `data-bind` will not update a JavaScript property if filters are used in the keypath.

## data-source

`data-source` creates a one way binding which propagates only changes from JavaScript land to the DOM, and never vice versa. `data-source` has the same semantics with regards to how it operates on different tags as `data-bind`, but it will only ever update the DOM and never the JavaScript land property.

For example, the HTML below will never update the `title` property on the product, even if the user changes it. Each time the `title` attribute changes from a `set` in JavaScript land, the value of the input will be updated to the new value of `title`, erasing any potential changes that have been made to the value of the input by the user.

```html
<input type="text" data-source="product.title">
```

_Note_: `data-source-attribute` is equivalent to `data-bind-attribute`, since the former is defined as never making JS land changes, and the latter is unable to.

## data-target

`data-target` creates a one way binding which propagates only changes from the DOM to JavaScript land, and never vice versa. `data-target` has the same semantics with regards to how it operates on different tags as `data-bind`, but it will never update the DOM even if the JavaScript land value changes.

_Note_: `data-target-attribute` is unavailable, because DOM changes to node attributes can't be monitored.

## data-showif / data-hideif

`data-showif` and `data-hideif` bind to keypaths and show or hide the node they appear on based on the truthiness of the result. `data-showif` will show a node if the given keypath evaluates to something truthy, and `data-hideif` will leave a node visible until its given keypath becomes truthy, at which point the node will be hidden. `data-showif` and `data-hideif` show and hide nodes by adding `display: none !important;` to the node's `style` attribute.

For example, if the HTML below is rendered where the keypath `product.published` evaluated to true, the `<button>` will be visible.

```html
<button data-showif="product.published">Unpublish Product</button>
```

This is the Batman equivalent of a templating language's `if` construct, where else branches are implemented using the opposite binding.

```html
<button data-showif="product.published">Unpublish Product</button>
<button data-hideif="product.published">Publish Product</button>
```

## data-addclass / data-removeclass

`data-addclass` and `data-removeclass` bindings can be used to conditionally add or remove a class from a node based on a boolean keypath. Specify the class to add using the "double dash" syntax; for example,`data-addclass-big="some.keypath"` on a node will add the "big" class to that node's classes if `some.keypath` is truthy. `data-removeclass` will remove a class (usually one which is present in the HTML) if the keypath passed to it is truthy.

The outer span in the HTML below will have an "error" class when the `product.errors.length` keypath evaluates to anything other than 0, since 0 is falsy and other numbers are truthy.

```html
<span data-addclass-error="product.errors.length">This product has <span data-bind="product.errors.length"></span> errors.</button>
```

## data-foreach

`data-foreach` is used to loop over an iterable object in Batman views. `data-foreach` duplicates the node it occurs on for each item in the collection found at the keypath given to it, and renders each duplicated node with that node's object from the collection by putting it in the context under a name passed to it using the "double dash" syntax.

The `<option>` node below will be duplicated for each item in the `Set` at the `products` keypath.

```html
<select>
  <option data-foreach-product="products" data-bind="product.name"></option>
</select>
```

Batman will execute the `data-foreach` binding before the `data-bind` on the `<option>` node, which means that the `data-bind` will be processed for each duplicated node with each separate Product in the `products` Set in scope for each separate node. If there were say 3 Products in the `products` set, the HTML would look similar to this once rendered:

```html
<select>
  <option data-bind="product.name">Product A</option>
  <option data-bind="product.name">Product B</option>
  <option data-bind="product.name">Product C</option>
  <!-- end products -->
</select>
```

`data-foreach` can be used to iterate over `Batman.Set`s, and most often should be, because it observes any Sets and will update the DOM with new nodes if items are added to the set, or remove nodes from the DOM if their corresponding nodes are removed from the set. `data-foreach`, like every other binding, is keypath aware, such that if the `Set` instance at the keypath changes, or any previous segment of the keypath changes, `data-foreach` will remove all the nodes currently in the DOM, and add new nodes for each new item in the incoming `Set`.

Sometimes you'll need to add some custom logic to the iteration nodes. For example, a custom `viewDidAppear` handler so you can know whenever a new iteration node appears in the DOM. You can do this by specifying a custom subclass of `Batman.IterationView`.

```html
<ul>
  <li data-foreach-product="products" data-view="ProductIterationView">
    <span data-bind="product.name"></span>
  </li>
</ul>
```

```coffeescript
class MyApp.ProductIterationView extends Batman.IterationView
  viewDidAppear: ->
    $(@get('node')).draggable()
```

_Note_: `data-foreach` expects to find an iterable object at the keypath given to it, and will emit a warning if it finds `undefined`.

_Note_: `data-foreach` expects the passed enumerable to be unique. It creates a map of nodes to items, so every node needs to be able to reference exactly one object. If you simply have a set of values that you're iterating over, you should wrap your values in objects, e.g. `[{value: true}, {value: true}]`.

## data-formfor

`data-formfor` creates a special addition to the context stack to represent an object under edit within a form. Usually this object is a model. Using the double dash syntax, the name for the model to reside under can be specified.

==== Automatic Validation Display

`data-formfor` also has some handy functionality for displaying the result of validating the object under edit in the form. This will only be enabled if the object has an `errors` Set, like `Batman.Models` do.

If a tag matching the relative selector `.errors` is found, it will populate this element with a list of the errors found during validation on the object. The selector for the errors container can be changed by adding a `data-errors-list` attribute with the value of the selector to the form with the `data-formfor` binding on it, or editing `Batman.DOM.FormBinding::defaultErrorsListSelector`.

If value bindings are made using `data-bind` to attributes on the model within the form, automatic `data-addclass-error` bindings will be added to the elements on which the `data-bind` occurs to add the "error" class when the model has errors on the attribute which `data-bind` binds to.

In the HTML below, an automatic `data-addclass-error` will be added to the `<input>` which activates when the `product` model has validation errors on the `name` attribute.

```html
<form data-formfor-product="currentProduct">
  <input type="text" data-bind="product.name"></input>
</form>
```

The class which gets automatically added to inputs binding to invalid attributes can be customized by editing `Batman.DOM.FormBinding::errorClass`.

## data-context

`data-context` bindings add the object found at the key to the context stack, optionally under a key using the double dash syntax.

For example, if a `product` object exists in the current context, the `data-context` binding below will expose its attributes at the root level of the context:

```html
<div data-context="product">
  <span data-bind="name"></span>
  <span data-bind="cost"></span>
</div>
```

Contexts added to the stack can also be scoped under a key using `data-context-`:

```html
<div data-context-currentProduct="product">
  <span data-bind="currentProduct"></span>
  <span data-bind="currentProduct"></span>
</div>
```

This is a useful mechanism for passing local variables to partial views.

## data-event

`data-event` bindings add DOM event listeners to the nodes they exist on which call the function found at the passed keypath. `data-event` bindings use the double dash syntax to specify the name of the event to listen for.

In the HTML below, if the keypath `controller.nextAction` resolves to a function, that function will be executed each time the `<button>` element is clicked.

```html
<button data-event-click="controller.nextAction"></button>
```

Functions which `data-event` calls will be passed the node and the `DOMEvent` object: `(node, event) ->`.

`data-event` supports the following types of events formally and should "do the right thing" when attached to elements which fire these events:

 + click
 + doubleclick
 + change
 + submit

If the event name used doesn't match the above events, the event name used will just fall through and be passed to `window.addEventListener`.

## data-route

`data-route` bindings are used to dispatch a new controller action upon the clicking of the node they bind to. `data-route` expects to find either a string or a `NamedRouteQuery` at the keypath passed to it. With this route, it will add an event handler to the `click` action of the element which dispatches the route and prevents the default action of the DOMEvent. `data-route` will also populate the `href` attribute if it occurs on an `<a>` tag so that other functons like "Copy Link Address" and Alt+Click continue to work on the link.

The first way to use `data-route` is by passing it a string, which can be built using filters or an accessor, but the preferred way is to use the `NamedRouteQuery`. These objects are generated for you by starting keypaths at the `App.routes` property. All `Batman.App`s have a `routes` property which holds a nested list of all the routes, which you descend into by passing various key segments and objects. Since the `App` object is present in the default context stack, `data-route` keypaths can just start with `routes`.

For example, assume the following routes definition in the current `Batman.App`:

```coffeescript
class Alfred extends Batman.App
  @resources 'todos'
```

This means that routes like `/todos` and `/todos/:id` exist. To route to the collection action, use the plural name of the resource:

```html
<a data-route="routes.todos"></a>
```

To route to an individual todo things get a bit more complicated. If we have a Todo model with ID# `42` in the context as `todo`, use the `get` filter shorthand on the `NamedRouteQuery` returned by `routes.todos` to generate a member route:

```html
<a data-route="routes.todos[todo]"></a>
```

Underneath, this is calling `Alfred.get('routes.todos').get(todo)`; the todo object is being passed as a key to the `NamedRouteQuery`, which knows how to generate a member route when given a record. The above HTML when rendered will look like this:

```html
<a data-route="routes.todos[todo]" href="/todos/42"></a>
```

This syntax can be extended to nested routes. If we have nested routes, we can use chained gets to generated nested routes

```coffeescript
class Tracker extends Batman.App
  @resources 'villains', ->
    @resources 'crimes'
```

Routes for collection and member crimes should look like `/villains/:villain_id/crimes` and `/villains/:villain_id/crimes/:id` respectively. Assuming the presence of a `villain` and a `crime` in the context, chained `get`s on `NamedRouteQuery`s achieve this:

```html
<!-- Collection of crimes for a particular villain -->
<a data-route="routes.villains[villain].crimes"></a>
<!-- One crime of a particular villain -->
<a data-route="routes.villains[villain].crimes[crime]"></a>
```

_Note_: `data-route` bindings route only to internal dispatch, and not external links. Use a regular `<a>` tag to link away from the application.

## data-view

`data-view` bindings attach custom `Batman.View` instances or instantiate custom `View` subclasses to / on a node. `data-view` expects either a `Batman.View` instance or subclass at the keypath passed to it. If an instance is passed, it will `set` the `node` property of the view to the node the `data-view` occurs on. If a class is passed, that class will be instantiated with the context the `data-view` binding executed in and with the node it occurred upon. See `Batman.View` for more information on custom Views and their uses.

_Note_: `data-view` bindings will bind to the passed keypath until it exists, that is to say until the value of it is not `undefined`. After the `View` has been set up, the `data-view` binding will remove itself and stop observing the keypath.

## data-partial

`data-partial` pulls in a partial template and renders it in the current context of the node the `data-partial` occurs in. `data-partial` expects the name of the view to render in the value of the HTML attribute. __Warning__: This value is not a keypath. The HTML attribute's value is interpreted as a string, and the template which resides at that view path will be rendered.

If we have this HTML at `views/villains/_stub.html` in our app:

```html
<span data-bind="villain.name"></span>
```

and in `views/villains/show.html` we have this HTML:

```html
<h1>A villain!</h1>
<div data-partial="villains/_stub"></div>
```

the contents of the `stub` partial will be inserted and rendered in the `<div>` above.

## data-mixin

## data-defineview

## data-renderif

## data-yield

## data-contentfor

## data-replace

# Batman.View Filters

## raw(value) : string

The `raw` filter renders the unescaped value.

```html
<span data-bind="someHTMLyString | raw"></span>
```

## get(value, key) : value

## value[key] : value

Shorthand for the `get` filter.

## equals(left, right) : boolean

## not(value) : boolean

## matches(value, string) : boolean

## truncate(value, length, end = '...') : string

## default(value, defaultValue) : value

## prepend(value, string) : string

## append(value, string) : string

## replace(value, searchString, replaceString[, flags]) : string

## downcase(value) : string

## upcase(value) : string

## pluralize(value, count) : string

## humanize(string) : string

## join(value, separator = '') : string

## sort(value) : value

## map(iterable) : value

## has(iterable, item) : boolean

## first(iterable) : value

## meta(value, keypath) : value

## interpolate(string, valuesObject) : string

## withArguments(function, curriedArguments...) : function

## routeToAction(model, action) : string

## escape(value) : string

# Batman View Bindings

Batman's view bindings are how data gets shown and collected from the user. They center on the notion of "bindings": that the view representation and the JavaScript land value are always guaranteed to be in sync, such that when one changes, the other will reflect it.

## How to use bindings

Bindings are declared as attributes on nodes under the `data` namespace. In practice, it looks like this:

```html
<div data-bind="name"></div>
```

This instantiates a binding on the `div` node which will update the node's `innerHTML` with the value found at the `name` keypath in the current context. Whenever the `name` key changes, the div's `innerHTML` will update to the new value.

Nodes can have multiple bindings:

```html
<p data-bind="body" data-showif="isPublished"></p>
```

or attribute bindings:

```html
<p data-bind-id="currentID"></p>
```

and bindings can be on inputs which the user can change:

```html
<input type="text" data-bind="title"></input>
```

When the `title` property changes on the JavaScript object this `input` is bound to, the `input`'s value will be updated. When the user types into the `input` (and `change` or `keyup` events are triggered), the `title` property in JavaScript land will be updated.

## Binding Keypaths

A `keypath` is the value of the HTML attribute a binding references. Importantly, keypaths can have multiple segments:

```html
<p data-bind="order.customer.name"></p>
```

The keypath in the above HTML is `order.customer.name`. When you create a binding to a keypath like this (with dots separating segments), the binding will update the HTML value when _any_ of those segments change. In the above example, this means the `p` tag's `innerHTML` will be updated when:

 1. the order changes,
 2. the order's customer changes,
 3. or the order's customer's name changes.

This is important because it means you can rely on a binding to "just work" when anything it depends on changes. If say you had a `<select>` on the page which changed the `order`'s `customer` property, bindings which bind to `order.customer.name` will update each time you change that select to reflect the new customer's name.

## Binding Contexts

All bindings render in a context. Binding contexts, known internally to Batman as `RenderContext`s, are objects which emulate the notion of variable scope in JavaScript code. When a controller action renders, it passes a context to the view consisting of itself, the `App`, and an object with a `window` key pointing to the host `window` object.

## Keypath Filters

Bindings can bind to filtered keypaths:

```html
<p data-bind="post.body | truncate 100"></p>
```

The above `<p>` will have 100 characters worth of the post's body. Whenever the post's body changes, it will be retruncated and the `<p>`'s `innerHTML` will be updated.

Filter chains can be arbitrarily long:

```html
<span data-bind="knight.title | prepend 'Sir' | append ', the honourable'."></span>
```

and filter chains can use other keypaths as arguments to the filters:

```html
<span data-bind="person.name | prepend ' ' | prepend person.title"></span>
```

The above `<span>`'s `innerHTML` will be updated whenever the person's name or title changes.

#### Two Way Bindings and Filters

Note that filtered keypaths cannot propagate DOM land changes because values can't always be "unfiltered". For example, if we bind an input to the truncated version of a string:

```html
<input data-bind="post.body | truncate 100"></input>
```

The `<input>`'s value can be updated when the `post.body` property changes but if a user types into this input field, they will edit the truncated body. If Batman updated the `post.body` property with the contents of the input, all characters which had been truncated will be lost to the nether. To avoid this loss of information and inconsistency, bindings to filtered keypaths will _only update from JavaScript land to HTML_, and never vice versa.

## Keypath Literals

Keypaths also support a select few literals within them. Numbers, strings, and booleans can be passed as arguments to filters or used as the actual value of the keypath.

The following are all valid, albeit contrived, bindings:

```html
<!-- String literal used as an argument -->
<p data-bind="body | append ' ... '"></p>

<!-- Boolean literal used as an argument -->
<p data-showif="shouldShow | default true"></p>

<!-- Number literal used as an argument -->
<p data-bind="body | truncate 100"></p>

<!-- String literal used as the value -->
<p data-bind="'Hardcoded'"></p>

<!-- Boolean literal used as the value -->
<p data-showif="true"></p>
```

## data-bind

`data-bind` creates a two way binding between a property on a `Batman.Object` and an HTML element. Bindings created via `data-bind` will update the HTML element with the value of the JS land property as soon as they are created and each time the property changes after, and if the HTML element can be observed for changes, it will update the JS land property with the value from the HTML.

`data-bind` will change its behaviour depending on what kind of tag it is attached to:

 + `<input type="checkbox">`: the binding will edit the `checked` property of the checkbox and populate the keypath with a boolean.
 + `<input type="text">` and similar, `<textarea`>: the binding will edit the `value` property of the input and populate the keypath with the string found at `value`.
 + `<input type="file">`: the binding will _not_ edit the `value` property of the input, but it will update the keypath with a host `File` object or objects if the node has the `multiple` attribute.
 + `<select>`: the binding will edit the `selected` property of each `<option>` tag within the `<select>` matching the property at the keypath. If the `<select>` has the multiple attribute, the value at the keypath can be an array of selected `<option>` values. You can also use `data-bind-selected` bindings on the individual options to toggle option selectedness.
 + All other tags: the binding will edit the `innerHTML` property of the tag and will not populate the keypath.

`data-bind` can also be used to bind an attribute of a node to a JavaScript property. Since attributes can't be observed for changes, this is a one way binding which will never update the JavaScript land property. Specify which attribute to bind using the "double dash" syntax like so: `data-bind-attribute="some.keypath"`. For example, to bind the `placeholder` attribute of an input, use `data-bind-placeholder`.

```html
<input type="text" data-bind-placeholder="'Specify a subtitle for product ' | append product.name">
```

_Note_: `data-bind` will not update a JavaScript property if filters are used in the keypath.

## data-source

`data-source` creates a one way binding which propagates only changes from JavaScript land to the DOM, and never vice versa. `data-source` has the same semantics with regards to how it operates on different tags as `data-bind`, but it will only ever update the DOM and never the JavaScript land property.

For example, the HTML below will never update the `title` property on the product, even if the user changes it. Each time the `title` attribute changes from a `set` in JavaScript land, the value of the input will be updated to the new value of `title`, erasing any potential changes that have been made to the value of the input by the user.

```html
<input type="text" data-source="product.title">
```

_Note_: `data-source-attribute` is equivalent to `data-bind-attribute`, since the former is defined as never making JS land changes, and the latter is unable to.

## data-target

`data-target` creates a one way binding which propagates only changes from the DOM to JavaScript land, and never vice versa. `data-target` has the same semantics with regards to how it operates on different tags as `data-bind`, but it will never update the DOM even if the JavaScript land value changes.

_Note_: `data-target-attribute` is unavailable, because DOM changes to node attributes can't be monitored.

## data-showif / data-hideif

`data-showif` and `data-hideif` bind to keypaths and show or hide the node they appear on based on the truthiness of the result. `data-showif` will show a node if the given keypath evaluates to something truthy, and `data-hideif` will leave a node visible until its given keypath becomes truthy, at which point the node will be hidden. `data-showif` and `data-hideif` show and hide nodes by adding `display: none !important;` to the node's `style` attribute.

For example, if the HTML below is rendered where the keypath `product.published` evaluated to true, the `<button>` will be visible.

```html
<button data-showif="product.published">Unpublish Product</button>
```

This is the Batman equivalent of a templating language's `if` construct, where else branches are implemented using the opposite binding.

```html
<button data-showif="product.published">Unpublish Product</button>
<button data-hideif="product.published">Publish Product</button>
```

## data-addclass / data-removeclass

`data-addclass` and `data-removeclass` bindings can be used to conditionally add or remove a class from a node based on a boolean keypath. Specify the class to add using the "double dash" syntax; for example,`data-addclass-big="some.keypath"` on a node will add the "big" class to that node's classes if `some.keypath` is truthy. `data-removeclass` will remove a class (usually one which is present in the HTML) if the keypath passed to it is truthy.

The outer span in the HTML below will have an "error" class when the `product.errors.length` keypath evaluates to anything other than 0, since 0 is falsy and other numbers are truthy.

```html
<span data-addclass-error="product.errors.length">This product has <span data-bind="product.errors.length"></span> errors.</button>
```

## data-foreach

`data-foreach` is used to loop over an iterable object in Batman views. `data-foreach` duplicates the node it occurs on for each item in the collection found at the keypath given to it, and renders each duplicated node with that node's object from the collection by putting it in the context under a name passed to it using the "double dash" syntax.

The `<option>` node below will be duplicated for each item in the `Set` at the `products` keypath.

```html
<select>
  <option data-foreach-product="products" data-bind="product.name"></option>
</select>
```

Batman will execute the `data-foreach` binding before the `data-bind` on the `<option>` node, which means that the `data-bind` will be processed for each duplicated node with each separate Product in the `products` Set in scope for each separate node. If there were say 3 Products in the `products` set, the HTML would look similar to this once rendered:

```html
<select>
  <option data-bind="product.name">Product A</option>
  <option data-bind="product.name">Product B</option>
  <option data-bind="product.name">Product C</option>
  <!-- end products -->
</select>
```

`data-foreach` can be used to iterate over `Batman.Set`s, and most often should be, because it observes any Sets and will update the DOM with new nodes if items are added to the set, or remove nodes from the DOM if their corresponding nodes are removed from the set. `data-foreach`, like every other binding, is keypath aware, such that if the `Set` instance at the keypath changes, or any previous segment of the keypath changes, `data-foreach` will remove all the nodes currently in the DOM, and add new nodes for each new item in the incoming `Set`.

Sometimes you'll need to add some custom logic to the iteration nodes. For example, a custom `viewDidAppear` handler so you can know whenever a new iteration node appears in the DOM. You can do this by specifying a custom subclass of `Batman.IterationView`.

```html
<ul>
  <li data-foreach-product="products" data-view="ProductIterationView">
    <span data-bind="product.name"></span>
  </li>
</ul>
```

```coffeescript
class MyApp.ProductIterationView extends Batman.IterationView
  viewDidAppear: ->
    $(@get('node')).draggable()
```

_Note_: `data-foreach` expects to find an iterable object at the keypath given to it, and will emit a warning if it finds `undefined`.

_Note_: `data-foreach` expects the passed enumerable to be unique. It creates a map of nodes to items, so every node needs to be able to reference exactly one object. If you simply have a set of values that you're iterating over, you should wrap your values in objects, e.g. `[{value: true}, {value: true}]`.

## data-formfor

`data-formfor` creates a special addition to the context stack to represent an object under edit within a form. Usually this object is a model. Using the double dash syntax, the name for the model to reside under can be specified.

==== Automatic Validation Display

`data-formfor` also has some handy functionality for displaying the result of validating the object under edit in the form. This will only be enabled if the object has an `errors` Set, like `Batman.Models` do.

If a tag matching the relative selector `.errors` is found, it will populate this element with a list of the errors found during validation on the object. The selector for the errors container can be changed by adding a `data-errors-list` attribute with the value of the selector to the form with the `data-formfor` binding on it, or editing `Batman.DOM.FormBinding::defaultErrorsListSelector`.

If value bindings are made using `data-bind` to attributes on the model within the form, automatic `data-addclass-error` bindings will be added to the elements on which the `data-bind` occurs to add the "error" class when the model has errors on the attribute which `data-bind` binds to.

In the HTML below, an automatic `data-addclass-error` will be added to the `<input>` which activates when the `product` model has validation errors on the `name` attribute.

```html
<form data-formfor-product="currentProduct">
  <input type="text" data-bind="product.name"></input>
</form>
```

The class which gets automatically added to inputs binding to invalid attributes can be customized by editing `Batman.DOM.FormBinding::errorClass`.

## data-context

`data-context` bindings add the object found at the key to the context stack, optionally under a key using the double dash syntax.

For example, if a `product` object exists in the current context, the `data-context` binding below will expose its attributes at the root level of the context:

```html
<div data-context="product">
  <span data-bind="name"></span>
  <span data-bind="cost"></span>
</div>
```

Contexts added to the stack can also be scoped under a key using `data-context-`:

```html
<div data-context-currentProduct="product">
  <span data-bind="currentProduct"></span>
  <span data-bind="currentProduct"></span>
</div>
```

This is a useful mechanism for passing local variables to partial views.

## data-event

`data-event` bindings add DOM event listeners to the nodes they exist on which call the function found at the passed keypath. `data-event` bindings use the double dash syntax to specify the name of the event to listen for.

In the HTML below, if the keypath `controller.nextAction` resolves to a function, that function will be executed each time the `<button>` element is clicked.

```html
<button data-event-click="controller.nextAction"></button>
```

Functions which `data-event` calls will be passed the node and the `DOMEvent` object: `(node, event) ->`.

`data-event` supports the following types of events formally and should "do the right thing" when attached to elements which fire these events:

 + click
 + doubleclick
 + change
 + submit

If the event name used doesn't match the above events, the event name used will just fall through and be passed to `window.addEventListener`.

## data-route

`data-route` bindings are used to dispatch a new controller action upon the clicking of the node they bind to. `data-route` expects to find either a string or a `NamedRouteQuery` at the keypath passed to it. With this route, it will add an event handler to the `click` action of the element which dispatches the route and prevents the default action of the DOMEvent. `data-route` will also populate the `href` attribute if it occurs on an `<a>` tag so that other functons like "Copy Link Address" and Alt+Click continue to work on the link.

The first way to use `data-route` is by passing it a string, which can be built using filters or an accessor, but the preferred way is to use the `NamedRouteQuery`. These objects are generated for you by starting keypaths at the `App.routes` property. All `Batman.App`s have a `routes` property which holds a nested list of all the routes, which you descend into by passing various key segments and objects. Since the `App` object is present in the default context stack, `data-route` keypaths can just start with `routes`.

For example, assume the following routes definition in the current `Batman.App`:

```coffeescript
class Alfred extends Batman.App
  @resources 'todos'
```

This means that routes like `/todos` and `/todos/:id` exist. To route to the collection action, use the plural name of the resource:

```html
<a data-route="routes.todos"></a>
```

To route to an individual todo things get a bit more complicated. If we have a Todo model with ID# `42` in the context as `todo`, use the `get` filter shorthand on the `NamedRouteQuery` returned by `routes.todos` to generate a member route:

```html
<a data-route="routes.todos[todo]"></a>
```

Underneath, this is calling `Alfred.get('routes.todos').get(todo)`; the todo object is being passed as a key to the `NamedRouteQuery`, which knows how to generate a member route when given a record. The above HTML when rendered will look like this:

```html
<a data-route="routes.todos[todo]" href="/todos/42"></a>
```

This syntax can be extended to nested routes. If we have nested routes, we can use chained gets to generated nested routes

```coffeescript
class Tracker extends Batman.App
  @resources 'villains', ->
    @resources 'crimes'
```

Routes for collection and member crimes should look like `/villains/:villain_id/crimes` and `/villains/:villain_id/crimes/:id` respectively. Assuming the presence of a `villain` and a `crime` in the context, chained `get`s on `NamedRouteQuery`s achieve this:

```html
<!-- Collection of crimes for a particular villain -->
<a data-route="routes.villains[villain].crimes"></a>
<!-- One crime of a particular villain -->
<a data-route="routes.villains[villain].crimes[crime]"></a>
```

_Note_: `data-route` bindings route only to internal dispatch, and not external links. Use a regular `<a>` tag to link away from the application.

## data-view

`data-view` bindings attach custom `Batman.View` instances or instantiate custom `View` subclasses to / on a node. `data-view` expects either a `Batman.View` instance or subclass at the keypath passed to it. If an instance is passed, it will `set` the `node` property of the view to the node the `data-view` occurs on. If a class is passed, that class will be instantiated with the context the `data-view` binding executed in and with the node it occurred upon. See `Batman.View` for more information on custom Views and their uses.

_Note_: `data-view` bindings will bind to the passed keypath until it exists, that is to say until the value of it is not `undefined`. After the `View` has been set up, the `data-view` binding will remove itself and stop observing the keypath.

## data-partial

`data-partial` pulls in a partial template and renders it in the current context of the node the `data-partial` occurs in. `data-partial` expects the name of the view to render in the value of the HTML attribute. __Warning__: This value is not a keypath. The HTML attribute's value is interpreted as a string, and the template which resides at that view path will be rendered.

If we have this HTML at `views/villains/_stub.html` in our app:

```html
<span data-bind="villain.name"></span>
```

and in `views/villains/show.html` we have this HTML:

```html
<h1>A villain!</h1>
<div data-partial="villains/_stub"></div>
```

the contents of the `stub` partial will be inserted and rendered in the `<div>` above.

## data-mixin

## data-defineview

## data-renderif

## data-yield

## data-contentfor

## data-replace

# Batman View Filters

## raw(value) : string

The `raw` filter renders the unescaped value.

```html
<span data-bind="someHTMLyString | raw"></span>
```

## get(value, key) : value

## value[key] : value

Shorthand for the `get` filter.

## equals(left, right) : boolean

## not(value) : boolean

## matches(value, string) : boolean

## truncate(value, length, end = '...') : string

## default(value, defaultValue) : value

## prepend(value, string) : string

## append(value, string) : string

## replace(value, searchString, replaceString[, flags]) : string

## downcase(value) : string

## upcase(value) : string

## pluralize(value, count) : string

## humanize(string) : string

## join(value, separator = '') : string

## sort(value) : value

## map(iterable) : value

## has(iterable, item) : boolean

## first(iterable) : value

## meta(value, keypath) : value

## interpolate(string, valuesObject) : string

## withArguments(function, curriedArguments...) : function

## routeToAction(model, action) : string

## escape(value) : string


model values getter

model values getter

Copyright 2014 - 2015
Author: Varuna Jayasiri http://blog.varunajayasiri.com

#Model Base

    Mod.require 'Weya',
     'Models.Properties'
     'Models.Util'
     (Weya, PROPERTIES, UTIL) ->

Class

      class Model
       _initialize: []
       _properties: {}
       _requiredFunctions: {}
       on: {}

       @extend: ->
        @::_initialize = @::_initialize.slice()
        @::_properties = UTIL.extend {}, @::_properties
        @::_requiredFunctions = UTIL.extend {}, @::_requiredFunctions
        @::on = UTIL.extend {}, @::on

       @include: (obj) ->
        if not obj?
         throw new Error 'Cannot include a null object'
        for k, v of obj
         switch k
          when 'initialize'
           @::_initialize.push v
          when 'property'
           for name, obj of v
            @_addProperty name, obj
          when 'requireFunction'
           for name, desc of v
            @::_requiredFunctions[name] = desc
          when 'on'
           for event, listener of v
            if not @::on[event]?
             @::on[event] = listener
          else
           @prototype[k] = v

        return null

 Initialize variables.

       @initialize: (func) ->
        @::_initialize.push func

Add listener

       @listen: (name, func) ->
        @::on[name] = func

Register a property

       @property: (name, obj) ->
        if (typeof name) is 'string'
         @_addProperty name, obj
        else
         objs = name
         for name, obj of objs
          @_addProperty name, obj

       @_addProperty: (name, obj) ->
        if (typeof name) isnt 'string'
         throw new Error "Property name not a string: #{name}"
        if (typeof obj) isnt 'object'
         throw new Error "Property not an object: #{name}"

        @::_properties[name] = PROPERTIES.create obj, name

       @requireFunction: (name, desc) ->
        if (typeof name) is 'string'
         @::_requiredFunctions[name] = desc
        else
         obj = name
         for name, desc of obj
          @::_requiredFunctions[name] = desc

Check properties

       @check: ->
        if not @::type?
         throw new Error "Object type not defined"
        type = @::type

        mentioned =
         type: true
        for func, desc of @::_requiredFunctions
         mentioned[func] = true
         if not @::[func]?
          throw new Error "#{type}: Function not defined: #{func} - #{desc}"
         if (typeof @::[func]) isnt 'function'
          throw new Error "#{type}: Not a function: #{func} - #{desc}"

        extra = []
        for k of this.prototype
         continue if k in ['on', 'values']
         if not mentioned[k]?
          if k[0] isnt '_'
           extra.push k

        if extra.length > 0
         console.error type, extra

        @::_checked = true

Get values

       @::__defineGetter__ 'values', -> @_values

       constructor: ->
        @initialize.apply this, arguments

##Override

##Initialize

       initialize: (options) ->
        if @_checked isnt on
         throw new Error "Object #{@type} wasnt checked"

        @_bindEvents()

        for init in @_initialize
         init.call this

       @requireFunction
        'initialize': 'Initialize'
        'parse': 'Parse'
        'render': 'Render element'
        'weya': 'Render weya template'
        'html': 'Render html'
        'template': 'Render template'
        'toJSON': 'To JSON'
        'toJSONFull': 'To JSON Full'
        'isDefault': 'Is default value'
        'edit': 'Render editor'
        'valueChanged': 'A property value change event'

##Public functions

       parse: (data, stack = []) ->
        stack = stack.slice 0
        stack.push this
        excess = 0
        @_errors = []
        fields = 0
        @_score = 0
        @_values = {}

        for name of data when not @_properties[name]?
         @_errors.push ": #{name} excess"
         excess++

        for name, prop of @_properties
         fields++
         r = prop.parse data[name], stack
         @_values[name] = r.value
         if not prop.isDefault r.value, stack
          @_score += r.score
         for e in r.errors
          @_errors.push "#{name}(#{@type})/#{e}"

        if fields is 0
         @_score = (if excess > 0 then 0 else 1)
        else
         @_score = (@_score - excess) / fields
        @_score = 0 if @_score < 0
        if @_score > 1
         throw new Error "Score greater than 1: #{score}"

        return {
         score: @_score,
         value: this
         errors: @_errors
        }

       weya: (weya, stack = []) ->
        @template.call weya, this, stack

       render: (elem, stack = []) ->
        self = this
        Weya elem: elem, ->
         self.weya this, stack

       html: (stack = []) ->
        self = this
        Weya.markup {}, ->
         self.weya this, stack

       toJSON: (stack = [])->
        stack = stack.slice 0
        stack.push this
        data = {}
        for name, prop of @_properties
         v = prop.toJSON @_values[name], stack
         if not prop.isDefault v, stack
          data[name] = v

        return data

       toJSONFull: (stack = []) ->
        stack = stack.slice 0
        stack.push this
        data = {}
        for name, prop of @_properties
         data[name] = prop.toJSONFull @_values[name], stack

        return data

       isDefault: (stack = []) ->
        stack = stack.slice 0
        stack.push this
        for name, prop of @_properties
         v = prop.toJSON @_values[name]
         if not prop.isDefault v, stack
          return false

        return true

       edit: (elem, changed, stack = []) ->
        stack = stack.slice 0
        stack.push this
        @onChanged = changed
        @_editElems = {}
        Weya elem: elem, context: this, ->
         for name, prop of @$._properties
          @div ".property.property-type-#{prop.propertyType}", ->
           @span ".property-name", name
           @$._editElems[name] = @div ".property-value", ""

        for name, prop of @_properties
         prop.edit @_editElems[name], @_values[name],
          @valueChanged.bind self: this, name: name
          stack

       valueChanged: (value, changed) ->
        @self._values[@name] = value
        @self.onChanged @self, false

##Private functions

Bind

       _bindEvents: ->
        events = @on
        @on = {}
        for k, v of events
         @on[k] = v.bind this

      Mod.set 'Models.Model.Base', Model

Copyright 2014 - 2015
Author: Varuna Jayasiri http://blog.varunajayasiri.com

#Model Base

    Mod.require 'Weya',
     'Models.Properties'
     'Models.Util'
     (Weya, PROPERTIES, UTIL) ->

Class

      class Model
       _initialize: []
       _properties: {}
       _requiredFunctions: {}
       on: {}

       @extend: ->
        @::_initialize = @::_initialize.slice()
        @::_properties = UTIL.extend {}, @::_properties
        @::_requiredFunctions = UTIL.extend {}, @::_requiredFunctions
        @::on = UTIL.extend {}, @::on

       @include: (obj) ->
        if not obj?
         throw new Error 'Cannot include a null object'
        for k, v of obj
         switch k
          when 'initialize'
           @::_initialize.push v
          when 'property'
           for name, obj of v
            @_addProperty name, obj
          when 'requireFunction'
           for name, desc of v
            @::_requiredFunctions[name] = desc
          when 'on'
           for event, listener of v
            if not @::on[event]?
             @::on[event] = listener
          else
           @prototype[k] = v

        return null

 Initialize variables.

       @initialize: (func) ->
        @::_initialize.push func

Add listener

       @listen: (name, func) ->
        @::on[name] = func

Register a property

       @property: (name, obj) ->
        if (typeof name) is 'string'
         @_addProperty name, obj
        else
         objs = name
         for name, obj of objs
          @_addProperty name, obj

       @_addProperty: (name, obj) ->
        if (typeof name) isnt 'string'
         throw new Error "Property name not a string: #{name}"
        if (typeof obj) isnt 'object'
         throw new Error "Property not an object: #{name}"

        @::_properties[name] = PROPERTIES.create obj, name

       @requireFunction: (name, desc) ->
        if (typeof name) is 'string'
         @::_requiredFunctions[name] = desc
        else
         obj = name
         for name, desc of obj
          @::_requiredFunctions[name] = desc

Check properties

       @check: ->
        if not @::type?
         throw new Error "Object type not defined"
        type = @::type

        mentioned =
         type: true
        for func, desc of @::_requiredFunctions
         mentioned[func] = true
         if not @::[func]?
          throw new Error "#{type}: Function not defined: #{func} - #{desc}"
         if (typeof @::[func]) isnt 'function'
          throw new Error "#{type}: Not a function: #{func} - #{desc}"

        extra = []
        for k of this.prototype
         continue if k is 'on'
         if not mentioned[k]?
          if k[0] isnt '_'
           extra.push k

        if extra.length > 0
         console.error type, extra

        @::_checked = true

       constructor: ->
        @initialize.apply this, arguments

##Override

##Initialize

       initialize: (options) ->
        if @_checked isnt on
         throw new Error "Object #{@type} wasnt checked"

        @_bindEvents()

        for init in @_initialize
         init.call this

       @requireFunction
        'initialize': 'Initialize'
        'parse': 'Parse'
        'render': 'Render element'
        'weya': 'Render weya template'
        'html': 'Render html'
        'template': 'Render template'
        'toJSON': 'To JSON'
        'toJSONFull': 'To JSON Full'
        'isDefault': 'Is default value'
        'edit': 'Render editor'
        'valueChanged': 'A property value change event'

##Public functions

       parse: (data, stack = []) ->
        stack = stack.slice 0
        stack.push this
        excess = 0
        @_errors = []
        fields = 0
        @_score = 0
        @_values = {}

        for name of data when not @_properties[name]?
         @_errors.push ": #{name} excess"
         excess++

        for name, prop of @_properties
         fields++
         r = prop.parse data[name], stack
         @_values[name] = r.value
         if not prop.isDefault r.value, stack
          @_score += r.score
         for e in r.errors
          @_errors.push "#{name}(#{@type})/#{e}"

        if fields is 0
         @_score = (if excess > 0 then 0 else 1)
        else
         @_score = (@_score - excess) / fields
        @_score = 0 if @_score < 0
        if @_score > 1
         throw new Error "Score greater than 1: #{score}"

        return {
         score: @_score,
         value: this
         errors: @_errors
        }

       weya: (weya, stack = []) ->
        @template.call weya, this, stack

       render: (elem, stack = []) ->
        self = this
        Weya elem: elem, ->
         self.weya this, stack

       html: (stack = []) ->
        self = this
        Weya.markup {}, ->
         self.weya this, stack

       toJSON: (stack = [])->
        stack = stack.slice 0
        stack.push this
        data = {}
        for name, prop of @_properties
         v = prop.toJSON @_values[name], stack
         if not prop.isDefault v, stack
          data[name] = v

        return data

       toJSONFull: (stack = []) ->
        stack = stack.slice 0
        stack.push this
        data = {}
        for name, prop of @_properties
         data[name] = prop.toJSONFull @_values[name], stack

        return data

       isDefault: (stack = []) ->
        stack = stack.slice 0
        stack.push this
        for name, prop of @_properties
         v = prop.toJSON @_values[name]
         if not prop.isDefault v, stack
          return false

        return true

       edit: (elem, changed, stack = []) ->
        stack = stack.slice 0
        stack.push this
        @onChanged = changed
        @_editElems = {}
        Weya elem: elem, context: this, ->
         for name, prop of @$._properties
          @div ".property.property-type-#{prop.propertyType}", ->
           @span ".property-name", name
           @$._editElems[name] = @div ".property-value", ""

        for name, prop of @_properties
         prop.edit @_editElems[name], @_values[name],
          @valueChanged.bind self: this, name: name
          stack

       valueChanged: (value, changed) ->
        @self._values[@name] = value
        @self.onChanged @self, false

##Private functions

Bind

       _bindEvents: ->
        events = @on
        @on = {}
        for k, v of events
         @on[k] = v.bind this

      Mod.set 'Models.Model.Base', Model