<commit_before>
process.title = "npm"

if (require.main === module) {
  console.error(["It looks like you're doing 'node npm.js'."
                ,"Don't do that.  Instead, run 'make install'"
                ,"and then use the 'npm' command line utility."
                ].join("\n"))
  process.exit(1)
}

var EventEmitter = require("events").EventEmitter
  , npm = module.exports = new EventEmitter
  , config = require("./lib/config")
  , set = require("./lib/utils/set")
  , get = require("./lib/utils/get")
  , ini = require("./lib/utils/ini")
  , log = require("./lib/utils/log")
  , fs = require("./lib/utils/graceful-fs")
  , path = require("path")
  , abbrev = require("./lib/utils/abbrev")
  , which = require("./lib/utils/which")
  , semver = require("semver")
  , findPrefix = require("./lib/utils/find-prefix")

npm.commands = {}
npm.ELIFECYCLE = {}
npm.E404 = {}
npm.EPUBLISHCONFLICT = {}
npm.EJSONPARSE = {}
npm.EISGIT = {}
npm.ECYCLE = {}
npm.EENGINE = {}

try {
  // startup, ok to do this synchronously
  var j = JSON.parse(fs.readFileSync(path.join(__dirname, "package.json"))+"")
  npm.version = j.version
  npm.nodeVersionRequired = j.engines.node
  if (!semver.satisfies(process.version, j.engines.node)) {
    log.error([""
              ,"npm requires node version: "+j.engines.node
              ,"And you have: "+process.version
              ,"which is not satisfactory."
              ,""
              ,"Bad things will likely happen.  You have been warned."
              ,""].join("\n"), "unsupported version")
  }
} catch (ex) {
  try {
    log(ex, "error reading version")
  } catch (er) {}
  npm.version = ex
}

var commandCache = {}
  // short names for common things
  , aliases = { "rm" : "uninstall"
              , "r" : "uninstall"
              , "un" : "uninstall"
              , "rb" : "rebuild"
              , "bn" : "bundle"
              , "list" : "ls"
              , "la" : "ls"
              , "ll" : "ls"
              , "ln" : "link"
              , "i" : "install"
              , "up" : "update"
              , "c" : "config"
              , "info" : "view"
              , "find" : "search"
              , "s" : "search"
              , "author" : "owner"
              }
  , aliasNames = Object.keys(aliases)
  // these are filenames in ./lib
  , cmdList = [ "install"
              , "uninstall"
              , "cache"
              , "config"
              , "set"
              , "get"
              , "update"
              , "outdated"
              , "prune"

              , "rebuild"
              , "link"

              , "publish"
              , "tag"
              , "adduser"
              , "unpublish"
              , "owner"
              , "deprecate"

              , "help"
              , "ls"
              , "search"
              , "view"
              , "init"
              , "version"
              , "edit"
              , "explore"
              , "docs"
              , "faq"
              , "xmas"
              , "root"
              , "prefix"
              , "bin"

              , "test"
              , "stop"
              , "start"
              , "restart"
              , "run-script"
              , "completion"
              ]
  , plumbing = [ "build"
               , "unbuild"
               ]
  , fullList = npm.fullList = cmdList.concat(aliasNames).filter(function (c) {
      return plumbing.indexOf(c) === -1
    })
  , abbrevs = abbrev(fullList)

Object.keys(abbrevs).concat(plumbing).forEach(function (c) {
  Object.defineProperty(npm.commands, c, { get : function () {
    if (!loaded) throw new Error(
      "Call npm.load(conf, cb) before using this command.\n"+
      "See the README.md or cli.js for example usage.")
    var a = npm.deref(c)
    if (c === "la" || c === "ll") {
      npm.config.set("long", true)
    }
    if (commandCache[a]) return commandCache[a]
    return commandCache[a] = require(__dirname+"/lib/"+a)
  }, enumerable: fullList.indexOf(c) !== -1 })
})

npm.deref = function (c) {
  if (plumbing.indexOf(c) !== -1) return c
  var a = abbrevs[c]
  if (aliases[a]) a = aliases[a]
  return a
}

var loaded = false
  , loading = false
  , loadListeners = []

npm.load = function (conf, cb_) {
  if (!cb_ && typeof conf === "function") cb_ = conf , conf = {}
  loadListeners.push(cb_)
  if (loaded) return cb()
  if (loading) return
  loading = true
  var onload = true

  function handleError (er) {
    loadListeners.forEach(function (cb) {
      process.nextTick(function () { cb(er, npm) })
    })
  }

  function cb (er) {
    if (er) return handleError(er)
    loaded = true
    loadListeners.forEach(function (cb) {
      process.nextTick(function () { cb(er, npm) })
    })
    loadListeners.length = 0
    if (onload = onload && npm.config.get("onload-script")) {
      require(onload)
      onload = false
    }
  }
  log.waitForConfig()
  which(process.argv[0], function (er, node) {
    if (!er && node !== process.execPath) {
      log.verbose("node symlink", node)
      process.execPath = node
    }
    ini.resolveConfigs(conf, function (er) {
      if (er) return handleError(er)
      var p
      if (!npm.config.get("global")
          && !conf.hasOwnProperty("prefix")) {
        p = process.cwd()
      } else {
        p = npm.config.get("prefix")
      }
      // try to guess at a good node_modules location.
      findPrefix(p, function (er, p) {
        if (er) return handleError(er)
        Object.defineProperty(npm, "prefix",
          { get : function () { return p }
          , set : function (r) { return p = r }
          , enumerable : true
          })
        return cb()
      })
    })
  })
}

var path = require("path")
npm.config =
  { get : function (key) { return ini.get(key) }
  , set : function (key, val) { return ini.set(key, val, "cli") }
  , del : function (key, val) { return ini.del(key, val, "cli") }
  }

Object.defineProperty(npm, "dir",
  { get : function () {
      if (npm.config.get("global")) {
        return path.resolve(npm.prefix, "lib", "node_modules")
      } else {
        return path.resolve(npm.prefix, "node_modules")
      }
    }
  , enumerable : true
  })

Object.defineProperty(npm, "cache",
  { get : function () { return npm.config.get("cache") }
  , set : function (r) { return npm.config.set("cache", r) }
  , enumerable : true
  })
var tmpFolder
Object.defineProperty(npm, "tmp",
  { get : function () {
      if (!tmpFolder) tmpFolder = "npm-"+Date.now()
      return path.resolve(npm.config.get("tmp"), tmpFolder)
    }
  , enumerable : true
  })
<commit_msg>bundle is removed, so should be bn<commit_after>
process.title = "npm"

if (require.main === module) {
  console.error(["It looks like you're doing 'node npm.js'."
                ,"Don't do that.  Instead, run 'make install'"
                ,"and then use the 'npm' command line utility."
                ].join("\n"))
  process.exit(1)
}

var EventEmitter = require("events").EventEmitter
  , npm = module.exports = new EventEmitter
  , config = require("./lib/config")
  , set = require("./lib/utils/set")
  , get = require("./lib/utils/get")
  , ini = require("./lib/utils/ini")
  , log = require("./lib/utils/log")
  , fs = require("./lib/utils/graceful-fs")
  , path = require("path")
  , abbrev = require("./lib/utils/abbrev")
  , which = require("./lib/utils/which")
  , semver = require("semver")
  , findPrefix = require("./lib/utils/find-prefix")

npm.commands = {}
npm.ELIFECYCLE = {}
npm.E404 = {}
npm.EPUBLISHCONFLICT = {}
npm.EJSONPARSE = {}
npm.EISGIT = {}
npm.ECYCLE = {}
npm.EENGINE = {}

try {
  // startup, ok to do this synchronously
  var j = JSON.parse(fs.readFileSync(path.join(__dirname, "package.json"))+"")
  npm.version = j.version
  npm.nodeVersionRequired = j.engines.node
  if (!semver.satisfies(process.version, j.engines.node)) {
    log.error([""
              ,"npm requires node version: "+j.engines.node
              ,"And you have: "+process.version
              ,"which is not satisfactory."
              ,""
              ,"Bad things will likely happen.  You have been warned."
              ,""].join("\n"), "unsupported version")
  }
} catch (ex) {
  try {
    log(ex, "error reading version")
  } catch (er) {}
  npm.version = ex
}

var commandCache = {}
  // short names for common things
  , aliases = { "rm" : "uninstall"
              , "r" : "uninstall"
              , "un" : "uninstall"
              , "rb" : "rebuild"
              , "list" : "ls"
              , "la" : "ls"
              , "ll" : "ls"
              , "ln" : "link"
              , "i" : "install"
              , "up" : "update"
              , "c" : "config"
              , "info" : "view"
              , "find" : "search"
              , "s" : "search"
              , "author" : "owner"
              }
  , aliasNames = Object.keys(aliases)
  // these are filenames in ./lib
  , cmdList = [ "install"
              , "uninstall"
              , "cache"
              , "config"
              , "set"
              , "get"
              , "update"
              , "outdated"
              , "prune"

              , "rebuild"
              , "link"

              , "publish"
              , "tag"
              , "adduser"
              , "unpublish"
              , "owner"
              , "deprecate"

              , "help"
              , "ls"
              , "search"
              , "view"
              , "init"
              , "version"
              , "edit"
              , "explore"
              , "docs"
              , "faq"
              , "xmas"
              , "root"
              , "prefix"
              , "bin"

              , "test"
              , "stop"
              , "start"
              , "restart"
              , "run-script"
              , "completion"
              ]
  , plumbing = [ "build"
               , "unbuild"
               ]
  , fullList = npm.fullList = cmdList.concat(aliasNames).filter(function (c) {
      return plumbing.indexOf(c) === -1
    })
  , abbrevs = abbrev(fullList)

Object.keys(abbrevs).concat(plumbing).forEach(function (c) {
  Object.defineProperty(npm.commands, c, { get : function () {
    if (!loaded) throw new Error(
      "Call npm.load(conf, cb) before using this command.\n"+
      "See the README.md or cli.js for example usage.")
    var a = npm.deref(c)
    if (c === "la" || c === "ll") {
      npm.config.set("long", true)
    }
    if (commandCache[a]) return commandCache[a]
    return commandCache[a] = require(__dirname+"/lib/"+a)
  }, enumerable: fullList.indexOf(c) !== -1 })
})

