<commit_before>/*
---

script: Document.js

description: Provides a virtual root to all the widgets. DOM-Compatible for Slick traversals.

license: Public domain (http://unlicense.org).

authors: Yaroslaff Fedin

requires:
  - LSD.Widget
  - Core/DomReady
  - Core/Options
  - Core/Events
  - More/String.QueryString
  - LSD
  - LSD.Module.Attributes
  - LSD.Module.Properties
  - LSD.Module.Render
  - LSD.Module.Selectors

provides:
  - LSD.Document

...
*/

/*
  Document is a big disguise proxy class that contains the tree
  of widgets and a link to document element.

  It is DOM-compatible (to some degree), so tools that crawl DOM
  tree (we use Slick) can work with the widget tree like it usually
  does with the real DOM so we get selector engine for free.

  The document itself is not in the tree, it's a container.

  The class contains a few hacks that allows Slick to initialize.
*/

LSD.Document = new Class({

  Implements: [Events, Options, LSD.Module.Attributes, LSD.Module.Properties, LSD.Module.Render],

  options: {
    context: 'element',
    namespace: 'LSD'
  },

  initialize: function(document, options) {
    if (options && options.documentElement) options = [document, document = options][0];
    if (document == null) document = window.document;
    if (!LSD.document) LSD.document = this;
    this.setOptions(options || {});
    this.document = this;
    this.element = document;
    this.sourceIndex = 1;
    this.layout = this.getLayout();
    this.childNodes = [];
    this.factory = Object.getFromPath(window[this.options.namespace], LSD.toClassName(this.options.context));
    LSD.uid(this);
    if (this.constructors.properties) this.constructors.properties.apply(this, arguments);
    if (this.constructors.render) this.constructors.render.apply(this, arguments);

    /*
      Trick Slick into thinking that LSD elements tree is an XML node
      tree (so it won't try speeding up the queries with optimizations)
    */
    this.documentElement = this;
    this.xml = true;
    this.slickFeatures = LSD.Module.Selectors.Features;
    this.nodeType = 9;
    this.attributes = {};

    this.params = (location.search.length > 1) ? location.search.substr(1, location.search.length - 1).parseQueryString() : {}
    if (this.element && this.element.documentElement) {
      this.element.addEvent('domready', function() {
        this.building = true;
        if ("benchmark" in this.params) LSD.console.profile();
        this.build();
        if ("benchmark" in this.params) LSD.console.profileEnd();
        this.building = false;
      }.bind(this));
      this.element.addEvent('click', this.onClick.bind(this));
      this.element.addEvent('mousedown', this.onMousedown.bind(this));
    } else {
      this.build();
    }
  },

  /*
    Single relay click listener is put upon document.
    It spies for all clicks on elements and finds out if
    any links were clicked. If the link is not widget,
    the listener creates a lightweight link class instance and
    calls click on it to trigger commands and interactions.

    This way there's no need to preinitialize all link handlers,
    and only instantiate class when the link was actually clicked.
  */
  onClick: function(event) {
    if (event.target.ownerDocument == document && // click is in the same frame
       !event.rightClick &&                       // and click is not right click
       !(event.control || event.meta) &&          // and ctrl/command is not held
       !(event.event.which == 3))                 // and it's not the middle button
    for (var target = event.target, link, widget; target && target.tagName; target = target.parentNode) {
      widget = target.uid && Element.retrieve(target, 'widget');
      var a = (LSD.toLowerCase(target.tagName) == 'a');
      if (a) {
        if (!widget) {
          var parent = LSD.Module.DOM.find(target)
          widget = new LSD.Widget(target, {
            pseudos: ['clickable', 'command'],
            document: this
          });
          parent.appendChild(widget, false);
        }
        event.preventDefault();
      }
      if (widget && widget.pseudos.clickable) {
        event.stopPropagation();
         if (widget.click(event)) break;
      }
    };
  },

  onMousedown: function(event) {
    if (event.target.ownerDocument == document)
    for (var target = event.target, widget; target && target.tagName; target = target.parentNode) {
      widget = target.localName ? target.uid && Element.retrieve(target, 'widget') : target;
      if (widget && widget.pseudos.activatable) {
        widget.fireEvent('mousedown', event);
        target = widget;
      }
    };
  },

  setHead: function(head) {
    for (var i = 0, el, els = head.getElementsByTagName('meta'); el = els[i++];) {
      var type = el.getAttribute('rel');
      if (type) {
        type += 's';
        if (!this[type]) this[type] = {};
        var content = el.getAttribute('content')
        if (content) this[type][el.getAttribute('name')] = (content.charAt(0) =="{") ? JSON.decode(content) : content;
      }
    }
    // Attach stylesheets, if there are stylesheets loaded
    if (LSD.Sheet && LSD.Sheet.stylesheets) for (var i = 0, sheet; sheet = LSD.Sheet.stylesheets[i++];) this.addStylesheet(sheet);
  },

  getLayout: function() {
    if (this.layout) return this.layout;
    this.layout = new LSD.Layout;
    this.layout.document = this;
    return this.layout;
  },

  create: function(element, options) {
    if (!options) options = {};
    options.document = this;
    return this.factory.create(element, options);
  },

  build: function(document) {
    this.fireEvent('beforeBuild', document)
    this.built = true;
    if (this.element !== false) {
      if (!document) document = this.element || window.document;
      this.setHead(document.head);
      var element = this.element = document.body;
      this.setBody(document.body);
    }
    this.render();
    this.fireEvent('build', document)
  },

  setBody: function(element) {
    if (!element) element = this.getBodyElement();
    this.fireEvent('beforeBody', element);
    var options = {
      document: this,
      events: {
        self: {
          boot: function() {
            this.document.body = this;
          }
        }
      },
      tag: 'body'
    };
    if (this.options.mutations) options.mutations = this.options.mutations;
    if (this.options.context) options.context = this.options.context;
    new LSD.Widget(element, options);
    this.fireEvent('body', [this.body, element]);
    this.childNodes.push(this.body)
    return element;
  },

  getBodyElement: function() {
    return this.document.body;
  },

  redirect: function(url) {
    window.location.href = url;
  },

  getElements: function() {
    return this.body.getElements.apply(this.body, arguments);
  },

  getElement: function() {
    return this.body.getElement.apply(this.body, arguments);
  },

  addStylesheet: function(sheet) {
    if (!this.stylesheets) this.stylesheets = [];
    this.stylesheets.include(sheet);
    sheet.attach(this);
  },

  removeStylesheet: function(sheet) {
    if (!this.stylesheets) return;
    this.stylesheets.erase(sheet);
    sheet.detach(this);
  },

  $family: Function.from('document')
});<commit_msg>fixed Document<commit_after>/*
---

script: Document.js

description: Provides a virtual root to all the widgets. DOM-Compatible for Slick traversals.

license: Public domain (http://unlicense.org).

authors: Yaroslaff Fedin

requires:
  - LSD.Widget
  - Core/DomReady
  - Core/Options
  - Core/Events
  - More/String.QueryString
  - LSD
  - LSD.Module.Attributes
  - LSD.Module.Properties
  - LSD.Module.Render
  - LSD.Module.Selectors

provides:
  - LSD.Document

...
*/

/*
  Document is a big disguise proxy class that contains the tree
  of widgets and a link to document element.

  It is DOM-compatible (to some degree), so tools that crawl DOM
  tree (we use Slick) can work with the widget tree like it usually
  does with the real DOM so we get selector engine for free.

  The document itself is not in the tree, it's a container.

  The class contains a few hacks that allows Slick to initialize.
*/

LSD.Document = new Class({

  Implements: [Events, Options, LSD.Module.Attributes, LSD.Module.Properties, LSD.Module.Render],

  options: {
    context: 'element',
    namespace: 'LSD'
  },

  initialize: function(document, options) {
    if (options && options.documentElement || document && !document.documentElement)
      options = [document, document = options][0];
    if (document == null) document = window.document;
    if (!LSD.document) LSD.document = this;
    this.setOptions(options || {});
    this.document = this;
    this.element = document;
    this.sourceIndex = 1;
    this.layout = this.getLayout();
    this.childNodes = [];
    this.factory = Object.getFromPath(window[this.options.namespace], LSD.toClassName(this.options.context));
    LSD.uid(this);
    if (this.constructors.properties) this.constructors.properties.apply(this, arguments);
    if (this.constructors.render) this.constructors.render.apply(this, arguments);

    /*
      Trick Slick into thinking that LSD elements tree is an XML node
      tree (so it won't try speeding up the queries with optimizations)
    */
    this.documentElement = this;
    this.xml = true;
    this.slickFeatures = LSD.Module.Selectors.Features;
    this.nodeType = 9;
    this.attributes = {};

    this.params = (location.search.length > 1) ? location.search.substr(1, location.search.length - 1).parseQueryString() : {}
    if (this.element && this.element.documentElement) {
      this.element.addEvent('domready', function() {
        this.building = true;
        if ("benchmark" in this.params) LSD.console.profile();
        this.build();
        if ("benchmark" in this.params) LSD.console.profileEnd();
        this.building = false;
      }.bind(this));
      this.element.addEvent('click', this.onClick.bind(this));
      this.element.addEvent('mousedown', this.onMousedown.bind(this));
    } else {
      this.build();
    }
  },

  /*
    Single relay click listener is put upon document.
    It spies for all clicks on elements and finds out if
    any links were clicked. If the link is not widget,
    the listener creates a lightweight link class instance and
    calls click on it to trigger commands and interactions.

    This way there's no need to preinitialize all link handlers,
    and only instantiate class when the link was actually clicked.
  */
  onClick: function(event) {
    if (event.target.ownerDocument == document && // click is in the same frame
       !event.rightClick &&                       // and click is not right click
       !(event.control || event.meta) &&          // and ctrl/command is not held
       !(event.event.which == 3))                 // and it's not the middle button
    for (var target = event.target, link, widget; target && target.tagName; target = target.parentNode) {
      widget = target.uid && Element.retrieve(target, 'widget');
      var a = (LSD.toLowerCase(target.tagName) == 'a');
      if (a) {
        if (!widget) {
          var parent = LSD.Module.DOM.find(target)
          widget = new LSD.Widget(target, {
            pseudos: ['clickable', 'command'],
            document: this
          });
          parent.appendChild(widget, false);
        }
        event.preventDefault();
      }
      if (widget && widget.pseudos.clickable) {
        event.stopPropagation();
         if (widget.click(event)) break;
      }
    };
  },

  onMousedown: function(event) {
    if (event.target.ownerDocument == document)
    for (var target = event.target, widget; target && target.tagName; target = target.parentNode) {
      widget = target.localName ? target.uid && Element.retrieve(target, 'widget') : target;
      if (widget && widget.pseudos.activatable) {
        widget.fireEvent('mousedown', event);
        target = widget;
      }
    };
  },

  setHead: function(head) {
    for (var i = 0, el, els = head.getElementsByTagName('meta'); el = els[i++];) {
      var type = el.getAttribute('rel');
      if (type) {
        type += 's';
        if (!this[type]) this[type] = {};
        var content = el.getAttribute('content')
        if (content) this[type][el.getAttribute('name')] = (content.charAt(0) =="{") ? JSON.decode(content) : content;
      }
    }
    // Attach stylesheets, if there are stylesheets loaded
    if (LSD.Sheet && LSD.Sheet.stylesheets) for (var i = 0, sheet; sheet = LSD.Sheet.stylesheets[i++];) this.addStylesheet(sheet);
  },

  getLayout: function() {
    if (this.layout) return this.layout;
    this.layout = new LSD.Layout;
    this.layout.document = this;
    return this.layout;
  },

  create: function(element, options) {
    if (!options) options = {};
    options.document = this;
    return this.factory.create(element, options);
  },

  build: function(document) {
    this.fireEvent('beforeBuild', document)
    this.built = true;
    if (this.element !== false) {
      if (!document) document = this.element || window.document;
      this.setHead(document.head);
      var element = this.element = document.body;
      this.setBody(document.body);
    }
    this.render();
    this.fireEvent('build', document)
  },

  setBody: function(element) {
    if (!element) element = this.getBodyElement();
    this.fireEvent('beforeBody', element);
    var options = {
      document: this,
      events: {
        self: {
          boot: function() {
            this.document.body = this;
          }
        }
      },
      tag: 'body'
    };
    if (this.options.mutations) options.mutations = this.options.mutations;
    if (this.options.context) options.context = this.options.context;
    new LSD.Widget(element, options);
    this.fireEvent('body', [this.body, element]);
    this.childNodes.push(this.body)
    return element;
  },

  getBodyElement: function() {
    return this.document.body;
  },

  redirect: function(url) {
    window.location.href = url;
  },

  getElements: function() {
    return this.body.getElements.apply(this.body, arguments);
  },

  getElement: function() {
    return this.body.getElement.apply(this.body, arguments);
  },

  addStylesheet: function(sheet) {
    if (!this.stylesheets) this.stylesheets = [];
    this.stylesheets.include(sheet);
    sheet.attach(this);
  },

  removeStylesheet: function(sheet) {
    if (!this.stylesheets) return;
    this.stylesheets.erase(sheet);
    sheet.detach(this);
  },

  $family: Function.from('document')
});<|endoftext|>


