<commit_before>/*!
**  rey -- Framework based on React and Flux that looks like AngularJS.
**  Copyright (c) 2016 Yuri Neves Silveira <http://yneves.com>
**  Licensed under The MIT License <http://opensource.org/licenses/MIT>
**  Distributed on <http://github.com/yneves/rey>
*/
// - -------------------------------------------------------------------- - //

"use strict";

var bluebird = require("bluebird");
window.Promise = bluebird;

var axios = require("axios");
var factory = require("bauer-factory");
var Rooter = require("rooter");
var Fluks = require("fluks");
var React = require("react-immutable");
var ReactDOM = require("react-dom");
var Immutable = require("immutable");
var classNames = require("classnames");
var CSSTransitionGroup = require("react-addons-css-transition-group");
var parseArgs = require("./args.js");

window.React = React;

module.exports = factory.createClass({

  constructor: function() {

    this.factories = {};
    this.instances = {};

    this.factory("Flux", function() {
      return Fluks.createFlux();
    });

    this.factory("Immutable", function() {
      return Immutable;
    });

    this.factory("classNames", function() {
      return classNames;
    });

    this.factory("React", function() {
      return React;
    });

    this.factory("ReactDOM", function() {
      return ReactDOM;
    });

    this.factory("CSSTransitionGroup", function() {
      return CSSTransitionGroup;
    });

    this.factory("http", function() {
      return axios;
    });

    this.factory("Dispatcher", ["Flux", function(Flux) {
      return Flux.dispatcher;
    }]);

  },

  isString: factory.isString,
  isNumber: factory.isNumber,
  isBoolean: factory.isBoolean,
  isArray: factory.isArray,
  isObject: factory.isObject,
  isNull: factory.isNull,
  isDefined: factory.isDefined,
  isUndefined: factory.isUndefined,
  isFunction: factory.isFunction,
  isError: factory.isError,
  isDate: factory.isDate,
  isRegExp: factory.isRegExp,
  isArguments: factory.isArguments,

  isStore: Fluks.isStore,
  isAction: Fluks.isAction,
  isDispatcher: Fluks.isDispatcher,

  isRouter: function(arg) { return arg instanceof Rooter; },
  isPromise: function(arg) { return arg instanceof Promise; },
  isComponent: factory.isObject,
  isController: function() {

  },

  merge: factory.merge,
  extend: factory.extend,

  createClass: factory.createClass,
  createObject: factory.createObject,

  createController: {

    // .createController(controller Object) :Component
    o: function(controller) {

      var mixin = {};
      var reserved = ["storeDidChange", "store", "component", "pageTitle"];

      Object.keys(controller).forEach(function(key) {
        if (reserved.indexOf(key) === -1) {
          mixin[key] = controller[key];
        }
      });

      var mixins = [mixin];

      if (this.isArray(controller.store)) {
        controller.store.forEach(function(store) {
          if (!this.isStore(store)) {
            store = this.inject(store);
          }
          if (this.isStore(store)) {
            mixins.push(store.createMixin());
          }
        }, this);

      } else if (this.isStore(controller.store)) {
        mixins.push(controller.store.createMixin());

      } else {
        var store = this.inject(controller.store);
        if (this.isStore(store)) {
          mixins.push(store.createMixin());
        }
      }

      var storeDidChange = this.isFunction(controller.storeDidChange) ?
        controller.storeDidChange :
        function(store) { this.setState(store.getState()); }

      var component = this.isString(controller.component) ?
        this.inject(controller.component) : controller.component;

      return React.createClass({

        displayName: name,
        mixins: mixins,
        storeDidChange: storeDidChange,

        componentDidMount: function() {
          if (controller.pageTitle) {
            var pageTitle = factory.isFunction(controller.pageTitle) ?
              controller.pageTitle.call(this) : controller.pageTitle;
            this.previousTitle = document.title;
            document.title = pageTitle;
          }
        },

        componentWillUnmount: function() {
          if (this.previousTitle) {
            document.title = this.previousTitle;
          }
        },

        render: function() {
          return React.createElement(component, this.state);
        }
      });
    }
  },

  factory: {

    // .factory(name String, injectable Function) :void
    sf: function(name, injectable) {
      this.factories[name] = injectable;
      return this;
    },

    // .factory(name String, injectable Array) :void
    sa: function(name, injectable) {
      this.factories[name] = injectable;
      return this;
    }
  },

  inject: {

    // .inject(name String) :Object
    s: function(name) {
      if (!this.factories[name]) {
        throw new Error("unknown dependency requested: " + name);
      }
      if (!this.instances[name]) {
        this.instances[name] = this.inject(this.factories[name]);
      }
      return this.instances[name];
    },

    // .inject(code Function) :Object
    f: function(code) {
      return this.inject(parseArgs(code).concat(code));
    },

    // .inject(dependencies Array) :Object
    a: function(deps) {
      if (!factory.isFunction(deps[deps.length - 1])) {
        throw new Error("Last element must be a function.");
      }
      var code = deps[deps.length - 1];
      var len = deps.length - 1;
      var args = [];
      var i;
      for (i = 0; i < len; i++) {
        args[i] = this.inject(deps[i]);
      }
      return code.apply(this, args);
    }
  },

  immutable: {

    // .immutable(name String, factory Function) :void
    sf: function(name, code) {
      return this.immutable(name, parseArgs(code).concat(code));
    },

    // .immutable(name String, dependencies Array) :void
    sa: function(name, deps) {
      return this.factory(name, [function() {
        return Immutable.fromJS(this.inject(deps));
      }]);
    }
  },

  store: {

    // .store(name String, factory Function) :void
    sf: function(name, code) {
      return this.store(name, parseArgs(code).concat(code));
    },

    // .store(name String, dependencies Array) :void
    sa: function(name, deps) {
      return this.factory(name, ["Flux", function(Flux) {
        var storeOptions = this.inject(deps);
        var store = Flux.createStore(storeOptions);
        if (storeOptions.registerHandler) {
          store.register(storeOptions.registerHandler);
        }
        return store;
      }]);
    }
  },

  action: {

    // .action(name String, factory Function) :void
    sf: function(name, code) {
      return this.action(name, parseArgs(code).concat(code));
    },

    // .action(name String, dependencies Array) :void
    sa: function(name, deps) {
      return this.factory(name, ["Flux", function(Flux) {
        return Flux.createAction(this.inject(deps));
      }]);
    }
  },

  controller: {

    // .controller(name String, factory Function) :void
    sf: function(name, code) {
      return this.controller(name, parseArgs(code).concat(code));
    },

    // .controller(name String, dependencies Array) :void
    sa: function(name, deps) {
      return this.factory(name, [function() {
        return this.createController(this.inject(deps));
      }]);
    }
  },

  component: {

    // .component(name String, factory Function) :void
    sf: function(name, code) {
      return this.component(name, parseArgs(code).concat(code));
    },

    // .component(name String, dependencies Array) :void
    sa: function(name, deps) {
      this.factory(name, [function() {
        var component = this.inject(deps);
        if (!component.displayName) {
          component.displayName = name;
        }
        try {
          return React.createClass(component);
        } catch(e) {
          throw new Error("failed to create component: " + name);
        }
      }]);
    }
  },

  router: {

    // .router(name String, factory Function) :void
    sf: function(name, code) {
      return this.router(name, parseArgs(code).concat(code));
    },

    // .router(name String, dependencies Array) :void
    sa: function(name, deps) {
      this.factory(name, [function() {

        var routes = this.inject(deps);

        if (factory.isObject(routes)) {

          Object.keys(routes).forEach(function(href) {

            var route = routes[href];
            if (factory.isObject(route)) {

              if (!factory.isDefined(route.handler)) {
                route.handler = function(activeRoute) {

                  var controller = factory.isString(route.controller) ?
                    this.inject(route.controller) : route.controller;

                  var container = factory.isString(route.container) ?
                    document.getElementById(route.container) :
                    factory.isFunction(route.container) ?
                      route.container() : route.container;

                  var element = React.createElement(controller, activeRoute);
                  ReactDOM.render(element, container);

                }.bind(this);
              }

              var routeCopy = {};
              Object.keys(route).forEach(function(key) {
                if (key !== "controller" && key !== "container") {
                  routeCopy[key] = route[key];
                }
              });
              routes[href] = routeCopy;

            } else if (factory.isFunction(route)) {
              routes[href] = { handler: route };
            }
          }, this);
        }

        var router = new Rooter();
        router.setRoute(routes);
        return router;
      }]);
    }
  },

  load: {

    // .run(dependencies Array) :void
    a: function(deps) {
      this.inject(deps.concat([function() {}]));
      return this;
    }
  },

  run: {

    // .run(code Function) :void
    f: function(code) {
      return this.run(parseArgs(code).concat(code));
    },

    // .run(dependencies Array) :void
    a: function(deps) {
      this.inject(deps);
      return this;
    }
  }

});

// - -------------------------------------------------------------------- - //
<commit_msg>Promise service<commit_after>/*!
**  rey -- Framework based on React and Flux that looks like AngularJS.
**  Copyright (c) 2016 Yuri Neves Silveira <http://yneves.com>
**  Licensed under The MIT License <http://opensource.org/licenses/MIT>
**  Distributed on <http://github.com/yneves/rey>
*/
// - -------------------------------------------------------------------- - //

"use strict";

var bluebird = require("bluebird");
window.Promise = bluebird;

var axios = require("axios");
var factory = require("bauer-factory");
var Rooter = require("rooter");
var Fluks = require("fluks");
var React = require("react-immutable");
var ReactDOM = require("react-dom");
var Immutable = require("immutable");
var classNames = require("classnames");
var CSSTransitionGroup = require("react-addons-css-transition-group");
var parseArgs = require("./args.js");

window.React = React;