npm.deref = function (c) {
  if (plumbing.indexOf(c) !== -1) return c
  var a = abbrevs[c]
  if (aliases[a]) a = aliases[a]
  return a
}

var loaded = false
  , loading = false
  , loadListeners = []

npm.load = function (conf, cb_) {
  if (!cb_ && typeof conf === "function") cb_ = conf , conf = {}
  loadListeners.push(cb_)
  if (loaded) return cb()
  if (loading) return
  loading = true
  var onload = true

  function handleError (er) {
    loadListeners.forEach(function (cb) {
      process.nextTick(function () { cb(er, npm) })
    })
  }

  function cb (er) {
    if (er) return handleError(er)
    loaded = true
    loadListeners.forEach(function (cb) {
      process.nextTick(function () { cb(er, npm) })
    })
    loadListeners.length = 0
    if (onload = onload && npm.config.get("onload-script")) {
      require(onload)
      onload = false
    }
  }
  log.waitForConfig()
  which(process.argv[0], function (er, node) {
    if (!er && node !== process.execPath) {
      log.verbose("node symlink", node)
      process.execPath = node
    }
    ini.resolveConfigs(conf, function (er) {
      if (er) return handleError(er)
      var p
      if (!npm.config.get("global")
          && !conf.hasOwnProperty("prefix")) {
        p = process.cwd()
      } else {
        p = npm.config.get("prefix")
      }
      // try to guess at a good node_modules location.
      findPrefix(p, function (er, p) {
        if (er) return handleError(er)
        Object.defineProperty(npm, "prefix",
          { get : function () { return p }
          , set : function (r) { return p = r }
          , enumerable : true
          })
        return cb()
      })
    })
  })
}

var path = require("path")
npm.config =
  { get : function (key) { return ini.get(key) }
  , set : function (key, val) { return ini.set(key, val, "cli") }
  , del : function (key, val) { return ini.del(key, val, "cli") }
  }

Object.defineProperty(npm, "dir",
  { get : function () {
      if (npm.config.get("global")) {
        return path.resolve(npm.prefix, "lib", "node_modules")
      } else {
        return path.resolve(npm.prefix, "node_modules")
      }
    }
  , enumerable : true
  })

Object.defineProperty(npm, "cache",
  { get : function () { return npm.config.get("cache") }
  , set : function (r) { return npm.config.set("cache", r) }
  , enumerable : true
  })
var tmpFolder
Object.defineProperty(npm, "tmp",
  { get : function () {
      if (!tmpFolder) tmpFolder = "npm-"+Date.now()
      return path.resolve(npm.config.get("tmp"), tmpFolder)
    }
  , enumerable : true
  })
<|endoftext|>


<commit_before>/*
MIT License

Copyright (c) 2016 jrvieira

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

// import chain from 'chainchainchain'
//export default chain
module.exports = chain

let settings = Object.preventExtensions({
	owncontext: false, // functions remain in owner's context
	//uniqueness: false, // prevent duplicate objects in chain
	allowloops: false, // allow loops (only happens when chaining Ch objects)
	setchained: false // values are set on the youngest chained owner
}) // every setting defaults to false

const origin = Symbol('origin')
const chi = Symbol('chi')

function Ch (arr) {
	this[origin] = {}
	this[chi] = arr
}

let handler = {
	get: function (target, prop, receiver) {
		// return origin
		if (prop === origin) return target[origin]
		// return chi
		if (prop === chi) return target[chi]
		// avoid loop object
		let avoid = chain.findloop(target)

		if (!settings.allowloops && avoid) throw new Error('Loop in chain', avoid)
		// iterate through origin and chained objects
		for (let o of [target[origin], ...target[chi]]) {
			// return false on loop object
			if (avoid && avoid === o) return false
			// if object has property
			if (typeof o[prop] !== 'undefined') {
				// return property or properly bound method // x && y means if x == true return y else return x
				return o[prop] instanceof Function ? o[prop].bind(!settings.owncontext && receiver || o) : o[prop]
			}
		}

		return undefined
	},
	set: function (target, prop, value) {
		// set chi
		if (prop === chi) return target[chi] = value
		// set origin
		if (!settings.setchained) return target[origin][prop] = value
		// iterate through origin and chained objects
		for (let o of [target[origin], ...target[chi]]) {
			// if object has property
			if (typeof o[prop] !== 'undefined') {
				// set it
				return o[prop] = value
			}
		}

		console.warn(prop+' is not a chained property')
		return false
	}
}

function chain (...oo) {
	// validate o
	if (typeof oo === 'undefined') throw new TypeError('Argument undefined')
	// create proxied Ch instance
	let ch = new Proxy(new Ch(oo), handler)
	// find loops
	if (chain.findloop(ch)) {
		if (!settings.allowloops) throw new Error('Loop in chain', chain.findloop(ch))
		console.warn('Loop in chain', chain.findloop(ch))
	}

	return ch
}

Object.defineProperties(chain, {
	// settings object
	set: {
		value: new Proxy(settings, {
			get: function (target, prop) {

				return !!target[prop]
			},
			set: function (target, prop, value) {
				//if (!(prop in target)) throw new Error(prop+' is not a setting')
				if (typeof value !== 'boolean') console.warn('Chain settings should be Boolean, assuming '+!!value+' for '+prop)

				return target[prop] = !!value
			}
		})
	},
	// mind that if you create a loop there is a RangeError: Maximum call stack size exceeded
	findloop: {
		value: function (ch, set = new Set()) {

			set.add(ch)

			for (let o of ch[chi]) {
				if (chain.is(o) && (set.has(o) || chain.findloop(o, set))) {
					return o
				}
			}

			return false
		}
	},
	// returns true if object is chain
	is: {
		value: function (ch) {

			return ch instanceof Ch ? true : false
		}
	},
	// returns origin object
	origin: {
		value: function (ch) {

			if (!(ch instanceof Ch)) throw new TypeError(ch+' is not a chain')

			return ch[origin]
		}
	},
	// returns array of objects in chain
	arr: {
		value: function (ch) {

			return chain.is(ch) ? [ch[origin], ...ch[chi]] : false
		}
	},
	// returns array of properties in chain
	raw: {
		value: function (ch, prop, callback) {

			if (!(ch instanceof Ch)) throw new TypeError(ch+' is not a chain')
			// validate p
			if (typeof prop === 'undefined') throw new TypeError('Argument undefined')

			let raw = new Map()
			// iterate through origin and chained objects
			for (let o of [ch[origin], ...ch[chi]]) {
				// memo property or properly bound method // x && y means if x == true return y else return x
				raw.set(o, o[prop] instanceof Function ? o[prop].bind(!settings.owncontext && ch[origin] || o) : o[prop])
			}

			return callback ? callback(raw) : Array.from(raw.values())
		}
	},
	// MANIPULATION
	// adds objects to chain
	add: {
		value: function (ch, oo = []) {

			if (!(ch instanceof Ch)) throw new TypeError(ch+' is not a chain')

			if (!(oo instanceof Array)) oo = [oo]
			// appends objects to chain
			ch[chi].push(...oo)
			// find loops
			if (chain.findloop(ch)) {
				if (!settings.allowloops) throw new Error('Loop in chain', chain.findloop(ch))
				console.warn('Loop in chain', chain.findloop(ch))
			}

			return [ch[origin], ...ch[chi]]
		}
	},
	// adds objects to chain, after the origin
	pre: {
		value: function (ch, oo = []) {

			if (!(ch instanceof Ch)) throw new TypeError(ch+' is not a chain')

			if (!(oo instanceof Array)) oo = [oo]
			// prepends objects to chain
			ch[chi].unshift(...oo)
			// find loops
			if (chain.findloop(ch)) {
				if (!settings.allowloops) throw new Error('Loop in chain', chain.findloop(ch))
				console.warn('Loop in chain', chain.findloop(ch))
			}

			return [ch[origin], ...ch[chi]]
		}
	},
	// replaces chained objects
	rep: {
		value: function (ch, x, o) {

			if (!(ch instanceof Ch)) throw new TypeError(ch+' is not a chain')

			if (typeof x === 'undefined' || typeof o === 'undefined') throw new Error('not enough arguments')
			// replaces objects in chain
			while (!(ch[chi].indexOf(x) < 0)) {
				ch[chi].splice(ch[chi].indexOf(x),1,o)
			}
			// find loops
			if (chain.findloop(ch)) {
				if (!settings.allowloops) throw new Error('Loop in chain', chain.findloop(ch))
				console.warn('Loop in chain', chain.findloop(ch))
			}

			return [ch[origin], ...ch[chi]]
		}
	},
	// removes chained objects
	rem: {
		value: function (ch, xx = []) {

			if (!(ch instanceof Ch)) throw new TypeError(ch+' is not a chain')

			if (!(xx instanceof Array)) xx = [xx]
			// filters objects out of chain
			ch[chi] = ch[chi].filter(function (o) {
				return !xx.includes(o)
			})

			return [ch[origin], ...ch[chi]]
		}
	},
	// removes last chained object
	pop: {
		value: function (ch) {

			if (!(ch instanceof Ch)) throw new TypeError(ch+' is not a chain')

			return ch[chi].pop()
		}
	},
	// removes first chained object
	shift: {
		value: function (ch) {

			if (!(ch instanceof Ch)) throw new TypeError(ch+' is not a chain')

			return ch[chi].shift()
		}
	},
	// rotates chained objects
	rol: {
		value: function (ch, n = 1) {

			if (!(ch instanceof Ch)) throw new TypeError(ch+' is not a chain')

			if (n > 0) {
				for (let i = 0; i < n; i ++) {
					ch[chi].push(ch[chi].shift())
				}
			} else if (n < 0) {
				for (let i = 0; i > n ;i --) {
					ch[chi].unshift(ch[chi].pop())
				}
			}

			return [ch[origin], ...ch[chi]]
		}
	}

})
<commit_msg>Update chainchainchain.js<commit_after>/*
MIT License

Copyright (c) 2016 jrvieira

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

// import chain from 'chainchainchain'
//export default chain
module.exports = chain

let settings = Object.preventExtensions({
	owncontext: false, // functions remain in owner's context
	//uniqueness: false, // prevent duplicate objects in chain
	allowloops: false, // allow loops (only happens when chaining Ch objects)
	setchained: false // values are set on the youngest chained owner
}) // every setting defaults to false

const origin = Symbol('origin')
const chi = Symbol('chi')

function Ch (arr) {
	this[origin] = {}
	this[chi] = arr
}

let handler = {
	get: function (target, prop, receiver) {
		// return origin
		if (prop === origin) return target[origin]
		// return chi
		if (prop === chi) return target[chi]
		// avoid loop object
		let avoid = chain.findloop(target)

		if (!settings.allowloops && avoid) throw new Error('Loop in chain', avoid)
		// iterate through origin and chained objects
		for (let o of [target[origin], ...target[chi]]) {
			// return false on loop object
			if (avoid && avoid === o) return false
			// if object has property
			if (typeof o[prop] !== 'undefined') {
				// return property or properly bound method // x && y means if x == true return y else return x
				return o[prop] instanceof Function ? o[prop].bind(!settings.owncontext && receiver || o) : o[prop]
			}
		}

		return undefined
	},
	set: function (target, prop, value) {
		// set chi
		if (prop === chi) return target[chi] = value
		// set origin
		if (!settings.setchained) return target[origin][prop] = value
		// iterate through origin and chained objects
		for (let o of [target[origin], ...target[chi]]) {
			// if object has property
			if (typeof o[prop] !== 'undefined') {
				// set it
				return o[prop] = value
			}
		}

		console.warn(prop, 'is not a chained property')
		return false
	}
}

function chain (...oo) {
	// validate o
	if (typeof oo === 'undefined') throw new TypeError('Argument undefined')
	// create proxied Ch instance
	let ch = new Proxy(new Ch(oo), handler)
	// find loops
	if (chain.findloop(ch)) {
		if (!settings.allowloops) throw new Error('Loop in chain', chain.findloop(ch))
		console.warn('Loop in chain', chain.findloop(ch))
	}

	return ch
}

Object.defineProperties(chain, {
	// settings object
	set: {
		value: new Proxy(settings, {
			get: function (target, prop) {

				return !!target[prop]
			},
			set: function (target, prop, value) {
				//if (!(prop in target)) throw new Error(prop, 'is not a setting')
				if (typeof value !== 'boolean') console.warn('Chain settings should be Boolean, assuming', !!value, 'for', prop)

				return target[prop] = !!value
			}
		})
	},
	// mind that if you create a loop there is a RangeError: Maximum call stack size exceeded
	findloop: {
		value: function (ch, set = new Set()) {

			set.add(ch)

			for (let o of ch[chi]) {
				if (chain.is(o) && (set.has(o) || chain.findloop(o, set))) {
					return o
				}
			}

			return false
		}
	},
	// returns true if object is chain
	is: {
		value: function (ch) {

			return ch instanceof Ch ? true : false
		}
	},
	// returns origin object
	origin: {
		value: function (ch) {

			if (!(ch instanceof Ch)) throw new TypeError(ch, 'is not a chain')

			return ch[origin]
		}
	},
	// returns array of objects in chain
	arr: {
		value: function (ch) {

			return chain.is(ch) ? [ch[origin], ...ch[chi]] : false
		}
	},
	// returns array of properties in chain
	raw: {
		value: function (ch, prop, callback) {

			if (!(ch instanceof Ch)) throw new TypeError(ch, 'is not a chain')
			// validate p
			if (typeof prop === 'undefined') throw new TypeError('Argument undefined')

			let raw = new Map()
			// iterate through origin and chained objects
			for (let o of [ch[origin], ...ch[chi]]) {
				// memo property or properly bound method // x && y means if x == true return y else return x
				raw.set(o, o[prop] instanceof Function ? o[prop].bind(!settings.owncontext && ch[origin] || o) : o[prop])
			}

			return callback ? callback(raw) : Array.from(raw.values())
		}
	},
	// MANIPULATION
	// adds objects to chain
	add: {
		value: function (ch, oo = []) {

			if (!(ch instanceof Ch)) throw new TypeError(ch, 'is not a chain')

			if (!(oo instanceof Array)) oo = [oo]
			// appends objects to chain
			ch[chi].push(...oo)
			// find loops
			if (chain.findloop(ch)) {
				if (!settings.allowloops) throw new Error('Loop in chain', chain.findloop(ch))
				console.warn('Loop in chain', chain.findloop(ch))
			}

			return [ch[origin], ...ch[chi]]
		}
	},
	// adds objects to chain, after the origin
	pre: {
		value: function (ch, oo = []) {

			if (!(ch instanceof Ch)) throw new TypeError(ch, 'is not a chain')

			if (!(oo instanceof Array)) oo = [oo]
			// prepends objects to chain
			ch[chi].unshift(...oo)
			// find loops
			if (chain.findloop(ch)) {
				if (!settings.allowloops) throw new Error('Loop in chain', chain.findloop(ch))
				console.warn('Loop in chain', chain.findloop(ch))
			}

			return [ch[origin], ...ch[chi]]
		}
	},
	// replaces chained objects
	rep: {
		value: function (ch, x, o) {

			if (!(ch instanceof Ch)) throw new TypeError(ch, 'is not a chain')

			if (typeof x === 'undefined' || typeof o === 'undefined') throw new Error('not enough arguments')
			// replaces objects in chain
			while (!(ch[chi].indexOf(x) < 0)) {
				ch[chi].splice(ch[chi].indexOf(x),1,o)
			}
			// find loops
			if (chain.findloop(ch)) {
				if (!settings.allowloops) throw new Error('Loop in chain', chain.findloop(ch))
				console.warn('Loop in chain', chain.findloop(ch))
			}

			return [ch[origin], ...ch[chi]]
		}
	},
	// removes chained objects
	rem: {
		value: function (ch, xx = []) {

			if (!(ch instanceof Ch)) throw new TypeError(ch, 'is not a chain')

			if (!(xx instanceof Array)) xx = [xx]
			// filters objects out of chain
			ch[chi] = ch[chi].filter(function (o) {
				return !xx.includes(o)
			})

			return [ch[origin], ...ch[chi]]
		}
	},
	// removes last chained object
	pop: {
		value: function (ch) {

			if (!(ch instanceof Ch)) throw new TypeError(ch, 'is not a chain')

			return ch[chi].pop()
		}
	},
	// removes first chained object
	shift: {
		value: function (ch) {

			if (!(ch instanceof Ch)) throw new TypeError(ch, 'is not a chain')

			return ch[chi].shift()
		}
	},
	// rotates chained objects
	rol: {
		value: function (ch, n = 1) {

			if (!(ch instanceof Ch)) throw new TypeError(ch, 'is not a chain')

			if (n > 0) {
				for (let i = 0; i < n; i ++) {
					ch[chi].push(ch[chi].shift())
				}
			} else if (n < 0) {
				for (let i = 0; i > n ;i --) {
					ch[chi].unshift(ch[chi].pop())
				}
			}

			return [ch[origin], ...ch[chi]]
		}
	}

})
<|endoftext|>


<commit_before>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 * @flow
 * @emails oncall+draft_js
 */