<commit_before>/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
"use strict";

const Template = require("../Template");
const SyncWaterfallHook = require("tapable").SyncWaterfallHook;

class JsonpMainTemplatePlugin {
	apply(mainTemplate) {
		const needChunkOnDemandLoadingCode = chunk => {
			for (const chunkGroup of chunk.groupsIterable) {
				if (chunkGroup.getNumberOfChildren() > 0) return true;
			}
			return false;
		};
		const needChunkLoadingCode = chunk => {
			for (const chunkGroup of chunk.groupsIterable) {
				if (chunkGroup.chunks.length > 1) return true;
				if (chunkGroup.getNumberOfChildren() > 0) return true;
			}
			return false;
		};
		const needEntryDeferringCode = chunk => {
			for (const chunkGroup of chunk.groupsIterable) {
				if (chunkGroup.chunks.length > 1) return true;
			}
			return false;
		};
		// TODO refactor this
		if (!mainTemplate.hooks.jsonpScript) {
			mainTemplate.hooks.jsonpScript = new SyncWaterfallHook([
				"source",
				"chunk",
				"hash"
			]);
		}

		mainTemplate.hooks.localVars.tap(
			"JsonpMainTemplatePlugin",
			(source, chunk) => {
				if (needChunkLoadingCode(chunk)) {
					return Template.asString([
						source,
						"",
						"// object to store loaded and loading chunks",
						"var installedChunks = {",
						Template.indent(
							chunk.ids.map(id => `${JSON.stringify(id)}: 0`).join(",\n")
						),
						"};",
						"",
						needEntryDeferringCode(chunk) ? "var deferredModules = [];" : ""
					]);
				}
				return source;
			}
		);
		mainTemplate.hooks.jsonpScript.tap(
			"JsonpMainTemplatePlugin",
			(_, chunk, hash) => {
				const chunkFilename = mainTemplate.outputOptions.chunkFilename;
				const chunkMaps = chunk.getChunkMaps();
				const crossOriginLoading =
					mainTemplate.outputOptions.crossOriginLoading;
				const chunkLoadTimeout = mainTemplate.outputOptions.chunkLoadTimeout;
				const jsonpScriptType = mainTemplate.outputOptions.jsonpScriptType;
				const scriptSrcPath = mainTemplate.getAssetPath(
					JSON.stringify(chunkFilename),
					{
						hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`,
						hashWithLength: length =>
							`" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "`,
						chunk: {
							id: '" + chunkId + "',
							hash: `" + ${JSON.stringify(chunkMaps.hash)}[chunkId] + "`,
							hashWithLength(length) {
								const shortChunkHashMap = Object.create(null);
								for (const chunkId of Object.keys(chunkMaps.hash)) {
									if (typeof chunkMaps.hash[chunkId] === "string")
										shortChunkHashMap[chunkId] = chunkMaps.hash[chunkId].substr(
											0,
											length
										);
								}
								return `" + ${JSON.stringify(shortChunkHashMap)}[chunkId] + "`;
							},
							name: `" + (${JSON.stringify(
								chunkMaps.name
							)}[chunkId]||chunkId) + "`
						}
					}
				);
				return Template.asString([
					"var script = document.createElement('script');",
					jsonpScriptType
						? `script.type = ${JSON.stringify(jsonpScriptType)};`
						: "",
					"script.charset = 'utf-8';",
					`script.timeout = ${chunkLoadTimeout};`,
					crossOriginLoading
						? `script.crossOrigin = ${JSON.stringify(crossOriginLoading)};`
						: "",
					`if (${mainTemplate.requireFn}.nc) {`,
					Template.indent(
						`script.setAttribute("nonce", ${mainTemplate.requireFn}.nc);`
					),
					"}",
					`script.src = ${mainTemplate.requireFn}.p + ${scriptSrcPath};`,
					"var timeout = setTimeout(function(){",
					Template.indent([
						"onScriptComplete({ type: 'timeout', target: script });"
					]),
					`}, ${chunkLoadTimeout});`,
					"script.onerror = script.onload = onScriptComplete;",
					"function onScriptComplete(event) {",
					Template.indent([
						"// avoid mem leaks in IE.",
						"script.onerror = script.onload = null;",
						"clearTimeout(timeout);",
						"var chunk = installedChunks[chunkId];",
						"if(chunk !== 0) {",
						Template.indent([
							"if(chunk) {",
							Template.indent([
								"var errorType = event && (event.type === 'load' ? 'missing' : event.type);",
								"var realSrc = event && event.target && event.target.src;",
								"var error = new Error('Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')');",
								"error.type = errorType;",
								"error.request = realSrc;",
								"chunk[1](error);"
							]),
							"}",
							"installedChunks[chunkId] = undefined;"
						]),
						"}"
					]),
					"};"
				]);
			}
		);
		mainTemplate.hooks.requireEnsure.tap(
			"JsonpMainTemplatePlugin",
			(source, chunk, hash) => {
				return Template.asString([
					source,
					"",
					"// JSONP chunk loading for javascript",
					"",
					"var installedChunkData = installedChunks[chunkId];",
					'if(installedChunkData !== 0) { // 0 means "already installed".',
					Template.indent([
						"",
						'// a Promise means "currently loading".',
						"if(installedChunkData) {",
						Template.indent(["promises.push(installedChunkData[2]);"]),
						"} else {",
						Template.indent([
							"// setup Promise in chunk cache",
							"var promise = new Promise(function(resolve, reject) {",
							Template.indent([
								"installedChunkData = installedChunks[chunkId] = [resolve, reject];"
							]),
							"});",
							"promises.push(installedChunkData[2] = promise);",
							"",
							"// start chunk loading",
							"var head = document.getElementsByTagName('head')[0];",
							mainTemplate.hooks.jsonpScript.call("", chunk, hash),
							"head.appendChild(script);"
						]),
						"}"
					]),
					"}"
				]);
			}
		);
		mainTemplate.hooks.requireExtensions.tap(
			"JsonpMainTemplatePlugin",
			(source, chunk) => {
				if (!needChunkOnDemandLoadingCode(chunk)) return source;

				return Template.asString([
					source,
					"",
					"// on error function for async loading",
					`${
						mainTemplate.requireFn
					}.oe = function(err) { console.error(err); throw err; };`
				]);
			}
		);
		mainTemplate.hooks.bootstrap.tap(
			"JsonpMainTemplatePlugin",
			(source, chunk, hash) => {
				if (needChunkLoadingCode(chunk)) {
					const withDefer = needEntryDeferringCode(chunk);
					return Template.asString([
						source,
						"",
						"// install a JSONP callback for chunk loading",
						"function webpackJsonpCallback(data) {",
						Template.indent([
							"var chunkIds = data[0];",
							"var moreModules = data[1]",
							withDefer ? "var executeModules = data[2];" : "",
							'// add "moreModules" to the modules object,',
							'// then flag all "chunkIds" as loaded and fire callback',
							"var moduleId, chunkId, i = 0, resolves = [];",
							"for(;i < chunkIds.length; i++) {",
							Template.indent([
								"chunkId = chunkIds[i];",
								"if(installedChunks[chunkId]) {",
								Template.indent("resolves.push(installedChunks[chunkId][0]);"),
								"}",
								"installedChunks[chunkId] = 0;"
							]),
							"}",
							"for(moduleId in moreModules) {",
							Template.indent([
								"if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {",
								Template.indent(
									mainTemplate.renderAddModule(
										hash,
										chunk,
										"moduleId",
										"moreModules[moduleId]"
									)
								),
								"}"
							]),
							"}",
							"if(parentJsonpFunction) parentJsonpFunction(data);",
							"while(resolves.length) {",
							Template.indent("resolves.shift()();"),
							"}",
							withDefer
								? Template.asString([
										"",
										"// add entry modules from loaded chunk to deferred list",
										"deferredModules.push.apply(deferredModules, executeModules || []);",
										"",
										"// run deferred modules when all chunks ready",
										"return checkDeferredModules();"
									])
								: ""
						]),
						"};",
						withDefer
							? Template.asString([
									"function checkDeferredModules() {",
									Template.indent([
										"var result;",
										"for(var i = 0; i < deferredModules.length; i++) {",
										Template.indent([
											"var deferredModule = deferredModules[i];",
											"var fulfilled = true;",
											"for(var j = 1; j < deferredModule.length; j++) {",
											Template.indent([
												"var depId = deferredModule[j];",
												"if(installedChunks[depId] !== 0) fulfilled = false;"
											]),
											"}",
											"if(fulfilled) {",
											Template.indent([
												"deferredModules.splice(i--, 1);",
												"result = " +
													mainTemplate.requireFn +
													"(" +
													mainTemplate.requireFn +
													".s = deferredModule[0]);"
											]),
											"}"
										]),
										"}",
										"return result;"
									]),
									"}"
								])
							: ""
					]);
				}
				return source;
			}
		);
		mainTemplate.hooks.beforeStartup.tap(
			"JsonpMainTemplatePlugin",
			(source, chunk, hash) => {
				if (needChunkLoadingCode(chunk)) {
					var jsonpFunction = mainTemplate.outputOptions.jsonpFunction;
					var globalObject = mainTemplate.outputOptions.globalObject;
					return Template.asString([
						`var jsonpArray = ${globalObject}[${JSON.stringify(
							jsonpFunction
						)}] = ${globalObject}[${JSON.stringify(jsonpFunction)}] || [];`,
						"var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);",
						"jsonpArray.push = webpackJsonpCallback;",
						"jsonpArray = jsonpArray.slice();",
						"for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);",
						"var parentJsonpFunction = oldJsonpFunction;",
						"",
						source
					]);
				}
				return source;
			}
		);
		mainTemplate.hooks.startup.tap(
			"JsonpMainTemplatePlugin",
			(source, chunk, hash) => {
				if (needEntryDeferringCode(chunk)) {
					if (chunk.hasEntryModule()) {
						const entries = [chunk.entryModule].filter(Boolean).map(m =>
							[m.id].concat(
								Array.from(chunk.groupsIterable)[0]
									.chunks.filter(c => c !== chunk)
									.map(c => c.id)
							)
						);
						return Template.asString([
							"// add entry module to deferred list",
							`deferredModules.push(${entries
								.map(e => JSON.stringify(e))
								.join(", ")});`,
							"// run deferred modules when ready",
							"return checkDeferredModules();"
						]);
					} else {
						return Template.asString([
							"// run deferred modules from other chunks",
							"checkDeferredModules();"
						]);
					}
				}
				return source;
			}
		);
		mainTemplate.hooks.hotBootstrap.tap(
			"JsonpMainTemplatePlugin",
			(source, chunk, hash) => {
				const globalObject = mainTemplate.outputOptions.globalObject;
				const hotUpdateChunkFilename =
					mainTemplate.outputOptions.hotUpdateChunkFilename;
				const hotUpdateMainFilename =
					mainTemplate.outputOptions.hotUpdateMainFilename;
				const crossOriginLoading =
					mainTemplate.outputOptions.crossOriginLoading;
				const hotUpdateFunction = mainTemplate.outputOptions.hotUpdateFunction;
				const currentHotUpdateChunkFilename = mainTemplate.getAssetPath(
					JSON.stringify(hotUpdateChunkFilename),
					{
						hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`,
						hashWithLength: length =>
							`" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "`,
						chunk: {
							id: '" + chunkId + "'
						}
					}
				);
				const currentHotUpdateMainFilename = mainTemplate.getAssetPath(
					JSON.stringify(hotUpdateMainFilename),
					{
						hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`,
						hashWithLength: length =>
							`" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "`
					}
				);
				const runtimeSource = Template.getFunctionContent(
					require("./JsonpMainTemplate.runtime.js")
				)
					.replace(/\/\/\$semicolon/g, ";")
					.replace(/\$require\$/g, mainTemplate.requireFn)
					.replace(
						/\$crossOriginLoading\$/g,
						crossOriginLoading
							? `script.crossOrigin = ${JSON.stringify(crossOriginLoading)}`
							: ""
					)
					.replace(/\$hotMainFilename\$/g, currentHotUpdateMainFilename)
					.replace(/\$hotChunkFilename\$/g, currentHotUpdateChunkFilename)
					.replace(/\$hash\$/g, JSON.stringify(hash));
				return `${source}
function hotDisposeChunk(chunkId) {
	delete installedChunks[chunkId];
}
var parentHotUpdateCallback = ${globalObject}[${JSON.stringify(
					hotUpdateFunction
				)}];
${globalObject}[${JSON.stringify(hotUpdateFunction)}] = ${runtimeSource}`;
			}
		);
		mainTemplate.hooks.hash.tap("JsonpMainTemplatePlugin", hash => {
			hash.update("jsonp");
			hash.update("5");
			hash.update(`${mainTemplate.outputOptions.globalObject}`);
			hash.update(`${mainTemplate.outputOptions.chunkFilename}`);
			hash.update(`${mainTemplate.outputOptions.jsonpFunction}`);
			hash.update(`${mainTemplate.outputOptions.hotUpdateFunction}`);
		});
	}
}
module.exports = JsonpMainTemplatePlugin;
<commit_msg>fix(bug) #5964 convert MS into S for scripts timeout attr<commit_after>/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
"use strict";