module.exports = factory.createClass({

  constructor: function() {

    this.factories = {};
    this.instances = {};

    this.factory("Flux", function() {
      return Fluks.createFlux();
    });

    this.factory("Immutable", function() {
      return Immutable;
    });

    this.factory("classNames", function() {
      return classNames;
    });

    this.factory("React", function() {
      return React;
    });

    this.factory("ReactDOM", function() {
      return ReactDOM;
    });

    this.factory("CSSTransitionGroup", function() {
      return CSSTransitionGroup;
    });

    this.factory("http", function() {
      return axios;
    });

    this.factory("Promise", function() {
      return bluebird;
    });

    this.factory("Dispatcher", ["Flux", function(Flux) {
      return Flux.dispatcher;
    }]);

  },

  isString: factory.isString,
  isNumber: factory.isNumber,
  isBoolean: factory.isBoolean,
  isArray: factory.isArray,
  isObject: factory.isObject,
  isNull: factory.isNull,
  isDefined: factory.isDefined,
  isUndefined: factory.isUndefined,
  isFunction: factory.isFunction,
  isError: factory.isError,
  isDate: factory.isDate,
  isRegExp: factory.isRegExp,
  isArguments: factory.isArguments,

  isStore: Fluks.isStore,
  isAction: Fluks.isAction,
  isDispatcher: Fluks.isDispatcher,

  isRouter: function(arg) { return arg instanceof Rooter; },
  isPromise: function(arg) { return arg instanceof Promise; },
  isComponent: factory.isObject,
  isController: function() {

  },

  merge: factory.merge,
  extend: factory.extend,

  createClass: factory.createClass,
  createObject: factory.createObject,

  createController: {

    // .createController(controller Object) :Component
    o: function(controller) {

      var mixin = {};
      var reserved = ["storeDidChange", "store", "component", "pageTitle"];

      Object.keys(controller).forEach(function(key) {
        if (reserved.indexOf(key) === -1) {
          mixin[key] = controller[key];
        }
      });

      var mixins = [mixin];

      if (this.isArray(controller.store)) {
        controller.store.forEach(function(store) {
          if (!this.isStore(store)) {
            store = this.inject(store);
          }
          if (this.isStore(store)) {
            mixins.push(store.createMixin());
          }
        }, this);

      } else if (this.isStore(controller.store)) {
        mixins.push(controller.store.createMixin());

      } else {
        var store = this.inject(controller.store);
        if (this.isStore(store)) {
          mixins.push(store.createMixin());
        }
      }

      var storeDidChange = this.isFunction(controller.storeDidChange) ?
        controller.storeDidChange :
        function(store) { this.setState(store.getState()); }

      var component = this.isString(controller.component) ?
        this.inject(controller.component) : controller.component;

      return React.createClass({

        displayName: name,
        mixins: mixins,
        storeDidChange: storeDidChange,

        componentDidMount: function() {
          if (controller.pageTitle) {
            var pageTitle = factory.isFunction(controller.pageTitle) ?
              controller.pageTitle.call(this) : controller.pageTitle;
            this.previousTitle = document.title;
            document.title = pageTitle;
          }
        },

        componentWillUnmount: function() {
          if (this.previousTitle) {
            document.title = this.previousTitle;
          }
        },

        render: function() {
          return React.createElement(component, this.state);
        }
      });
    }
  },

  factory: {

    // .factory(name String, injectable Function) :void
    sf: function(name, injectable) {
      this.factories[name] = injectable;
      return this;
    },

    // .factory(name String, injectable Array) :void
    sa: function(name, injectable) {
      this.factories[name] = injectable;
      return this;
    }
  },

  inject: {

    // .inject(name String) :Object
    s: function(name) {
      if (!this.factories[name]) {
        throw new Error("unknown dependency requested: " + name);
      }
      if (!this.instances[name]) {
        this.instances[name] = this.inject(this.factories[name]);
      }
      return this.instances[name];
    },

    // .inject(code Function) :Object
    f: function(code) {
      return this.inject(parseArgs(code).concat(code));
    },

    // .inject(dependencies Array) :Object
    a: function(deps) {
      if (!factory.isFunction(deps[deps.length - 1])) {
        throw new Error("Last element must be a function.");
      }
      var code = deps[deps.length - 1];
      var len = deps.length - 1;
      var args = [];
      var i;
      for (i = 0; i < len; i++) {
        args[i] = this.inject(deps[i]);
      }
      return code.apply(this, args);
    }
  },

  immutable: {

    // .immutable(name String, factory Function) :void
    sf: function(name, code) {
      return this.immutable(name, parseArgs(code).concat(code));
    },

    // .immutable(name String, dependencies Array) :void
    sa: function(name, deps) {
      return this.factory(name, [function() {
        return Immutable.fromJS(this.inject(deps));
      }]);
    }
  },

  store: {

    // .store(name String, factory Function) :void
    sf: function(name, code) {
      return this.store(name, parseArgs(code).concat(code));
    },

    // .store(name String, dependencies Array) :void
    sa: function(name, deps) {
      return this.factory(name, ["Flux", function(Flux) {
        var storeOptions = this.inject(deps);
        var store = Flux.createStore(storeOptions);
        if (storeOptions.registerHandler) {
          store.register(storeOptions.registerHandler);
        }
        return store;
      }]);
    }
  },

  action: {

    // .action(name String, factory Function) :void
    sf: function(name, code) {
      return this.action(name, parseArgs(code).concat(code));
    },

    // .action(name String, dependencies Array) :void
    sa: function(name, deps) {
      return this.factory(name, ["Flux", function(Flux) {
        return Flux.createAction(this.inject(deps));
      }]);
    }
  },

  controller: {

    // .controller(name String, factory Function) :void
    sf: function(name, code) {
      return this.controller(name, parseArgs(code).concat(code));
    },

    // .controller(name String, dependencies Array) :void
    sa: function(name, deps) {
      return this.factory(name, [function() {
        return this.createController(this.inject(deps));
      }]);
    }
  },

  component: {

    // .component(name String, factory Function) :void
    sf: function(name, code) {
      return this.component(name, parseArgs(code).concat(code));
    },

    // .component(name String, dependencies Array) :void
    sa: function(name, deps) {
      this.factory(name, [function() {
        var component = this.inject(deps);
        if (!component.displayName) {
          component.displayName = name;
        }
        try {
          return React.createClass(component);
        } catch(e) {
          throw new Error("failed to create component: " + name);
        }
      }]);
    }
  },

  router: {

    // .router(name String, factory Function) :void
    sf: function(name, code) {
      return this.router(name, parseArgs(code).concat(code));
    },

    // .router(name String, dependencies Array) :void
    sa: function(name, deps) {
      this.factory(name, [function() {

        var routes = this.inject(deps);

        if (factory.isObject(routes)) {

          Object.keys(routes).forEach(function(href) {

            var route = routes[href];
            if (factory.isObject(route)) {

              if (!factory.isDefined(route.handler)) {
                route.handler = function(activeRoute) {

                  var controller = factory.isString(route.controller) ?
                    this.inject(route.controller) : route.controller;

                  var container = factory.isString(route.container) ?
                    document.getElementById(route.container) :
                    factory.isFunction(route.container) ?
                      route.container() : route.container;

                  var element = React.createElement(controller, activeRoute);
                  ReactDOM.render(element, container);

                }.bind(this);
              }

              var routeCopy = {};
              Object.keys(route).forEach(function(key) {
                if (key !== "controller" && key !== "container") {
                  routeCopy[key] = route[key];
                }
              });
              routes[href] = routeCopy;

            } else if (factory.isFunction(route)) {
              routes[href] = { handler: route };
            }
          }, this);
        }

        var router = new Rooter();
        router.setRoute(routes);
        return router;
      }]);
    }
  },

  load: {

    // .run(dependencies Array) :void
    a: function(deps) {
      this.inject(deps.concat([function() {}]));
      return this;
    }
  },

  run: {

    // .run(code Function) :void
    f: function(code) {
      return this.run(parseArgs(code).concat(code));
    },

    // .run(dependencies Array) :void
    a: function(deps) {
      this.inject(deps);
      return this;
    }
  }

});

// - -------------------------------------------------------------------- - //
<|endoftext|>


<commit_before>'use strict';

import React from 'react/addons';

import Icon from './Icon.js';

import LeftColumnActions from '../actions/LeftColumnActions.js';
import SearchActions from '../actions/SearchActions.js';

class MenuButton extends React.Component {
  constructor(props) {
    super(props);

    this._onClick = this._onClick.bind(this);
  }

  render() {
    return (

        <Icon icon="menu-hamburger"/>

    );
  }

  _onClick() {
    LeftColumnActions.toggleVisibility();
  }
}

export default class Top extends React.Component {
  constructor(props) {
    super(props);

    this._onChange = this._onChange.bind(this);
  }

  render() {
    return (

        <MenuButton />

          <Icon icon="search" />
          <input type="text" name="search" placeholder="Search Music" onChange={this._onChange} />

    );
  }

  _onChange(e) {
    SearchActions.search(e.currentTarget.value);
  }
}
<commit_msg>Select search text on click<commit_after>'use strict';

import React from 'react/addons';

import Icon from './Icon.js';

import LeftColumnActions from '../actions/LeftColumnActions.js';
import SearchActions from '../actions/SearchActions.js';

class MenuButton extends React.Component {
  constructor(props) {
    super(props);

    this._onClick = this._onClick.bind(this);
  }

  render() {
    return (

        <Icon icon="menu-hamburger"/>

    );
  }

  _onClick() {
    LeftColumnActions.toggleVisibility();
  }
}

export default class Top extends React.Component {
  constructor(props) {
    super(props);

    this._onChange = this._onChange.bind(this);
    this._onClick = this._onClick.bind(this);
  }

  render() {
    return (

        <MenuButton />

          <Icon icon="search" />
          <input type="text" name="search" placeholder="Search Music" onChange={this._onChange} onClick={this._onClick} />

    );
  }

  _onChange(e) {
    SearchActions.search(e.currentTarget.value);
  }

  _onClick(e) {
    e.currentTarget.select();
  }
}
<|endoftext|>


<commit_before>require([
    'jquery/jquery-1.11.1.min',
    'game/level13',
    'game/constants/GameConstants',
], function (jQuery, Level13, GameConstants) {
    'use strict';

    function Level13App() {

        this.initialise = function () {

            // TODO define when cheats are enabled neater
            var isLocal = document.URL.indexOf("file:///") >= 0;
            var isGithub = document.URL.indexOf("github.com/nroutasuo") >= 0;
            GameConstants.isCheatsEnabled = isLocal || isGithub;
            GameConstants.isDebugOutputEnabled = isLocal;

            GameConstants.STARTTimeStart = new Date().getTime();
            GameConstants.STARTTimeNow = function () {
                return new Date().getTime() - this.STARTTimeStart;
            }

            var level13 = new Level13();
            level13.start();

            if (GameConstants.isCheatsEnabled) {
                window.app = level13;
            }
        };

    }

    new Level13App().initialise();
}
);
<commit_msg>enable cheats for github version<commit_after>require([
    'jquery/jquery-1.11.1.min',
    'game/level13',
    'game/constants/GameConstants',
], function (jQuery, Level13, GameConstants) {
    'use strict';

    function Level13App() {

        this.initialise = function () {

            // TODO define when cheats are enabled neater
            var isLocal = document.URL.indexOf("file:///") >= 0;
            var isGithub = document.URL.indexOf("nroutasuo.github") >= 0;
            GameConstants.isCheatsEnabled = isLocal || isGithub;
            GameConstants.isDebugOutputEnabled = isLocal;

            GameConstants.STARTTimeStart = new Date().getTime();
            GameConstants.STARTTimeNow = function () {
                return new Date().getTime() - this.STARTTimeStart;
            }

            var level13 = new Level13();
            level13.start();

            if (GameConstants.isCheatsEnabled) {
                window.app = level13;
            }
        };

    }

    new Level13App().initialise();
}
);
<|endoftext|>


<commit_before>MLS.ui ={

	tabs: function(){}
};<commit_msg>tabs and thangs<commit_after>MLS.ui = {

	tabs: function(element) {
		var scope = element,
			tabs = $('.tab-content li', scope),
			activeClass = "active";

		$('.tab-menu li', scope).each(function(i, el) {
			$(this).add(tabs[i]).attr("tab", i + 1);
		});

		$('.tab-menu li', scope).on('click', function() {
			var tab = $(this).attr("tab");
			$('.tab-menu li, .tab-content li').removeClass(activeClass);
			$(this).addClass(activeClass);
			$('.tab-content li[tab=' + tab + ']', scope).addClass(activeClass);
		});

		$('.tab-menu li:first-child,.tab-content li:first-child', scope).addClass(activeClass);
	}
};<|endoftext|>


<commit_before>import md5 from 'md5';
import { Base64 } from 'js-base64';

import {
  VERSION,
  DOMAIN_REGEX,
  DEFAULT_OPTIONS,
  DPR_QUALITIES
} from './constants.js';