'use strict';

import type {BlockMap} from 'BlockMap';
import type {BlockNodeRawConfig} from 'BlockNode';
import type {BlockNodeRecord} from 'BlockNodeRecord';
import type {ContentStateRawType} from 'ContentStateRawType';
import type DraftEntityInstance from 'DraftEntityInstance';
import type {DraftEntityMutability} from 'DraftEntityMutability';
import type {DraftEntityType} from 'DraftEntityType';
import type {EntityMap} from 'EntityMap';

const BlockMapBuilder = require('BlockMapBuilder');
const CharacterMetadata = require('CharacterMetadata');
const ContentBlock = require('ContentBlock');
const ContentBlockNode = require('ContentBlockNode');
const DraftEntity = require('DraftEntity');
const SelectionState = require('SelectionState');

const generateRandomKey = require('generateRandomKey');
const getOwnObjectValues = require('getOwnObjectValues');
const gkx = require('gkx');
const Immutable = require('immutable');
const sanitizeDraftText = require('sanitizeDraftText');

const {List, Record, Repeat, Map: ImmutableMap, OrderedMap} = Immutable;

type ContentStateRecordType = {
  entityMap: ?any,
  blockMap: ?BlockMap,
  selectionBefore: ?SelectionState,
  selectionAfter: ?SelectionState,
  ...
};

const defaultRecord: ContentStateRecordType = {
  entityMap: null,
  blockMap: null,
  selectionBefore: null,
  selectionAfter: null,
};

// Immutable 3 typedefs are not good, so ContentState ends up
// subclassing `any`. Define a rudimentary type for the
// supercalss here instead.
declare class ContentStateRecordHelper {
  constructor(args: any): ContentState;
  merge(args: any): any;
  setIn(keyPath: Array<string>, value: any): ContentState;
  equals(other: ContentState): boolean;
  mergeDeep(other: any): ContentState;
}

const ContentStateRecord: typeof ContentStateRecordHelper = (Record(
  defaultRecord,
): any);

/* $FlowFixMe[signature-verification-failure] Supressing a `signature-
 * verification-failure` error here. TODO: T65949050 Clean up the branch for
 * this GK */
const ContentBlockNodeRecord = gkx('draft_tree_data_support')
  ? ContentBlockNode
  : ContentBlock;

class ContentState extends ContentStateRecord {
  getEntityMap(): EntityMap {
    // TODO: update this when we fully remove DraftEntity
    return DraftEntity;
  }

  getBlockMap(): BlockMap {
    return (this: any).get('blockMap');
  }

  getSelectionBefore(): SelectionState {
    return (this: any).get('selectionBefore');
  }

  getSelectionAfter(): SelectionState {
    return (this: any).get('selectionAfter');
  }

  getBlockForKey(key: string): BlockNodeRecord {
    const block: BlockNodeRecord = this.getBlockMap().get(key);
    return block;
  }

  getKeyBefore(key: string): ?string {
    return this.getBlockMap()
      .reverse()
      .keySeq()
      .skipUntil(v => v === key)
      .skip(1)
      .first();
  }