const Template = require("../Template");
const SyncWaterfallHook = require("tapable").SyncWaterfallHook;

class JsonpMainTemplatePlugin {
	apply(mainTemplate) {
		const needChunkOnDemandLoadingCode = chunk => {
			for (const chunkGroup of chunk.groupsIterable) {
				if (chunkGroup.getNumberOfChildren() > 0) return true;
			}
			return false;
		};
		const needChunkLoadingCode = chunk => {
			for (const chunkGroup of chunk.groupsIterable) {
				if (chunkGroup.chunks.length > 1) return true;
				if (chunkGroup.getNumberOfChildren() > 0) return true;
			}
			return false;
		};
		const needEntryDeferringCode = chunk => {
			for (const chunkGroup of chunk.groupsIterable) {
				if (chunkGroup.chunks.length > 1) return true;
			}
			return false;
		};
		// TODO refactor this
		if (!mainTemplate.hooks.jsonpScript) {
			mainTemplate.hooks.jsonpScript = new SyncWaterfallHook([
				"source",
				"chunk",
				"hash"
			]);
		}

		mainTemplate.hooks.localVars.tap(
			"JsonpMainTemplatePlugin",
			(source, chunk) => {
				if (needChunkLoadingCode(chunk)) {
					return Template.asString([
						source,
						"",
						"// object to store loaded and loading chunks",
						"var installedChunks = {",
						Template.indent(
							chunk.ids.map(id => `${JSON.stringify(id)}: 0`).join(",\n")
						),
						"};",
						"",
						needEntryDeferringCode(chunk) ? "var deferredModules = [];" : ""
					]);
				}
				return source;
			}
		);
		mainTemplate.hooks.jsonpScript.tap(
			"JsonpMainTemplatePlugin",
			(_, chunk, hash) => {
				const chunkFilename = mainTemplate.outputOptions.chunkFilename;
				const chunkMaps = chunk.getChunkMaps();
				const crossOriginLoading =
					mainTemplate.outputOptions.crossOriginLoading;
				const chunkLoadTimeout = mainTemplate.outputOptions.chunkLoadTimeout;
				const jsonpScriptType = mainTemplate.outputOptions.jsonpScriptType;
				const scriptSrcPath = mainTemplate.getAssetPath(
					JSON.stringify(chunkFilename),
					{
						hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`,
						hashWithLength: length =>
							`" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "`,
						chunk: {
							id: '" + chunkId + "',
							hash: `" + ${JSON.stringify(chunkMaps.hash)}[chunkId] + "`,
							hashWithLength(length) {
								const shortChunkHashMap = Object.create(null);
								for (const chunkId of Object.keys(chunkMaps.hash)) {
									if (typeof chunkMaps.hash[chunkId] === "string")
										shortChunkHashMap[chunkId] = chunkMaps.hash[chunkId].substr(
											0,
											length
										);
								}
								return `" + ${JSON.stringify(shortChunkHashMap)}[chunkId] + "`;
							},
							name: `" + (${JSON.stringify(
								chunkMaps.name
							)}[chunkId]||chunkId) + "`
						}
					}
				);
				return Template.asString([
					"var script = document.createElement('script');",
					jsonpScriptType
						? `script.type = ${JSON.stringify(jsonpScriptType)};`
						: "",
					"script.charset = 'utf-8';",
					`script.timeout = ${chunkLoadTimeout / 1000};`,
					crossOriginLoading
						? `script.crossOrigin = ${JSON.stringify(crossOriginLoading)};`
						: "",
					`if (${mainTemplate.requireFn}.nc) {`,
					Template.indent(
						`script.setAttribute("nonce", ${mainTemplate.requireFn}.nc);`
					),
					"}",
					`script.src = ${mainTemplate.requireFn}.p + ${scriptSrcPath};`,
					"var timeout = setTimeout(function(){",
					Template.indent([
						"onScriptComplete({ type: 'timeout', target: script });"
					]),
					`}, ${chunkLoadTimeout});`,
					"script.onerror = script.onload = onScriptComplete;",
					"function onScriptComplete(event) {",
					Template.indent([
						"// avoid mem leaks in IE.",
						"script.onerror = script.onload = null;",
						"clearTimeout(timeout);",
						"var chunk = installedChunks[chunkId];",
						"if(chunk !== 0) {",
						Template.indent([
							"if(chunk) {",
							Template.indent([
								"var errorType = event && (event.type === 'load' ? 'missing' : event.type);",
								"var realSrc = event && event.target && event.target.src;",
								"var error = new Error('Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')');",
								"error.type = errorType;",
								"error.request = realSrc;",
								"chunk[1](error);"
							]),
							"}",
							"installedChunks[chunkId] = undefined;"
						]),
						"}"
					]),
					"};"
				]);
			}
		);
		mainTemplate.hooks.requireEnsure.tap(
			"JsonpMainTemplatePlugin",
			(source, chunk, hash) => {
				return Template.asString([
					source,
					"",
					"// JSONP chunk loading for javascript",
					"",
					"var installedChunkData = installedChunks[chunkId];",
					'if(installedChunkData !== 0) { // 0 means "already installed".',
					Template.indent([
						"",
						'// a Promise means "currently loading".',
						"if(installedChunkData) {",
						Template.indent(["promises.push(installedChunkData[2]);"]),
						"} else {",
						Template.indent([
							"// setup Promise in chunk cache",
							"var promise = new Promise(function(resolve, reject) {",
							Template.indent([
								"installedChunkData = installedChunks[chunkId] = [resolve, reject];"
							]),
							"});",
							"promises.push(installedChunkData[2] = promise);",
							"",
							"// start chunk loading",
							"var head = document.getElementsByTagName('head')[0];",
							mainTemplate.hooks.jsonpScript.call("", chunk, hash),
							"head.appendChild(script);"
						]),
						"}"
					]),
					"}"
				]);
			}
		);
		mainTemplate.hooks.requireExtensions.tap(
			"JsonpMainTemplatePlugin",
			(source, chunk) => {
				if (!needChunkOnDemandLoadingCode(chunk)) return source;

				return Template.asString([
					source,
					"",
					"// on error function for async loading",
					`${
						mainTemplate.requireFn
					}.oe = function(err) { console.error(err); throw err; };`
				]);
			}
		);
		mainTemplate.hooks.bootstrap.tap(
			"JsonpMainTemplatePlugin",
			(source, chunk, hash) => {
				if (needChunkLoadingCode(chunk)) {
					const withDefer = needEntryDeferringCode(chunk);
					return Template.asString([
						source,
						"",
						"// install a JSONP callback for chunk loading",
						"function webpackJsonpCallback(data) {",
						Template.indent([
							"var chunkIds = data[0];",
							"var moreModules = data[1]",
							withDefer ? "var executeModules = data[2];" : "",
							'// add "moreModules" to the modules object,',
							'// then flag all "chunkIds" as loaded and fire callback',
							"var moduleId, chunkId, i = 0, resolves = [];",
							"for(;i < chunkIds.length; i++) {",
							Template.indent([
								"chunkId = chunkIds[i];",
								"if(installedChunks[chunkId]) {",
								Template.indent("resolves.push(installedChunks[chunkId][0]);"),
								"}",
								"installedChunks[chunkId] = 0;"
							]),
							"}",
							"for(moduleId in moreModules) {",
							Template.indent([
								"if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {",
								Template.indent(
									mainTemplate.renderAddModule(
										hash,
										chunk,
										"moduleId",
										"moreModules[moduleId]"
									)
								),
								"}"
							]),
							"}",
							"if(parentJsonpFunction) parentJsonpFunction(data);",
							"while(resolves.length) {",
							Template.indent("resolves.shift()();"),
							"}",
							withDefer
								? Template.asString([
										"",
										"// add entry modules from loaded chunk to deferred list",
										"deferredModules.push.apply(deferredModules, executeModules || []);",
										"",
										"// run deferred modules when all chunks ready",
										"return checkDeferredModules();"
									])
								: ""
						]),
						"};",
						withDefer
							? Template.asString([
									"function checkDeferredModules() {",
									Template.indent([
										"var result;",
										"for(var i = 0; i < deferredModules.length; i++) {",
										Template.indent([
											"var deferredModule = deferredModules[i];",
											"var fulfilled = true;",
											"for(var j = 1; j < deferredModule.length; j++) {",
											Template.indent([
												"var depId = deferredModule[j];",
												"if(installedChunks[depId] !== 0) fulfilled = false;"
											]),
											"}",
											"if(fulfilled) {",
											Template.indent([
												"deferredModules.splice(i--, 1);",
												"result = " +
													mainTemplate.requireFn +
													"(" +
													mainTemplate.requireFn +
													".s = deferredModule[0]);"
											]),
											"}"
										]),
										"}",
										"return result;"
									]),
									"}"
								])
							: ""
					]);
				}
				return source;
			}
		);
		mainTemplate.hooks.beforeStartup.tap(
			"JsonpMainTemplatePlugin",
			(source, chunk, hash) => {
				if (needChunkLoadingCode(chunk)) {
					var jsonpFunction = mainTemplate.outputOptions.jsonpFunction;
					var globalObject = mainTemplate.outputOptions.globalObject;
					return Template.asString([
						`var jsonpArray = ${globalObject}[${JSON.stringify(
							jsonpFunction
						)}] = ${globalObject}[${JSON.stringify(jsonpFunction)}] || [];`,
						"var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);",
						"jsonpArray.push = webpackJsonpCallback;",
						"jsonpArray = jsonpArray.slice();",
						"for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);",
						"var parentJsonpFunction = oldJsonpFunction;",
						"",
						source
					]);
				}
				return source;
			}
		);
		mainTemplate.hooks.startup.tap(
			"JsonpMainTemplatePlugin",
			(source, chunk, hash) => {
				if (needEntryDeferringCode(chunk)) {
					if (chunk.hasEntryModule()) {
						const entries = [chunk.entryModule].filter(Boolean).map(m =>
							[m.id].concat(
								Array.from(chunk.groupsIterable)[0]
									.chunks.filter(c => c !== chunk)
									.map(c => c.id)
							)
						);
						return Template.asString([
							"// add entry module to deferred list",
							`deferredModules.push(${entries
								.map(e => JSON.stringify(e))
								.join(", ")});`,
							"// run deferred modules when ready",
							"return checkDeferredModules();"
						]);
					} else {
						return Template.asString([
							"// run deferred modules from other chunks",
							"checkDeferredModules();"
						]);
					}
				}
				return source;
			}
		);
		mainTemplate.hooks.hotBootstrap.tap(
			"JsonpMainTemplatePlugin",
			(source, chunk, hash) => {
				const globalObject = mainTemplate.outputOptions.globalObject;
				const hotUpdateChunkFilename =
					mainTemplate.outputOptions.hotUpdateChunkFilename;
				const hotUpdateMainFilename =
					mainTemplate.outputOptions.hotUpdateMainFilename;
				const crossOriginLoading =
					mainTemplate.outputOptions.crossOriginLoading;
				const hotUpdateFunction = mainTemplate.outputOptions.hotUpdateFunction;
				const currentHotUpdateChunkFilename = mainTemplate.getAssetPath(
					JSON.stringify(hotUpdateChunkFilename),
					{
						hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`,
						hashWithLength: length =>
							`" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "`,
						chunk: {
							id: '" + chunkId + "'
						}
					}
				);
				const currentHotUpdateMainFilename = mainTemplate.getAssetPath(
					JSON.stringify(hotUpdateMainFilename),
					{
						hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`,
						hashWithLength: length =>
							`" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "`
					}
				);
				const runtimeSource = Template.getFunctionContent(
					require("./JsonpMainTemplate.runtime.js")
				)
					.replace(/\/\/\$semicolon/g, ";")
					.replace(/\$require\$/g, mainTemplate.requireFn)
					.replace(
						/\$crossOriginLoading\$/g,
						crossOriginLoading
							? `script.crossOrigin = ${JSON.stringify(crossOriginLoading)}`
							: ""
					)
					.replace(/\$hotMainFilename\$/g, currentHotUpdateMainFilename)
					.replace(/\$hotChunkFilename\$/g, currentHotUpdateChunkFilename)
					.replace(/\$hash\$/g, JSON.stringify(hash));
				return `${source}
function hotDisposeChunk(chunkId) {
	delete installedChunks[chunkId];
}
var parentHotUpdateCallback = ${globalObject}[${JSON.stringify(
					hotUpdateFunction
				)}];
${globalObject}[${JSON.stringify(hotUpdateFunction)}] = ${runtimeSource}`;
			}
		);
		mainTemplate.hooks.hash.tap("JsonpMainTemplatePlugin", hash => {
			hash.update("jsonp");
			hash.update("5");
			hash.update(`${mainTemplate.outputOptions.globalObject}`);
			hash.update(`${mainTemplate.outputOptions.chunkFilename}`);
			hash.update(`${mainTemplate.outputOptions.jsonpFunction}`);
			hash.update(`${mainTemplate.outputOptions.hotUpdateFunction}`);
		});
	}
}
module.exports = JsonpMainTemplatePlugin;
<|endoftext|>