import {
  validateRange,
  validateWidths,
  validateAndDestructureOptions,
  validateVariableQuality,
  validateWidthTolerance
} from './validators.js';

export default class ImgixClient {
  constructor(opts = {}) {
    this.settings = { ...DEFAULT_OPTIONS, ...opts };
    // a cache to store memoized srcset width-pairs
    this.targetWidthsCache = {};
    if (typeof this.settings.domain != "string") {
      throw new Error('ImgixClient must be passed a valid string domain');
    }

    if (DOMAIN_REGEX.exec(this.settings.domain) == null) {
      throw new Error(
        'Domain must be passed in as fully-qualified ' +
        'domain name and should not include a protocol or any path ' +
        'element, i.e. "example.imgix.net".');
    }

    if (this.settings.includeLibraryParam) {
      this.settings.libraryParam = "js-" + VERSION;
    }

    this.settings.urlPrefix = this.settings.useHTTPS ? 'https://' : 'http://';
  }

  buildURL(path = '', params = {}) {
    const sanitizedPath = this._sanitizePath(path);

    const queryParams = this._buildParams(params);
    if (!!this.settings.secureURLToken) {
      const securedParams = this._signParams(sanitizedPath, queryParams);
      return this.settings.urlPrefix + this.settings.domain + sanitizedPath + securedParams;
    }
    return this.settings.urlPrefix + this.settings.domain + sanitizedPath + queryParams;
  }

  _buildParams(params = {}) {
    const queryParams = [];
    if (this.settings.libraryParam) {
      queryParams.push('ixlib=' + this.settings.libraryParam)
    }

    for (const key in params) {
      const val = params[key];
      const encodedKey = encodeURIComponent(key);

      let encodedVal;
      if (key.substr(-2) === '64') {
        encodedVal = Base64.encodeURI(val);
      } else {
        encodedVal = encodeURIComponent(val);
      }
      queryParams.push(encodedKey + "=" + encodedVal);
    }

    if (queryParams[0]) {
      queryParams[0] = "?" + queryParams[0];
    }
    return queryParams.join('&');
  }

  _signParams(path, queryParams) {
    const signatureBase = this.settings.secureURLToken + path + queryParams;
    const signature = md5(signatureBase);

    if (queryParams.length > 0) {
      return queryParams = queryParams + "&s=" + signature;
    } else {
      return queryParams = "?s=" + signature;
    }
  }