  getKeyAfter(key: string): ?string {
    return this.getBlockMap()
      .keySeq()
      .skipUntil(v => v === key)
      .skip(1)
      .first();
  }

  getBlockAfter(key: string): ?BlockNodeRecord {
    return this.getBlockMap()
      .skipUntil((_, k) => k === key)
      .skip(1)
      .first();
  }

  getBlockBefore(key: string): ?BlockNodeRecord {
    return this.getBlockMap()
      .reverse()
      .skipUntil((_, k) => k === key)
      .skip(1)
      .first();
  }

  getBlocksAsArray(): Array<BlockNodeRecord> {
    return this.getBlockMap().toArray();
  }

  getFirstBlock(): BlockNodeRecord {
    return this.getBlockMap().first();
  }

  getLastBlock(): BlockNodeRecord {
    return this.getBlockMap().last();
  }

  getPlainText(delimiter?: string): string {
    return this.getBlockMap()
      .map(block => {
        return block ? block.getText() : '';
      })
      .join(delimiter || '\n');
  }

  getLastCreatedEntityKey(): string {
    // TODO: update this when we fully remove DraftEntity
    return DraftEntity.__getLastCreatedEntityKey();
  }

  hasText(): boolean {
    const blockMap = this.getBlockMap();
    return (
      blockMap.size > 1 ||
      // make sure that there are no zero width space chars
      escape(blockMap.first().getText()).replace(/%u200B/g, '').length > 0
    );
  }

  createEntity(
    type: DraftEntityType,
    mutability: DraftEntityMutability,
    data?: Object,
  ): ContentState {
    // TODO: update this when we fully remove DraftEntity
    DraftEntity.__create(type, mutability, data);
    return this;
  }

  mergeEntityData(
    key: string,
    toMerge: {[key: string]: any, ...},
  ): ContentState {
    // TODO: update this when we fully remove DraftEntity
    DraftEntity.__mergeData(key, toMerge);
    return this;
  }

  replaceEntityData(
    key: string,
    newData: interface {[key: string]: any},
  ): ContentState {
    // TODO: update this when we fully remove DraftEntity
    /* $FlowFixMe[class-object-subtyping] added when improving typing for this
     * parameters */
    DraftEntity.__replaceData(key, newData);
    return this;
  }

  addEntity(instance: DraftEntityInstance): ContentState {
    // TODO: update this when we fully remove DraftEntity
    DraftEntity.__add(instance);
    return this;
  }

  getEntity(key: string): DraftEntityInstance {
    // TODO: update this when we fully remove DraftEntity
    return DraftEntity.__get(key);
  }

  getAllEntities(): OrderedMap<string, DraftEntityInstance> {
    return DraftEntity.__getAll();
  }

  setEntityMap(
    entityMap: OrderedMap<string, DraftEntityInstance>,
  ): ContentState {
    DraftEntity.__loadWithEntities(entityMap);
    return this;
  }

  static mergeEntityMaps(
    to: OrderedMap<string, DraftEntityInstance>,
    from: EntityMap,
  ): OrderedMap<string, DraftEntityInstance> {
    return to.merge(from.__getAll());
  }

  // TODO: when EntityMap is moved into content state this and `setEntityMap`
  // Will be the exact same. Merge them then.
  replaceEntityMap(entityMap: EntityMap): ContentState {
    return this.setEntityMap(entityMap.__getAll());
  }

  setSelectionBefore(selection: SelectionState): ContentState {
    return (this: any).set('selectionBefore', selection);
  }

  setSelectionAfter(selection: SelectionState): ContentState {
    return (this: any).set('selectionAfter', selection);
  }

  setBlockMap(blockMap: BlockMap): ContentState {
    return (this: any).set('blockMap', blockMap);
  }

  static createFromBlockArray(
    // TODO: update flow type when we completely deprecate the old entity API
    blocks:
      | Array<BlockNodeRecord>
      | {contentBlocks: Array<BlockNodeRecord>, ...},
    entityMap: ?any,
  ): ContentState {
    // TODO: remove this when we completely deprecate the old entity API
    const theBlocks = Array.isArray(blocks) ? blocks : blocks.contentBlocks;
    const blockMap = BlockMapBuilder.createFromArray(theBlocks);
    const selectionState = blockMap.isEmpty()
      ? new SelectionState()
      : SelectionState.createEmpty(blockMap.first().getKey());
    return new ContentState({
      blockMap,
      entityMap: entityMap || DraftEntity,
      selectionBefore: selectionState,
      selectionAfter: selectionState,
    });
  }

  static createFromText(
    text: string,
    delimiter?: string | RegExp = /\r\n?|\n/g,
  ): ContentState {
    const strings = text.split(delimiter);
    const blocks = strings.map(block => {
      block = sanitizeDraftText(block);
      return new ContentBlockNodeRecord({
        key: generateRandomKey(),
        text: block,
        type: 'unstyled',
        characterList: List(Repeat(CharacterMetadata.EMPTY, block.length)),
      });
    });
    return ContentState.createFromBlockArray(blocks);
  }

  static fromJS(state: ContentStateRawType): ContentState {
    return new ContentState({
      ...state,
      blockMap: OrderedMap(state.blockMap).map(
        // $FlowFixMe[method-unbinding]
        ContentState.createContentBlockFromJS,
      ),
      selectionBefore: new SelectionState(state.selectionBefore),
      selectionAfter: new SelectionState(state.selectionAfter),
    });
  }

  static createContentBlockFromJS(
    block: BlockNodeRawConfig,
  ): ContentBlockNodeRecord {
    const characterList = block.characterList;

    return new ContentBlockNodeRecord({
      ...block,
      data: ImmutableMap(block.data),
      characterList:
        characterList != null
          ? List(
              (Array.isArray(characterList)
                ? characterList
                : getOwnObjectValues(characterList)
              ).map(c => CharacterMetadata.fromJS(c)),
            )
          : undefined,
    });
  }
}

module.exports = ContentState;
<commit_msg>remove (this: any) casts from the codebase<commit_after>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 * @flow
 * @emails oncall+draft_js
 */

'use strict';

import type {BlockMap} from 'BlockMap';
import type {BlockNodeRawConfig} from 'BlockNode';
import type {BlockNodeRecord} from 'BlockNodeRecord';
import type {ContentStateRawType} from 'ContentStateRawType';
import type DraftEntityInstance from 'DraftEntityInstance';
import type {DraftEntityMutability} from 'DraftEntityMutability';
import type {DraftEntityType} from 'DraftEntityType';
import type {EntityMap} from 'EntityMap';

const BlockMapBuilder = require('BlockMapBuilder');
const CharacterMetadata = require('CharacterMetadata');
const ContentBlock = require('ContentBlock');
const ContentBlockNode = require('ContentBlockNode');
const DraftEntity = require('DraftEntity');
const SelectionState = require('SelectionState');

const generateRandomKey = require('generateRandomKey');
const getOwnObjectValues = require('getOwnObjectValues');
const gkx = require('gkx');
const Immutable = require('immutable');
const sanitizeDraftText = require('sanitizeDraftText');

const {List, Record, Repeat, Map: ImmutableMap, OrderedMap} = Immutable;

type ContentStateRecordType = {
  entityMap: ?any,
  blockMap: ?BlockMap,
  selectionBefore: ?SelectionState,
  selectionAfter: ?SelectionState,
  ...
};

const defaultRecord: ContentStateRecordType = {
  entityMap: null,
  blockMap: null,
  selectionBefore: null,
  selectionAfter: null,
};

// Immutable 3 typedefs are not good, so ContentState ends up
// subclassing `any`. Define a rudimentary type for the
// supercalss here instead.
declare class ContentStateRecordHelper {
  constructor(args: any): ContentState;
  merge(args: any): any;
  setIn(keyPath: Array<string>, value: any): ContentState;
  equals(other: ContentState): boolean;
  mergeDeep(other: any): ContentState;
}

const ContentStateRecord: typeof ContentStateRecordHelper = (Record(
  defaultRecord,
): any);

/* $FlowFixMe[signature-verification-failure] Supressing a `signature-
 * verification-failure` error here. TODO: T65949050 Clean up the branch for
 * this GK */
const ContentBlockNodeRecord = gkx('draft_tree_data_support')
  ? ContentBlockNode
  : ContentBlock;

class ContentState extends ContentStateRecord {
  getEntityMap(): EntityMap {
    // TODO: update this when we fully remove DraftEntity
    return DraftEntity;
  }

  getBlockMap(): BlockMap {
    // $FlowFixMe[prop-missing] found when removing casts of this to any
    return this.get('blockMap');
  }

  getSelectionBefore(): SelectionState {
    // $FlowFixMe[prop-missing] found when removing casts of this to any
    return this.get('selectionBefore');
  }

  getSelectionAfter(): SelectionState {
    // $FlowFixMe[prop-missing] found when removing casts of this to any
    return this.get('selectionAfter');
  }

  getBlockForKey(key: string): BlockNodeRecord {
    const block: BlockNodeRecord = this.getBlockMap().get(key);
    return block;
  }

  getKeyBefore(key: string): ?string {
    return this.getBlockMap()
      .reverse()
      .keySeq()
      .skipUntil(v => v === key)
      .skip(1)
      .first();
  }

  getKeyAfter(key: string): ?string {
    return this.getBlockMap()
      .keySeq()
      .skipUntil(v => v === key)
      .skip(1)
      .first();
  }

  getBlockAfter(key: string): ?BlockNodeRecord {
    return this.getBlockMap()
      .skipUntil((_, k) => k === key)
      .skip(1)
      .first();
  }

  getBlockBefore(key: string): ?BlockNodeRecord {
    return this.getBlockMap()
      .reverse()
      .skipUntil((_, k) => k === key)
      .skip(1)
      .first();
  }

  getBlocksAsArray(): Array<BlockNodeRecord> {
    return this.getBlockMap().toArray();
  }

  getFirstBlock(): BlockNodeRecord {
    return this.getBlockMap().first();
  }

  getLastBlock(): BlockNodeRecord {
    return this.getBlockMap().last();
  }