<commit_before>
const config = require('./webpack.config.js');

const copyStatic = require('./../etc/copy-static');
copyStatic(config.version);

module.exports = config;
<commit_msg>[+] webpack out file minimization<commit_after>
const config = require('./webpack.config');
const webpack = require('webpack');

const copyStatic = require('./../etc/copy-static');
copyStatic(config.version);

config.plugins.push(new webpack.optimize.UglifyJsPlugin({
    compress: {
        warnings: false
    }
}));

config.plugins.push(new webpack.optimize.MinChunkSizePlugin({
    minChunkSize : 2000
}));

module.exports = config;
<|endoftext|>


<commit_before>/**
 * Terminal/WindowManager core script
 * jQuery plugin for opening windows from the terminal
 * Espen Andersen, Norwegian Broadcast Corporation
 * espen.andersen@nrk.no
 * (c) 2013 - NRK Investigative unit
 * Released under the MIT license
 * http://opensource.org/licenses/MIT
 */
( function( $ ) {

	var
		ROOT_SELECTOR = '.__window__manager__root__',

		that,
		root,
		persistent = { windows: { } },

		public_members = {
			'close_window': closeWindow,
			'flash_window': flashWindow,
			'move_window': moveWindow,
			'open_window': openWindow,
			'send_message': sendMessage,
			'set_focus': setFocus
		};

	// Produce a random, unique hexadecimal ID string
	function getUniqueId( prefix ) {
		return 	prefix +
					 String( '00000000' +
							 Math.floor( 0xFFFFFFFF * Math.random() )
							.toString( 16 ) )
					.slice( -8 );
	}

	// brings specified window to the front, normalizing but preserving
	// the z-order index for the other windows
	function bringToFront( hWnd ) {

		var
			i,

			hierarchy =
				root
					.find( '.window' )
					.toArray();

		persistent.windows[ hWnd ].css( 'z-index', 9999 );
		hierarchy.sort( function( a, b ) {
			return ( Number( a.style.zIndex ) - Number( b.style.zIndex ) );
		} );

		for( i = 0; i < hierarchy.length; i++ ) {
			$( hierarchy[ i ] ).css( 'z-index', 10 + i );
		}
	};

	// Close window, param must be either the window handle,
	// or an object with the handle stored in a hWnd property.
	function closeWindow( param ) {

		var
			hWnd = typeof param === 'object' ? param.hWnd : param;

		if( persistent.windows[ hWnd ] ) {

			var

				win =
					root
						.find( '#' + hWnd ),

				winInfo =
					win.data( 'wininfo' );

			sendMessage( { msg: 'wm_before_close' }, winInfo.hWnd );

			win
				.removeData( 'wininfo' );

			delete winInfo.hWnd;

			root
				.find( '.overlay textarea' )
				.prop( 'disabled', true );

			win
				.remove();

			delete persistent.windows[ hWnd ];

			var e = new $.Event( 'notify' );
			e.msg = 'close_window';
			e.winInfo = winInfo;
			that.trigger( e );
		}
	};

	// Flash window title bar, param must be either the window handle,
	// or an object with the handle stored in a hWnd property.
	function flashWindow( param ) {

		var
			hWnd = typeof param === 'object' ? param.hWnd : param,
			win = $( '#' + hWnd ),
			counter = 0,
			timer;

		if( persistent.windows[ hWnd ] ) {
			if( timer ) {
				clearInterval( timer );
				timer = 0;
				counter = 0;
			}
			timer =
				setInterval( function( e ) {
					if( ++counter >= 8 ) {
						clearInterval( timer );
						timer = 0;
						win.removeClass( 'flash' );
						counter = 0;
					}
					else {
						win.toggleClass( 'flash' );
					}
				}, 50 );
		}
	};

	// Create new window
	function createWindow( param ) {

		var

			styles = { display: 'none' },

			winCount = root.find( '.window' ).length,

			winInfo = {
				eventDispatcher: that,
				windowManager: root,
				hWnd: getUniqueId( 'win_' ),
				wndTitle: ( param && param.wndTitle ) || '',
				wndClass: ( param && param.wndClass ) || 'default',
				wndClose: ( param && param.wndClose ) || '',
				statusBar: param.statusBar === true,
				resizeHandle: param.resizeHandle === true
			};

			if( param ) {
				if( param.width ) styles.width = param.width;
				if( param.height ) styles.height = param.height;
			}
			else {
				param = { };
			}

			// Default positioning:
			if( styles.left === undefined ) {
				//styles.left = ( 1 + winCount ) * 30;
			}
			if( styles.top === undefined ) {
				//styles.top = ( 1 + winCount ) * 30;
			}

		var newWin = { };
		newWin[ winInfo.hWnd ] =

			root
				.prepend( 	'
' +
						   		'
' +
									'' + winInfo.wndTitle + '' +
									'X' +
								'
' +
								'
' +
								'
' +
							'
' )

				.find( '#' + winInfo.hWnd )
				.addClass( winInfo.wndClass )
				.data( 'wininfo', winInfo )
				.css( styles )
				.draggable( {
					handle: 'h2',
					start:
						function( e ) {
							bringToFront( $( e.target ).closest( '.window' ).attr( 'id' ) );
						}
				} )
				.find( '.titleBar .close' )
				.click( function( e ) {
					var
						hWnd =
							$( e.target )
								.closest( '.window' )
								.attr( 'id' );

					closeWindow( hWnd );
					e.preventDefault();
					e.stopPropagation();
				} )
				.end()
				.find( '.clientRect' )
				.on( 'mousewheel', function( scr, d ) {
					var w = $( this );
					if( d > 0 && w.scrollTop() === 0 ) {
						scr.preventDefault();
					}
					else if( d < 0 && ( w.scrollTop() >= ( w.get( 0 ).scrollHeight - w.innerHeight() - 1 ) ) ) {
						scr.preventDefault();
					}
				} )
				.end();

		if( winInfo.statusBar || winInfo.resizeHandle ) {
			root
				.find( '#' + winInfo.hWnd )
				.addClass( 'withStatusBar' )
				.append( '

Ready

' );
		}

		if( winInfo.resizeHandle ) {
			root
				.find( '#' + winInfo.hWnd )
				.find( '.statusBar' )
				.append( '

' );

			root.find( '#' + winInfo.hWnd ).resizable( { handles: "se" } );
		}

		persistent.windows = $.extend( { }, persistent.windows, newWin );

		param && param.wndProc && param.wndProc( winInfo );

		return winInfo;
	}

	// Default window proc displays en empty window
	function defaultWndProc( winInfo ) {
		showWindow( winInfo.hWnd );
	}

	// Initialize WindowManager
	function init( _options ) {

		root =
			$( that )
				.html( '

' )
				.find( ROOT_SELECTOR );
		root
			.on( 'click', '.window', function( e ) {
				$( e.target )
					.closest( '.window' )
					.each( function( index, win ) {
						var
							hWnd = $( win ).attr( 'id' );
						bringToFront( hWnd );
					} )
					.siblings( '.focus' )
					.removeClass( 'focus' )
					.end()
					.addClass( 'focus' );
			} )
			.on( 'drag', '.window', function( e ) {

				var
					hWnd = $( e.target ).attr( 'id' );

				if( persistent.windows[ hWnd ] ) {
					persistent.windows[ hWnd ].userPositioned = true;
				}

			} );
	};

	function isTopmost( hWnd ) {
		return $( '#' + hWnd ).css( 'z-index' ) == getTopmostIndex();
	};

	function getTopmostIndex() {
		var
			zOrder = [ ],
			windows = $( '.windowManager .window' );

		windows
			.each( function( i, e ) {
				zOrder[ i ] = $( e ).css( 'z-index' );
			} );

		var
			iTopMost =
				( zOrder
					.sort(
						function( a, b ) {
							return a - b;
						} )
					.reverse() ) [ 0 ]
		return iTopMost;
	};

	// Move a window
	function moveWindow( hWnd, pos ) {
		root
			.find( '#' + hWnd )
			.css( {
				top: pos.top,
				left: pos.left } );
	}

	// Open a window, create new if no handle to existing window is provided
	function openWindow( param ) {

		var winInfo;

		if( param === undefined ||
			param.hWnd === undefined ||
			persistent.windows[ param.hWnd ] === undefined ) {

			winInfo = createWindow( param );
		}
		else {
			winInfo = param;
		}

		showWindow( winInfo.hWnd );

		var e = new $.Event( 'notify' );
		e.msg = 'open_window';
		e.winInfo = winInfo;
		that.trigger( e );
	};

	// WindowManager data store
	function savePersistent() {
		root
			.data( 'persistent', persistent );
	};

	// Send message to one or all windows. If no handle is provided
	// (i.e. undefined), the message is broadcasted to all windows
	function sendMessage( param, hWnd ) {
		if( param && param.msg ) {
			var
				e = new $.Event( param.msg ),
				selector = hWnd !== undefined ? '#' + hWnd : '.window';
			e.msg = param.msg;
			e.param = param;
			root
				.find( selector )
				.trigger( e );
		}
	};

	// Bring window to front and activate it
	function setFocus( param ) {
		if( param && param.hWnd ) {
			bringToFront( param.hWnd );
		}
	};

	// Make window visible
	function showWindow( hWnd ) {

		var
			wnd = $( persistent.windows[ hWnd ] );

		bringToFront( hWnd );

		if( wnd.length === 1 ) {

			var
				x = parseInt( wnd.css( 'left' ) ),
				y = parseInt( wnd.css( 'top' ) );

			wnd
				.css( { display: 'block', left: 0, top: 0, opacity: 0.0 } )
				.animate( { left: x, top: y, opacity: 1.0 }, 500 );
		}
	};

	// Expose interface
	$.fn.windowManager = function( param ) {

		var retVal,
			index = 0,
			argv = arguments,
			argc = argv.length;

		this.each( function() {
			that = $( this );
			if( param === undefined || typeof param === 'object' ) {
				// Initialization
				init.apply( this, [ param ] );
				savePersistent();
			}
			else if( public_members[ param ] !== undefined ) {
				// Call to public member
				root = that.find( ROOT_SELECTOR );
				persistent = $( root ).data( 'persistent' );
				retVal = public_members[ param ].apply( this, Array.prototype.slice.call( argv, 1 ) );
				// Callback func should be the last argument
				if( argc > 0 && typeof argv[ argc - 1 ] === 'function' ) {
					// Pass return value for each element to callback function
					( argv[ argc - 1 ] )( index, retVal );
					savePersistent();
					retVal = null;
				}
				else {
					savePersistent();
					// No callback; break loop if return value was present
					if( retVal ) return false;
				}
			}
			else {
				$.error( 'Method not found in windowManager' );
			}
			index++;
		} );
		// Maintain chainability unless returning something
		return retVal || this;
	}

} )( jQuery );<commit_msg>iPad behavior tweak<commit_after>/**
 * Terminal/WindowManager core script
 * jQuery plugin for opening windows from the terminal
 * Espen Andersen, Norwegian Broadcast Corporation
 * espen.andersen@nrk.no
 * (c) 2013 - NRK Investigative unit
 * Released under the MIT license
 * http://opensource.org/licenses/MIT
 */
( function( $ ) {

	var
		ROOT_SELECTOR = '.__window__manager__root__',

		that,
		root,
		persistent = { windows: { } },

		public_members = {
			'close_window': closeWindow,
			'flash_window': flashWindow,
			'move_window': moveWindow,
			'open_window': openWindow,
			'send_message': sendMessage,
			'set_focus': setFocus
		};

	// Produce a random, unique hexadecimal ID string
	function getUniqueId( prefix ) {
		return 	prefix +
					 String( '00000000' +
							 Math.floor( 0xFFFFFFFF * Math.random() )
							.toString( 16 ) )
					.slice( -8 );
	}

	// brings specified window to the front, normalizing but preserving
	// the z-order index for the other windows
	function bringToFront( hWnd ) {

		var
			i,

			hierarchy =
				root
					.find( '.window' )
					.toArray();

		persistent.windows[ hWnd ].css( 'z-index', 9999 );
		hierarchy.sort( function( a, b ) {
			return ( Number( a.style.zIndex ) - Number( b.style.zIndex ) );
		} );

		for( i = 0; i < hierarchy.length; i++ ) {
			$( hierarchy[ i ] ).css( 'z-index', 10 + i );
		}
	};

	// Close window, param must be either the window handle,
	// or an object with the handle stored in a hWnd property.
	function closeWindow( param ) {

		var
			hWnd = typeof param === 'object' ? param.hWnd : param;

		if( persistent.windows[ hWnd ] ) {

			var

				win =
					root
						.find( '#' + hWnd ),

				winInfo =
					win.data( 'wininfo' );

			sendMessage( { msg: 'wm_before_close' }, winInfo.hWnd );

			win
				.removeData( 'wininfo' );

			delete winInfo.hWnd;

			root
				.find( '.overlay textarea' )
				.attr( 'disabled', 'disabled' );

			win
				.remove();

			delete persistent.windows[ hWnd ];

			var e = new $.Event( 'notify' );
			e.msg = 'close_window';
			e.winInfo = winInfo;
			that.trigger( e );
		}
	};

	// Flash window title bar, param must be either the window handle,
	// or an object with the handle stored in a hWnd property.
	function flashWindow( param ) {

		var
			hWnd = typeof param === 'object' ? param.hWnd : param,
			win = $( '#' + hWnd ),
			counter = 0,
			timer;

		if( persistent.windows[ hWnd ] ) {
			if( timer ) {
				clearInterval( timer );
				timer = 0;
				counter = 0;
			}
			timer =
				setInterval( function( e ) {
					if( ++counter >= 8 ) {
						clearInterval( timer );
						timer = 0;
						win.removeClass( 'flash' );
						counter = 0;
					}
					else {
						win.toggleClass( 'flash' );
					}
				}, 50 );
		}
	};

	// Create new window
	function createWindow( param ) {

		var

			styles = { display: 'none' },

			winCount = root.find( '.window' ).length,

			winInfo = {
				eventDispatcher: that,
				windowManager: root,
				hWnd: getUniqueId( 'win_' ),
				wndTitle: ( param && param.wndTitle ) || '',
				wndClass: ( param && param.wndClass ) || 'default',
				wndClose: ( param && param.wndClose ) || '',
				statusBar: param.statusBar === true,
				resizeHandle: param.resizeHandle === true
			};

			if( param ) {
				if( param.width ) styles.width = param.width;
				if( param.height ) styles.height = param.height;
			}
			else {
				param = { };
			}

			// Default positioning:
			if( styles.left === undefined ) {
				//styles.left = ( 1 + winCount ) * 30;
			}
			if( styles.top === undefined ) {
				//styles.top = ( 1 + winCount ) * 30;
			}

		var newWin = { };
		newWin[ winInfo.hWnd ] =

			root
				.prepend( 	'
' +
						   		'
' +
									'' + winInfo.wndTitle + '' +
									'X' +
								'
' +
								'
' +
								'
' +
							'
' )

				.find( '#' + winInfo.hWnd )
				.addClass( winInfo.wndClass )
				.data( 'wininfo', winInfo )
				.css( styles )
				.draggable( {
					handle: 'h2',
					start:
						function( e ) {
							bringToFront( $( e.target ).closest( '.window' ).attr( 'id' ) );
						}
				} )
				.find( '.titleBar .close' )
				.click( function( e ) {
					var
						hWnd =
							$( e.target )
								.closest( '.window' )
								.attr( 'id' );

					closeWindow( hWnd );
					e.preventDefault();
					e.stopPropagation();
				} )
				.end()
				.find( '.clientRect' )
				.on( 'mousewheel', function( scr, d ) {
					var w = $( this );
					if( d > 0 && w.scrollTop() === 0 ) {
						scr.preventDefault();
					}
					else if( d < 0 && ( w.scrollTop() >= ( w.get( 0 ).scrollHeight - w.innerHeight() - 1 ) ) ) {
						scr.preventDefault();
					}
				} )
				.end();

		if( winInfo.statusBar || winInfo.resizeHandle ) {
			root
				.find( '#' + winInfo.hWnd )
				.addClass( 'withStatusBar' )
				.append( '

Ready

' );
		}

		if( winInfo.resizeHandle ) {
			root
				.find( '#' + winInfo.hWnd )
				.find( '.statusBar' )
				.append( '

' );

			root.find( '#' + winInfo.hWnd ).resizable( { handles: "se" } );
		}

		persistent.windows = $.extend( { }, persistent.windows, newWin );

		param && param.wndProc && param.wndProc( winInfo );

		return winInfo;
	}

	// Default window proc displays en empty window
	function defaultWndProc( winInfo ) {
		showWindow( winInfo.hWnd );
	}

	// Initialize WindowManager
	function init( _options ) {

		root =
			$( that )
				.html( '

' )
				.find( ROOT_SELECTOR );
		root
			.on( 'click', '.window', function( e ) {
				$( e.target )
					.closest( '.window' )
					.each( function( index, win ) {
						var
							hWnd = $( win ).attr( 'id' );
						bringToFront( hWnd );
					} )
					.siblings( '.focus' )
					.removeClass( 'focus' )
					.end()
					.addClass( 'focus' );
			} )
			.on( 'drag', '.window', function( e ) {

				var
					hWnd = $( e.target ).attr( 'id' );

				if( persistent.windows[ hWnd ] ) {
					persistent.windows[ hWnd ].userPositioned = true;
				}

			} );
	};

	function isTopmost( hWnd ) {
		return $( '#' + hWnd ).css( 'z-index' ) == getTopmostIndex();
	};

	function getTopmostIndex() {
		var
			zOrder = [ ],
			windows = $( '.windowManager .window' );

		windows
			.each( function( i, e ) {
				zOrder[ i ] = $( e ).css( 'z-index' );
			} );

		var
			iTopMost =
				( zOrder
					.sort(
						function( a, b ) {
							return a - b;
						} )
					.reverse() ) [ 0 ]
		return iTopMost;
	};

	// Move a window
	function moveWindow( hWnd, pos ) {
		root
			.find( '#' + hWnd )
			.css( {
				top: pos.top,
				left: pos.left } );
	}

	// Open a window, create new if no handle to existing window is provided
	function openWindow( param ) {

		var winInfo;

		if( param === undefined ||
			param.hWnd === undefined ||
			persistent.windows[ param.hWnd ] === undefined ) {

			winInfo = createWindow( param );
		}
		else {
			winInfo = param;
		}

		showWindow( winInfo.hWnd );

		var e = new $.Event( 'notify' );
		e.msg = 'open_window';
		e.winInfo = winInfo;
		that.trigger( e );
	};

	// WindowManager data store
	function savePersistent() {
		root
			.data( 'persistent', persistent );
	};

	// Send message to one or all windows. If no handle is provided
	// (i.e. undefined), the message is broadcasted to all windows
	function sendMessage( param, hWnd ) {
		if( param && param.msg ) {
			var
				e = new $.Event( param.msg ),
				selector = hWnd !== undefined ? '#' + hWnd : '.window';
			e.msg = param.msg;
			e.param = param;
			root
				.find( selector )
				.trigger( e );
		}
	};

	// Bring window to front and activate it
	function setFocus( param ) {
		if( param && param.hWnd ) {
			bringToFront( param.hWnd );
		}
	};

	// Make window visible
	function showWindow( hWnd ) {

		var
			wnd = $( persistent.windows[ hWnd ] );

		bringToFront( hWnd );

		if( wnd.length === 1 ) {

			var
				x = parseInt( wnd.css( 'left' ) ),
				y = parseInt( wnd.css( 'top' ) );

			wnd
				.css( { display: 'block', left: 0, top: 0, opacity: 0.0 } )
				.animate( { left: x, top: y, opacity: 1.0 }, 500 );
		}
	};

	// Expose interface
	$.fn.windowManager = function( param ) {

		var retVal,
			index = 0,
			argv = arguments,
			argc = argv.length;

		this.each( function() {
			that = $( this );
			if( param === undefined || typeof param === 'object' ) {
				// Initialization
				init.apply( this, [ param ] );
				savePersistent();
			}
			else if( public_members[ param ] !== undefined ) {
				// Call to public member
				root = that.find( ROOT_SELECTOR );
				persistent = $( root ).data( 'persistent' );
				retVal = public_members[ param ].apply( this, Array.prototype.slice.call( argv, 1 ) );
				// Callback func should be the last argument
				if( argc > 0 && typeof argv[ argc - 1 ] === 'function' ) {
					// Pass return value for each element to callback function
					( argv[ argc - 1 ] )( index, retVal );
					savePersistent();
					retVal = null;
				}
				else {
					savePersistent();
					// No callback; break loop if return value was present
					if( retVal ) return false;
				}
			}
			else {
				$.error( 'Method not found in windowManager' );
			}
			index++;
		} );
		// Maintain chainability unless returning something
		return retVal || this;
	}

} )( jQuery );<|endoftext|>


<commit_before>define(["Tone/core/Tone"], function (Tone) {

	/**
	 *  @class Tone.TimeBase is a flexible encoding of time
	 *         which can be evaluated to and from a string.
	 *  @extends {Tone}
	 *  @param  {Time}  val    The time value as a number or string
	 *  @param  {String=}  units  Unit values
	 *  @example
	 * Tone.TimeBase(4, "n")
	 * Tone.TimeBase(2, "t")
	 * Tone.TimeBase("2t")
	 * Tone.TimeBase("2t") + Tone.TimeBase("4n");
	 */
	Tone.TimeBase = function(val, units){

		//allows it to be constructed with or without 'new'
		if (this instanceof Tone.TimeBase) {

			/**
			 *  The value
			 *  @type  {Number|String|Tone.TimeBase}
			 *  @private
			 */
			this._val = val;

			/**
			 * The units
			 * @type {String?}
			 */
			this._units = units;

			//test if the value is a string representation of a number
			if (Tone.isUndef(this._units) && Tone.isString(this._val) &&
				// eslint-disable-next-line eqeqeq
				parseFloat(this._val) == this._val && this._val.charAt(0) !== "+"){
				this._val = parseFloat(this._val);
				this._units = this._defaultUnits;
			} else if (val && val.constructor === this.constructor){
				//if they're the same type, just copy values over
				this._val = val._val;
				this._units = val._units;
			} else if (val instanceof Tone.TimeBase){
				switch(this._defaultUnits){
					case "s" :
						this._val = val.toSeconds();
						break;
					case "i" :
						this._val = val.toTicks();
						break;
					case "hz" :
						this._val = val.toFrequency();
						break;
					case "midi" :
						this._val = val.toMidi();
						break;
					default :
						throw new Error("Unrecognized default units "+this._defaultUnits);
				}
			}

		} else {

			return new Tone.TimeBase(val, units);
		}
	};

	Tone.extend(Tone.TimeBase);

	///////////////////////////////////////////////////////////////////////////
	//	ABSTRACT SYNTAX TREE PARSER
	///////////////////////////////////////////////////////////////////////////

	/**
	 *  All the primary expressions.
	 *  @private
	 *  @type  {Object}
	 */
	Tone.TimeBase.prototype._expressions = {
		"n" : {
			regexp : /^(\d+)n(\.?)$/i,
			method : function(value, dot){
				value = parseInt(value);
				var scalar = dot === "." ? 1.5 : 1;
				if (value === 1){
					return this._beatsToUnits(this._getTimeSignature())*scalar;
				} else {
					return this._beatsToUnits(4 / value)*scalar;
				}
			}
		},
		"t" : {
			regexp : /^(\d+)t$/i,
			method : function(value){
				value = parseInt(value);
				return this._beatsToUnits(8 / (parseInt(value) * 3));
			}
		},
		"m" : {
			regexp : /^(\d+)m$/i,
			method : function(value){
				return this._beatsToUnits(parseInt(value) * this._getTimeSignature());
			}
		},
		"i" : {
			regexp : /^(\d+)i$/i,
			method : function(value){
				return this._ticksToUnits(parseInt(value));
			}
		},
		"hz" : {
			regexp : /^(\d+(?:\.\d+)?)hz$/i,
			method : function(value){
				return this._frequencyToUnits(parseFloat(value));
			}
		},
		"tr" : {
			regexp : /^(\d+(?:\.\d+)?):(\d+(?:\.\d+)?):?(\d+(?:\.\d+)?)?$/,
			method : function(m, q, s){
				var total = 0;
				if (m && m !== "0"){
					total += this._beatsToUnits(this._getTimeSignature() * parseFloat(m));
				}
				if (q && q !== "0"){
					total += this._beatsToUnits(parseFloat(q));
				}
				if (s && s !== "0"){
					total += this._beatsToUnits(parseFloat(s) / 4);
				}
				return total;
			}
		},
		"s" : {
			regexp : /^(\d+(?:\.\d+)?s)$/,
			method : function(value){
				return this._secondsToUnits(parseFloat(value));
			}
		},
		"samples" : {
			regexp : /^(\d+)samples$/,
			method : function(value){
				return parseInt(value) / this.context.sampleRate;
			}
		},
		"default" : {
			regexp : /^(\d+(?:\.\d+)?)$/,
			method : function(value){
				return this._expressions[this._defaultUnits].method.call(this, value);
			}
		}
	};

	/**
	 *  The default units if none are given.
	 *  @type {String}
	 *  @private
	 */
	Tone.TimeBase.prototype._defaultUnits = "s";

	///////////////////////////////////////////////////////////////////////////
	//	TRANSPORT FALLBACKS
	///////////////////////////////////////////////////////////////////////////

	/**
	 * Return the bpm, or 120 if Transport is not available
	 * @type {Number}
	 * @private
	 */
	Tone.TimeBase.prototype._getBpm = function(){
		if (Tone.Transport){
			return Tone.Transport.bpm.value;
		} else {
			return 120;
		}
	};

	/**
	 * Return the timeSignature or 4 if Transport is not available
	 * @type {Number}
	 * @private
	 */
	Tone.TimeBase.prototype._getTimeSignature = function(){
		if (Tone.Transport){
			return Tone.Transport.timeSignature;
		} else {
			return 4;
		}
	};

	/**
	 * Return the PPQ or 192 if Transport is not available
	 * @type {Number}
	 * @private
	 */
	Tone.TimeBase.prototype._getPPQ = function(){
		if (Tone.Transport){
			return Tone.Transport.PPQ;
		} else {
			return 192;
		}
	};

	/**
	 * Return the current time in whichever context is relevant
	 * @type {Number}
	 * @private
	 */
	Tone.TimeBase.prototype._now = function(){
		return this.now();
	};

	///////////////////////////////////////////////////////////////////////////
	//	UNIT CONVERSIONS
	///////////////////////////////////////////////////////////////////////////

	/**
	 *  Returns the value of a frequency in the current units
	 *  @param {Frequency} freq
	 *  @return  {Number}
	 *  @private
	 */
	Tone.TimeBase.prototype._frequencyToUnits = function(freq){
		return 1/freq;
	};

	/**
	 *  Return the value of the beats in the current units
	 *  @param {Number} beats
	 *  @return  {Number}
	 *  @private
	 */
	Tone.TimeBase.prototype._beatsToUnits = function(beats){
		return (60 / this._getBpm()) * beats;
	};

	/**
	 *  Returns the value of a second in the current units
	 *  @param {Seconds} seconds
	 *  @return  {Number}
	 *  @private
	 */
	Tone.TimeBase.prototype._secondsToUnits = function(seconds){
		return seconds;
	};

	/**
	 *  Returns the value of a tick in the current time units
	 *  @param {Ticks} ticks
	 *  @return  {Number}
	 *  @private
	 */
	Tone.TimeBase.prototype._ticksToUnits = function(ticks){
		return ticks * (this._beatsToUnits(1) / this._getPPQ());
	};

	/**
	 * With no arguments, return 'now'
	 *  @return  {Number}
	 *  @private
	 */
	Tone.TimeBase.prototype._noArg = function(){
		return this._now();
	};

	///////////////////////////////////////////////////////////////////////////
	//	EXPRESSIONS
	///////////////////////////////////////////////////////////////////////////

	/**
	 *  Evaluate the time value. Returns the time
	 *  in seconds.
	 *  @return  {Seconds}
	 */
	Tone.TimeBase.prototype.valueOf = function(){
		if (Tone.isUndef(this._val)){
			return this._noArg();
		} else if (Tone.isString(this._val) && Tone.isUndef(this._units)){
			for (var units in this._expressions){
				if (this._expressions[units].regexp.test(this._val.trim())){
					this._units = units;
					break;
				}
			}
		}
		if (!Tone.isUndef(this._units)){
			var expr = this._expressions[this._units];
			var matching = this._val.toString().trim().match(expr.regexp);
			if (matching){
				return expr.method.apply(this, matching.slice(1));
			} else {
				return expr.method.call(this, parseFloat(this._val));
			}
		} else {
			return this._val;
		}
	};

	/**
	 *  Return the value in seconds
	 *  @return {Seconds}
	 */
	Tone.TimeBase.prototype.toSeconds = function(){
		return this.valueOf();
	};

	/**
	 *  Return the value in hertz
	 *  @return {Frequency}
	 */
	Tone.TimeBase.prototype.toFrequency = function(){
		return 1 / this.toSeconds();
	};

	/**
	 *  Return the time in samples
	 *  @return  {Samples}
	 */
	Tone.TimeBase.prototype.toSamples = function(){
		return this.toSeconds() * this.context.sampleRate;
	};

	/**
	 *  Return the time in milliseconds.
	 *  @return  {Milliseconds}
	 */
	Tone.TimeBase.prototype.toMilliseconds = function(){
		return this.toSeconds() * 1000;
	};

	/**
	 *  Clean up
	 *  @return {Tone.TimeBase} this
	 */
	Tone.TimeBase.prototype.dispose = function(){
		this._val = null;
		this._units = null;
	};

	return Tone.TimeBase;
});
<commit_msg>updating regex<commit_after>define(["Tone/core/Tone"], function (Tone) {

	/**
	 *  @class Tone.TimeBase is a flexible encoding of time
	 *         which can be evaluated to and from a string.
	 *  @extends {Tone}
	 *  @param  {Time}  val    The time value as a number or string
	 *  @param  {String=}  units  Unit values
	 *  @example
	 * Tone.TimeBase(4, "n")
	 * Tone.TimeBase(2, "t")
	 * Tone.TimeBase("2t")
	 * Tone.TimeBase("2t") + Tone.TimeBase("4n");
	 */
	Tone.TimeBase = function(val, units){

		//allows it to be constructed with or without 'new'
		if (this instanceof Tone.TimeBase) {

			/**
			 *  The value
			 *  @type  {Number|String|Tone.TimeBase}
			 *  @private
			 */
			this._val = val;

			/**
			 * The units
			 * @type {String?}
			 */
			this._units = units;

			//test if the value is a string representation of a number
			if (Tone.isUndef(this._units) && Tone.isString(this._val) &&
				// eslint-disable-next-line eqeqeq
				parseFloat(this._val) == this._val && this._val.charAt(0) !== "+"){
				this._val = parseFloat(this._val);
				this._units = this._defaultUnits;
			} else if (val && val.constructor === this.constructor){
				//if they're the same type, just copy values over
				this._val = val._val;
				this._units = val._units;
			} else if (val instanceof Tone.TimeBase){
				switch(this._defaultUnits){
					case "s" :
						this._val = val.toSeconds();
						break;
					case "i" :
						this._val = val.toTicks();
						break;
					case "hz" :
						this._val = val.toFrequency();
						break;
					case "midi" :
						this._val = val.toMidi();
						break;
					default :
						throw new Error("Unrecognized default units "+this._defaultUnits);
				}
			}

		} else {

			return new Tone.TimeBase(val, units);
		}
	};

	Tone.extend(Tone.TimeBase);

	///////////////////////////////////////////////////////////////////////////
	//	ABSTRACT SYNTAX TREE PARSER
	///////////////////////////////////////////////////////////////////////////

	/**
	 *  All the primary expressions.
	 *  @private
	 *  @type  {Object}
	 */
	Tone.TimeBase.prototype._expressions = {
		"n" : {
			regexp : /^(\d+)n(\.?)$/i,
			method : function(value, dot){
				value = parseInt(value);
				var scalar = dot === "." ? 1.5 : 1;
				if (value === 1){
					return this._beatsToUnits(this._getTimeSignature())*scalar;
				} else {
					return this._beatsToUnits(4 / value)*scalar;
				}
			}
		},
		"t" : {
			regexp : /^(\d+)t$/i,
			method : function(value){
				value = parseInt(value);
				return this._beatsToUnits(8 / (parseInt(value) * 3));
			}
		},
		"m" : {
			regexp : /^(\d+)m$/i,
			method : function(value){
				return this._beatsToUnits(parseInt(value) * this._getTimeSignature());
			}
		},
		"i" : {
			regexp : /^(\d+)i$/i,
			method : function(value){
				return this._ticksToUnits(parseInt(value));
			}
		},
		"hz" : {
			regexp : /^(\d+(?:\.\d+)?)hz$/i,
			method : function(value){
				return this._frequencyToUnits(parseFloat(value));
			}
		},
		"tr" : {
			regexp : /^(\d+(?:\.\d+)?):(\d+(?:\.\d+)?):?(\d+(?:\.\d+)?)?$/,
			method : function(m, q, s){
				var total = 0;
				if (m && m !== "0"){
					total += this._beatsToUnits(this._getTimeSignature() * parseFloat(m));
				}
				if (q && q !== "0"){
					total += this._beatsToUnits(parseFloat(q));
				}
				if (s && s !== "0"){
					total += this._beatsToUnits(parseFloat(s) / 4);
				}
				return total;
			}
		},
		"s" : {
			regexp : /^(\d+(?:\.\d+)?)s$/,
			method : function(value){
				return this._secondsToUnits(parseFloat(value));
			}
		},
		"samples" : {
			regexp : /^(\d+)samples$/,
			method : function(value){
				return parseInt(value) / this.context.sampleRate;
			}
		},
		"default" : {
			regexp : /^(\d+(?:\.\d+)?)$/,
			method : function(value){
				return this._expressions[this._defaultUnits].method.call(this, value);
			}
		}
	};

	/**
	 *  The default units if none are given.
	 *  @type {String}
	 *  @private
	 */
	Tone.TimeBase.prototype._defaultUnits = "s";

	///////////////////////////////////////////////////////////////////////////
	//	TRANSPORT FALLBACKS
	///////////////////////////////////////////////////////////////////////////

	/**
	 * Return the bpm, or 120 if Transport is not available
	 * @type {Number}
	 * @private
	 */
	Tone.TimeBase.prototype._getBpm = function(){
		if (Tone.Transport){
			return Tone.Transport.bpm.value;
		} else {
			return 120;
		}
	};

	/**
	 * Return the timeSignature or 4 if Transport is not available
	 * @type {Number}
	 * @private
	 */
	Tone.TimeBase.prototype._getTimeSignature = function(){
		if (Tone.Transport){
			return Tone.Transport.timeSignature;
		} else {
			return 4;
		}
	};

	/**
	 * Return the PPQ or 192 if Transport is not available
	 * @type {Number}
	 * @private
	 */
	Tone.TimeBase.prototype._getPPQ = function(){
		if (Tone.Transport){
			return Tone.Transport.PPQ;
		} else {
			return 192;
		}
	};

	/**
	 * Return the current time in whichever context is relevant
	 * @type {Number}
	 * @private
	 */
	Tone.TimeBase.prototype._now = function(){
		return this.now();
	};

	///////////////////////////////////////////////////////////////////////////
	//	UNIT CONVERSIONS
	///////////////////////////////////////////////////////////////////////////

	/**
	 *  Returns the value of a frequency in the current units
	 *  @param {Frequency} freq
	 *  @return  {Number}
	 *  @private
	 */
	Tone.TimeBase.prototype._frequencyToUnits = function(freq){
		return 1/freq;
	};

	/**
	 *  Return the value of the beats in the current units
	 *  @param {Number} beats
	 *  @return  {Number}
	 *  @private
	 */
	Tone.TimeBase.prototype._beatsToUnits = function(beats){
		return (60 / this._getBpm()) * beats;
	};

	/**
	 *  Returns the value of a second in the current units
	 *  @param {Seconds} seconds
	 *  @return  {Number}
	 *  @private
	 */
	Tone.TimeBase.prototype._secondsToUnits = function(seconds){
		return seconds;
	};

	/**
	 *  Returns the value of a tick in the current time units
	 *  @param {Ticks} ticks
	 *  @return  {Number}
	 *  @private
	 */
	Tone.TimeBase.prototype._ticksToUnits = function(ticks){
		return ticks * (this._beatsToUnits(1) / this._getPPQ());
	};

	/**
	 * With no arguments, return 'now'
	 *  @return  {Number}
	 *  @private
	 */
	Tone.TimeBase.prototype._noArg = function(){
		return this._now();
	};

	///////////////////////////////////////////////////////////////////////////
	//	EXPRESSIONS
	///////////////////////////////////////////////////////////////////////////

	/**
	 *  Evaluate the time value. Returns the time
	 *  in seconds.
	 *  @return  {Seconds}
	 */
	Tone.TimeBase.prototype.valueOf = function(){
		if (Tone.isUndef(this._val)){
			return this._noArg();
		} else if (Tone.isString(this._val) && Tone.isUndef(this._units)){
			for (var units in this._expressions){
				if (this._expressions[units].regexp.test(this._val.trim())){
					this._units = units;
					break;
				}
			}
		}
		if (!Tone.isUndef(this._units)){
			var expr = this._expressions[this._units];
			var matching = this._val.toString().trim().match(expr.regexp);
			if (matching){
				return expr.method.apply(this, matching.slice(1));
			} else {
				return expr.method.call(this, parseFloat(this._val));
			}
		} else {
			return this._val;
		}
	};

	/**
	 *  Return the value in seconds
	 *  @return {Seconds}
	 */
	Tone.TimeBase.prototype.toSeconds = function(){
		return this.valueOf();
	};

	/**
	 *  Return the value in hertz
	 *  @return {Frequency}
	 */
	Tone.TimeBase.prototype.toFrequency = function(){
		return 1 / this.toSeconds();
	};

	/**
	 *  Return the time in samples
	 *  @return  {Samples}
	 */
	Tone.TimeBase.prototype.toSamples = function(){
		return this.toSeconds() * this.context.sampleRate;
	};

	/**
	 *  Return the time in milliseconds.
	 *  @return  {Milliseconds}
	 */
	Tone.TimeBase.prototype.toMilliseconds = function(){
		return this.toSeconds() * 1000;
	};

	/**
	 *  Clean up
	 *  @return {Tone.TimeBase} this
	 */
	Tone.TimeBase.prototype.dispose = function(){
		this._val = null;
		this._units = null;
	};

	return Tone.TimeBase;
});
<|endoftext|>


<commit_before>'use strict';

const selenium = require('selenium-standalone');
const cp = require('child_process');
const path = require('path');
const fs = require('fs');
const mkdirp = require('mkdirp');
const util = require('util');

const NIGHTWATCH_CONFIG = process.env.NIGHTWATCH_CONFIG;
const LOG_DIR = process.env.LOG_DIR;
const REPORT_DIR = process.env.REPORT_DIR;
const NIGHTWATCH_ENV = process.env.NIGHTWATCH_ENV;
const WEBPACK_CONFIG = process.env.WEBPACK_CONFIG;
const NODE_PORT = process.env.NODE_PORT;
const PORT = process.env.PORT;
const TUNNEL_IDENTIFIER = process.env.TUNNEL_IDENTIFIER;

const createWebpackServer = config => {
  const webpack = require('webpack');
  const WebpackDevServer = require('webpack-dev-server');

  const webpackConfig = require(config.webpackConfig);

  return new WebpackDevServer(webpack(webpackConfig), {quiet: true});
};

const getConfig = options => {
  let nightwatchConfig = NIGHTWATCH_CONFIG ?
    path.resolve(NIGHTWATCH_CONFIG) : path.resolve(process.cwd(), 'nightwatch.json');

  try {
    require(nightwatchConfig);
  } catch (err) {
    console.log('Fallback to default nightwatch.json config');
    nightwatchConfig = path.resolve(__dirname, 'nightwatch.json');
  }

  const config = Object.assign({
    logDir: LOG_DIR ?
      path.resolve(LOG_DIR) : path.resolve(process.cwd(), 'reports'),
    reportDir: REPORT_DIR ?
      path.resolve(REPORT_DIR) : path.resolve(process.cwd(), 'reports', 'test-e2e'),
    nightwatchConfig,
    nightwatchEnv: NIGHTWATCH_ENV || 'default',
    webpackConfig: WEBPACK_CONFIG ?
      path.resolve(WEBPACK_CONFIG) : path.resolve(process.cwd(), 'webpack.config.js'),
    port: NODE_PORT || PORT || 8080,
    tunnelIdentifier: TUNNEL_IDENTIFIER || undefined
  }, options);

  console.log(`Running with config:\n${util.inspect(config, {depth: 0, colors: true})}`);

  return Object.assign({}, config, {
    server: config.server || createWebpackServer(config)
  });
};

module.exports = options => {
  const config = getConfig(options);

  const startServer = callback =>
    config.server.listen(config.port, '0.0.0.0', callback);

  const onServerStarted = seleniumChild => err => {
    if (err) {
      console.error(err.stack);
      process.exit(1);
    }

    mkdirp.sync(config.reportDir);

    const which = require('npm-which')(__dirname);

    const nightwatchRunner = which.sync('nightwatch');

    const args = [
      '--config', config.nightwatchConfig,
      '--env', config.nightwatchEnv,
      '--output', config.reportDir
    ];

    cp.spawn(nightwatchRunner, args, {stdio: 'inherit'})
      .on('error', err2 => {
        console.error(err2.stack);
        process.exit(1);
      })
      .on('close', code => {
        seleniumChild.kill('SIGINT');
        process.exit(code);
      });
  };

  function onSeleniumStarted(err, seleniumChild) {
    if (err) {
      console.error(err.stack);
      process.exit(1);
    }

    mkdirp.sync(config.logDir);

    const seleniumLog = fs.createWriteStream(path.resolve(config.logDir, 'selenium.log'));

    seleniumChild.stdout.pipe(seleniumLog);
    seleniumChild.stderr.pipe(seleniumLog);

    process.on('uncaughtException', err2 => {
      console.error(err2.stack);
      seleniumChild.kill('SIGINT');
      process.exit(1);
    });

    startServer(onServerStarted(seleniumChild));
  }

  function onSeleniumInstalled(err) {
    if (err) {
      console.error(err.stack);
      process.exit(1);
    }

    selenium.start({seleniumArgs: ['-debug']}, onSeleniumStarted);
  }

  selenium.install({}, onSeleniumInstalled);
};
<commit_msg>Add logger for selenium-standalone<commit_after>'use strict';

const selenium = require('selenium-standalone');
const cp = require('child_process');
const path = require('path');
const fs = require('fs');
const mkdirp = require('mkdirp');
const util = require('util');

const NIGHTWATCH_CONFIG = process.env.NIGHTWATCH_CONFIG;
const LOG_DIR = process.env.LOG_DIR;
const REPORT_DIR = process.env.REPORT_DIR;
const NIGHTWATCH_ENV = process.env.NIGHTWATCH_ENV;
const WEBPACK_CONFIG = process.env.WEBPACK_CONFIG;
const NODE_PORT = process.env.NODE_PORT;
const PORT = process.env.PORT;
const TUNNEL_IDENTIFIER = process.env.TUNNEL_IDENTIFIER;

const createWebpackServer = config => {
  const webpack = require('webpack');
  const WebpackDevServer = require('webpack-dev-server');

  const webpackConfig = require(config.webpackConfig);

  return new WebpackDevServer(webpack(webpackConfig), {quiet: true});
};

const getConfig = options => {
  let nightwatchConfig = NIGHTWATCH_CONFIG ?
    path.resolve(NIGHTWATCH_CONFIG) : path.resolve(process.cwd(), 'nightwatch.json');

  try {
    require(nightwatchConfig);
  } catch (err) {
    console.log('Fallback to default nightwatch.json config');
    nightwatchConfig = path.resolve(__dirname, 'nightwatch.json');
  }

  const config = Object.assign({
    logDir: LOG_DIR ?
      path.resolve(LOG_DIR) : path.resolve(process.cwd(), 'reports'),
    reportDir: REPORT_DIR ?
      path.resolve(REPORT_DIR) : path.resolve(process.cwd(), 'reports', 'test-e2e'),
    nightwatchConfig,
    nightwatchEnv: NIGHTWATCH_ENV || 'default',
    webpackConfig: WEBPACK_CONFIG ?
      path.resolve(WEBPACK_CONFIG) : path.resolve(process.cwd(), 'webpack.config.js'),
    port: NODE_PORT || PORT || 8080,
    tunnelIdentifier: TUNNEL_IDENTIFIER || undefined
  }, options);

  console.log(`Running with config:\n${util.inspect(config, {depth: 0, colors: true})}`);

  return Object.assign({}, config, {
    server: config.server || createWebpackServer(config)
  });
};

module.exports = options => {
  const config = getConfig(options);

  const startServer = callback =>
    config.server.listen(config.port, '0.0.0.0', callback);

  const onServerStarted = seleniumChild => err => {
    if (err) {
      console.error(err.stack);
      process.exit(1);
    }

    mkdirp.sync(config.reportDir);

    const which = require('npm-which')(__dirname);

    const nightwatchRunner = which.sync('nightwatch');

    const args = [
      '--config', config.nightwatchConfig,
      '--env', config.nightwatchEnv,
      '--output', config.reportDir
    ];

    cp.spawn(nightwatchRunner, args, {stdio: 'inherit'})
      .on('error', err2 => {
        console.error(err2.stack);
        process.exit(1);
      })
      .on('close', code => {
        seleniumChild.kill('SIGINT');
        process.exit(code);
      });
  };

  function onSeleniumStarted(err, seleniumChild) {
    if (err) {
      console.error(err.stack);
      process.exit(1);
    }

    mkdirp.sync(config.logDir);

    const seleniumLog = fs.createWriteStream(path.resolve(config.logDir, 'selenium.log'));

    seleniumChild.stdout.pipe(seleniumLog);
    seleniumChild.stderr.pipe(seleniumLog);

    process.on('uncaughtException', err2 => {
      console.error(err2.stack);
      seleniumChild.kill('SIGINT');
      process.exit(1);
    });

    startServer(onServerStarted(seleniumChild));
  }

  function onSeleniumInstalled(err) {
    if (err) {
      console.error(err.stack);
      process.exit(1);
    }

    selenium.start({seleniumArgs: ['-debug']}, onSeleniumStarted);
  }

  selenium.install({
    logger: message => console.log(message),
    progressCb: (totalLength, progressLength) =>
      console.log(`Downloading: ${(100 * (progressLength / totalLength)).toFixed(2)}%`)
  }, onSeleniumInstalled);
};
<|endoftext|>