  _sanitizePath(path) {
    // Strip leading slash first (we'll re-add after encoding)
    let _path = path.replace(/^\//, '');

    if (/^https?:\/\//.test(_path)) {
      // Use de/encodeURIComponent to ensure *all* characters are handled,
      // since it's being used as a path
      _path = encodeURIComponent(_path);
    } else {
      // Use de/encodeURI if we think the path is just a path,
      // so it leaves legal characters like '/' and '@' alone
      _path = encodeURI(_path).replace(/[#?:]/g, encodeURIComponent);
    }

    return '/' + _path;
  }

  buildSrcSet(path, params, options) {
    const _options = options || {};
    const _params = params || {};
    const width = _params.w;
    const height = _params.h;
    const aspectRatio = _params.ar;

    if ((width) || (height && aspectRatio)) {
      return this._buildDPRSrcSet(path, _params, _options);
    } else {
      return this._buildSrcSetPairs(path, _params, _options);
    }
  }

  _buildSrcSetPairs(path, params, options) {
    const [widthTolerance, minWidth, maxWidth]  = validateAndDestructureOptions(options);
    const srcset = [];
    const customWidths = options.widths;

    let targetWidths;
    if (customWidths) {
      validateWidths(customWidths);
      targetWidths = customWidths;
    } else {
      validateRange(minWidth, maxWidth);
      validateWidthTolerance(widthTolerance);
      targetWidths = this._generateTargetWidths(widthTolerance, minWidth, maxWidth);
    }

    let queryParams = {};
    for (const key in params) {
      queryParams[key] = params[key];
    }

    for (let i = 0; i < targetWidths.length; i++) {
      const currentWidth = targetWidths[i];
      queryParams.w = currentWidth;
      srcset.push(this.buildURL(path, queryParams) + ' ' + currentWidth + 'w')
    }

    return srcset.join(',\n')
  };

  _buildDPRSrcSet(path, params, options) {
    const srcset = [];
    const targetRatios = [1, 2, 3, 4, 5];
    const disableVariableQuality = options.disableVariableQuality || false;

    const queryParams = {};
    for (const key in params) {
      queryParams[key] = params[key];
    }

    const quality = queryParams.q;
    if (!disableVariableQuality) {
      validateVariableQuality(disableVariableQuality);
    }

    for (let i = 0; i < targetRatios.length; i++) {
      const currentRatio = targetRatios[i];
      queryParams.dpr = currentRatio;

      if (!disableVariableQuality) {
        queryParams.q = quality || DPR_QUALITIES[currentRatio];
      }
      srcset.push(this.buildURL(path, queryParams) + ' ' + currentRatio + 'x')
    }

    return srcset.join(',\n');
  };

  // returns an array of width values used during scrset generation
  _generateTargetWidths(widthTolerance, minWidth, maxWidth) {
    const resolutions = [];
    const INCREMENT_PERCENTAGE = widthTolerance;
    const _minWidth = Math.floor(minWidth);
    const _maxWidth = Math.floor(maxWidth);
    const cacheKey = INCREMENT_PERCENTAGE + '/' + _minWidth + '/' + _maxWidth;

    if (cacheKey in this.targetWidthsCache) {
      return this.targetWidthsCache[cacheKey];
    }

    const ensureEven = (n) => {
      return 2 * Math.round(n / 2);
    };

    let prev = _minWidth;
    while (prev < _maxWidth) {
      resolutions.push(ensureEven(prev));
      prev *= 1 + (INCREMENT_PERCENTAGE * 2);
    }

    resolutions.push(_maxWidth);

    this.targetWidthsCache[cacheKey] = resolutions;

    return resolutions;
  };
}
<commit_msg>refactor: use spread operator and destructure syntax<commit_after>import md5 from 'md5';
import { Base64 } from 'js-base64';

import {
  VERSION,
  DOMAIN_REGEX,
  DEFAULT_OPTIONS,
  DPR_QUALITIES
} from './constants.js';

import {
  validateRange,
  validateWidths,
  validateAndDestructureOptions,
  validateVariableQuality,
  validateWidthTolerance
} from './validators.js';

export default class ImgixClient {
  constructor(opts = {}) {
    this.settings = { ...DEFAULT_OPTIONS, ...opts };
    // a cache to store memoized srcset width-pairs
    this.targetWidthsCache = {};
    if (typeof this.settings.domain != "string") {
      throw new Error('ImgixClient must be passed a valid string domain');
    }

    if (DOMAIN_REGEX.exec(this.settings.domain) == null) {
      throw new Error(
        'Domain must be passed in as fully-qualified ' +
        'domain name and should not include a protocol or any path ' +
        'element, i.e. "example.imgix.net".');
    }

    if (this.settings.includeLibraryParam) {
      this.settings.libraryParam = "js-" + VERSION;
    }

    this.settings.urlPrefix = this.settings.useHTTPS ? 'https://' : 'http://';
  }

  buildURL(path = '', params = {}) {
    const sanitizedPath = this._sanitizePath(path);

    const queryParams = this._buildParams(params);
    if (!!this.settings.secureURLToken) {
      const securedParams = this._signParams(sanitizedPath, queryParams);
      return this.settings.urlPrefix + this.settings.domain + sanitizedPath + securedParams;
    }
    return this.settings.urlPrefix + this.settings.domain + sanitizedPath + queryParams;
  }

  _buildParams(params = {}) {
    const queryParams = [];
    if (this.settings.libraryParam) {
      queryParams.push('ixlib=' + this.settings.libraryParam)
    }

    for (const key in params) {
      const val = params[key];
      const encodedKey = encodeURIComponent(key);

      let encodedVal;
      if (key.substr(-2) === '64') {
        encodedVal = Base64.encodeURI(val);
      } else {
        encodedVal = encodeURIComponent(val);
      }
      queryParams.push(encodedKey + "=" + encodedVal);
    }

    if (queryParams[0]) {
      queryParams[0] = "?" + queryParams[0];
    }
    return queryParams.join('&');
  }

  _signParams(path, queryParams) {
    const signatureBase = this.settings.secureURLToken + path + queryParams;
    const signature = md5(signatureBase);

    if (queryParams.length > 0) {
      return queryParams = queryParams + "&s=" + signature;
    } else {
      return queryParams = "?s=" + signature;
    }
  }

  _sanitizePath(path) {
    // Strip leading slash first (we'll re-add after encoding)
    let _path = path.replace(/^\//, '');

    if (/^https?:\/\//.test(_path)) {
      // Use de/encodeURIComponent to ensure *all* characters are handled,
      // since it's being used as a path
      _path = encodeURIComponent(_path);
    } else {
      // Use de/encodeURI if we think the path is just a path,
      // so it leaves legal characters like '/' and '@' alone
      _path = encodeURI(_path).replace(/[#?:]/g, encodeURIComponent);
    }

    return '/' + _path;
  }

  buildSrcSet(path, params = {}, options = {}) {
    const _options = {...options};
    const _params = {...params};
    const {w, h, ar} = _params;

    if ((w) || (h && ar)) {
      return this._buildDPRSrcSet(path, _params, _options);
    } else {
      return this._buildSrcSetPairs(path, _params, _options);
    }
  }

  _buildSrcSetPairs(path, params, options) {
    const [widthTolerance, minWidth, maxWidth]  = validateAndDestructureOptions(options);
    const srcset = [];
    const customWidths = options.widths;

    let targetWidths;
    if (customWidths) {
      validateWidths(customWidths);
      targetWidths = customWidths;
    } else {
      validateRange(minWidth, maxWidth);
      validateWidthTolerance(widthTolerance);
      targetWidths = this._generateTargetWidths(widthTolerance, minWidth, maxWidth);
    }

    let queryParams = {};
    for (const key in params) {
      queryParams[key] = params[key];
    }

    for (let i = 0; i < targetWidths.length; i++) {
      const currentWidth = targetWidths[i];
      queryParams.w = currentWidth;
      srcset.push(this.buildURL(path, queryParams) + ' ' + currentWidth + 'w')
    }

    return srcset.join(',\n')
  };

  _buildDPRSrcSet(path, params, options) {
    const srcset = [];
    const targetRatios = [1, 2, 3, 4, 5];
    const disableVariableQuality = options.disableVariableQuality || false;

    const queryParams = {};
    for (const key in params) {
      queryParams[key] = params[key];
    }

    const quality = queryParams.q;
    if (!disableVariableQuality) {
      validateVariableQuality(disableVariableQuality);
    }

    for (let i = 0; i < targetRatios.length; i++) {
      const currentRatio = targetRatios[i];
      queryParams.dpr = currentRatio;

      if (!disableVariableQuality) {
        queryParams.q = quality || DPR_QUALITIES[currentRatio];
      }
      srcset.push(this.buildURL(path, queryParams) + ' ' + currentRatio + 'x')
    }

    return srcset.join(',\n');
  };

  // returns an array of width values used during scrset generation
  _generateTargetWidths(widthTolerance, minWidth, maxWidth) {
    const resolutions = [];
    const INCREMENT_PERCENTAGE = widthTolerance;
    const _minWidth = Math.floor(minWidth);
    const _maxWidth = Math.floor(maxWidth);
    const cacheKey = INCREMENT_PERCENTAGE + '/' + _minWidth + '/' + _maxWidth;

    if (cacheKey in this.targetWidthsCache) {
      return this.targetWidthsCache[cacheKey];
    }

    const ensureEven = (n) => {
      return 2 * Math.round(n / 2);
    };

    let prev = _minWidth;
    while (prev < _maxWidth) {
      resolutions.push(ensureEven(prev));
      prev *= 1 + (INCREMENT_PERCENTAGE * 2);
    }

    resolutions.push(_maxWidth);

    this.targetWidthsCache[cacheKey] = resolutions;

    return resolutions;
  };
}
<|endoftext|>


<commit_before>function getInner(contents) {
  var retval;
  if (contents.firstChild === null) {
    retval = null;
  } else if (contents.firstChild.nodeType !== Node.TEXT_NODE) {
    retval = contents.firstChild.innerText;
  } else {
    retval = contents.innerText.trim();
  }
  return retval;
}

function getRow(table) {
  var data = [];
  var headers = [];

  for (var r = 0, n = table.rows.length; r < n; r++) {
    var rowdata = [];

    for (var c = 0, m = table.rows[r].cells.length; c < m; c++) {
      var contents = table.rows[r].cells[c];
      rowdata[c] = getInner(contents);
    }

    if (r === 0) {
      headers = rowdata;
    } else {
      data[r] = rowdata;
    }
  }
  var string = "Kvittering for utlån

";
  for (var i = 1, l = data.length; i < l; i++) {

    for (var k = 0, f = data[i].length; k < f; k++) {
      string += headers[k] + ":  " + data[i][k] + "
";
    }
    string += "
";
  }
  return string;
}
printWindow = window.open("");
printWindow.document.write(getRow(document.getElementById("checkedintable")));
printWindow.print();
printWindow.close();

<commit_msg>Update script with library details, remove erroneously committed dirs<commit_after>function leadingZero(number) {
  var retval = number;
  if (number < 10) {
    retval = '0' + number;
  }
  return retval;
}

function now() {
  var today = new Date();
  var day = today.getDate();
  var month = today.getMonth()+1; //January is 0!
  var year = today.getFullYear();
  var hours = today.getHours();
  var getMinutes = today.getMinutes();
  var seconds = today.getSeconds();

  return leadingZero(day)
         + '.' + leadingZero(month)
         + '.' + leadingZero(year)
         + " " + leadingZero(today.getHours())
         + ":" + leadingZero(today.getMinutes())
         + ":" + leadingZero(today.getSeconds());
}

var header = "DEICHMANSKE BIBLIOTEK
"
           + "Tlf: 23432900
"
           + "postmottak.deichman@oslo.kommune.no
"
           + "Kvittering på innlevert materiale
"
           + now() + "
"
           + "

";

function getInner(contents) {
  var retval;
  if (contents.firstChild === null) {
    retval = "";
  } else if (contents.firstChild.nodeType !== Node.TEXT_NODE) {
    retval = contents.firstChild.innerText;
  } else {
    retval = contents.innerText.trim();
  }
  return retval;
}

function getRow(table) {
  var data = [];
  var headers = [];

  for (var r = 0, n = table.rows.length; r < n; r++) {
    var rowdata = [];

    for (var c = 0, m = table.rows[r].cells.length; c < m; c++) {
      var contents = table.rows[r].cells[c];
      rowdata[c] = getInner(contents);
    }

    if (r === 0) {
      headers = rowdata;
    } else {
      data[r] = rowdata;
    }
  }
  var string = header;
  for (var i = 1, l = data.length; i < l; i++) {

    for (var k = 0, f = data[i].length; k < f; k++) {
      string += headers[k] + ":  " + data[i][k] + "
";
    }
    string += "
";
  }
  return string;
}
printWindow = window.open("");
printWindow.document.write(getRow(document.getElementById("checkedintable")));
printWindow.document.write("

")
printWindow.print();
printWindow.close();

<|endoftext|>


<commit_before>/*
 Copyright 2017 Aleksandar Jankovic

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

const List = require('../base/List');
const StandardView = require('../base/StandardView');
const DialogBox = require('../DialogBox');
const elementCreator = require('../../ElementCreator');
const socketManager = require('../../SocketManager');
const storageManager = require('../../StorageManager');
const eventCentral = require('../../EventCentral');
const soundLibrary = require('../../audio/SoundLibrary');

// TODO Duplicate code in DialogBox
/**
 * Mark empty fields. Returns true if one of them were empty
 * @param {HTMLInputElement[]} inputs - Inputs to check
 * @returns {boolean} Is one of the fields empty?
 */
function markEmptyFields(inputs) {
  let emptyFields = false;

  inputs.forEach((input) => {
    if (input.value === '') {
      emptyFields = true;
      input.classList.add('markedInput');
    }
  });

  return emptyFields;
}

class DocsViewer extends StandardView {
  constructor({ isFullscreen }) {
    super({ isFullscreen });

    this.element.setAttribute('id', 'docsViewer');
    this.viewer.classList.add('selectedView');
    this.selectedItem = null;

    this.populateList();
  }

  showDoc(docFile) {
    const docFragment = document.createDocumentFragment();
    docFragment.appendChild(elementCreator.createParagraph({ text: `${docFile.positionName}`, classes: ['positionName'] }));
    docFragment.appendChild(elementCreator.createParagraph({ text: `ID: ${docFile.docFileId.toUpperCase()}` }));
    docFragment.appendChild(elementCreator.createParagraph({ text: `Public: ${docFile.isPublic ? 'Yes' : 'No'}` }));

    docFile.text.forEach(line => docFragment.appendChild(elementCreator.createParagraph({ text: line })));

    this.viewer.classList.remove('flash');

    setTimeout(() => {
      this.viewer.innerHTML = '';
      this.viewer.classList.add('flash');
      this.viewer.scrollTop = this.viewer.scrollHeight;
      this.viewer.appendChild(docFragment);
    }, 100);
  }

  createDocFileButton(docFile) {
    const title = `${docFile.positionName || docFile.docFileId}`;
    const button = elementCreator.createButton({
      text: title.length > 30 ? `${title.slice(0, 20)} ... ${title.slice(title.length - 5, title.length)}` : title,
      func: () => {
        if (this.selectedItem) {
          this.selectedItem.classList.remove('selectedItem');
        }

        this.selectedItem = button.parentElement;
        this.selectedItem.classList.add('selectedItem');

        socketManager.emitEvent('getDocFile', { docFileId: docFile.docFileId }, ({ docFileError, data: docFileData }) => {
          if (docFileError) {
            console.log(docFileError);

            return;
          }

          this.showDoc(docFileData.docFile);
        });
      },
    });

    return button;
  }

  populateList() {
    const systemList = new List({ shouldSort: false, title: 'SYSTEM' });
    const userDocs = new List({ viewId: 'userDocuments', shouldSort: true, title: 'Yours' });
    const teamDocs = new List({ viewId: 'teamDocuments', shouldSort: true, title: 'Team' });
    const publicDocs = new List({ viewId: 'publicDocuments', shouldSort: true, title: 'Public' });

    const searchButton = elementCreator.createButton({
      text: 'ID search',
      func: () => {
        const idDialog = new DialogBox({
          buttons: {
            left: {
              text: 'Cancel',
              eventFunc: () => {
                idDialog.removeView();
              },
            },
            right: {
              text: 'Search',
              eventFunc: () => {
                const emptyFields = idDialog.markEmptyFields();

                if (emptyFields) {
                  soundLibrary.playSound('fail');
                  idDialog.changeExtraDescription({ text: ['You cannot leave obligatory fields empty!'] });

                  return;
                }

                const documentId = idDialog.inputs.find(({ inputName }) => inputName === 'documentId').inputElement.value.toLowerCase();

                socketManager.emitEvent('getDocFile', { docFileId: documentId }, ({ error: docError, data: { docFile } }) => {
                  if (docError) {
                    console.log(docError);

                    return;
                  } else if (!docFile || docFile === null) {
                    idDialog.changeExtraDescription({ text: ['Unable to retrieve document with sent ID. Please try again'] });

                    return;
                  }

                  this.showDoc(docFile);
                  idDialog.removeView();
                });
              },
            },
          },
          inputs: [{
            placeholder: 'Document ID',
            inputName: 'documentId',
            isRequired: true,
          }],
          description: [
            'Retrieve a document from the archives',
          ],
          extraDescription: ['Enter the ID of the document'],
        });
        idDialog.appendTo(this.element.parentElement);
      },
    });
    const createButton = elementCreator.createButton({
      classes: ['hide'],
      text: 'Create doc',
      func: () => {
        this.viewer.innerHTML = '';

        const docFragment = document.createDocumentFragment();
        const titleInput = elementCreator.createInput({ placeholder: 'Title', inputName: 'docTitle', isRequired: true });
        const idInput = elementCreator.createInput({ placeholder: 'ID to access the document with', inputName: 'docId', isRequired: true });
        const bodyInput = elementCreator.createInput({ placeholder: 'Text', inputName: 'docBody', isRequired: true, multiLine: true });
        const visibilitySet = elementCreator.createRadioSet({
          title: 'Who should be able to view the document? Those with the correct document ID will always be able to view the document.',
          optionName: 'visibility',
          options: [
            { optionId: 'visPublic', optionLabel: 'Everyone' },
            { optionId: 'visPrivate', optionLabel: 'Only those with the correct ID' },
          ],
        });
        const teamSet = elementCreator.createRadioSet({
          title: 'Should the document be added to the team directory?',
          optionName: 'team',
          options: [
            { optionId: 'teamYes', optionLabel: 'Yes' },
            { optionId: 'teamNo', optionLabel: 'No' },
          ],
        });
        const buttons = elementCreator.createContainer({ classes: ['buttons'] });

        // TODO Duplicate code in Messenger
        bodyInput.addEventListener('input', () => {
          bodyInput.style.height = 'auto';
          bodyInput.style.height = `${bodyInput.scrollHeight}px`;
        });

        docFragment.appendChild(titleInput);
        docFragment.appendChild(idInput);
        docFragment.appendChild(bodyInput);
        docFragment.appendChild(visibilitySet);

        if (storageManager.getTeam()) { docFragment.appendChild(teamSet); }

        buttons.appendChild(elementCreator.createButton({
          text: 'Save',
          func: () => {
            if (!markEmptyFields([titleInput, bodyInput, idInput])) {
              const docFile = {
                title: titleInput.value,
                docFileId: idInput.value,
                text: bodyInput.value.split('\n'),
                isPublic: document.getElementById('visPublic').checked === true,
                teamDir: storageManager.getTeam() && document.getElementById('teamYes').checked === true,
              };

              socketManager.emitEvent('createDocFile', docFile, ({ error: docFileError }) => {
                if (docFileError) {
                  console.log(docFileError);

                  return;
                }

                this.viewer.innerHTML = '';
                this.viewer.appendChild(document.createTextNode('Document has been saved'));
                eventCentral.triggerEvent({ event: eventCentral.Events.CREATEDOCFILE, params: { docFile } });
              });
            }
          },
        }));
        docFragment.appendChild(buttons);

        this.viewer.appendChild(docFragment);
      },
    });
    systemList.addItems({ items: [searchButton, createButton] });

    this.itemList.appendChild(systemList.element);
    this.itemList.appendChild(userDocs.element);
    this.itemList.appendChild(teamDocs.element);
    this.itemList.appendChild(publicDocs.element);

    this.accessElements.push({
      element: createButton,
      accessLevel: 1,
    });

    eventCentral.addWatcher({
      watcherParent: this,
      event: eventCentral.Events.DOCFILE,
      func: ({ docFile }) => {
        const userName = storageManager.getSelectedAlias() || storageManager.getUserName();

        if (docFile.creator === userName) {
          userDocs.addItem({ item: this.createDocFileButton(docFile) });
        } else if (docFile.team && docFile.team !== '') {
          teamDocs.addItem({ item: this.createDocFileButton(docFile) });
        } else if (docFile.isPublic) {
          publicDocs.addItem({ item: this.createDocFileButton(docFile) });
        }
      },
    });

    eventCentral.addWatcher({
      watcherParent: this,
      event: eventCentral.Events.CREATEDOCFILE,
      func: ({ docFile }) => {
        userDocs.addItem({ item: this.createDocFileButton(docFile) });
      },
    });

    eventCentral.addWatcher({
      watcherParent: this,
      event: eventCentral.Events.USER,
      func: ({ changedUser }) => {
        if (changedUser) {
          this.viewer.innerHTML = '';
        }

        socketManager.emitEvent('getDocFilesList', {}, ({ error, data }) => {
          if (error) {
            console.log(error);

            return;
          }

          const { userDocFiles = [], publicDocFiles = [], teamDocFiles = [] } = data;

          userDocs.replaceAllItems({ items: userDocFiles.map(docFile => this.createDocFileButton(docFile)) });
          teamDocs.replaceAllItems({ items: teamDocFiles.map(docFile => this.createDocFileButton(docFile)) });
          publicDocs.replaceAllItems({ items: publicDocFiles.map(docFile => this.createDocFileButton(docFile)) });
        });
      },
    });
  }

  removeView() {
    super.removeView();
    this.viewer.classList.remove('flash');
  }
}

module.exports = DocsViewer;
<commit_msg>Check if doc file is null. Prints error message if not found<commit_after>/*
 Copyright 2017 Aleksandar Jankovic

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

const List = require('../base/List');
const StandardView = require('../base/StandardView');
const DialogBox = require('../DialogBox');
const elementCreator = require('../../ElementCreator');
const socketManager = require('../../SocketManager');
const storageManager = require('../../StorageManager');
const eventCentral = require('../../EventCentral');
const soundLibrary = require('../../audio/SoundLibrary');

// TODO Duplicate code in DialogBox
/**
 * Mark empty fields. Returns true if one of them were empty
 * @param {HTMLInputElement[]} inputs - Inputs to check
 * @returns {boolean} Is one of the fields empty?
 */
function markEmptyFields(inputs) {
  let emptyFields = false;

  inputs.forEach((input) => {
    if (input.value === '') {
      emptyFields = true;
      input.classList.add('markedInput');
    }
  });

  return emptyFields;
}

class DocsViewer extends StandardView {
  constructor({ isFullscreen }) {
    super({ isFullscreen });

    this.element.setAttribute('id', 'docsViewer');
    this.viewer.classList.add('selectedView');
    this.selectedItem = null;

    this.populateList();
  }

  showDoc(docFile) {
    const docFragment = document.createDocumentFragment();
    docFragment.appendChild(elementCreator.createParagraph({ text: `${docFile.title}`, classes: ['title'] }));
    docFragment.appendChild(elementCreator.createParagraph({ text: `ID: ${docFile.docFileId.toUpperCase()}` }));
    docFragment.appendChild(elementCreator.createParagraph({ text: `Public: ${docFile.isPublic ? 'Yes' : 'No'}` }));
    docFragment.appendChild(elementCreator.createParagraph({ text: '------' }));

    docFile.text.forEach(line => docFragment.appendChild(elementCreator.createParagraph({ text: line })));

    this.viewer.classList.remove('flash');

    setTimeout(() => {
      this.viewer.innerHTML = '';
      this.viewer.classList.add('flash');
      this.viewer.scrollTop = this.viewer.scrollHeight;
      this.viewer.appendChild(docFragment);
    }, 100);
  }

  createDocFileButton(docFile) {
    const title = `${docFile.title || docFile.docFileId}`;
    const button = elementCreator.createButton({
      text: title.length > 30 ? `${title.slice(0, 20)} ... ${title.slice(title.length - 5, title.length)}` : title,
      func: () => {
        if (this.selectedItem) {
          this.selectedItem.classList.remove('selectedItem');
        }

        this.selectedItem = button.parentElement;
        this.selectedItem.classList.add('selectedItem');

        socketManager.emitEvent('getDocFile', { docFileId: docFile.docFileId }, ({ docFileError, data: docFileData }) => {
          if (docFileError) {
            console.log(docFileError);

            return;
          } else if (!docFileData.docFile) {
            const paragraph = elementCreator.createParagraph({ text: `${docFile.docFileId} - File not found` });

            this.viewer.innerHTML = '';
            this.viewer.appendChild(paragraph);
          }

          this.showDoc(docFileData.docFile);
        });
      },
    });

    return button;
  }

  populateList() {
    const systemList = new List({ shouldSort: false, title: 'SYSTEM' });
    const userDocs = new List({ viewId: 'userDocuments', shouldSort: true, title: 'Yours' });
    const teamDocs = new List({ viewId: 'teamDocuments', shouldSort: true, title: 'Team' });
    const publicDocs = new List({ viewId: 'publicDocuments', shouldSort: true, title: 'Public' });

    const searchButton = elementCreator.createButton({
      text: 'ID search',
      func: () => {
        const idDialog = new DialogBox({
          buttons: {
            left: {
              text: 'Cancel',
              eventFunc: () => {
                idDialog.removeView();
              },
            },
            right: {
              text: 'Search',
              eventFunc: () => {
                const emptyFields = idDialog.markEmptyFields();

                if (emptyFields) {
                  soundLibrary.playSound('fail');
                  idDialog.changeExtraDescription({ text: ['You cannot leave obligatory fields empty!'] });

                  return;
                }

                const documentId = idDialog.inputs.find(({ inputName }) => inputName === 'documentId').inputElement.value.toLowerCase();

                socketManager.emitEvent('getDocFile', { docFileId: documentId }, ({ error: docError, data: { docFile } }) => {
                  if (docError) {
                    console.log(docError);

                    return;
                  } else if (!docFile || docFile === null) {
                    idDialog.changeExtraDescription({ text: ['Unable to retrieve document with sent ID. Please try again'] });

                    return;
                  }

                  this.showDoc(docFile);
                  idDialog.removeView();
                });
              },
            },
          },
          inputs: [{
            placeholder: 'Document ID',
            inputName: 'documentId',
            isRequired: true,
          }],
          description: [
            'Retrieve a document from the archives',
          ],
          extraDescription: ['Enter the ID of the document'],
        });
        idDialog.appendTo(this.element.parentElement);
      },
    });
    const createButton = elementCreator.createButton({
      classes: ['hide'],
      text: 'Create doc',
      func: () => {
        this.viewer.innerHTML = '';

        const docFragment = document.createDocumentFragment();
        const titleInput = elementCreator.createInput({ placeholder: 'Title', inputName: 'docTitle', isRequired: true });
        const idInput = elementCreator.createInput({ placeholder: 'ID to access the document with', inputName: 'docId', isRequired: true });
        const bodyInput = elementCreator.createInput({ placeholder: 'Text', inputName: 'docBody', isRequired: true, multiLine: true });
        const visibilitySet = elementCreator.createRadioSet({
          title: 'Who should be able to view the document? Those with the correct document ID will always be able to view the document.',
          optionName: 'visibility',
          options: [
            { optionId: 'visPublic', optionLabel: 'Everyone' },
            { optionId: 'visPrivate', optionLabel: 'Only those with the correct ID' },
          ],
        });
        const teamSet = elementCreator.createRadioSet({
          title: 'Should the document be added to the team directory?',
          optionName: 'team',
          options: [
            { optionId: 'teamYes', optionLabel: 'Yes' },
            { optionId: 'teamNo', optionLabel: 'No' },
          ],
        });
        const buttons = elementCreator.createContainer({ classes: ['buttons'] });

        // TODO Duplicate code in Messenger
        bodyInput.addEventListener('input', () => {
          bodyInput.style.height = 'auto';
          bodyInput.style.height = `${bodyInput.scrollHeight}px`;
        });

        docFragment.appendChild(titleInput);
        docFragment.appendChild(idInput);
        docFragment.appendChild(bodyInput);
        docFragment.appendChild(visibilitySet);

        if (storageManager.getTeam()) { docFragment.appendChild(teamSet); }

        buttons.appendChild(elementCreator.createButton({
          text: 'Save',
          func: () => {
            if (!markEmptyFields([titleInput, bodyInput, idInput])) {
              const docFile = {
                title: titleInput.value,
                docFileId: idInput.value,
                text: bodyInput.value.split('\n'),
                isPublic: document.getElementById('visPublic').checked === true,
                teamDir: storageManager.getTeam() && document.getElementById('teamYes').checked === true,
              };

              socketManager.emitEvent('createDocFile', docFile, ({ error: docFileError }) => {
                if (docFileError) {
                  console.log(docFileError);

                  return;
                }

                this.viewer.innerHTML = '';
                this.viewer.appendChild(document.createTextNode('Document has been saved'));
                eventCentral.triggerEvent({ event: eventCentral.Events.CREATEDOCFILE, params: { docFile } });
              });
            }
          },
        }));
        docFragment.appendChild(buttons);

        this.viewer.appendChild(docFragment);
      },
    });
    systemList.addItems({ items: [searchButton, createButton] });

    this.itemList.appendChild(systemList.element);
    this.itemList.appendChild(userDocs.element);
    this.itemList.appendChild(teamDocs.element);
    this.itemList.appendChild(publicDocs.element);

    this.accessElements.push({
      element: createButton,
      accessLevel: 1,
    });

    eventCentral.addWatcher({
      watcherParent: this,
      event: eventCentral.Events.DOCFILE,
      func: ({ docFile }) => {
        const userName = storageManager.getSelectedAlias() || storageManager.getUserName();

        if (docFile.creator === userName) {
          userDocs.addItem({ item: this.createDocFileButton(docFile) });
        } else if (docFile.team && docFile.team !== '') {
          teamDocs.addItem({ item: this.createDocFileButton(docFile) });
        } else if (docFile.isPublic) {
          publicDocs.addItem({ item: this.createDocFileButton(docFile) });
        }
      },
    });

    eventCentral.addWatcher({
      watcherParent: this,
      event: eventCentral.Events.CREATEDOCFILE,
      func: ({ docFile }) => {
        userDocs.addItem({ item: this.createDocFileButton(docFile) });
      },
    });

    eventCentral.addWatcher({
      watcherParent: this,
      event: eventCentral.Events.USER,
      func: ({ changedUser }) => {
        if (changedUser) {
          this.viewer.innerHTML = '';
        }

        socketManager.emitEvent('getDocFilesList', {}, ({ error, data }) => {
          if (error) {
            console.log(error);

            return;
          }

          const { userDocFiles = [], publicDocFiles = [], teamDocFiles = [] } = data;

          userDocs.replaceAllItems({ items: userDocFiles.map(docFile => this.createDocFileButton(docFile)) });
          teamDocs.replaceAllItems({ items: teamDocFiles.map(docFile => this.createDocFileButton(docFile)) });
          publicDocs.replaceAllItems({ items: publicDocFiles.map(docFile => this.createDocFileButton(docFile)) });
        });
      },
    });
  }

  removeView() {
    super.removeView();
    this.viewer.classList.remove('flash');
  }
}

module.exports = DocsViewer;
<|endoftext|>


<commit_before>'use strict';

const chai = require('chai');
const expect = chai.expect;
const Support = require('../../support');
const dialect = Support.getTestDialect();

if (dialect.match(/^mssql/)) {
  describe('[MSSQL Specific] Query Queue', () => {
    it('should work with handleDisconnects', () => {
      const sequelize = Support.createSequelizeInstance({ pool: { min: 1, max: 1, idle: 5000 } });
      const cm = sequelize.connectionManager;
      let conn;

      return sequelize
        .sync()
        .then(() => cm.getConnection())
        .then(connection => {
          // Save current connection
          conn = connection;

          // simulate a unexpected end
          // connection removed from pool by MSSQL Conn Manager
          conn.unwrap().emit('error', {code: 'ECONNRESET'});
        })
        .then(() => cm.getConnection())
        .then(connection => {
          expect(conn).to.not.be.equal(connection);
          expect(cm.validate(conn)).to.not.be.ok;

          return cm.releaseConnection(connection);
        });
    });

    it('should handle double disconnect', () => {
      const sequelize = Support.createSequelizeInstance({ pool: { min: 1, max: 1, idle: 5000 } });
      const cm = sequelize.connectionManager;
      let count = 0;
      let conn = null;

      return sequelize
        .sync()
        .then(() => cm.getConnection())
        .then(connection => {
          conn = connection;
          const unwrapConn = conn.unwrap();
          unwrapConn.on('end', () => {
            count++;
          });

          return cm.disconnect(conn);
        })
        .then(() => cm.disconnect(conn))
        .then(() => {
          expect(count).to.be.eql(1);
        });
    });

    it('should not throw when non pooled connection is unexpectedly closed', () => {
      const sequelize = Support.createSequelizeInstance({ pool: { min: 1, max: 1, idle: 5000 } });
      const cm = sequelize.connectionManager;

      let conn;

      return sequelize
        .sync()
        .then(() => cm.getConnection())
        .then(connection => {
          conn = connection;

          // remove from pool
          return cm.pool.destroy(connection);
        })
        .then(() => {
          // unexpected disconnect
          const unwrapConn = conn.unwrap();
          unwrapConn.emit('error', {
            code: 'ESOCKET'
          });
        });
    });

    describe('Errors', () => {
      it('ECONNREFUSED', () => {
        const sequelize = Support.createSequelizeInstance({ port: 34237 });
        return expect(sequelize.connectionManager.getConnection()).to.have.been.rejectedWith(sequelize.ConnectionRefusedError);
      });

      it('ENOTFOUND', () => {
        const sequelize = Support.createSequelizeInstance({ host: 'http://wowow.example.com' });
        return expect(sequelize.connectionManager.getConnection()).to.have.been.rejectedWith(sequelize.HostNotFoundError);
      });

      it('EHOSTUNREACH', () => {
        const sequelize = Support.createSequelizeInstance({ host: '255.255.255.255' });
        return expect(sequelize.connectionManager.getConnection()).to.have.been.rejectedWith(sequelize.HostNotReachableError);
      });

      it('ER_ACCESS_DENIED_ERROR | ELOGIN', () => {
        const sequelize = new Support.Sequelize('localhost', 'was', 'ddsd', Support.sequelize.options);
        return expect(sequelize.connectionManager.getConnection()).to.have.been.rejectedWith(sequelize.AccessDeniedError);
      });
    });
  });
}
<commit_msg>fix(connection-manager.test): mssql<commit_after>'use strict';

const chai = require('chai');
const expect = chai.expect;
const Support = require('../../support');
const dialect = Support.getTestDialect();

if (dialect.match(/^mssql/)) {
  describe('[MSSQL Specific] Query Queue', () => {
    it('should work with handleDisconnects', () => {
      const sequelize = Support.createSequelizeInstance({ pool: { min: 1, max: 1, idle: 5000 } });
      const cm = sequelize.connectionManager;
      let conn;

      return sequelize
        .sync()
        .then(() => cm.getConnection())
        .then(connection => {
          // Save current connection
          conn = connection;

          // simulate a unexpected end
          // connection removed from pool by MSSQL Conn Manager
          conn.unwrap().emit('error', {code: 'ECONNRESET'});
        })
        .then(() => cm.getConnection())
        .then(connection => {
          expect(conn).to.not.be.equal(connection);
          expect(cm.validate(conn)).to.not.be.ok;

          return cm.releaseConnection(connection);
        });
    });

    it('should handle double disconnect', () => {
      const sequelize = Support.createSequelizeInstance({ pool: { min: 1, max: 1, idle: 5000 } });
      const cm = sequelize.connectionManager;
      let count = 0;
      let conn = null;

      return sequelize
        .sync()
        .then(() => cm.getConnection())
        .then(connection => {
          conn = connection;
          const unwrapConn = conn.unwrap();
          unwrapConn.on('end', () => {
            count++;
          });

          return cm.disconnect(conn);
        })
        .then(() => cm.disconnect(conn))
        .then(() => {
          expect(count).to.be.eql(1);
        });
    });

    it('should not throw when non pooled connection is unexpectedly closed', () => {
      const sequelize = Support.createSequelizeInstance({ pool: { min: 1, max: 1, idle: 5000 } });
      const cm = sequelize.connectionManager;

      let conn;

      return sequelize
        .sync()
        .then(() => cm.getConnection())
        .then(connection => {
          conn = connection;

          // remove from pool
          return cm.pool.destroy(connection);
        })
        .then(() => {
          // unexpected disconnect
          const unwrapConn = conn.unwrap();
          unwrapConn.emit('error', {
            code: 'ESOCKET'
          });
        });
    });

    describe('Errors', () => {
      it('ECONNREFUSED', () => {
        const sequelize = Support.createSequelizeInstance({ port: 34237 });
        return expect(sequelize.connectionManager.getConnection()).to.have.been.rejectedWith(sequelize.ConnectionRefusedError);
      });

      it('ENOTFOUND', () => {
        const sequelize = Support.createSequelizeInstance({ host: 'http://wowow.example.com' });
        return expect(sequelize.connectionManager.getConnection()).to.have.been.rejectedWith(sequelize.HostNotFoundError);
      });

      it('EHOSTUNREACH', () => {
        const sequelize = Support.createSequelizeInstance({ host: '255.255.255.255' });
        return expect(sequelize.connectionManager.getConnection()).to.have.been.rejectedWith(sequelize.ConnectionRefusedError);
      });

      it('ER_ACCESS_DENIED_ERROR | ELOGIN', () => {
        const sequelize = new Support.Sequelize('localhost', 'was', 'ddsd', Support.sequelize.options);
        return expect(sequelize.connectionManager.getConnection()).to.have.been.rejectedWith(sequelize.AccessDeniedError);
      });
    });
  });
}
<|endoftext|>


<commit_before>define(function(require) {
    'use strict';

    var Ember = require('ember'),
        debouncer;

    return Ember.Component.extend({
        layoutName: 'messageBar',
        classNames: ['message-bar'],
        content: null,
        fading: false,
        visible: false,
        fadeOut: function() {
            this.set('fading', true);

            this.$().fadeOut(500, function() {
                this.set('fading', false);
                this.set('visible', false)
            }.bind(this));
            console.log('3');
        },
        update: function() {
            console.log('4');
            if (!Ember.isEmpty(this.get('content'))) {
                if (this.get('fading')) {
                    this.$().stop(true, true).fadeOut();
                }

                if (!this.get('visible')) {
                    this.$().show();
                }

                debouncer = Ember.run.debounce(this, this.fadeOut, 2000);
            }
        }.observes('content').on('didInsertElement'),
        click: function() {
            Ember.run.cancel(debouncer);

            if (!this.get('fading')) {
                this.fadeOut();
            }
        },
        didInsertElement: function() {
            this.$().hide();
        }
    });
});
<commit_msg>Removed logs<commit_after>define(function(require) {
    'use strict';

    var Ember = require('ember'),
        debouncer;

    return Ember.Component.extend({
        layoutName: 'messageBar',
        classNames: ['message-bar'],
        content: null,
        fading: false,
        visible: false,
        fadeOut: function() {
            this.set('fading', true);

            this.$().fadeOut(500, function() {
                this.set('fading', false);
                this.set('visible', false)
            }.bind(this));
        },
        update: function() {
            if (!Ember.isEmpty(this.get('content'))) {
                if (this.get('fading')) {
                    this.$().stop(true, true).fadeOut();
                }

                if (!this.get('visible')) {
                    this.$().show();
                }

                debouncer = Ember.run.debounce(this, this.fadeOut, 2000);
            }
        }.observes('content').on('didInsertElement'),
        click: function() {
            Ember.run.cancel(debouncer);

            if (!this.get('fading')) {
                this.fadeOut();
            }
        },
        didInsertElement: function() {
            this.$().hide();
        }
    });
});
<|endoftext|>


<commit_before>var config = require(process.env.HOME + "/.jsiidConfig.js");
var net = require("net");

var clients = [];

var handleClientMessage = function(msg, socket) {
    var chanLongName = msg.server + ':' + msg.chan;
    chanLongName = chanLongName.toLowerCase();
    if(msg.cmd === "backlog") {
        // get nicklist for chan if we already haven't
        initChan(msg.server, msg.chan, true);

        if(ircChans[chanLongName]) {
            // send backlog
            for(var i = 0; i < config.backlog && i < ircChans[chanLongName].messages.length; i++) {
                broadcastMsg([socket], JSON.stringify(ircChans[chanLongName].messages[i]));
            }

            // send the nicklist
            broadcastMsg([socket], JSON.stringify({
                "cmd": "nicklist",
                "nicks": Object.keys(ircChans[chanLongName].nicks),
                "server": msg.server,
                "chan": msg.chan
            }));

        }
    } else if (msg.cmd === "search") {
        if(ircChans[chanLongName]) {
            // send search results
            var id = 0;
            for(var i = ircChans[chanLongName].messages.length - 1; i >= 0; i--) {
                var origMsg = ircChans[chanLongName].messages[i];
                if(origMsg.message &&
                   origMsg.message.match(new RegExp(msg.searchRE))) {

                    if(msg.skip > 0) {
                        msg.skip--;
                        continue;
                    }

                    var message = origMsg.message;
                    if(msg.onlyMatching) {
                        message = message.match(new RegExp(msg.searchRE))[0];
                    }

                    var results = {
                        "cmd": "searchResults",
                        "type": msg.type,
                        "id": id++,
                        "server": origMsg.server,
                        "chan": origMsg.chan,
                        "message": message,
                        "nick": origMsg.nick
                    }

                    broadcastMsg([socket], JSON.stringify(results));

                    if(msg.firstMatchOnly)
                        return;
                }
            }
        }
    } else {
        sendIrcMsg(msg, socket);
    }
};

var handleClientDisconnect = function(socket) {
    console.log("client disconnected.");
    clients.splice(clients.indexOf(socket), 1);
};

var createListener = function() {
    var listener = net.createServer(function (socket) {
        console.log("client connected.");
        var buffer = "";

        socket.on("data", function(data) {
            console.log("got client data:" + data);
            buffer += data.toString('utf8');
            var lastNL = buffer.lastIndexOf('\n');
            if(lastNL !== -1) {
                var recvdLines = buffer.substr(0, lastNL).split('\n');
                buffer = buffer.substr(lastNL + 1);

                for(var i = 0; i < recvdLines.length; i++) {
                    var msg = JSON.parse(recvdLines[i]);
                    handleClientMessage(msg, socket);
                }
            }
        });
        socket.on("end", function() {
            socket.end();
        });
        socket.on("error", function(err) {
            console.log('client socket error: ' + err.code);
        });
        socket.on("close", function() {
            handleClientDisconnect(socket);
        });

        clients.push(socket);
    });

    listener.listen(config.listenPort, config.listenAddr);
};

var broadcastMsg = function(clients, msg) {
    // msg shouldn't contain any newlines, but let's be sure
    if(msg.message)
        msg.message.replace('\n', '');

    for(var i = 0; i < clients.length; i++) {
        clients[i].write(msg + '\n');
    }
    console.log("broadcastMsg(): " + msg);
};

var ircChans = {};
var ircServers = {};

var recvdIrcMsg = function(serverName, cmd, chan, nick, msgString, noBroadcast) {
    var chanLongName = serverName + ':' + chan;
    chanLongName = chanLongName.toLowerCase();

    var msg = {
        "server": serverName,
        "cmd": cmd,
        "chan": chan,
        "nick": nick,
        "message": msgString
    };

    if(chan && msgString) {
        ircChans[chanLongName].messages.push(msg);
        if(ircChans[chanLongName].messages.length > config.backlog)
            ircChans[chanLongName].messages.shift();
    }

    if(!noBroadcast)
        broadcastMsg(clients, JSON.stringify(msg));
};

var sendIrcMsg = function(msg, client) {
    var ircServer = ircServers[msg.server];
    if(!ircServer)
        broadcastMsg([client], JSON.stringify({"error": "Server not found."}));
    else {
        if(!msg.message) {
            broadcastMsg([client], JSON.stringify({"error": "No message provided."}));
        } else if (msg.cmd === 'command') {
            ircServer.send(msg.message);
        } else if (msg.cmd === 'action') {
            if(!msg.chan)  {
                broadcastMsg([client], JSON.stringify({"error": "Invalid recepient."}));
                return;
            }
            initChan(msg.server, msg.chan, true);

            // add message to our backlog and send it
            broadcastMsg(clients, JSON.stringify(msg));
            recvdIrcMsg(msg.server, 'action', msg.chan, msg.nick, msg.message, true);

            ircServer.send('PRIVMSG ' + msg.chan + ' :\001ACTION ' + msg.message);
        } else {
            if(!msg.chan)  {
                broadcastMsg([client], JSON.stringify({"error": "Invalid recepient."}));
                return;
            }
            initChan(msg.server, msg.chan, true);

            // add message to our backlog and send it
            broadcastMsg(clients, JSON.stringify(msg));
            recvdIrcMsg(msg.server, "message", msg.chan, msg.nick, msg.message, true);
            ircServer.send('PRIVMSG ' + msg.chan + ' :' + msg.message);
        }
    }
};

var initChan = function(serverName, chan) {
    var chanLongName = serverName + ':' + chan;
    chanLongName = chanLongName.toLowerCase();

    if(!ircChans[chanLongName]) {
        ircChans[chanLongName] = {
            "messages": [],
            "nicks": {}
        };
    }
};

var handleIrcLine = function(line, server, ircServer) {
    var tokens = line.split(' ');

    //console.log(server.name + ': ' + line);
    if(tokens[0] === "PING") {
        console.log('got PING, sending PONG to ' + tokens[1].substr(1));
        ircServer.send("PONG " + tokens[1].substr(1));
    } else if (tokens[0][0] === ":") {
        var prefix = tokens[0].substr(1);
        var nick = prefix.substr(0, prefix.indexOf('!'));
        var cmd = tokens[1];
        var chan = tokens[2];
        chan = chan.replace(':', '');

        var chanLongName = server.name + ':' + chan;
        chanLongName = chanLongName.toLowerCase();

        if(prefix === server.serverLongName) {
            tokens.shift(); tokens.shift(); tokens.shift();
            var msg = tokens.join(' ');
            // nicklist
            if (cmd === "353") {
                chan = msg.split(':')[0];
                chan = chan.split(' ')[1];
                var nicks = msg.split(':')[1];
                nicks = nicks.split(' ');

                chanLongName = server.name + ':' + chan;
                chanLongName = chanLongName.toLowerCase();
                initChan(server.name, chan, false);

                for(var i = 0; i < nicks.length; i++) {
                    ircChans[chanLongName].nicks[nicks[i]] = true;
                }

                // send the nicklist
                broadcastMsg(clients, JSON.stringify({
                    "cmd": "nicklist",
                    "nicks": Object.keys(ircChans[chanLongName].nicks),
                    "server": msg.server,
                    "chan": msg.chan
                }));
            } else {
                initChan(server.name, server.name, false);
                recvdIrcMsg(server.name, "message", server.name, server.name, msg);
            }
        } else if(cmd === "PRIVMSG") {
            tokens.shift(); tokens.shift(); tokens.shift();
            var msg = tokens.join(' ').substr(1);

            // query message
            if(chan === (server.nick || config.nick)) {
                chan = nick;
            }

            initChan(server.name, chan, true);

            if(msg.substr(0, 8) === '\001ACTION ') {
                recvdIrcMsg(server.name, "action", chan, nick, msg.substr(8));
            } else {
                recvdIrcMsg(server.name, "message", chan, nick, msg);
            }
        } else if (cmd === "JOIN") {
            initChan(server.name, chan, true);
            if(nick !== (server.nick || config.nick)) {
                recvdIrcMsg(server.name, "join", chan, nick, null);
                ircChans[chanLongName].nicks[nick] = true;
            }
        } else if (cmd === "PART") {
            initChan(server.name, chan, true);
            recvdIrcMsg(server.name, "part", chan, nick, null);
            delete(ircChans[chanLongName].nicks[nick]);
        } else if (cmd === "QUIT") {
            for(var key in ircChans) {
                for(var chanNick in ircChans[key].nicks) {
                    if(chanNick === nick) {
                        recvdIrcMsg(server.name, "part", key, nick, null);
                        delete(ircChans[key].nicks[nick]);
                    }
                }
            }
        } else if (cmd === "001") {
            server.serverLongName = prefix;
            console.log("serverLongName changed to " + server.serverLongName);
        } else if (cmd === "PONG") {
            console.log("got PONG from " + server.address);
        } else {
            console.log("got unknown msg from " + nick + ": " + line);
        }
    } else {
        console.log("got unknown msg on " + server.name + ": " + line);
    }
};

var ircConnect = function(serverConfig, oldReconnectTimer) {
    var buffer = "";

    var ircServer = net.connect({
        "port": serverConfig.port,
        "host": serverConfig.address
    }, function() {
        // logging
        console.log('connected to irc server');
        var msg = {
            nick: '!',
            message: serverConfig.name + ': Connected to IRC.',
            broadcast: true
        };

        broadcastMsg(clients, JSON.stringify(msg));

        var passString = "";
        if(serverConfig.password)
            passString = "PASS " + serverConfig.password + "\r\n";

        ircServer.write(passString +
                     "NICK " + (serverConfig.nick || config.nick) + "\r\n" +
                     "USER " + (serverConfig.nick || config.nick) + " " +
                     "localhost " + serverConfig.address + " :" +
                     (serverConfig.nick || config.nick) + "\r\n");

        ircServer.resetPingTimer();
    });

    ircServer.send = function(data) {
        console.log("sending data to IRC: " + data);
        ircServer.write(data + '\r\n');
    };

    ircServer.on('data', function(data) {
        ircServer.resetPingTimer();

        buffer += data.toString('utf8');
        var lastNL = buffer.lastIndexOf('\n');

        // have we received at least one whole line? else wait for more data
        if(lastNL !== -1) {
            var recvdLines = buffer.substr(0, lastNL + 1).split('\r\n');
            buffer = buffer.substr(lastNL + 1);

            for(var i = 0; i < recvdLines.length; i++) {
                if(recvdLines[i] !== '') {
                    console.log('irc server sent ' + recvdLines[i]);
                    handleIrcLine(recvdLines[i], serverConfig, ircServer);
                }
            }
        }
    });

    ircServer.reconnect = function(message) {
        // cleanup
        clearTimeout(ircServer.pingTimer);
        ircServer.removeAllListeners('end');
        ircServer.removeAllListeners('close');
        ircServer.removeAllListeners('error');

        ircServer.destroy();

        // logging
        console.log(message);
        var msg = {
            nick: '!',
            message: message,
            broadcast: true
        };

        broadcastMsg(clients, JSON.stringify(msg));

        // delay reconnect by config.reconnectDelay ms
        ircServer.reconnectTimer = setTimeout(function() {
            console.log(serverConfig.name + ': reconnecting...');
            ircConnect(serverConfig);
        }, config.reconnectDelay);
    };

    ircServer.on('end', function() {
        ircServer.reconnect(serverConfig.name + ': connection to irc ended.');
    });
    ircServer.on('close', function() {
        ircServer.reconnect(serverConfig.name + ': connection to irc closed.');
    });
    ircServer.on('error', function(err) {
        ircServer.reconnect(serverConfig.name + ': irc socket error: ' + err.code);
    });

    // call whenever irc server sends data to postpone timeout timers
    ircServer.resetPingTimer = function() {
        // ping the server after config.pingDelay of inactivity
        clearTimeout(ircServer.pingTimer);
        ircServer.pingTimer = setTimeout(function() {
            ircServer.send('PING ' + ircServer.config.address);
        }, config.pingDelay);
    };

    ircServer.setTimeout(config.timeoutDelay, function() {
        ircServer.reconnect(serverConfig.name + ': connection to irc timed out.');
    });

    ircServer.config = serverConfig;
    ircServers[serverConfig.name] = ircServer;
};

createListener();

for(var i = 0; i < config.servers.length; i++) {
    ircConnect(config.servers[i]);
}
<commit_msg>decrease verbosity<commit_after>var config = require(process.env.HOME + "/.jsiidConfig.js");
var net = require("net");

var clients = [];

var handleClientMessage = function(msg, socket) {
    var chanLongName = msg.server + ':' + msg.chan;
    chanLongName = chanLongName.toLowerCase();
    if(msg.cmd === "backlog") {
        // get nicklist for chan if we already haven't
        initChan(msg.server, msg.chan, true);

        if(ircChans[chanLongName]) {
            // send backlog
            for(var i = 0; i < config.backlog && i < ircChans[chanLongName].messages.length; i++) {
                broadcastMsg([socket], JSON.stringify(ircChans[chanLongName].messages[i]));
            }

            // send the nicklist
            broadcastMsg([socket], JSON.stringify({
                "cmd": "nicklist",
                "nicks": Object.keys(ircChans[chanLongName].nicks),
                "server": msg.server,
                "chan": msg.chan
            }));

        }
    } else if (msg.cmd === "search") {
        if(ircChans[chanLongName]) {
            // send search results
            var id = 0;
            for(var i = ircChans[chanLongName].messages.length - 1; i >= 0; i--) {
                var origMsg = ircChans[chanLongName].messages[i];
                if(origMsg.message &&
                   origMsg.message.match(new RegExp(msg.searchRE))) {

                    if(msg.skip > 0) {
                        msg.skip--;
                        continue;
                    }

                    var message = origMsg.message;
                    if(msg.onlyMatching) {
                        message = message.match(new RegExp(msg.searchRE))[0];
                    }

                    var results = {
                        "cmd": "searchResults",
                        "type": msg.type,
                        "id": id++,
                        "server": origMsg.server,
                        "chan": origMsg.chan,
                        "message": message,
                        "nick": origMsg.nick
                    }

                    broadcastMsg([socket], JSON.stringify(results));

                    if(msg.firstMatchOnly)
                        return;
                }
            }
        }
    } else {
        sendIrcMsg(msg, socket);
    }
};

var handleClientDisconnect = function(socket) {
    //console.log("client disconnected.");
    clients.splice(clients.indexOf(socket), 1);
};

var createListener = function() {
    var listener = net.createServer(function (socket) {
        //console.log("client connected.");
        var buffer = "";

        socket.on("data", function(data) {
            //console.log("got client data:" + data);
            buffer += data.toString('utf8');
            var lastNL = buffer.lastIndexOf('\n');
            if(lastNL !== -1) {
                var recvdLines = buffer.substr(0, lastNL).split('\n');
                buffer = buffer.substr(lastNL + 1);

                for(var i = 0; i < recvdLines.length; i++) {
                    var msg = JSON.parse(recvdLines[i]);
                    handleClientMessage(msg, socket);
                }
            }
        });
        socket.on("end", function() {
            socket.end();
        });
        socket.on("error", function(err) {
            //console.log('client socket error: ' + err.code);
        });
        socket.on("close", function() {
            handleClientDisconnect(socket);
        });

        clients.push(socket);
    });

    listener.listen(config.listenPort, config.listenAddr);
};

var broadcastMsg = function(clients, msg) {
    // msg shouldn't contain any newlines, but let's be sure
    if(msg.message)
        msg.message.replace('\n', '');

    for(var i = 0; i < clients.length; i++) {
        clients[i].write(msg + '\n');
    }
    //console.log("broadcastMsg(): " + msg);
};

var ircChans = {};
var ircServers = {};

var recvdIrcMsg = function(serverName, cmd, chan, nick, msgString, noBroadcast) {
    var chanLongName = serverName + ':' + chan;
    chanLongName = chanLongName.toLowerCase();

    var msg = {
        "server": serverName,
        "cmd": cmd,
        "chan": chan,
        "nick": nick,
        "message": msgString
    };

    if(chan && msgString) {
        ircChans[chanLongName].messages.push(msg);
        if(ircChans[chanLongName].messages.length > config.backlog)
            ircChans[chanLongName].messages.shift();
    }

    if(!noBroadcast)
        broadcastMsg(clients, JSON.stringify(msg));
};

var sendIrcMsg = function(msg, client) {
    var ircServer = ircServers[msg.server];
    if(!ircServer)
        broadcastMsg([client], JSON.stringify({"error": "Server not found."}));
    else {
        if(!msg.message) {
            broadcastMsg([client], JSON.stringify({"error": "No message provided."}));
        } else if (msg.cmd === 'command') {
            ircServer.send(msg.message);
        } else if (msg.cmd === 'action') {
            if(!msg.chan)  {
                broadcastMsg([client], JSON.stringify({"error": "Invalid recepient."}));
                return;
            }
            initChan(msg.server, msg.chan, true);

            // add message to our backlog and send it
            broadcastMsg(clients, JSON.stringify(msg));
            recvdIrcMsg(msg.server, 'action', msg.chan, msg.nick, msg.message, true);

            ircServer.send('PRIVMSG ' + msg.chan + ' :\001ACTION ' + msg.message);
        } else {
            if(!msg.chan)  {
                broadcastMsg([client], JSON.stringify({"error": "Invalid recepient."}));
                return;
            }
            initChan(msg.server, msg.chan, true);

            // add message to our backlog and send it
            broadcastMsg(clients, JSON.stringify(msg));
            recvdIrcMsg(msg.server, "message", msg.chan, msg.nick, msg.message, true);
            ircServer.send('PRIVMSG ' + msg.chan + ' :' + msg.message);
        }
    }
};

var initChan = function(serverName, chan) {
    var chanLongName = serverName + ':' + chan;
    chanLongName = chanLongName.toLowerCase();

    if(!ircChans[chanLongName]) {
        ircChans[chanLongName] = {
            "messages": [],
            "nicks": {}
        };
    }
};

var handleIrcLine = function(line, server, ircServer) {
    var tokens = line.split(' ');

    //console.log(server.name + ': ' + line);
    if(tokens[0] === "PING") {
        //console.log('got PING, sending PONG to ' + tokens[1].substr(1));
        ircServer.send("PONG " + tokens[1].substr(1));
    } else if (tokens[0][0] === ":") {
        var prefix = tokens[0].substr(1);
        var nick = prefix.substr(0, prefix.indexOf('!'));
        var cmd = tokens[1];
        var chan = tokens[2];
        chan = chan.replace(':', '');

        var chanLongName = server.name + ':' + chan;
        chanLongName = chanLongName.toLowerCase();

        if(prefix === server.serverLongName) {
            tokens.shift(); tokens.shift(); tokens.shift();
            var msg = tokens.join(' ');
            // nicklist
            if (cmd === "353") {
                chan = msg.split(':')[0];
                chan = chan.split(' ')[1];
                var nicks = msg.split(':')[1];
                nicks = nicks.split(' ');

                chanLongName = server.name + ':' + chan;
                chanLongName = chanLongName.toLowerCase();
                initChan(server.name, chan, false);

                for(var i = 0; i < nicks.length; i++) {
                    ircChans[chanLongName].nicks[nicks[i]] = true;
                }

                // send the nicklist
                broadcastMsg(clients, JSON.stringify({
                    "cmd": "nicklist",
                    "nicks": Object.keys(ircChans[chanLongName].nicks),
                    "server": msg.server,
                    "chan": msg.chan
                }));
            } else {
                initChan(server.name, server.name, false);
                recvdIrcMsg(server.name, "message", server.name, server.name, msg);
            }
        } else if(cmd === "PRIVMSG") {
            tokens.shift(); tokens.shift(); tokens.shift();
            var msg = tokens.join(' ').substr(1);

            // query message
            if(chan === (server.nick || config.nick)) {
                chan = nick;
            }

            initChan(server.name, chan, true);

            if(msg.substr(0, 8) === '\001ACTION ') {
                recvdIrcMsg(server.name, "action", chan, nick, msg.substr(8));
            } else {
                recvdIrcMsg(server.name, "message", chan, nick, msg);
            }
        } else if (cmd === "JOIN") {
            initChan(server.name, chan, true);
            if(nick !== (server.nick || config.nick)) {
                recvdIrcMsg(server.name, "join", chan, nick, null);
                ircChans[chanLongName].nicks[nick] = true;
            }
        } else if (cmd === "PART") {
            initChan(server.name, chan, true);
            recvdIrcMsg(server.name, "part", chan, nick, null);
            delete(ircChans[chanLongName].nicks[nick]);
        } else if (cmd === "QUIT") {
            for(var key in ircChans) {
                for(var chanNick in ircChans[key].nicks) {
                    if(chanNick === nick) {
                        recvdIrcMsg(server.name, "part", key, nick, null);
                        delete(ircChans[key].nicks[nick]);
                    }
                }
            }
        } else if (cmd === "001") {
            server.serverLongName = prefix;
            //console.log("serverLongName changed to " + server.serverLongName);
        } else if (cmd === "PONG") {
            //console.log("got PONG from " + server.address);
        } else {
            //console.log("got unknown msg from " + nick + ": " + line);
        }
    } else {
        //console.log("got unknown msg on " + server.name + ": " + line);
    }
};

var ircConnect = function(serverConfig, oldReconnectTimer) {
    var buffer = "";

    var ircServer = net.connect({
        "port": serverConfig.port,
        "host": serverConfig.address
    }, function() {
        // logging
        console.log('connected to irc server');
        var msg = {
            nick: '!',
            message: serverConfig.name + ': Connected to IRC.',
            broadcast: true
        };

        broadcastMsg(clients, JSON.stringify(msg));

        var passString = "";
        if(serverConfig.password)
            passString = "PASS " + serverConfig.password + "\r\n";

        ircServer.write(passString +
                     "NICK " + (serverConfig.nick || config.nick) + "\r\n" +
                     "USER " + (serverConfig.nick || config.nick) + " " +
                     "localhost " + serverConfig.address + " :" +
                     (serverConfig.nick || config.nick) + "\r\n");

        ircServer.resetPingTimer();
    });

    ircServer.send = function(data) {
        //console.log("sending data to IRC: " + data);
        ircServer.write(data + '\r\n');
    };

    ircServer.on('data', function(data) {
        ircServer.resetPingTimer();

        buffer += data.toString('utf8');
        var lastNL = buffer.lastIndexOf('\n');

        // have we received at least one whole line? else wait for more data
        if(lastNL !== -1) {
            var recvdLines = buffer.substr(0, lastNL + 1).split('\r\n');
            buffer = buffer.substr(lastNL + 1);

            for(var i = 0; i < recvdLines.length; i++) {
                if(recvdLines[i] !== '') {
                    //console.log('irc server sent ' + recvdLines[i]);
                    handleIrcLine(recvdLines[i], serverConfig, ircServer);
                }
            }
        }
    });

    ircServer.reconnect = function(message) {
        // cleanup
        clearTimeout(ircServer.pingTimer);
        ircServer.removeAllListeners('end');
        ircServer.removeAllListeners('close');
        ircServer.removeAllListeners('error');

        ircServer.destroy();

        // logging
        //console.log(message);
        var msg = {
            nick: '!',
            message: message,
            broadcast: true
        };

        broadcastMsg(clients, JSON.stringify(msg));

        // delay reconnect by config.reconnectDelay ms
        ircServer.reconnectTimer = setTimeout(function() {
            console.log(serverConfig.name + ': reconnecting...');
            ircConnect(serverConfig);
        }, config.reconnectDelay);
    };

    ircServer.on('end', function() {
        ircServer.reconnect(serverConfig.name + ': connection to irc ended.');
    });
    ircServer.on('close', function() {
        ircServer.reconnect(serverConfig.name + ': connection to irc closed.');
    });
    ircServer.on('error', function(err) {
        ircServer.reconnect(serverConfig.name + ': irc socket error: ' + err.code);
    });

    // call whenever irc server sends data to postpone timeout timers
    ircServer.resetPingTimer = function() {
        // ping the server after config.pingDelay of inactivity
        clearTimeout(ircServer.pingTimer);
        ircServer.pingTimer = setTimeout(function() {
            ircServer.send('PING ' + ircServer.config.address);
        }, config.pingDelay);
    };

    ircServer.setTimeout(config.timeoutDelay, function() {
        ircServer.reconnect(serverConfig.name + ': connection to irc timed out.');
    });

    ircServer.config = serverConfig;
    ircServers[serverConfig.name] = ircServer;
};

createListener();

for(var i = 0; i < config.servers.length; i++) {
    ircConnect(config.servers[i]);
}
<|endoftext|>