  getPlainText(delimiter?: string): string {
    return this.getBlockMap()
      .map(block => {
        return block ? block.getText() : '';
      })
      .join(delimiter || '\n');
  }

  getLastCreatedEntityKey(): string {
    // TODO: update this when we fully remove DraftEntity
    return DraftEntity.__getLastCreatedEntityKey();
  }

  hasText(): boolean {
    const blockMap = this.getBlockMap();
    return (
      blockMap.size > 1 ||
      // make sure that there are no zero width space chars
      escape(blockMap.first().getText()).replace(/%u200B/g, '').length > 0
    );
  }

  createEntity(
    type: DraftEntityType,
    mutability: DraftEntityMutability,
    data?: Object,
  ): ContentState {
    // TODO: update this when we fully remove DraftEntity
    DraftEntity.__create(type, mutability, data);
    return this;
  }

  mergeEntityData(
    key: string,
    toMerge: {[key: string]: any, ...},
  ): ContentState {
    // TODO: update this when we fully remove DraftEntity
    DraftEntity.__mergeData(key, toMerge);
    return this;
  }

  replaceEntityData(
    key: string,
    newData: interface {[key: string]: any},
  ): ContentState {
    // TODO: update this when we fully remove DraftEntity
    /* $FlowFixMe[class-object-subtyping] added when improving typing for this
     * parameters */
    DraftEntity.__replaceData(key, newData);
    return this;
  }

  addEntity(instance: DraftEntityInstance): ContentState {
    // TODO: update this when we fully remove DraftEntity
    DraftEntity.__add(instance);
    return this;
  }

  getEntity(key: string): DraftEntityInstance {
    // TODO: update this when we fully remove DraftEntity
    return DraftEntity.__get(key);
  }

  getAllEntities(): OrderedMap<string, DraftEntityInstance> {
    return DraftEntity.__getAll();
  }

  setEntityMap(
    entityMap: OrderedMap<string, DraftEntityInstance>,
  ): ContentState {
    DraftEntity.__loadWithEntities(entityMap);
    return this;
  }

  static mergeEntityMaps(
    to: OrderedMap<string, DraftEntityInstance>,
    from: EntityMap,
  ): OrderedMap<string, DraftEntityInstance> {
    return to.merge(from.__getAll());
  }

  // TODO: when EntityMap is moved into content state this and `setEntityMap`
  // Will be the exact same. Merge them then.
  replaceEntityMap(entityMap: EntityMap): ContentState {
    return this.setEntityMap(entityMap.__getAll());
  }

  setSelectionBefore(selection: SelectionState): ContentState {
    // $FlowFixMe[prop-missing] found when removing casts of this to any
    return this.set('selectionBefore', selection);
  }

  setSelectionAfter(selection: SelectionState): ContentState {
    // $FlowFixMe[prop-missing] found when removing casts of this to any
    return this.set('selectionAfter', selection);
  }

  setBlockMap(blockMap: BlockMap): ContentState {
    // $FlowFixMe[prop-missing] found when removing casts of this to any
    return this.set('blockMap', blockMap);
  }

  static createFromBlockArray(
    // TODO: update flow type when we completely deprecate the old entity API
    blocks:
      | Array<BlockNodeRecord>
      | {contentBlocks: Array<BlockNodeRecord>, ...},
    entityMap: ?any,
  ): ContentState {
    // TODO: remove this when we completely deprecate the old entity API
    const theBlocks = Array.isArray(blocks) ? blocks : blocks.contentBlocks;
    const blockMap = BlockMapBuilder.createFromArray(theBlocks);
    const selectionState = blockMap.isEmpty()
      ? new SelectionState()
      : SelectionState.createEmpty(blockMap.first().getKey());
    return new ContentState({
      blockMap,
      entityMap: entityMap || DraftEntity,
      selectionBefore: selectionState,
      selectionAfter: selectionState,
    });
  }

  static createFromText(
    text: string,
    delimiter?: string | RegExp = /\r\n?|\n/g,
  ): ContentState {
    const strings = text.split(delimiter);
    const blocks = strings.map(block => {
      block = sanitizeDraftText(block);
      return new ContentBlockNodeRecord({
        key: generateRandomKey(),
        text: block,
        type: 'unstyled',
        characterList: List(Repeat(CharacterMetadata.EMPTY, block.length)),
      });
    });
    return ContentState.createFromBlockArray(blocks);
  }

  static fromJS(state: ContentStateRawType): ContentState {
    return new ContentState({
      ...state,
      blockMap: OrderedMap(state.blockMap).map(
        // $FlowFixMe[method-unbinding]
        ContentState.createContentBlockFromJS,
      ),
      selectionBefore: new SelectionState(state.selectionBefore),
      selectionAfter: new SelectionState(state.selectionAfter),
    });
  }

  static createContentBlockFromJS(
    block: BlockNodeRawConfig,
  ): ContentBlockNodeRecord {
    const characterList = block.characterList;

    return new ContentBlockNodeRecord({
      ...block,
      data: ImmutableMap(block.data),
      characterList:
        characterList != null
          ? List(
              (Array.isArray(characterList)
                ? characterList
                : getOwnObjectValues(characterList)
              ).map(c => CharacterMetadata.fromJS(c)),
            )
          : undefined,
    });
  }
}

module.exports = ContentState;
<|endoftext|>


<commit_before>module.exports = function hawkTemplates(Hawkejs, Blast) {

	var Templates,
	    Template;

	/**
	 * The Templates class
	 *
	 * @author   Jelle De Loecker   <jelle@codedor.be>
	 * @since    1.0.0
	 * @version  1.0.0
	 *
	 * @param    {String}   name
	 * @param    {Object}   options
	 */
	Templates = Blast.Classes.Informer.extend(function Templates(renderer, names, options) {

		var i;

		this.renderer = renderer;
		this.hawkejs = Object.create(renderer.hawkejs);

		// Create the options object
		this.options = options || {};

		// Make sure names is an array
		if (!Array.isArray(names)) {
			names = [names];
		} else {
			names = Blast.Bound.Array.flatten(names);
		}

		// Create the templates object
		this.templates = new Array(names.length);

		for (i = 0; i < names.length; i++) {
			this.templates[i] = new Template(renderer, names[i]);
		}

		// Store the active, found template
		this.active = null;
	});

	/**
	 * unDry an object
	 *
	 * @author   Jelle De Loecker   <jelle@codedor.be>
	 * @since    1.0.0
	 * @version  1.0.0
	 *
	 * @return   {Object}
	 */
	Templates.setStatic(function unDry(obj) {

		var result = Object.create(Templates.prototype),
		    inst;

		if (typeof hawkejs != undefined) {
			inst = hawkejs;
		} else {
			inst = {};
		}

		result.hawkejs = inst;
		result.renderer = {};

		Object.assign(result, obj);

		return result;
	});

	/**
	 * Return an object for json-drying this object
	 *
	 * @author   Jelle De Loecker   <jelle@codedor.be>
	 * @since    1.0.0
	 * @version  1.0.0
	 *
	 * @return   {Object}
	 */
	Templates.setMethod(function toDry() {
		return {
			value: {
				templates: this.templates,
				active: this.active,
				options: this.options
			},
			path: 'hawkejs.constructor.Templates'
		};
	});

	/**
	 * Get the template names
	 *
	 * @author   Jelle De Loecker   <jelle@codedor.be>
	 * @since    1.0.0
	 * @version  1.0.0
	 */
	Templates.setMethod(function getNames() {

		var result = '',
		    i;

		for (i = 0; i < this.templates.length; i++) {
			result += this.templates[i].name + ', ';
		}

		return result;
	});

	/**
	 * Set a theme
	 *
	 * @author   Jelle De Loecker   <jelle@codedor.be>
	 * @since    1.0.0
	 * @version  1.0.0
	 */
	Templates.setMethod(function setTheme(name) {

		var i;

		for (i = 0; i < this.templates.length; i++) {
			this.templates[i].setTheme(name);
		}

		this.theme = name;
	});

	/**
	 * Get the first available compiled template
	 *
	 * @author   Jelle De Loecker   <jelle@codedor.be>
	 * @since    1.0.0
	 * @version  1.0.0
	 *
	 * @param    {Function}   callback
	 */
	Templates.setMethod(function getCompiled(callback) {

		var that = this,
		    found,
		    iter;

		if (this.active && this.active.fnc) {
			return callback(null, this.active.fnc, this.active);
		}

		iter = new Blast.Classes.Iterator(this.templates);

		Blast.Bound.Function.while(function test() {
			return iter.hasNext() && !found;
		}, function task(next) {
			var template = iter.next().value;

			template.getCompiled(function gotCompiled(err, fnc) {

				if (err != null || !fnc) {
					return next();
				}

				found = template;
				next();
			});
		}, function done(err) {

			if (err != null) {
				return callback(err);
			}

			if (!found) {
				return callback(new Error('Could not find any template'));
			}

			// Set the active template
			that.active = found;

			callback(null, found.fnc, found);
		});
	});

	/**
	 * The Template class
	 *
	 * @author   Jelle De Loecker   <jelle@codedor.be>
	 * @since    1.0.0
	 * @version  1.0.0
	 *
	 * @param    {String}   name
	 * @param    {Object}   options
	 */
	Template = Blast.Classes.Informer.extend(function Template(renderer, name, options) {

		this.renderer = renderer;
		this.hawkejs = Object.create(renderer.hawkejs);

		// Store the name of this template
		this.name = name;

		// Store the sourcename of this template
		this.sourceName = null;

		this.options = options || {};

		// Set wanted theme to default
		this.theme = 'default';

		// Set the active theme
		this.activeTheme = 'default';

		// Did we find the main element
		this.foundMain = null;

		// The found function
		this.fnc = null;
	});

	/**
	 * unDry an object
	 *
	 * @author   Jelle De Loecker   <jelle@codedor.be>
	 * @since    1.0.0
	 * @version  1.0.0
	 *
	 * @return   {Object}
	 */
	Template.setStatic(function unDry(obj) {

		var result = Object.create(Template.prototype),
		    inst;

		if (typeof hawkejs != undefined) {
			inst = hawkejs;
		} else {
			inst = {};
		}

		result.hawkejs = inst;
		result.renderer = {};

		Object.assign(result, obj);

		return result;
	});

	/**
	 * Return an object for json-drying this object
	 *
	 * @author   Jelle De Loecker   <jelle@codedor.be>
	 * @since    1.0.0
	 * @version  1.0.0
	 *
	 * @return   {Object}
	 */
	Template.setMethod(function toDry() {
		return {
			value: {
				name: this.name,
				sourceName: this.sourceName,
				options: this.options,
				theme: this.theme,
				activeTheme: this.activeTheme,
				foundMain: this.foundMain
			},
			path: 'hawkejs.constructor.Template'
		};
	});

	/**
	 * Set a theme
	 *
	 * @author   Jelle De Loecker   <jelle@codedor.be>
	 * @since    1.0.0
	 * @version  1.0.0
	 */
	Template.setMethod(function setTheme(name) {

		if (this.theme != name) {
			this.foundMain = null;
			this.fnc = null;
		}

		this.theme = name;
	});

	/**
	 * Get the compiled template
	 *
	 * @author   Jelle De Loecker   <jelle@codedor.be>
	 * @since    1.0.0
	 * @version  1.0.0
	 *
	 * @param    {Function}   callback
	 */
	Template.setMethod(function getCompiled(callback) {

		var that = this,
		    files = [this.name],
		    themeName;

		if (this.theme && this.theme != 'default') {
			themeName = this.theme + '/' + this.name;
			files.unshift(themeName);
		}

		this.hawkejs.getCompiled(files, function gotCompiledFile(err, fnc) {

			if (err != null) {
				return callback(err);
			}

			if (!fnc) {
				return callback(new Error('Error compiling template'));
			}

			if (files[0] == fnc.sourceName) {
				that.foundMain = true;
				that.activeTheme = that.theme;
			}

			that.fnc = fnc;
			that.sourceName = fnc.sourceName;

			return callback(null, fnc, that);
		});
	});

	Hawkejs.Templates = Templates;
};<commit_msg>Fix undrying templates issue<commit_after>module.exports = function hawkTemplates(Hawkejs, Blast) {

	var Templates,
	    Template;

	/**
	 * The Templates class
	 *
	 * @author   Jelle De Loecker   <jelle@codedor.be>
	 * @since    1.0.0
	 * @version  1.0.0
	 *
	 * @param    {String}   name
	 * @param    {Object}   options
	 */
	Templates = Blast.Classes.Informer.extend(function Templates(renderer, names, options) {

		var i;

		this.renderer = renderer;
		this.hawkejs = Object.create(renderer.hawkejs);

		// Create the options object
		this.options = options || {};

		// Make sure names is an array
		if (!Array.isArray(names)) {
			names = [names];
		} else {
			names = Blast.Bound.Array.flatten(names);
		}

		// Create the templates object
		this.templates = new Array(names.length);

		for (i = 0; i < names.length; i++) {
			this.templates[i] = new Template(renderer, names[i]);
		}

		// Store the active, found template
		this.active = null;
	});

	/**
	 * unDry an object
	 *
	 * @author   Jelle De Loecker   <jelle@codedor.be>
	 * @since    1.0.0
	 * @version  1.0.0
	 *
	 * @return   {Object}
	 */
	Templates.setStatic(function unDry(obj) {

		var result,
		    inst;

		if (typeof hawkejs != undefined) {
			inst = hawkejs;
		} else {
			inst = {};
		}

		result = Object.create(Templates.prototype, {
			hawkejs: {
				enumerable: false,
				value: inst
			},
			renderer: {
				enumerable: false,
				value: {}
			}
		});

		Object.assign(result, obj);

		return result;
	});

	/**
	 * Return an object for json-drying this object
	 *
	 * @author   Jelle De Loecker   <jelle@codedor.be>
	 * @since    1.0.0
	 * @version  1.0.0
	 *
	 * @return   {Object}
	 */
	Templates.setMethod(function toDry() {
		return {
			value: {
				templates: this.templates,
				active: this.active,
				options: this.options
			},
			path: 'hawkejs.constructor.Templates'
		};
	});

	/**
	 * Get the template names
	 *
	 * @author   Jelle De Loecker   <jelle@codedor.be>
	 * @since    1.0.0
	 * @version  1.0.0
	 */
	Templates.setMethod(function getNames() {

		var result = '',
		    i;

		for (i = 0; i < this.templates.length; i++) {
			result += this.templates[i].name + ', ';
		}

		return result;
	});

	/**
	 * Set a theme
	 *
	 * @author   Jelle De Loecker   <jelle@codedor.be>
	 * @since    1.0.0
	 * @version  1.0.0
	 */
	Templates.setMethod(function setTheme(name) {

		var i;

		for (i = 0; i < this.templates.length; i++) {
			this.templates[i].setTheme(name);
		}

		this.theme = name;
	});

	/**
	 * Get the first available compiled template
	 *
	 * @author   Jelle De Loecker   <jelle@codedor.be>
	 * @since    1.0.0
	 * @version  1.0.0
	 *
	 * @param    {Function}   callback
	 */
	Templates.setMethod(function getCompiled(callback) {

		var that = this,
		    found,
		    iter;

		if (this.active && this.active.fnc) {
			return callback(null, this.active.fnc, this.active);
		}

		iter = new Blast.Classes.Iterator(this.templates);

		Blast.Bound.Function.while(function test() {
			return iter.hasNext() && !found;
		}, function task(next) {
			var template = iter.next().value;

			template.getCompiled(function gotCompiled(err, fnc) {

				if (err != null || !fnc) {
					return next();
				}

				found = template;
				next();
			});
		}, function done(err) {

			if (err != null) {
				return callback(err);
			}

			if (!found) {
				return callback(new Error('Could not find any template'));
			}

			// Set the active template
			that.active = found;

			callback(null, found.fnc, found);
		});
	});

	/**
	 * The Template class
	 *
	 * @author   Jelle De Loecker   <jelle@codedor.be>
	 * @since    1.0.0
	 * @version  1.0.0
	 *
	 * @param    {String}   name
	 * @param    {Object}   options
	 */
	Template = Blast.Classes.Informer.extend(function Template(renderer, name, options) {

		this.renderer = renderer;
		this.hawkejs = Object.create(renderer.hawkejs);

		// Store the name of this template
		this.name = name;

		// Store the sourcename of this template
		this.sourceName = null;

		this.options = options || {};

		// Set wanted theme to default
		this.theme = 'default';

		// Set the active theme
		this.activeTheme = 'default';

		// Did we find the main element
		this.foundMain = null;

		// The found function
		this.fnc = null;
	});

	/**
	 * unDry an object
	 *
	 * @author   Jelle De Loecker   <jelle@codedor.be>
	 * @since    1.0.0
	 * @version  1.0.0
	 *
	 * @return   {Object}
	 */
	Template.setStatic(function unDry(obj) {

		var result = Object.create(Template.prototype),
		    inst;

		if (typeof hawkejs != undefined) {
			inst = hawkejs;
		} else {
			inst = {};
		}

		result.hawkejs = inst;
		result.renderer = {};

		Object.assign(result, obj);

		return result;
	});

	/**
	 * Return an object for json-drying this object
	 *
	 * @author   Jelle De Loecker   <jelle@codedor.be>
	 * @since    1.0.0
	 * @version  1.0.0
	 *
	 * @return   {Object}
	 */
	Template.setMethod(function toDry() {
		return {
			value: {
				name: this.name,
				sourceName: this.sourceName,
				options: this.options,
				theme: this.theme,
				activeTheme: this.activeTheme,
				foundMain: this.foundMain
			},
			path: 'hawkejs.constructor.Template'
		};
	});

	/**
	 * Set a theme
	 *
	 * @author   Jelle De Loecker   <jelle@codedor.be>
	 * @since    1.0.0
	 * @version  1.0.0
	 */
	Template.setMethod(function setTheme(name) {

		if (this.theme != name) {
			this.foundMain = null;
			this.fnc = null;
		}

		this.theme = name;
	});

	/**
	 * Get the compiled template
	 *
	 * @author   Jelle De Loecker   <jelle@codedor.be>
	 * @since    1.0.0
	 * @version  1.0.0
	 *
	 * @param    {Function}   callback
	 */
	Template.setMethod(function getCompiled(callback) {

		var that = this,
		    files = [this.name],
		    themeName;

		if (this.theme && this.theme != 'default') {
			themeName = this.theme + '/' + this.name;
			files.unshift(themeName);
		}

		this.hawkejs.getCompiled(files, function gotCompiledFile(err, fnc) {

			if (err != null) {
				return callback(err);
			}

			if (!fnc) {
				return callback(new Error('Error compiling template'));
			}

			if (files[0] == fnc.sourceName) {
				that.foundMain = true;
				that.activeTheme = that.theme;
			}

			that.fnc = fnc;
			that.sourceName = fnc.sourceName;

			return callback(null, fnc, that);
		});
	});

	Hawkejs.Templates = Templates;
};<|endoftext|>


<commit_before>var CloudCmd, Util, DOM, CloudFunc, Terminal;
(function(CloudCmd, Util, DOM, CloudFunc) {
    'use strict';

    CloudCmd.Terminal = TerminalProto;

    function TerminalProto(CallBack) {
        var Name            = 'Terminal',
            Loading,
            Element,
            MouseBinded,
            Term,
            Cell,
            Socket          = CloudCmd.Socket,
            Key             = CloudCmd.Key,
            ESC             = Key.ESC,
            Images          = DOM.Images,
            Notify          = DOM.Notify,

            Size            = {
                cols: 0,
                rows: 0
            },

            CHANNEL         = CloudFunc.CHANNEL_TERMINAL,
            CHANNEL_RESIZE  = CloudFunc.CHANNEL_TERMINAL_RESIZE,

            CloudTerm       = this;

        function init() {
            Loading = true;

            Util.loadOnLoad([
                DOM.jqueryLoad,
                CloudCmd.View,
                load,
                CloudCmd.Socket,
                /* rm view keys, it ruin terminal */
                function(callback) {
                    CloudCmd.View.rmKeys(),
                    Socket = CloudCmd.Socket;

                    Util.exec(callback);
                },
                CloudTerm.show,
                addListeners
            ]);
        }

        CloudTerm.show      = show;
        CloudTerm.write     = write;

        function show(callback) {
            var options = {
                onUpdate: onResize,
            };

            if (!Loading) {
                Images.showLoad({top:true});

                if (!Element) {
                    Element         = DOM.anyload({
                        name    : 'div',
                        id      : 'terminal',
                        style   : 'height :100%'
                    });

                   /* hack to determine console size
                     * inspired with
                     *
                     * https://github.com/petethepig/devtools-terminal
                     */
                    Cell            = DOM.anyload({
                        name    : 'div',
                        inner   : '&nbsp',
                        parent  : Element,
                        style   : 'position: absolute;' +
                                  'top      : -1000px;'
                    });

                    DOM.cssSet({
                        id      : 'terminal-css',
                        inner   : '#terminal, .terminal, #view {'   +
                                    'height'            + ': 100%;' +
                                '}'                                 +
                                  '.terminal-cursor {'              +
                                    'background'        + ': gray'  +
                                '}'
                    });

                    Term    = new Terminal({
                        screenKeys: true,
                        cursorBlink: false,
                    });

                    Term.open(Element);
                }

                CloudCmd.View.show(Element, function() {
                    Element.focus();
                    Terminal.brokenBold = true;

                    Util.exec(callback);
                }, options);
            }
        }

        function write(data) {
            Term.write(data);
        }

        function addListeners(callback) {
            var options = {
                    'connect': function() {
                        write(Socket.CONNECTED + '\r');
                    },
                    'disconnect': function() {
                        write(Socket.DISCONNECTED +'\r');
                    },
                };

            options[CHANNEL]        = write;
            options[CHANNEL_RESIZE] = function(size) {
                Term.resize(size.cols, size.rows);
            };

            Socket.on(options);

            Term.on('data', function(data) {
                Socket.emit(CHANNEL, data);
            });

            Term.on('resize', function(size) {
                Socket.emit(CHANNEL_RESIZE, size);
            });

            Util.exec(callback);
        }

        function getSize() {
            var wSubs   = Element.offsetWidth - Element.clientWidth,
                w       = Element.clientWidth - wSubs,

                hSubs   = Element.offsetHeight - Element.clientHeight,
                h       = Element.clientHeight - hSubs,

                x       = Cell.clientWidth,
                y       = Cell.clientHeight,

                cols    = Math.max(Math.floor(w / x), 10),
                rows    = Math.max(Math.floor(h / y), 10),

                size    = {
                    cols: cols,
                    rows: rows
                };

            return size;
        }

        function onResize() {
            var size    = getSize(),
                cols    = size.cols,
                rows    = size.rows;

            if (Size.cols !== cols || Size.rows !== rows) {
                Size = size;

                //Term.resize(size.cols, size.rows);
                Term.emit('resize', size);
            }
        }

        function load(pCallBack) {
            var dir     =  CloudCmd.LIBDIRCLIENT + 'terminal/',
                path    = dir + 'term.js';

            Util.time(Name + ' load');

            DOM.jsload(path, function() {
                Util.timeEnd(Name + ' load');
                Loading = false;

                Util.exec(pCallBack);
            });
        }

        init();
    }

})(CloudCmd, Util, DOM, CloudFunc);
<commit_msg>chore(terminal) rm unused vars<commit_after>var CloudCmd, Util, DOM, CloudFunc, Terminal;
(function(CloudCmd, Util, DOM, CloudFunc) {
    'use strict';

    CloudCmd.Terminal = TerminalProto;

    function TerminalProto() {
        var Name            = 'Terminal',
            Loading,
            Element,
            Term,
            Cell,
            Socket          = CloudCmd.Socket,
            Images          = DOM.Images,
            Size            = {
                cols: 0,
                rows: 0
            },

            CHANNEL         = CloudFunc.CHANNEL_TERMINAL,
            CHANNEL_RESIZE  = CloudFunc.CHANNEL_TERMINAL_RESIZE,

            CloudTerm       = this;

        function init() {
            Loading = true;

            Util.loadOnLoad([
                DOM.jqueryLoad,
                CloudCmd.View,
                load,
                CloudCmd.Socket,
                /* rm view keys, it ruin terminal */
                function(callback) {
                    CloudCmd.View.rmKeys(),
                    Socket = CloudCmd.Socket;

                    Util.exec(callback);
                },
                CloudTerm.show,
                addListeners
            ]);
        }

        CloudTerm.show      = show;
        CloudTerm.write     = write;

        function show(callback) {
            var options = {
                onUpdate: onResize,
            };

            if (!Loading) {
                Images.showLoad({top:true});

                if (!Element) {
                    Element         = DOM.anyload({
                        name    : 'div',
                        id      : 'terminal',
                        style   : 'height :100%'
                    });

                   /* hack to determine console size
                     * inspired with
                     *
                     * https://github.com/petethepig/devtools-terminal
                     */
                    Cell            = DOM.anyload({
                        name    : 'div',
                        inner   : '&nbsp',
                        parent  : Element,
                        style   : 'position: absolute;' +
                                  'top      : -1000px;'
                    });

                    DOM.cssSet({
                        id      : 'terminal-css',
                        inner   : '#terminal, .terminal, #view {'   +
                                    'height'            + ': 100%;' +
                                '}'                                 +
                                  '.terminal-cursor {'              +
                                    'background'        + ': gray'  +
                                '}'
                    });

                    Term    = new Terminal({
                        screenKeys: true,
                        cursorBlink: false,
                    });

                    Term.open(Element);
                }

                CloudCmd.View.show(Element, function() {
                    Element.focus();
                    Terminal.brokenBold = true;

                    Util.exec(callback);
                }, options);
            }
        }

        function write(data) {
            Term.write(data);
        }

        function addListeners(callback) {
            var options = {
                    'connect': function() {
                        write(Socket.CONNECTED + '\r');
                    },
                    'disconnect': function() {
                        write(Socket.DISCONNECTED +'\r');
                    },
                };

            options[CHANNEL]        = write;
            options[CHANNEL_RESIZE] = function(size) {
                Term.resize(size.cols, size.rows);
            };

            Socket.on(options);

            Term.on('data', function(data) {
                Socket.emit(CHANNEL, data);
            });

            Term.on('resize', function(size) {
                Socket.emit(CHANNEL_RESIZE, size);
            });

            Util.exec(callback);
        }

        function getSize() {
            var wSubs   = Element.offsetWidth - Element.clientWidth,
                w       = Element.clientWidth - wSubs,

                hSubs   = Element.offsetHeight - Element.clientHeight,
                h       = Element.clientHeight - hSubs,

                x       = Cell.clientWidth,
                y       = Cell.clientHeight,

                cols    = Math.max(Math.floor(w / x), 10),
                rows    = Math.max(Math.floor(h / y), 10),

                size    = {
                    cols: cols,
                    rows: rows
                };

            return size;
        }

        function onResize() {
            var size    = getSize(),
                cols    = size.cols,
                rows    = size.rows;

            if (Size.cols !== cols || Size.rows !== rows) {
                Size = size;

                //Term.resize(size.cols, size.rows);
                Term.emit('resize', size);
            }
        }

        function load(callback) {
            var dir     =  CloudCmd.LIBDIRCLIENT + 'terminal/',
                path    = dir + 'term.js';

            Util.time(Name + ' load');

            DOM.jsload(path, function() {
                Util.timeEnd(Name + ' load');
                Loading = false;

                Util.exec(callback);
            });
        }

        init();
    }

})(CloudCmd, Util, DOM, CloudFunc);
<|endoftext|>


<commit_before>var CloudCmd, Util, DOM, CloudFunc, Terminal;
(function(CloudCmd, Util, DOM, CloudFunc) {
    'use strict';

    CloudCmd.Terminal = TerminalProto;

    function TerminalProto(CallBack) {
        var Name            = 'Terminal',
            Loading,
            Element,
            MouseBinded,
            Term,
            Cell,
            Key             = CloudCmd.Key,
            ESC             = Key.ESC,
            Images          = DOM.Images,
            Notify          = DOM.Notify,

            CHANNEL         = CloudFunc.CHANNEL_TERMINAL,
            CHANNEL_RESIZE  = CloudFunc.CHANNEL_TERMINAL_RESIZE,

            CloudTerm       = this;

        function init() {
            Loading = true;

            Util.loadOnLoad([
                DOM.jqueryLoad,
                CloudCmd.View,
                /* rm view keys, it ruin terminal */
                function(callback) {
                    CloudCmd.View.rmKeys(),
                    Util.exec(callback);
                },
                load,
                CloudCmd.Socket,
                CloudTerm.show,
                addListeners
            ]);
        }

        CloudTerm.show      = show;
        CloudTerm.write     = write;

        function show(callback) {
            var size,
                socket = CloudCmd.Socket;

            if (!Loading) {
                Images.showLoad({top:true});

                if (!Element) {
                    Element         = DOM.anyload({
                        name    : 'div',
                        id      : 'terminal',
                        style   : 'height :100%'
                    });

                   /* hack to determine console size
                     * inspired with
                     *
                     * https://github.com/petethepig/devtools-terminal
                     */
                    Cell            = DOM.anyload({
                        name    : 'div',
                        inner   : '&nbsp',
                        parent  : Element,
                        style   : 'position: absolute;' +
                                  'top      : -1000px;'
                    });

                    DOM.cssSet({
                        id      : 'terminal-css',
                        inner   : '#terminal, .terminal, #view {'   +
                                    'height'            + ': 100%;' +
                                '}'                                 +
                                  '.terminal-cursor {'              +
                                    'background'        + ': gray'  +
                                '}'
                    });

                    size    = getSize();

                    Term    = new Terminal({
                        screenKeys: true,
                        cursorBlink: false,
                        cols: size.cols,
                        rows: size.rows
                    });

                    Term.open(Element);
                }

                CloudCmd.View.show(Element, function() {
                    Element.focus();
                    Terminal.brokenBold = true;

                    Util.exec(callback);
                }, {
                    onUpdate: function() {
                        var size = getSize();
                        Term.resize(size.cols, size.rows);
                        Term.emit('resize', size);
                    }
                });
            }
        }

        function write(data) {
            Term.write(data);
        }

        function addListeners(callback) {
            var socket  = CloudCmd.Socket;

            socket.on(CHANNEL, write);

            Term.on('data', function(data) {
                var code;

                if (data) {
                    code = data.charCodeAt(0);

                    /* when back to term
                     * first simbol wasn't wrote
                     */
                    socket.emit(CHANNEL, data);
                }
            });

            Term.on('resize', function(size) {
                socket.emit(CHANNEL_RESIZE, size);
            });

            Util.exec(callback);
        }

        function getSize() {
            var wSubs   = Element.offsetWidth - Element.clientWidth,
                w       = Element.clientWidth - wSubs,

                hSubs   = Element.offsetHeight - Element.clientHeight,
                h       = Element.clientHeight - hSubs,

                x       = Cell.clientWidth,
                y       = Cell.clientHeight,

                cols    = Math.max(Math.floor(w / x), 10),
                rows    = Math.max(Math.floor(h / y), 10),

                size    = {
                    cols: cols,
                    rows: rows
                };

            return size;
        }

        function load(pCallBack) {
            var dir     =  CloudCmd.LIBDIRCLIENT + 'terminal/',
                path    = dir + 'term.js';

            Util.time(Name + ' load');

            DOM.jsload(path, function() {
                Util.timeEnd(Name + ' load');
                Loading = false;

                Util.exec(pCallBack);
            });
        }

        init();
    }

})(CloudCmd, Util, DOM, CloudFunc);
<commit_msg>refactor(terminal) addListeners<commit_after>var CloudCmd, Util, DOM, CloudFunc, Terminal;
(function(CloudCmd, Util, DOM, CloudFunc) {
    'use strict';

    CloudCmd.Terminal = TerminalProto;

    function TerminalProto(CallBack) {
        var Name            = 'Terminal',
            Loading,
            Element,
            MouseBinded,
            Term,
            Cell,
            Key             = CloudCmd.Key,
            ESC             = Key.ESC,
            Images          = DOM.Images,
            Notify          = DOM.Notify,

            CHANNEL         = CloudFunc.CHANNEL_TERMINAL,
            CHANNEL_RESIZE  = CloudFunc.CHANNEL_TERMINAL_RESIZE,

            CloudTerm       = this;

        function init() {
            Loading = true;

            Util.loadOnLoad([
                DOM.jqueryLoad,
                CloudCmd.View,
                /* rm view keys, it ruin terminal */
                function(callback) {
                    CloudCmd.View.rmKeys(),
                    Util.exec(callback);
                },
                load,
                CloudCmd.Socket,
                CloudTerm.show,
                addListeners
            ]);
        }

        CloudTerm.show      = show;
        CloudTerm.write     = write;

        function show(callback) {
            var size,
                socket = CloudCmd.Socket;

            if (!Loading) {
                Images.showLoad({top:true});

                if (!Element) {
                    Element         = DOM.anyload({
                        name    : 'div',
                        id      : 'terminal',
                        style   : 'height :100%'
                    });

                   /* hack to determine console size
                     * inspired with
                     *
                     * https://github.com/petethepig/devtools-terminal
                     */
                    Cell            = DOM.anyload({
                        name    : 'div',
                        inner   : '&nbsp',
                        parent  : Element,
                        style   : 'position: absolute;' +
                                  'top      : -1000px;'
                    });

                    DOM.cssSet({
                        id      : 'terminal-css',
                        inner   : '#terminal, .terminal, #view {'   +
                                    'height'            + ': 100%;' +
                                '}'                                 +
                                  '.terminal-cursor {'              +
                                    'background'        + ': gray'  +
                                '}'
                    });

                    size    = getSize();

                    Term    = new Terminal({
                        screenKeys: true,
                        cursorBlink: false,
                        cols: size.cols,
                        rows: size.rows
                    });

                    Term.open(Element);
                }

                CloudCmd.View.show(Element, function() {
                    Element.focus();
                    Terminal.brokenBold = true;

                    Util.exec(callback);
                }, {
                    onUpdate: function() {
                        var size = getSize();
                        Term.resize(size.cols, size.rows);
                        Term.emit('resize', size);
                    }
                });
            }
        }

        function write(data) {
            Term.write(data);
        }

        function addListeners(callback) {
            var socket  = CloudCmd.Socket;

            socket.on(CHANNEL, write);

            Term.on('data', function(data) {
                socket.emit(CHANNEL, data);
            });

            Term.on('resize', function(size) {
                socket.emit(CHANNEL_RESIZE, size);
            });

            Util.exec(callback);
        }

        function getSize() {
            var wSubs   = Element.offsetWidth - Element.clientWidth,
                w       = Element.clientWidth - wSubs,

                hSubs   = Element.offsetHeight - Element.clientHeight,
                h       = Element.clientHeight - hSubs,

                x       = Cell.clientWidth,
                y       = Cell.clientHeight,

                cols    = Math.max(Math.floor(w / x), 10),
                rows    = Math.max(Math.floor(h / y), 10),

                size    = {
                    cols: cols,
                    rows: rows
                };

            return size;
        }

        function load(pCallBack) {
            var dir     =  CloudCmd.LIBDIRCLIENT + 'terminal/',
                path    = dir + 'term.js';

            Util.time(Name + ' load');

            DOM.jsload(path, function() {
                Util.timeEnd(Name + ' load');
                Loading = false;

                Util.exec(pCallBack);
            });
        }

        init();
    }

})(CloudCmd, Util, DOM, CloudFunc);
<|endoftext|>


<commit_before>var _ = require('../util').lodash,
    Property = require('./property').Property,
    PropertyList = require('./property-list').PropertyList,
    EventList = require('./event-list').EventList,
    Request = require('./request').Request,
    Response = require('./response').Response,

    Item;

_.inherit((
    /**
     * A Postman Collection Item that holds your request definition, responses and other stuff
     * @constructor
     * @extends {Property}
     *
     * @param {Object} options
     */
    Item = function PostmanItem (options) {
        // this constructor is intended to inherit and as such the super constructor is required to be excuted
        Item.super_.apply(this, arguments);
        if (!options) { return; } // in case definition object is missing, there is no point moving forward

        _.merge(this, /** @lends Item.prototype */ {
            /**
             * The request in this item
             * @type {Request}
             */
            request: new Request(options.request),
            /**
             * List of sample responses
             * @type {PropertyList<Response>}
             */
            responses: new PropertyList(Response, this, options.response),
            /**
             * Events of this item
             * @type {EventList}
             */
            events: new EventList(this, options.event)
        });
    }), Property);

_.extend(Item.prototype, /** @lends Item.prototype */ {
    /**
     * Defines whether this property instances requires an id
     * @private
     * @readOnly
     * @type {String}
     */
    _postman_requiresId: true,

    // TODO: Think about this name @shamasis
    processAuth: function () {
        return this.request.authorize();
    },

    /**
     * Returns Events corresponding to a particular event name. If no name is given, returns all events
     *
     * @param name {String}
     */
    getEvents: function (name) {
        if (!name) {
            return this.events.all(); // return all events if name is not provided.
        }
        return this.events.filter(function (ev) {
            return ev.listen === name;
        });
    }
});

_.extend(Item, /** @lends Item */ {
    /**
     * Defines the name of this property for internal use.
     * @private
     * @readOnly
     * @type {String}
     */
    _postman_propertyName: 'Item',

    /**
     * Check whether an object is an instance of PostmanItem.
     *
     * @param {*} obj
     * @returns {Boolean}
     */
    isItem: function (obj) {
        return obj && ((obj instanceof Item) ||
            _.inSuperChain(obj.constructor, '_postman_propertyName', Item._postman_propertyName));
    }
});

module.exports = {
    Item: Item
};
<commit_msg>Updated Item property to proceed with construction even when no definition object is provided<commit_after>var _ = require('../util').lodash,
    Property = require('./property').Property,
    PropertyList = require('./property-list').PropertyList,
    EventList = require('./event-list').EventList,
    Request = require('./request').Request,
    Response = require('./response').Response,

    Item;

_.inherit((
    /**
     * A Postman Collection Item that holds your request definition, responses and other stuff. An Item essentially is
     * a HTTP request definition along with the sample responses and test scripts clubbed together. One or more of these
     * items can be grouped together and placed in an {@link ItemGroup} and as such forms a {@link Collection} of
     * requests.
     *
     * @constructor
     * @extends {Property}
     *
     * @param {Item~definition=} [definition]
     */
    Item = function PostmanItem (definition) {
        // this constructor is intended to inherit and as such the super constructor is required to be excuted
        Item.super_.apply(this, arguments);

        _.merge(this, /** @lends Item.prototype */ {
            /**
             * The request in this item
             * @type {Request}
             */
            request: definition && (new Request(definition.request)),
            /**
             * List of sample responses
             * @type {PropertyList<Response>}
             */
            responses: new PropertyList(Response, this, definition && definition.response),
            /**
             * Events of this item
             * @type {EventList}
             */
            events: new EventList(this, definition && definition.event)
        });
    }), Property);

_.extend(Item.prototype, /** @lends Item.prototype */ {
    /**
     * Defines whether this property instances requires an id
     * @private
     * @readOnly
     * @type {String}
     */
    _postman_requiresId: true,

    // TODO: Think about this name @shamasis
    processAuth: function () {
        return this.request.authorize();
    },

    /**
     * Returns Events corresponding to a particular event name. If no name is given, returns all events
     *
     * @param name {String}
     */
    getEvents: function (name) {
        if (!name) {
            return this.events.all(); // return all events if name is not provided.
        }
        return this.events.filter(function (ev) {
            return ev.listen === name;
        });
    }
});

_.extend(Item, /** @lends Item */ {
    /**
     * Defines the name of this property for internal use.
     * @private
     * @readOnly
     * @type {String}
     */
    _postman_propertyName: 'Item',

    /**
     * Check whether an object is an instance of PostmanItem.
     *
     * @param {*} obj
     * @returns {Boolean}
     */
    isItem: function (obj) {
        return obj && ((obj instanceof Item) ||
            _.inSuperChain(obj.constructor, '_postman_propertyName', Item._postman_propertyName));
    }
});

module.exports = {
    Item: Item
};
<|endoftext|>