<commit_before>module.exports = class Feld {
  constructor(options) {
    options = options || {};
    this.SAMEPLAYERSTURNAFTERHIT = typeof options.SAMEPLAYERSTURNAFTERHIT === "undefined" ? true : options.SAMEPLAYERSTURNAFTERHIT;
    this.REQUIREDSHIPS = options.REQUIREDSHIPS || [0, 0, 1, 2, 1, 1]; // hier: 0x 0er, 0x 1er, 1x 2er, 2x 3er, 1x 4er, 1x 5er
    this.FIELD_HEIGHT = options.FIELD_HEIGHT || 10;
    this.FIELD_WIDTH = options.FIELD_WIDTH || 10;
    this.COLLISION_RULES = options.COLLISION_RULES || {
      ALLOW_CORNER_COLLISIONS: true // in the default field: [0,1,2,3,4,15,16] for example
    }
    this.SHIPCOUNTER = 0;
    this.SHIPPOSCOUNTER = 0;
    for (let i = 0; i < this.REQUIREDSHIPS.length; i++) {
      if (this.REQUIREDSHIPS[i] > 0) {
        this.SHIPCOUNTER += this.REQUIREDSHIPS[i];
      }
      this.SHIPPOSCOUNTER += this.REQUIREDSHIPS[i] * i;
    }
    this.ships = [];
    this.hits = [];
    this.misses = [];
  }

  isShipAt(pos) {
    let hit = false;
    for (let s of this.ships) {

      if (s.indexOf(pos) != -1) {
        hit = true;
        break;
      }
    }
    return hit;
  }

  hasAlreadyBeenHit(pos) {
    return this.hits.indexOf(pos) != -1;
  }

  hasAlreadyBeenMissed(pos) {
    return this.misses.indexOf(pos) != -1;
  }

  setShips(arr) {
    let data = this.checkShipArray(arr);
    if (data.status == "success") {
      this.ships = data.ships;
      return {
        status: "success"
      }
    }
    return {
      status: data.status,
      reason: data.reason
    }
  }

  checkShipArray(arr) {

    // sort ascending
    arr.sort((a, b) => a - b);

    // Prüfen, ob alle Schiffe platziert wurden
    if (arr.length != this.SHIPPOSCOUNTER) {
      return {
        status: "fail",
        reason: "Es ist ein Fehler aufgetreten. Es müssen folgende Schiffe platziert werden: " + this.getRequiredShipsListAsText()
      }
    }

    // Prüfen, ob alle Schiffe innerhalb des Spielfelds platziert wurden
    for (let s of arr) {
      if (s < 0 || s > this.FIELD_HEIGHT * this.FIELD_WIDTH - 1) {
        return {
          status: "fail",
          reason: "Es ist ein Fehler aufgetreten. Schiffe müssen innerhalb des Spielfelds platziert werden."
        }
      }
    }

    // Prüfen, ob keine Position auf dem Spielfeld doppelt vorkommt.
    let arr2 = [];
    for (let s of arr) {
      if (arr2[s] == undefined) {
        arr2[s] = true;
      } else {
        return {
          status: "fail",
          reason: "Es ist ein Fehler aufgetreten. Mindestens ein Position des Spielfelds wurde doppelt besetzt."
        }
      }
    }

    // Ein Array mit allen Schiffen bekommen (vorher: Array mit allen Positionen)
    let data = this.getShipsOfArray(arr);
    let ships = data.shipArray;
    let shipsH = data.shipArrayH;
    let shipsV = data.shipArrayV;

    // Prüfen, ob die Schiffe in Anzahl und Länge den Vorgaben entsprechen
    if (ships.length == this.SHIPCOUNTER) {
      // deep copy von den requirement erstellen und bei jedem Boot der Länge x den den Wert mit dem Inde x um 1 senken.
      // Danach prüfen, ob alle Werte des Arrays auf 0 sind.
      let reqCheckArr = JSON.parse(JSON.stringify(this.REQUIREDSHIPS));
      for (let s of ships) {
        reqCheckArr[s.length]--;
      }
      for (let x of reqCheckArr) {
        if (x != 0) {
          return {
            status: "fail",
            reason: "Es ist ein Fehler aufgetreten. Es müssen folgende Schiffe platziert werden: " + this.getRequiredShipsListAsText()
          }
        }
      }
    } else {
      return {
        status: "fail",
        reason: "Es ist ein Fehler aufgetreten. Es müssen folgende Schiffe platziert werden: " + this.getRequiredShipsListAsText()
      }
    }

    // Prüfen, ob alle Teile horiz. Schiff in der selben Reihe liegen ( [8,9,10,11,12] bspw. nicht akzeptieren).
    for (let s of shipsH) {
      let row = Math.floor(s[0] / this.FIELD_WIDTH);
      for (let i = 1; i < s.length; i++) {
        if (Math.floor(s[i] / this.FIELD_WIDTH) != row) {
          return {
            status: "fail",
            reason: "Es ist ein Fehler aufgetreten. Es müssen folgende Schiffe platziert werden: " + this.getRequiredShipsListAsText()
          }
        }
      }
    }

    // Gehe alle Schiffe durch und prüfe, ob sie auf verbotenen Positionen stehen
    let forbidden_positions = this.getForbiddenPos(shipsH, shipsV);
    for (let s of ships) {
      for (let pos of s) {
        if (forbidden_positions.indexOf(pos) != -1) {
          return {
            status: "fail",
            reason: "Fehler! Schiffe dürfen nicht miteinander kollidieren!"
          }
        }
      }
    }

    return {
      status: "success",
      ships: ships
    };
  }

  getShipsOfArray(arr) {
    let shipArray = [];
    let shipArrayH = [];
    let shipArrayV = [];
    let arr_h = []; // Array, das mit den Positionen aller horizontaler Schiffe gefüllt wird

    // Vertikale Schiffe finden.
    for (let s of arr) {
      // Falls die Position schon Teil eines Schiffs ist, continue
      let foundIt = false;
      for (let sh of shipArray) {
        if (sh.indexOf(s) != -1) {
          foundIt = true;
          break;
        }
      }
      if (foundIt) {
        continue;
      }

      let i = 0;
      while (arr.indexOf(s + (i + 1) * this.FIELD_WIDTH) != -1) {
        i++;
      }
      if (i == 0) {
        arr_h.push(s);
      } else {
        let newShip = [];
        for (let j = s; j < s + (i + 1) * this.FIELD_WIDTH; j += this.FIELD_WIDTH) {
          newShip.push(j);
        }
        shipArray.push(newShip);
        shipArrayV.push(newShip);
      }
    }

    // Horizontale Schiffe finden.
    for (let s of arr_h) {
      // Falls die Position schon Teil eines Schiffs ist, continue
      let foundIt = false;
      for (let sh of shipArray) {
        if (sh.indexOf(s) != -1) {
          foundIt = true;
          break;
        }
      }
      if (foundIt) {
        continue;
      }

      let i = 0;
      while (arr.indexOf(s + i + 1) != -1) {
        i++;
      }
      if (i != 0) {
        let newShip = [];
        for (let j = s; j < s + i + 1; j++) {
          newShip.push(j);
        }
        shipArray.push(newShip);
        shipArrayH.push(newShip);
      }
    }

    return {
      shipArray: shipArray,
      shipArrayH: shipArrayH,
      shipArrayV: shipArrayV
    }
  }

  getForbiddenPos(arrH, arrV) {
    // Erstelle ein Array mit (für Schiffe) vebotenen Positionen
    // (Schritt 1: horizontal)
    let forbidden_positions = [];
    for (let s of arrH) {

      // Positionen vor und hinter dem Schiff sind verboten
      if (s[0] % this.FIELD_WIDTH > 0) {
        forbidden_positions = this.pushPosInArray(s[0] - 1, forbidden_positions);
      }
      if ((s[0] + 1) % this.FIELD_WIDTH > 0) {
        forbidden_positions = this.pushPosInArray(s[s.length - 1] + 1, forbidden_positions);
      }

      // Reihen direkt neben dem Schiff & parallel zum Schiff sind verboten
      for (let i = 0; i < s.length; i++) {
        forbidden_positions = this.pushPosInArray(s[i] - this.FIELD_WIDTH, forbidden_positions);
        forbidden_positions = this.pushPosInArray(s[i] + this.FIELD_WIDTH, forbidden_positions);
      }

      // Positionen an den Ecken sind evtl. verboten
      if (!this.COLLISION_RULES.ALLOW_CORNER_COLLISIONS) {
        if (s[0] % this.FIELD_WIDTH > 0) {
          this.pushPosInArray(s[0] - (this.FIELD_WIDTH + 1), forbidden_positions);
          this.pushPosInArray(s[0] + (this.FIELD_WIDTH - 1), forbidden_positions);
        }
        if ((s[0] + 1) % this.FIELD_WIDTH > 0) {
          this.pushPosInArray(s[s.length - 1] - (this.FIELD_WIDTH - 1), forbidden_positions);
          this.pushPosInArray(s[s.length - 1] + (this.FIELD_WIDTH + 1), forbidden_positions);
        }
      }
    }

    // (Schritt 2: vertikal)
    for (let s of arrV) {

      // Positionen vor und hinter dem Schiff sind verboten
      forbidden_positions = this.pushPosInArray(s[0] - this.FIELD_WIDTH, forbidden_positions);
      forbidden_positions = this.pushPosInArray(s[s.length - 1] + this.FIELD_WIDTH, forbidden_positions);

      // Reihen direkt neben dem Schiff & parallel zum Schiff sind verboten
      for (let i = 0; i < s.length; i++) {
        if (s[i] % this.FIELD_WIDTH > 0) {
          forbidden_positions = this.pushPosInArray(s[i] - 1, forbidden_positions);
        }
        if ((s[i] + 1) % this.FIELD_WIDTH > 0) {
          forbidden_positions = this.pushPosInArray(s[i] + 1, forbidden_positions);
        }
      }

      // Positionen an den Ecken sind evtl. verboten
      if (!this.COLLISION_RULES.ALLOW_CORNER_COLLISIONS) {
        if (s[0] % this.FIELD_WIDTH > 0) {
          this.pushPosInArray(s[0] - (this.FIELD_WIDTH + 1), forbidden_positions);
          this.pushPosInArray(s[s.length - 1] + (this.FIELD_WIDTH - 1), forbidden_positions);
        }
        if ((s[0] + 1) % this.FIELD_WIDTH > 0) {
          this.pushPosInArray(s[0] - (this.FIELD_WIDTH - 1), forbidden_positions);
          this.pushPosInArray(s[s.length - 1] + (this.FIELD_WIDTH + 1), forbidden_positions);
        }
      }
    }
    return forbidden_positions;
  }

  getRequiredShipsListAsText(arr) {
    let req_ships = [];
    for (let i = 0; i < this.REQUIREDSHIPS.length; i++) {
      if (this.REQUIREDSHIPS[i] > 0) {
        req_ships.push(this.REQUIREDSHIPS[i] + "x " + i + "er");
      }
    }
    return req_ships.join(", ");
  }

  pushPosInArray(pos, arr) {
    if (arr.indexOf(pos) == -1) {
      if (pos >= 0 && pos < this.FIELD_HEIGHT * this.FIELD_WIDTH - 1) {
        arr.push(pos);
      }
    }
    return arr;
  }
}<commit_msg>Positionsduplikate eliminieren anstatt eine Fehlermeldung auszugeben<commit_after>module.exports = class Feld {
  constructor(options) {
    options = options || {};
    this.SAMEPLAYERSTURNAFTERHIT = typeof options.SAMEPLAYERSTURNAFTERHIT === "undefined" ? true : options.SAMEPLAYERSTURNAFTERHIT;
    this.REQUIREDSHIPS = options.REQUIREDSHIPS || [0, 0, 1, 2, 1, 1]; // hier: 0x 0er, 0x 1er, 1x 2er, 2x 3er, 1x 4er, 1x 5er
    this.FIELD_HEIGHT = options.FIELD_HEIGHT || 10;
    this.FIELD_WIDTH = options.FIELD_WIDTH || 10;
    this.COLLISION_RULES = options.COLLISION_RULES || {
      ALLOW_CORNER_COLLISIONS: true // in the default field: [0,1,2,3,4,15,16] for example
    }
    this.SHIPCOUNTER = 0;
    this.SHIPPOSCOUNTER = 0;
    for (let i = 0; i < this.REQUIREDSHIPS.length; i++) {
      if (this.REQUIREDSHIPS[i] > 0) {
        this.SHIPCOUNTER += this.REQUIREDSHIPS[i];
      }
      this.SHIPPOSCOUNTER += this.REQUIREDSHIPS[i] * i;
    }
    this.ships = [];
    this.hits = [];
    this.misses = [];
  }

  isShipAt(pos) {
    let hit = false;
    for (let s of this.ships) {

      if (s.indexOf(pos) != -1) {
        hit = true;
        break;
      }
    }
    return hit;
  }

  hasAlreadyBeenHit(pos) {
    return this.hits.indexOf(pos) != -1;
  }

  hasAlreadyBeenMissed(pos) {
    return this.misses.indexOf(pos) != -1;
  }

  setShips(arr) {
    let data = this.checkShipArray(arr);
    if (data.status == "success") {
      this.ships = data.ships;
      return {
        status: "success"
      }
    }
    return {
      status: data.status,
      reason: data.reason
    }
  }

  checkShipArray(arr) {

    // Duplikate eliminieren
    arr = Array.from(new Set(arr));

    // sort ascending
    arr.sort((a, b) => a - b);

    // Prüfen, ob alle Schiffe platziert wurden
    if (arr.length != this.SHIPPOSCOUNTER) {
      return {
        status: "fail",
        reason: "Es ist ein Fehler aufgetreten. Es müssen folgende Schiffe platziert werden: " + this.getRequiredShipsListAsText()
      }
    }

    // Prüfen, ob alle Schiffe innerhalb des Spielfelds platziert wurden
    for (let s of arr) {
      if (s < 0 || s > this.FIELD_HEIGHT * this.FIELD_WIDTH - 1) {
        return {
          status: "fail",
          reason: "Es ist ein Fehler aufgetreten. Schiffe müssen innerhalb des Spielfelds platziert werden."
        }
      }
    }

    // Ein Array mit allen Schiffen bekommen (vorher: Array mit allen Positionen)
    let data = this.getShipsOfArray(arr);
    let ships = data.shipArray;
    let shipsH = data.shipArrayH;
    let shipsV = data.shipArrayV;

    // Prüfen, ob die Schiffe in Anzahl und Länge den Vorgaben entsprechen
    if (ships.length == this.SHIPCOUNTER) {
      // deep copy von den requirement erstellen und bei jedem Boot der Länge x den den Wert mit dem Inde x um 1 senken.
      // Danach prüfen, ob alle Werte des Arrays auf 0 sind.
      let reqCheckArr = JSON.parse(JSON.stringify(this.REQUIREDSHIPS));
      for (let s of ships) {
        reqCheckArr[s.length]--;
      }
      for (let x of reqCheckArr) {
        if (x != 0) {
          return {
            status: "fail",
            reason: "Es ist ein Fehler aufgetreten. Es müssen folgende Schiffe platziert werden: " + this.getRequiredShipsListAsText()
          }
        }
      }
    } else {
      return {
        status: "fail",
        reason: "Es ist ein Fehler aufgetreten. Es müssen folgende Schiffe platziert werden: " + this.getRequiredShipsListAsText()
      }
    }

    // Prüfen, ob alle Teile horiz. Schiff in der selben Reihe liegen ( [8,9,10,11,12] bspw. nicht akzeptieren).
    for (let s of shipsH) {
      let row = Math.floor(s[0] / this.FIELD_WIDTH);
      for (let i = 1; i < s.length; i++) {
        if (Math.floor(s[i] / this.FIELD_WIDTH) != row) {
          return {
            status: "fail",
            reason: "Es ist ein Fehler aufgetreten. Es müssen folgende Schiffe platziert werden: " + this.getRequiredShipsListAsText()
          }
        }
      }
    }

    // Gehe alle Schiffe durch und prüfe, ob sie auf verbotenen Positionen stehen
    let forbidden_positions = this.getForbiddenPos(shipsH, shipsV);
    for (let s of ships) {
      for (let pos of s) {
        if (forbidden_positions.indexOf(pos) != -1) {
          return {
            status: "fail",
            reason: "Fehler! Schiffe dürfen nicht miteinander kollidieren!"
          }
        }
      }
    }

    return {
      status: "success",
      ships: ships
    };
  }

  getShipsOfArray(arr) {
    let shipArray = [];
    let shipArrayH = [];
    let shipArrayV = [];
    let arr_h = []; // Array, das mit den Positionen aller horizontaler Schiffe gefüllt wird

    // Vertikale Schiffe finden.
    for (let s of arr) {
      // Falls die Position schon Teil eines Schiffs ist, continue
      let foundIt = false;
      for (let sh of shipArray) {
        if (sh.indexOf(s) != -1) {
          foundIt = true;
          break;
        }
      }
      if (foundIt) {
        continue;
      }

      let i = 0;
      while (arr.indexOf(s + (i + 1) * this.FIELD_WIDTH) != -1) {
        i++;
      }
      if (i == 0) {
        arr_h.push(s);
      } else {
        let newShip = [];
        for (let j = s; j < s + (i + 1) * this.FIELD_WIDTH; j += this.FIELD_WIDTH) {
          newShip.push(j);
        }
        shipArray.push(newShip);
        shipArrayV.push(newShip);
      }
    }

    // Horizontale Schiffe finden.
    for (let s of arr_h) {
      // Falls die Position schon Teil eines Schiffs ist, continue
      let foundIt = false;
      for (let sh of shipArray) {
        if (sh.indexOf(s) != -1) {
          foundIt = true;
          break;
        }
      }
      if (foundIt) {
        continue;
      }

      let i = 0;
      while (arr.indexOf(s + i + 1) != -1) {
        i++;
      }
      if (i != 0) {
        let newShip = [];
        for (let j = s; j < s + i + 1; j++) {
          newShip.push(j);
        }
        shipArray.push(newShip);
        shipArrayH.push(newShip);
      }
    }

    return {
      shipArray: shipArray,
      shipArrayH: shipArrayH,
      shipArrayV: shipArrayV
    }
  }

  getForbiddenPos(arrH, arrV) {
    // Erstelle ein Array mit (für Schiffe) vebotenen Positionen
    // (Schritt 1: horizontal)
    let forbidden_positions = [];
    for (let s of arrH) {

      // Positionen vor und hinter dem Schiff sind verboten
      if (s[0] % this.FIELD_WIDTH > 0) {
        forbidden_positions = this.pushPosInArray(s[0] - 1, forbidden_positions);
      }
      if ((s[0] + 1) % this.FIELD_WIDTH > 0) {
        forbidden_positions = this.pushPosInArray(s[s.length - 1] + 1, forbidden_positions);
      }

      // Reihen direkt neben dem Schiff & parallel zum Schiff sind verboten
      for (let i = 0; i < s.length; i++) {
        forbidden_positions = this.pushPosInArray(s[i] - this.FIELD_WIDTH, forbidden_positions);
        forbidden_positions = this.pushPosInArray(s[i] + this.FIELD_WIDTH, forbidden_positions);
      }

      // Positionen an den Ecken sind evtl. verboten
      if (!this.COLLISION_RULES.ALLOW_CORNER_COLLISIONS) {
        if (s[0] % this.FIELD_WIDTH > 0) {
          this.pushPosInArray(s[0] - (this.FIELD_WIDTH + 1), forbidden_positions);
          this.pushPosInArray(s[0] + (this.FIELD_WIDTH - 1), forbidden_positions);
        }
        if ((s[0] + 1) % this.FIELD_WIDTH > 0) {
          this.pushPosInArray(s[s.length - 1] - (this.FIELD_WIDTH - 1), forbidden_positions);
          this.pushPosInArray(s[s.length - 1] + (this.FIELD_WIDTH + 1), forbidden_positions);
        }
      }
    }

    // (Schritt 2: vertikal)
    for (let s of arrV) {

      // Positionen vor und hinter dem Schiff sind verboten
      forbidden_positions = this.pushPosInArray(s[0] - this.FIELD_WIDTH, forbidden_positions);
      forbidden_positions = this.pushPosInArray(s[s.length - 1] + this.FIELD_WIDTH, forbidden_positions);

      // Reihen direkt neben dem Schiff & parallel zum Schiff sind verboten
      for (let i = 0; i < s.length; i++) {
        if (s[i] % this.FIELD_WIDTH > 0) {
          forbidden_positions = this.pushPosInArray(s[i] - 1, forbidden_positions);
        }
        if ((s[i] + 1) % this.FIELD_WIDTH > 0) {
          forbidden_positions = this.pushPosInArray(s[i] + 1, forbidden_positions);
        }
      }

      // Positionen an den Ecken sind evtl. verboten
      if (!this.COLLISION_RULES.ALLOW_CORNER_COLLISIONS) {
        if (s[0] % this.FIELD_WIDTH > 0) {
          this.pushPosInArray(s[0] - (this.FIELD_WIDTH + 1), forbidden_positions);
          this.pushPosInArray(s[s.length - 1] + (this.FIELD_WIDTH - 1), forbidden_positions);
        }
        if ((s[0] + 1) % this.FIELD_WIDTH > 0) {
          this.pushPosInArray(s[0] - (this.FIELD_WIDTH - 1), forbidden_positions);
          this.pushPosInArray(s[s.length - 1] + (this.FIELD_WIDTH + 1), forbidden_positions);
        }
      }
    }
    return forbidden_positions;
  }

  getRequiredShipsListAsText(arr) {
    let req_ships = [];
    for (let i = 0; i < this.REQUIREDSHIPS.length; i++) {
      if (this.REQUIREDSHIPS[i] > 0) {
        req_ships.push(this.REQUIREDSHIPS[i] + "x " + i + "er");
      }
    }
    return req_ships.join(", ");
  }

  pushPosInArray(pos, arr) {
    if (arr.indexOf(pos) == -1) {
      if (pos >= 0 && pos < this.FIELD_HEIGHT * this.FIELD_WIDTH - 1) {
        arr.push(pos);
      }
    }
    return arr;
  }
}<|endoftext|>


<commit_before>'use strict'

var ObjectId = require("mongodb").ObjectId;

require("mongodb-toolkit");

var DLModels = require('dl-models');
var map = DLModels.map;
var Unit = DLModels.master.Unit;
var BaseManager = require('../base-manager');
var i18n = require('dl-i18n');

module.exports = class UnitManager extends BaseManager {

    constructor(db, user) {
        super(db, user);
        this.collection = this.db.use(map.master.collection.Unit);
    }

    _getQuery(paging) {
        var deleted = {
            _deleted: false
        };
        var query = paging.keyword ? {
            '$and': [deleted]
        } : deleted;

        if (paging.keyword) {
            var regex = new RegExp(paging.keyword, "i");
             var filterDivision = {
                'division': {
                    '$regex': regex
                }
            };
            var filterSubDivision = {
                'subDivision': {
                    '$regex': regex
                }
            };

            var $or = {
                '$or': [filterDivision, filterSubDivision]
            };

            query['$and'].push($or);
        }
        return query;
    }

    _validate(unit) {
        var errors = {};
        return new Promise((resolve, reject) => {
            var valid = unit;
            // 1. begin: Declare promises.
            var getunitPromise = this.collection.singleOrDefault({
                "$and": [{
                    _id: {
                        '$ne': new ObjectId(valid._id)
                    }
                }, {
                        division: valid.division,
                        subDivision: valid.subDivision
                    }]
            });

            // 2. begin: Validation.
            Promise.all([getunitPromise])
                .then(results => {
                    var _unit = results[0];

                    if (!valid.division || valid.division == '')
                        errors["division"] = i18n.__("Unit.division.isRequired:%s is required", i18n.__("Unit.division._:Division")); //"Divisi Tidak Boleh Kosong";
                    else if (_unit) {
                        errors["division"] = i18n.__("Unit.division.isExists:%s is already exists", i18n.__("Unit.division._:Division"));//"Perpaduan Divisi dan Sub Divisi sudah terdaftar";
                    }

                    if (!valid.subDivision || valid.subDivision == '')
                        errors["subDivision"] = i18n.__("Unit.subDivision.isRequired:%s is required", i18n.__("Unit.subDivision._:SubDivision")); //"Sub Divisi Tidak Boleh Kosong";
                    else if (_unit) {
                        errors["subDivision"] = i18n.__("Unit.subDivision.isExists:%s is already exists", i18n.__("Unit.subDivision._:SubDivision"));//"Perpaduan Divisi dan Sub Divisi sudah terdaftar";
                    }

                     if (Object.getOwnPropertyNames(errors).length > 0) {
                        var ValidationError = require('../../validation-error');
                        reject(new ValidationError('data does not pass validation', errors));
                    }

                    valid = new Unit(unit);
                    valid.stamp(this.user.username, 'manager');
                    resolve(valid);
                })
                .catch(e => {
                    reject(e);
                })
        });
    }

}<commit_msg>make _createIndexes in module unit-manager<commit_after>'use strict'

var ObjectId = require("mongodb").ObjectId;

require("mongodb-toolkit");

var DLModels = require('dl-models');
var map = DLModels.map;
var Unit = DLModels.master.Unit;
var BaseManager = require('../base-manager');
var i18n = require('dl-i18n');

module.exports = class UnitManager extends BaseManager {

    constructor(db, user) {
        super(db, user);
        this.collection = this.db.use(map.master.collection.Unit);
    }

    _getQuery(paging) {
        var deleted = {
            _deleted: false
        };
        var query = paging.keyword ? {
            '$and': [deleted]
        } : deleted;

        if (paging.keyword) {
            var regex = new RegExp(paging.keyword, "i");
             var filterDivision = {
                'division': {
                    '$regex': regex
                }
            };
            var filterSubDivision = {
                'subDivision': {
                    '$regex': regex
                }
            };

            var $or = {
                '$or': [filterDivision, filterSubDivision]
            };

            query['$and'].push($or);
        }
        return query;
    }

    _validate(unit) {
        var errors = {};
        return new Promise((resolve, reject) => {
            var valid = unit;
            // 1. begin: Declare promises.
            var getunitPromise = this.collection.singleOrDefault({
                "$and": [{
                    _id: {
                        '$ne': new ObjectId(valid._id)
                    }
                }, {
                        division: valid.division,
                        subDivision: valid.subDivision
                    }]
            });

            // 2. begin: Validation.
            Promise.all([getunitPromise])
                .then(results => {
                    var _unit = results[0];

                    if (!valid.division || valid.division == '')
                        errors["division"] = i18n.__("Unit.division.isRequired:%s is required", i18n.__("Unit.division._:Division")); //"Divisi Tidak Boleh Kosong";
                    else if (_unit) {
                        errors["division"] = i18n.__("Unit.division.isExists:%s is already exists", i18n.__("Unit.division._:Division"));//"Perpaduan Divisi dan Sub Divisi sudah terdaftar";
                    }

                    if (!valid.subDivision || valid.subDivision == '')
                        errors["subDivision"] = i18n.__("Unit.subDivision.isRequired:%s is required", i18n.__("Unit.subDivision._:SubDivision")); //"Sub Divisi Tidak Boleh Kosong";
                    else if (_unit) {
                        errors["subDivision"] = i18n.__("Unit.subDivision.isExists:%s is already exists", i18n.__("Unit.subDivision._:SubDivision"));//"Perpaduan Divisi dan Sub Divisi sudah terdaftar";
                    }

                     if (Object.getOwnPropertyNames(errors).length > 0) {
                        var ValidationError = require('../../validation-error');
                        reject(new ValidationError('data does not pass validation', errors));
                    }

                    valid = new Unit(unit);
                    valid.stamp(this.user.username, 'manager');
                    resolve(valid);
                })
                .catch(e => {
                    reject(e);
                })
        });
    }
    _createIndexes() {
        var dateIndex = {
            name: `ix_${map.master.collection.Unit}__updatedDate`,
            key: {
                _updatedDate: -1
            }
        }

        var codeIndex = {
            name: `ix_${map.master.collection.Unit}_code`,
            key: {
                code: 1
            },
            unique: true
        }

        return this.collection.createIndexes([dateIndex, codeIndex]);
    }

}<|endoftext|>


<commit_before>
var _ = require('lodash');
var amqp = require('sz-amqp');

var publisher = null;

module.exports = function (options) {
  if (publisher) {
    return publisher;
  }

  var opts = {
    exchange: 'firehose',
    connection: {
      heartbeat: 1
    },
    confirmChannel: false
  };

  if (!_.isPlainObject(options)) {
    options = {};
  }

  _.merge(opts, options);

  publisher = new amqp.publisher(opts);

  publisher.connect();

  return publisher;
};<commit_msg>proper config for amqp exchange<commit_after>
var _ = require('lodash');
var amqp = require('sz-amqp');

var publisher = null;

module.exports = function (options) {
  if (publisher) {
    return publisher;
  }

  var opts = {
    exchange: {
      name: 'firehose',
      type: 'topic'
    },
    connection: {
      heartbeat: 1
    },
    confirmChannel: false
  };

  if (!_.isPlainObject(options)) {
    options = {};
  }

  _.merge(opts, options);

  publisher = new amqp.publisher(opts);

  publisher.connect();

  return publisher;
};<|endoftext|>


<commit_before>var fs = require("fs"),
    buffer = require("buffer"),
    pth = require("path");

fs.existsSync = fs.existsSync || pth.existsSync;

var ZipEntry = require("./zipEntry"),
    ZipFile =  require("./zipFile"),
    Utils = require("./util");

module.exports = function(/*String*/inPath) {
    var _zip = undefined,
        _filename = "";

    if (inPath && typeof inPath === "string") { // load zip file
        if (fs.existsSync(inPath)) {
            _filename = inPath;
            _zip = new ZipFile(fs.readFileSync(inPath));
        } else {
           throw Utils.Errors.INVALID_FILENAME;
        }
    } else if(inPath && Buffer.isBuffer(inPath)) { // load buffer
        _zip = new ZipFile(inPath);
    } else { // create new zip file
        _zip = new ZipFile();
    }

    function getEntry(/*Object*/entry) {
        if (entry && _zip) {
            var item;
            // If entry was given as a file name
            if (typeof entry === "string")
                item = _zip.getEntry(entry);
            // if entry was given as a ZipEntry object
            if (typeof entry === "object" && entry.entryName != undefined && entry.header != undefined)
                item =  _zip.getEntry(entry.entryName);

            if (item) {
                return item;
            }
        }
        return null;
    }

    //process.on('uncaughtException', function (err) {
    //    console.log('Caught exception: ' + err);
    //});

    return {
        /**
         * Extracts the given entry from the archive and returns the content as a Buffer object
         * @param entry ZipEntry object or String with the full path of the entry
         *
         * @return Buffer or Null in case of error
         */
        readFile : function(/*Object*/entry) {
            var item = getEntry(entry);
            return item && item.getData() || null;
        },
        /**
         * Asynchronous readFile
         * @param entry ZipEntry object or String with the full path of the entry
         * @param callback
         *
         * @return Buffer or Null in case of error
         */
        readFileAsync : function(/*Object*/entry, /*Function*/callback) {
            var item = getEntry(entry);
            if (item) {
                item.getDataAsync(callback);
            } else {
                callback(null,"getEntry failed for:" + entry)
            }
        },
        /**
         * Extracts the given entry from the archive and returns the content as plain text in the given encoding
         * @param entry ZipEntry object or String with the full path of the entry
         * @param encoding Optional. If no encoding is specified utf8 is used
         *
         * @return String
         */
        readAsText : function(/*Object*/entry, /*String - Optional*/encoding) {
            var item = getEntry(entry);
            if (item) {
                var data = item.getData();
                if (data && data.length) {
                    return data.toString(encoding || "utf8");
                }
            }
            return "";
        },
        /**
         * Asynchronous readAsText
         * @param entry ZipEntry object or String with the full path of the entry
         * @param callback
         * @param encoding Optional. If no encoding is specified utf8 is used
         *
         * @return String
         */
        readAsTextAsync : function(/*Object*/entry, /*Function*/callback, /*String - Optional*/encoding) {
            var item = getEntry(entry);
            if (item) {
                item.getDataAsync(function(data) {
                    if (data && data.length) {
                        callback(data.toString(encoding || "utf8"));
                    } else {
                        callback("");
                    }
                })
            } else {
                callback("");
            }
        },

        /**
         * Remove the entry from the file or the entry and all it's nested directories and files if the given entry is a directory
         *
         * @param entry
         */
        deleteFile : function(/*Object*/entry) { // @TODO: test deleteFile
            var item = getEntry(entry);
            if (item) {
                _zip.deleteEntry(item.entryName);
            }
        },

        /**
         * Adds a comment to the zip. The zip must be rewritten after adding the comment.
         *
         * @param comment
         */
        addZipComment : function(/*String*/comment) { // @TODO: test addZipComment
            _zip.comment = comment;
        },

        /**
         * Returns the zip comment
         *
         * @return String
         */
        getZipComment : function() {
            return _zip.comment || '';
        },

        /**
         * Adds a comment to a specified zipEntry. The zip must be rewritten after adding the comment
         * The comment cannot exceed 65535 characters in length
         *
         * @param entry
         * @param comment
         */
        addZipEntryComment : function(/*Object*/entry,/*String*/comment) {
            var item = getEntry(entry);
            if (item) {
                item.comment = comment;
            }
        },

        /**
         * Returns the comment of the specified entry
         *
         * @param entry
         * @return String
         */
        getZipEntryComment : function(/*Object*/entry) {
            var item = getEntry(entry);
            if (item) {
                return item.comment || '';
            }
            return ''
        },

        /**
         * Updates the content of an existing entry inside the archive. The zip must be rewritten after updating the content
         *
         * @param entry
         * @param content
         */
        updateFile : function(/*Object*/entry, /*Buffer*/content) {
            var item = getEntry(entry);
            if (item) {
                item.setData(content);
            }
        },

        /**
         * Adds a file from the disk to the archive
         *
         * @param localPath
         */
        addLocalFile : function(/*String*/localPath) {
             if (fs.existsSync(localPath)) {
                  // do stuff
             } else {
                 throw Utils.Errors.FILE_NOT_FOUND.replace("%s", localPath);
             }
        },

        /**
         * Adds a local directory and all its nested files and directories to the archive
         *
         * @param localPath
         */
        addLocalFolder : function(/*String*/localPath) {
			localPath = localPath.split("\\").join("/"); //windows fix
            if (localPath.charAt(localPath.length - 1) != "/")
                localPath += "/";

            if (fs.existsSync(localPath)) {
                var items = Utils.findFiles(localPath);
                if (items.length) {
                    items.forEach(function(path) {
                        var entry = new ZipEntry();
						entry.entryName = path.split("\\").join("/").replace(localPath, ""); //windows fix
                        var stats = fs.statSync(path);
                        if (stats.isDirectory()) {
                            entry.setData("");
                            entry.header.inAttr = stats.mode;
                            entry.header.attr = stats.mode
                        } else {
                            entry.setData(fs.readFileSync(path));
                            entry.header.inAttr = stats.mode;
                            entry.header.attr = stats.mode
                        }
                        entry.attr = stats.mode;
                        entry.header.time = stats.mtime;
                        _zip.setEntry(entry);
                    });
                }
            } else {
                throw Utils.Errors.FILE_NOT_FOUND.replace("%s", localPath);
            }
        },

        /**
         * Allows you to programmatically create a entry (file or directory) in the zip file.
         * If you want to create a directory the entryName must end in / and a null buffer should be provided.
         * Comment and attributes are optional
         *
         * @param entryName
         * @param content
         * @param comment
         * @param attr
         */
        addFile : function(/*String*/entryName, /*Buffer*/content, /*String*/comment, /*Number*/attr) {
            var entry = new ZipEntry();
            entry.entryName = entryName;
            entry.comment = comment || "";
            entry.attr = attr || 0666;
            if (entry.isDirectory && content.length) {
                throw Utils.Errors.DIRECTORY_CONTENT_ERROR;
            }
            entry.setData(content);
            entry.header.time = new Date();
            _zip.setEntry(entry);
        },

        /**
         * Returns an array of ZipEntry objects representing the files and folders inside the archive
         *
         * @return Array
         */
        getEntries : function() {
            if (_zip) {
               return _zip.entries;
            } else {
                return [];
            }
        },

        /**
         * Returns a ZipEntry object representing the file or folder specified by ``name``.
         *
         * @param name
         * @return ZipEntry
         */
        getEntry : function(/*String*/name) {
            return getEntry(name);
        },

        /**
         * Extracts the given entry to the given targetPath
         * If the entry is a directory inside the archive, the entire directory and it's subdirectories will be extracted
         *
         * @param entry ZipEntry object or String with the full path of the entry
         * @param targetPath Target folder where to write the file
         * @param maintainEntryPath If maintainEntryPath is true and the entry is inside a folder, the entry folder
         *                          will be created in targetPath as well. Default is TRUE
         * @param overwrite If the file already exists at the target path, the file will be overwriten if this is true.
         *                  Default is FALSE
         *
         * @return Boolean
         */
        extractEntryTo : function(/*Object*/entry, /*String*/targetPath, /*Boolean*/maintainEntryPath, /*Boolean*/overwrite) {
            overwrite = overwrite || false;
            maintainEntryPath = typeof maintainEntryPath == "undefned" ? true : maintainEntryPath;

            var item = getEntry(entry);
            if (!item) {
                throw Utils.Errors.NO_ENTRY;
            }

            var target = pth.resolve(targetPath, maintainEntryPath ? item.entryName : pth.basename(item.entryName));

            if (item.isDirectory) {
                target = pth.resolve(target, "..");
                var children = _zip.getEntryChildren(item);
                children.forEach(function(child) {
                    if (child.isDirectory) return;
                    var content = child.getData();
                    if (!content) {
                        throw Utils.Errors.CANT_EXTRACT_FILE;
                    }
                    Utils.writeFileTo(pth.resolve(targetPath, maintainEntryPath ? child.entryName : child.entryName.substr(item.entryName.length)), content, overwrite);
                });
                return true;
            }

            var content = item.getData();
            if (!content) throw Utils.Errors.CANT_EXTRACT_FILE;

            if (fs.existsSync(targetPath) && !overwrite) {
                throw Utils.Errors.CANT_OVERRIDE;
            }
            Utils.writeFileTo(target, content, overwrite);

            return true;
        },

        /**
         * Extracts the entire archive to the given location
         *
         * @param targetPath Target location
         * @param overwrite If the file already exists at the target path, the file will be overwriten if this is true.
         *                  Default is FALSE
         */
        extractAllTo : function(/*String*/targetPath, /*Boolean*/overwrite) {
            overwrite = overwrite || false;
            if (!_zip) {
                throw Utils.Errors.NO_ZIP;
            }

            _zip.entries.forEach(function(entry) {
                if (entry.isDirectory) return;
                var content = entry.getData();
                if (!content) {
                    throw Utils.Errors.CANT_EXTRACT_FILE + "2";
                }
                Utils.writeFileTo(pth.resolve(targetPath, entry.entryName), content, overwrite);
            })
        },

        /**
         * Writes the newly created zip file to disk at the specified location or if a zip was opened and no ``targetFileName`` is provided, it will overwrite the opened zip
         *
         * @param targetFileName
         */
        writeZip : function(/*String*/targetFileName, /*Function*/callback) {

            if (arguments.length == 1) {
                if (typeof targetFileName == "function") {
                    callback = targetFileName;
                    targetFileName = "";
                }
            }

            if (!targetFileName && _filename) {
                targetFileName = _filename;
            }
            if (!targetFileName) return;

            var zipData = _zip.toBuffer();
            if (zipData) {
                Utils.writeFileTo(targetFileName, zipData, true);
            }
        },

        /**
         * Returns the content of the entire zip file as a Buffer object
         *
         * @return Buffer
         */
        toBuffer : function(/*Function*/callback) {
            this.valueOf = 2;
            if (typeof callback == "function") {
                _zip.toAsyncBuffer(callback);
                return null;
            }
            return _zip.toBuffer()
        }

        /*get lastError () {
            var x = function() { console.log("2", arguments); };
            x.prototype = 2
            return x; //
        } */
    }
};<commit_msg>Fixed issue #29<commit_after>var fs = require("fs"),
    buffer = require("buffer"),
    pth = require("path");

fs.existsSync = fs.existsSync || pth.existsSync;

var ZipEntry = require("./zipEntry"),
    ZipFile =  require("./zipFile"),
    Utils = require("./util");

module.exports = function(/*String*/inPath) {
    var _zip = undefined,
        _filename = "";

    if (inPath && typeof inPath === "string") { // load zip file
        if (fs.existsSync(inPath)) {
            _filename = inPath;
            _zip = new ZipFile(fs.readFileSync(inPath));
        } else {
           throw Utils.Errors.INVALID_FILENAME;
        }
    } else if(inPath && Buffer.isBuffer(inPath)) { // load buffer
        _zip = new ZipFile(inPath);
    } else { // create new zip file
        _zip = new ZipFile();
    }

    function getEntry(/*Object*/entry) {
        if (entry && _zip) {
            var item;
            // If entry was given as a file name
            if (typeof entry === "string")
                item = _zip.getEntry(entry);
            // if entry was given as a ZipEntry object
            if (typeof entry === "object" && entry.entryName != undefined && entry.header != undefined)
                item =  _zip.getEntry(entry.entryName);

            if (item) {
                return item;
            }
        }
        return null;
    }

    //process.on('uncaughtException', function (err) {
    //    console.log('Caught exception: ' + err);
    //});

    return {
        /**
         * Extracts the given entry from the archive and returns the content as a Buffer object
         * @param entry ZipEntry object or String with the full path of the entry
         *
         * @return Buffer or Null in case of error
         */
        readFile : function(/*Object*/entry) {
            var item = getEntry(entry);
            return item && item.getData() || null;
        },
        /**
         * Asynchronous readFile
         * @param entry ZipEntry object or String with the full path of the entry
         * @param callback
         *
         * @return Buffer or Null in case of error
         */
        readFileAsync : function(/*Object*/entry, /*Function*/callback) {
            var item = getEntry(entry);
            if (item) {
                item.getDataAsync(callback);
            } else {
                callback(null,"getEntry failed for:" + entry)
            }
        },
        /**
         * Extracts the given entry from the archive and returns the content as plain text in the given encoding
         * @param entry ZipEntry object or String with the full path of the entry
         * @param encoding Optional. If no encoding is specified utf8 is used
         *
         * @return String
         */
        readAsText : function(/*Object*/entry, /*String - Optional*/encoding) {
            var item = getEntry(entry);
            if (item) {
                var data = item.getData();
                if (data && data.length) {
                    return data.toString(encoding || "utf8");
                }
            }
            return "";
        },
        /**
         * Asynchronous readAsText
         * @param entry ZipEntry object or String with the full path of the entry
         * @param callback
         * @param encoding Optional. If no encoding is specified utf8 is used
         *
         * @return String
         */
        readAsTextAsync : function(/*Object*/entry, /*Function*/callback, /*String - Optional*/encoding) {
            var item = getEntry(entry);
            if (item) {
                item.getDataAsync(function(data) {
                    if (data && data.length) {
                        callback(data.toString(encoding || "utf8"));
                    } else {
                        callback("");
                    }
                })
            } else {
                callback("");
            }
        },

        /**
         * Remove the entry from the file or the entry and all it's nested directories and files if the given entry is a directory
         *
         * @param entry
         */
        deleteFile : function(/*Object*/entry) { // @TODO: test deleteFile
            var item = getEntry(entry);
            if (item) {
                _zip.deleteEntry(item.entryName);
            }
        },

        /**
         * Adds a comment to the zip. The zip must be rewritten after adding the comment.
         *
         * @param comment
         */
        addZipComment : function(/*String*/comment) { // @TODO: test addZipComment
            _zip.comment = comment;
        },

        /**
         * Returns the zip comment
         *
         * @return String
         */
        getZipComment : function() {
            return _zip.comment || '';
        },

        /**
         * Adds a comment to a specified zipEntry. The zip must be rewritten after adding the comment
         * The comment cannot exceed 65535 characters in length
         *
         * @param entry
         * @param comment
         */
        addZipEntryComment : function(/*Object*/entry,/*String*/comment) {
            var item = getEntry(entry);
            if (item) {
                item.comment = comment;
            }
        },

        /**
         * Returns the comment of the specified entry
         *
         * @param entry
         * @return String
         */
        getZipEntryComment : function(/*Object*/entry) {
            var item = getEntry(entry);
            if (item) {
                return item.comment || '';
            }
            return ''
        },

        /**
         * Updates the content of an existing entry inside the archive. The zip must be rewritten after updating the content
         *
         * @param entry
         * @param content
         */
        updateFile : function(/*Object*/entry, /*Buffer*/content) {
            var item = getEntry(entry);
            if (item) {
                item.setData(content);
            }
        },

        /**
         * Adds a file from the disk to the archive
         *
         * @param localPath
         */
        addLocalFile : function(/*String*/localPath) {
             if (fs.existsSync(localPath)) {
                  // do stuff
             } else {
                 throw Utils.Errors.FILE_NOT_FOUND.replace("%s", localPath);
             }
        },

        /**
         * Adds a local directory and all its nested files and directories to the archive
         *
         * @param localPath
         */
        addLocalFolder : function(/*String*/localPath) {
			localPath = localPath.split("\\").join("/"); //windows fix
            if (localPath.charAt(localPath.length - 1) != "/")
                localPath += "/";

            if (fs.existsSync(localPath)) {
                var items = Utils.findFiles(localPath);
                if (items.length) {
                    items.forEach(function(path) {
                        var entry = new ZipEntry();
						entry.entryName = path.split("\\").join("/").replace(localPath, ""); //windows fix
                        var stats = fs.statSync(path);
                        if (stats.isDirectory()) {
                            entry.setData("");
                            entry.header.inAttr = stats.mode;
                            entry.header.attr = stats.mode
                        } else {
                            entry.setData(fs.readFileSync(path));
                            entry.header.inAttr = stats.mode;
                            entry.header.attr = stats.mode
                        }
                        entry.attr = stats.mode;
                        entry.header.time = stats.mtime;
                        _zip.setEntry(entry);
                    });
                }
            } else {
                throw Utils.Errors.FILE_NOT_FOUND.replace("%s", localPath);
            }
        },

        /**
         * Allows you to programmatically create a entry (file or directory) in the zip file.
         * If you want to create a directory the entryName must end in / and a null buffer should be provided.
         * Comment and attributes are optional
         *
         * @param entryName
         * @param content
         * @param comment
         * @param attr
         */
        addFile : function(/*String*/entryName, /*Buffer*/content, /*String*/comment, /*Number*/attr) {
            var entry = new ZipEntry();
            entry.entryName = entryName;
            entry.comment = comment || "";
            entry.attr = attr || 0666;
            if (entry.isDirectory && content.length) {
                throw Utils.Errors.DIRECTORY_CONTENT_ERROR;
            }
            entry.setData(content);
            entry.header.time = new Date();
            _zip.setEntry(entry);
        },

        /**
         * Returns an array of ZipEntry objects representing the files and folders inside the archive
         *
         * @return Array
         */
        getEntries : function() {
            if (_zip) {
               return _zip.entries;
            } else {
                return [];
            }
        },

        /**
         * Returns a ZipEntry object representing the file or folder specified by ``name``.
         *
         * @param name
         * @return ZipEntry
         */
        getEntry : function(/*String*/name) {
            return getEntry(name);
        },

        /**
         * Extracts the given entry to the given targetPath
         * If the entry is a directory inside the archive, the entire directory and it's subdirectories will be extracted
         *
         * @param entry ZipEntry object or String with the full path of the entry
         * @param targetPath Target folder where to write the file
         * @param maintainEntryPath If maintainEntryPath is true and the entry is inside a folder, the entry folder
         *                          will be created in targetPath as well. Default is TRUE
         * @param overwrite If the file already exists at the target path, the file will be overwriten if this is true.
         *                  Default is FALSE
         *
         * @return Boolean
         */
        extractEntryTo : function(/*Object*/entry, /*String*/targetPath, /*Boolean*/maintainEntryPath, /*Boolean*/overwrite) {
            overwrite = overwrite || false;
            maintainEntryPath = typeof maintainEntryPath == "undefined" ? true : maintainEntryPath;

            var item = getEntry(entry);
            if (!item) {
                throw Utils.Errors.NO_ENTRY;
            }

            var target = pth.resolve(targetPath, maintainEntryPath ? item.entryName : pth.basename(item.entryName));

            if (item.isDirectory) {
                target = pth.resolve(target, "..");
                var children = _zip.getEntryChildren(item);
                children.forEach(function(child) {
                    if (child.isDirectory) return;
                    var content = child.getData();
                    if (!content) {
                        throw Utils.Errors.CANT_EXTRACT_FILE;
                    }
                    Utils.writeFileTo(pth.resolve(targetPath, maintainEntryPath ? child.entryName : child.entryName.substr(item.entryName.length)), content, overwrite);
                });
                return true;
            }

            var content = item.getData();
            if (!content) throw Utils.Errors.CANT_EXTRACT_FILE;

            if (fs.existsSync(targetPath) && !overwrite) {
                throw Utils.Errors.CANT_OVERRIDE;
            }
            Utils.writeFileTo(target, content, overwrite);

            return true;
        },

        /**
         * Extracts the entire archive to the given location
         *
         * @param targetPath Target location
         * @param overwrite If the file already exists at the target path, the file will be overwriten if this is true.
         *                  Default is FALSE
         */
        extractAllTo : function(/*String*/targetPath, /*Boolean*/overwrite) {
            overwrite = overwrite || false;
            if (!_zip) {
                throw Utils.Errors.NO_ZIP;
            }

            _zip.entries.forEach(function(entry) {
                if (entry.isDirectory) return;
                var content = entry.getData();
                if (!content) {
                    throw Utils.Errors.CANT_EXTRACT_FILE + "2";
                }
                Utils.writeFileTo(pth.resolve(targetPath, entry.entryName), content, overwrite);
            })
        },

        /**
         * Writes the newly created zip file to disk at the specified location or if a zip was opened and no ``targetFileName`` is provided, it will overwrite the opened zip
         *
         * @param targetFileName
         */
        writeZip : function(/*String*/targetFileName, /*Function*/callback) {

            if (arguments.length == 1) {
                if (typeof targetFileName == "function") {
                    callback = targetFileName;
                    targetFileName = "";
                }
            }

            if (!targetFileName && _filename) {
                targetFileName = _filename;
            }
            if (!targetFileName) return;

            var zipData = _zip.toBuffer();
            if (zipData) {
                Utils.writeFileTo(targetFileName, zipData, true);
            }
        },

        /**
         * Returns the content of the entire zip file as a Buffer object
         *
         * @return Buffer
         */
        toBuffer : function(/*Function*/callback) {
            this.valueOf = 2;
            if (typeof callback == "function") {
                _zip.toAsyncBuffer(callback);
                return null;
            }
            return _zip.toBuffer()
        }

        /*get lastError () {
            var x = function() { console.log("2", arguments); };
            x.prototype = 2
            return x; //
        } */
    }
};
<|endoftext|>


<commit_before>$(function () {
	var data = [];
	for (var i = 0; i < 500; ++i) {
		data.push({
			"id": "#" + (i + 1),
			"created_at": "2014-05-02 12:22",
			"status": "In progress",
			"title": "Test " + i + Math.round(Math.random() * 1000),
			"count": Math.round(Math.random() * 100)
		});
	}

	var columns = [
		{name: "id", type: "string"},
		{name: "created_at", type: "string"},
		{name: "status", type: "string", editor: "CustomEditor"},
		{name: "title", type: "string"},
		{name: "count", type: "string"},
	];

	var grid = $(".sensei-grid").grid(data, columns);
	grid.registerEditor(BasicEditor);
	grid.registerEditor(CustomEditor);
	grid.render();
}); <commit_msg>Reduce sample size in default example.<commit_after>$(function () {
	var data = [];
	for (var i = 0; i < 10; ++i) {
		data.push({
			"id": "#" + (i + 1),
			"created_at": "2014-05-02 12:22",
			"status": "In progress",
			"title": "Test " + i + Math.round(Math.random() * 1000),
			"count": Math.round(Math.random() * 100)
		});
	}

	var columns = [
		{name: "id", type: "string"},
		{name: "created_at", type: "string"},
		{name: "status", type: "string", editor: "CustomEditor"},
		{name: "title", type: "string"},
		{name: "count", type: "string"},
	];

	var grid = $(".sensei-grid").grid(data, columns);
	grid.registerEditor(BasicEditor);
	grid.registerEditor(CustomEditor);
	grid.render();
}); <|endoftext|>


<commit_before>lobby.transporter.module.create('module_morph', function(requires) {

requires('lk_ext', 'rows_and_columns');

}, function(thisModule) {

thisModule.addSlots(modules.module_morph, function(add) {

    add.data('_directory', 'transporter');

});

thisModule.addSlots(transporter.module, function(add) {

  add.method('newMorph', function() {
    return new this.Morph(this);
  }, {category: ['user interface']});

  add.method('Morph', function Morph() { Class.initializer.apply(this, arguments); }, {category: ['user interface']});

});

thisModule.addSlots(transporter.module.Morph, function(add) {

  add.data('superclass', RowMorph);

  add.creator('prototype', Object.create(RowMorph.prototype));

  add.data('type', 'transporter.module.Morph');

  add.method('doneUpload', function(directory, name) {
    if (name.substr(-3) === '.js') { name = name.substr(0, name.length - 3); }
    transporter.module.fileIn(directory, name, function() {
      new MessageNotifierMorph(name + " has been loaded.", Color.green).showInCenterOfWorld(WorldMorph.current());
    });
  });
});

thisModule.addSlots(transporter.module.Morph.prototype, function(add) {

  add.data('constructor', transporter.module.Morph);

  add.method('initialize', function ($super, module) {
    $super();
    this._module = module;

    this.setPadding({top: 2, bottom: 2, left: 4, right: 4, between: 3});
    this.setFill(defaultFillWithColor(Color.red.lighter()));
    this.shape.roundEdgesBy(10);

    this._nameLabel = TextMorph.createLabel(function() { return module.name(); });
    this._fileOutButton = createButton('Save .js file', this.fileOut.bind(this), 2);

    this._changeIndicator = TextMorph.createLabel(function() { return this._module.hasChangedSinceLastFileOut() ? ' has changed ' : ''; }.bind(this));
    this._changeIndicator.setTextColor(Color.green.darker());

    this.setColumns([this._nameLabel, this._changeIndicator, this._fileOutButton, this.createDismissButton()]);

    this.startPeriodicallyUpdating();
  }, {category: ['creating']});

  add.method('inspect', function () { return this._module.name(); }, {category: ['printing']});

  add.method('fileOut', function (evt) {
    MessageNotifierMorph.showIfErrorDuring(function() { this._module.fileOut(); }.bind(this), evt);
    this.refreshContentOfMeAndSubmorphs();
  }, {category: ['commands']});

  add.method('fileOutWithoutAnnotations', function (evt) {
    MessageNotifierMorph.showIfErrorDuring(function() { this._module.fileOutWithoutAnnotations(); }.bind(this), evt);
    this.refreshContentOfMeAndSubmorphs();
  }, {category: ['commands']});

  add.method('forgetIWasChanged', function (evt) {
    this._module.markAsUnchanged();
    this.refreshContentOfMeAndSubmorphs();
  }, {category: ['commands']});

  add.method('getModuleObject', function (evt) {
    evt.hand.world().morphFor(reflect(this._module)).grabMe(evt);
  }, {category: ['commands']});

  add.method('getAllObjects', function (evt) {
    var w = evt.hand.world();
    w.assumePose(w.listPoseOfMorphsFor(this._module.objectsThatMightContainSlotsInMe().map(function(o) { return reflect(o); }), "objects in module " + this._module.name()));
  }, {category: ['commands']});

  add.method('addCommandsTo', function (cmdList) {
    cmdList.addItem({label: 'save .js file', pluralLabel: 'save .js files for modules', go: this.fileOut.bind(this)});

    cmdList.addItem({label: 'forget I was changed', go: this.forgetIWasChanged.bind(this)});

    cmdList.addLine();

    cmdList.addItem({label: 'get module object', go: this.getModuleObject.bind(this)});

    cmdList.addLine();

    cmdList.addItem({label: 'all objects', go: this.getAllObjects.bind(this)});
  }, {category: ['menu']});

});

thisModule.addSlots(transporter, function(add) {

  add.method('addMenuItemsTo', function(menu, evt) {
    menu.addLine();

    var snapshottingWorks = false; // aaa - turn this on once it works.
    if (snapshottingWorks) {
    menu.addItem(["save snapshot", function(evt) {
      var snapshotter = new Snapshotter();
      snapshotter.walk(lobby);
      var snapshot = snapshotter.completeSnapshotText();

      var baseDirURL = URL.source.getDirectory().withRelativePath("javascripts/snapshots/");
      var fileName = "snapshot_" + snapshotter._number + ".js";
      var url = baseDirURL.withFilename(fileName);
      var status = new Resource(Record.newPlainInstance({URL: url})).store(snapshot, true).getStatus();
      if (! status.isSuccess()) {
        throw "failed to write " + fileName + ", status is " + status.code();
      }
    }]);
    }

    menu.addItem(["all modules", function(evt) {
      var world = evt.hand.world();
      world.assumePose(world.listPoseOfMorphsFor(Object.newChildOf(enumerator, transporter.module, 'eachModule'), "all modules"));
    }]);

    menu.addItem(["changed modules", function(evt) {
      var world = evt.hand.world();
      world.assumePose(world.listPoseOfMorphsFor(transporter.module.changedOnes(), "all modules"));
    }]);

    /* Not working yet.
      menu.addItem(["aaa upload file...", function(evt) {
        var form = document.getElementById('uploadForm');
        var fileInput = form.fileToUpload;
        fileInput.click();
      }.bind(this)]);
    */

    // aaa - hack because I haven't managed to get WebDAV working on adamspitz.com yet
    if (URL.source.hostname.include("adamspitz.com")) {

    } else {

      menu.addItem(["file in...", function(evt) {
        var world = evt.hand.world();
        var baseDir = new FileDirectory(lobby.transporter.module.urlForCoreModulesDirectory());
        var modulesMenu = new MenuMorph(this.moduleMenuItemsForDir(baseDir, ""), world);
        modulesMenu.openIn(world, evt.point());
      }.bind(this)]);

    }

  }, {category: ['menu']});

  add.method('moduleMenuItemsForDir', function(dir, pathFromModuleSystemRootDir) {
    var menuItems = [];

    var subdirURLs = dir.subdirectories();
    subdirURLs.each(function(subdirURL) {
      var subdir = new FileDirectory(subdirURL);
      var subdirName = subdirURL.filename();
      menuItems.push([subdirName, this.moduleMenuItemsForDir(subdir, pathFromModuleSystemRootDir + "/" + subdirName)]);
    }.bind(this));

    var jsFileNames = dir.filenames().select(function(n) {return n.endsWith(".js");});
    jsFileNames.each(function(n) {
      menuItems.push([n, function(evt) {
        var moduleName = n.substring(0, n.length - 3);
        MessageNotifierMorph.showIfErrorDuring(function() {
          lobby.transporter.module.fileIn(pathFromModuleSystemRootDir, moduleName);
        }, evt);
      }]);
    });

    return menuItems;
  }, {category: ['menu']});

});

});
<commit_msg>Minor cosmetic changes.<commit_after>lobby.transporter.module.create('module_morph', function(requires) {

requires('lk_ext', 'rows_and_columns');

}, function(thisModule) {

thisModule.addSlots(modules.module_morph, function(add) {

    add.data('_directory', 'transporter');

});

thisModule.addSlots(transporter.module, function(add) {

  add.method('newMorph', function() {
    return new this.Morph(this);
  }, {category: ['user interface']});

  add.method('Morph', function Morph() { Class.initializer.apply(this, arguments); }, {category: ['user interface']});

});

thisModule.addSlots(transporter.module.Morph, function(add) {

  add.data('superclass', RowMorph);

  add.creator('prototype', Object.create(RowMorph.prototype));

  add.data('type', 'transporter.module.Morph');

  add.method('doneUpload', function(directory, name) {
    if (name.substr(-3) === '.js') { name = name.substr(0, name.length - 3); }
    transporter.module.fileIn(directory, name, function() {
      new MessageNotifierMorph(name + " has been loaded.", Color.green).showInCenterOfWorld(WorldMorph.current());
    });
  });
});

thisModule.addSlots(transporter.module.Morph.prototype, function(add) {

  add.data('constructor', transporter.module.Morph);

  add.method('initialize', function ($super, module) {
    $super();
    this._module = module;

    this.setPadding({top: 2, bottom: 2, left: 4, right: 4, between: 3});
    this.setFill(defaultFillWithColor(Color.red.lighter()));
    this.shape.roundEdgesBy(10);

    this._nameLabel = TextMorph.createLabel(function() { return module.name(); });
    this._fileOutButton = createButton('Save as .js file', this.fileOut.bind(this), 2);

    this._changeIndicator = TextMorph.createLabel(function() { return this._module.hasChangedSinceLastFileOut() ? ' has changed ' : ''; }.bind(this));
    this._changeIndicator.setTextColor(Color.green.darker());

    this.setColumns([this._nameLabel, this._changeIndicator, this._fileOutButton, this.createDismissButton()]);

    this.startPeriodicallyUpdating();
  }, {category: ['creating']});

  add.method('inspect', function () { return this._module.name(); }, {category: ['printing']});

  add.method('fileOut', function (evt) {
    MessageNotifierMorph.showIfErrorDuring(function() { this._module.fileOut(); }.bind(this), evt);
    this.refreshContentOfMeAndSubmorphs();
  }, {category: ['commands']});

  add.method('fileOutWithoutAnnotations', function (evt) {
    MessageNotifierMorph.showIfErrorDuring(function() { this._module.fileOutWithoutAnnotations(); }.bind(this), evt);
    this.refreshContentOfMeAndSubmorphs();
  }, {category: ['commands']});

  add.method('forgetIWasChanged', function (evt) {
    this._module.markAsUnchanged();
    this.refreshContentOfMeAndSubmorphs();
  }, {category: ['commands']});

  add.method('getModuleObject', function (evt) {
    evt.hand.world().morphFor(reflect(this._module)).grabMe(evt);
  }, {category: ['commands']});

  add.method('getAllObjects', function (evt) {
    var w = evt.hand.world();
    var objectsInPose = this._module.objectsThatMightContainSlotsInMe().map(function(o) { return reflect(o); });
    objectsInPose.unshift(this._module); // aaa - should really put it in a special place on the screen
    w.assumePose(w.listPoseOfMorphsFor(objectsInPose, "objects in module " + this._module.name()));
  }, {category: ['commands']});

  add.method('addCommandsTo', function (cmdList) {
    cmdList.addItem({label: 'save as .js file', pluralLabel: 'save modules as .js files', go: this.fileOut.bind(this)});

    cmdList.addItem({label: 'forget I was changed', go: this.forgetIWasChanged.bind(this)});

    cmdList.addLine();

    cmdList.addItem({label: 'get module object', go: this.getModuleObject.bind(this)});

    cmdList.addLine();

    cmdList.addItem({label: 'all objects', go: this.getAllObjects.bind(this)});
  }, {category: ['menu']});

});

thisModule.addSlots(transporter, function(add) {

  add.method('addMenuItemsTo', function(menu, evt) {
    menu.addLine();

    var snapshottingWorks = false; // aaa - turn this on once it works.
    if (snapshottingWorks) {
    menu.addItem(["save snapshot", function(evt) {
      var snapshotter = new Snapshotter();
      snapshotter.walk(lobby);
      var snapshot = snapshotter.completeSnapshotText();

      var baseDirURL = URL.source.getDirectory().withRelativePath("javascripts/snapshots/");
      var fileName = "snapshot_" + snapshotter._number + ".js";
      var url = baseDirURL.withFilename(fileName);
      var status = new Resource(Record.newPlainInstance({URL: url})).store(snapshot, true).getStatus();
      if (! status.isSuccess()) {
        throw "failed to write " + fileName + ", status is " + status.code();
      }
    }]);
    }

    menu.addItem(["all modules", function(evt) {
      var world = evt.hand.world();
      world.assumePose(world.listPoseOfMorphsFor(Object.newChildOf(enumerator, transporter.module, 'eachModule'), "all modules"));
    }]);

    menu.addItem(["changed modules", function(evt) {
      var world = evt.hand.world();
      world.assumePose(world.listPoseOfMorphsFor(transporter.module.changedOnes(), "all modules"));
    }]);

    /* Not working yet.
      menu.addItem(["aaa upload file...", function(evt) {
        var form = document.getElementById('uploadForm');
        var fileInput = form.fileToUpload;
        fileInput.click();
      }.bind(this)]);
    */

    // aaa - hack because I haven't managed to get WebDAV working on adamspitz.com yet
    if (URL.source.hostname.include("adamspitz.com")) {

    } else {

      menu.addItem(["file in...", function(evt) {
        var world = evt.hand.world();
        var baseDir = new FileDirectory(lobby.transporter.module.urlForCoreModulesDirectory());
        var modulesMenu = new MenuMorph(this.moduleMenuItemsForDir(baseDir, ""), world);
        modulesMenu.openIn(world, evt.point());
      }.bind(this)]);

    }

  }, {category: ['menu']});

  add.method('moduleMenuItemsForDir', function(dir, pathFromModuleSystemRootDir) {
    var menuItems = [];

    var subdirURLs = dir.subdirectories();
    subdirURLs.each(function(subdirURL) {
      var subdir = new FileDirectory(subdirURL);
      var subdirName = subdirURL.filename();
      menuItems.push([subdirName, this.moduleMenuItemsForDir(subdir, pathFromModuleSystemRootDir + "/" + subdirName)]);
    }.bind(this));

    var jsFileNames = dir.filenames().select(function(n) {return n.endsWith(".js");});
    jsFileNames.each(function(n) {
      menuItems.push([n, function(evt) {
        var moduleName = n.substring(0, n.length - 3);
        MessageNotifierMorph.showIfErrorDuring(function() {
          lobby.transporter.module.fileIn(pathFromModuleSystemRootDir, moduleName);
        }, evt);
      }]);
    });

    return menuItems;
  }, {category: ['menu']});

});

});
<|endoftext|>


<commit_before>(function (win) {

    if (!(win.history && win.history.pushState))
        return;

    var submitData = {};
    win.document.addEventListener('click', function (e) {
        var element = e.target;
        if (!e.ctrlKey && !e.shiftKey && ajaxOn(element, 'A')) {
            e.preventDefault();
            refreshAjax(element.getAttribute('href'), true, element);
        }
        if (element.tagName === 'INPUT' && element.name) {
            if (element.type === 'submit')
                submitData[element.name] = element.value;
            if (element.type === 'image') {
                submitData[element.name + '.x'] = win.Math.max(0, e.offsetX);
                submitData[element.name + '.y'] = win.Math.max(0, e.offsetY);
            }
        }
    });

    win.document.addEventListener('submit', function (e) {
        var element = e.target;
        if (ajaxOn(element, 'FORM')) {
            var req = new win.XMLHttpRequest();
            req.onreadystatechange = onReady(req, true);
            e.preventDefault();
            req.open('post', getAjaxLink(element.getAttribute('action'), element));
            req.setRequestHeader("Content-Type", "application/json");
            req.send(win.JSON.stringify(getFormData(element)));
        }
    });

    var tagNames = /^INPUT|TEXTAREA|SELECT$/;
    var ignoreTypes = /^button|image|submit|reset|file$/;
    var checkTypes = /^checkbox|radio$/;
    function getFormData(form) {
        var elements = form.elements;
        var data = {};
        for (var i = 0; i < elements.length; i++) {
            var element = elements[i];
            if (tagNames.test(element.tagName) && element.name
                && !ignoreTypes.test(element.type) && !element.disabled
                && (!checkTypes.test(element.type) || element.checked))
                data[element.name] = element.value;
        }
        for (var key in submitData)
            data[key] = submitData[key];
        submitData = {};
        return data;
    }

    function ajaxOn(element, tagName) {
        if (element.tagName === tagName
            && element.getAttribute('data-navigation') === 'refresh') {
            var ajax = true;
            while (!!element && ajax) {
                if (element.getAttribute)
                    ajax = element.getAttribute('data-navigation') !== 'noajax';
                element = element.parentNode;
            }
            return ajax;
        }
        return false;
    }

    var link = win.location.pathname + win.location.search;
    function refreshAjax(newLink, addHistory, target) {
        var req = new win.XMLHttpRequest();
        req.onreadystatechange = onReady(req, addHistory);
        req.open('get', getAjaxLink(newLink, target));
        req.send();
    }

    function getAjaxLink(baseLink, target) {
        baseLink += baseLink.indexOf('?') > 0 ? '&' : '?';
        baseLink += 'refreshajax=' + win.encodeURIComponent(link);
        baseLink += '&navigation=' + (target ? 'refresh' : 'history');
        if (target && target.getAttribute('data-include-current'))
            baseLink += '&includecurrent=true';
        baseLink = setKeys(target, baseLink, 'data-current-keys', 'currentkeys');
        baseLink = setKeys(target, baseLink, 'data-to-keys', 'tokeys');
        return baseLink;
    }

    function setKeys(target, link, attribute, name) {
        var keys = target ? target.getAttribute(attribute) : null;
        if (keys)
            link += '&' + name + '=' + win.encodeURIComponent(keys);
        return link;
    }

    var cache = {};
    function onReady(req, addHistory) {
        var oldLink = link;
        return function () {
            if (req.readyState === 4 && req.status === 200) {
                var resp = win.JSON.parse(req.responseText);
                handleRespone(resp, addHistory, oldLink);
            }
        };
    }

    function handleRespone(resp, addHistory, oldLink) {
        var newLink = resp.Link;
        cache[oldLink + '&' + newLink] = resp;
        if (link !== oldLink)
            return;
        for (var id in resp.Panels) {
            var panel = win.document.getElementById(id);
            panel.innerHTML = resp.Panels[id];
            var evt;
            if (typeof win.Event === 'function')
                evt = new win.Event('refreshajax');
            else {
                evt = win.document.createEvent('Event');
                evt.initEvent('refreshajax', false, false);
            }
            panel.dispatchEvent(evt);
        }
        if (addHistory && link !== newLink)
            win.history.pushState(newLink, win.document.title, newLink);
        link = newLink;
    }

    win.addEventListener('popstate', function (e) {
        var newLink = win.location.pathname + win.location.search;
        if (link !== newLink) {
            var resp = cache[link + '&' + newLink];
            if (!resp)
                refreshAjax(newLink, false);
            else
                handleRespone(resp, false, link);
        }
    });
})(window);<commit_msg>Tidied code up by building all attribute based query string values using shared function<commit_after>(function (win) {

    if (!(win.history && win.history.pushState))
        return;

    var submitData = {};
    win.document.addEventListener('click', function (e) {
        var element = e.target;
        if (!e.ctrlKey && !e.shiftKey && ajaxOn(element, 'A')) {
            e.preventDefault();
            refreshAjax(element.getAttribute('href'), true, element);
        }
        if (element.tagName === 'INPUT' && element.name) {
            if (element.type === 'submit')
                submitData[element.name] = element.value;
            if (element.type === 'image') {
                submitData[element.name + '.x'] = win.Math.max(0, e.offsetX);
                submitData[element.name + '.y'] = win.Math.max(0, e.offsetY);
            }
        }
    });

    win.document.addEventListener('submit', function (e) {
        var element = e.target;
        if (ajaxOn(element, 'FORM')) {
            var req = new win.XMLHttpRequest();
            req.onreadystatechange = onReady(req, true);
            e.preventDefault();
            req.open('post', getAjaxLink(element.getAttribute('action'), element));
            req.setRequestHeader("Content-Type", "application/json");
            req.send(win.JSON.stringify(getFormData(element)));
        }
    });

    var tagNames = /^INPUT|TEXTAREA|SELECT$/;
    var ignoreTypes = /^button|image|submit|reset|file$/;
    var checkTypes = /^checkbox|radio$/;
    function getFormData(form) {
        var elements = form.elements;
        var data = {};
        for (var i = 0; i < elements.length; i++) {
            var element = elements[i];
            if (tagNames.test(element.tagName) && element.name
                && !ignoreTypes.test(element.type) && !element.disabled
                && (!checkTypes.test(element.type) || element.checked))
                data[element.name] = element.value;
        }
        for (var key in submitData)
            data[key] = submitData[key];
        submitData = {};
        return data;
    }

    function ajaxOn(element, tagName) {
        if (element.tagName === tagName
            && element.getAttribute('data-navigation') === 'refresh') {
            var ajax = true;
            while (!!element && ajax) {
                if (element.getAttribute)
                    ajax = element.getAttribute('data-navigation') !== 'noajax';
                element = element.parentNode;
            }
            return ajax;
        }
        return false;
    }

    var link = win.location.pathname + win.location.search;
    function refreshAjax(newLink, addHistory, target) {
        var req = new win.XMLHttpRequest();
        req.onreadystatechange = onReady(req, addHistory);
        req.open('get', getAjaxLink(newLink, target));
        req.send();
    }

    function getAjaxLink(baseLink, target) {
        baseLink += baseLink.indexOf('?') > 0 ? '&' : '?';
        baseLink += 'refreshajax=' + win.encodeURIComponent(link);
        baseLink += '&navigation=' + (target ? 'refresh' : 'history');
        if (target) {
            baseLink = setKeys(target, baseLink, 'data-include-current', 'includecurrent');
            baseLink = setKeys(target, baseLink, 'data-current-keys', 'currentkeys');
            baseLink = setKeys(target, baseLink, 'data-to-keys', 'tokeys');
        }
        return baseLink;
    }

    function setKeys(target, link, attribute, name) {
        if (target.getAttribute(attribute))
            link += '&' + name + '=' + win.encodeURIComponent(target.getAttribute(attribute));
        return link;
    }

    var cache = {};
    function onReady(req, addHistory) {
        var oldLink = link;
        return function () {
            if (req.readyState === 4 && req.status === 200) {
                var resp = win.JSON.parse(req.responseText);
                handleRespone(resp, addHistory, oldLink);
            }
        };
    }

    function handleRespone(resp, addHistory, oldLink) {
        var newLink = resp.Link;
        cache[oldLink + '&' + newLink] = resp;
        if (link !== oldLink)
            return;
        for (var id in resp.Panels) {
            var panel = win.document.getElementById(id);
            panel.innerHTML = resp.Panels[id];
            var evt;
            if (typeof win.Event === 'function')
                evt = new win.Event('refreshajax');
            else {
                evt = win.document.createEvent('Event');
                evt.initEvent('refreshajax', false, false);
            }
            panel.dispatchEvent(evt);
        }
        if (addHistory && link !== newLink)
            win.history.pushState(newLink, win.document.title, newLink);
        link = newLink;
    }

    win.addEventListener('popstate', function (e) {
        var newLink = win.location.pathname + win.location.search;
        if (link !== newLink) {
            var resp = cache[link + '&' + newLink];
            if (!resp)
                refreshAjax(newLink, false);
            else
                handleRespone(resp, false, link);
        }
    });
})(window);<|endoftext|>


<commit_before>

"use strict";
var Main = module.parent.exports;

Main.ActionHSET = function(Request){
  if(Request.length < 3){
    throw new Error(Main.MSG_ARGS_LESS);
  }
  Main.ValidateArguments(Main.ARGS_ODD, Request.length);
  let Key = Request.shift();
  let Value = this.Database.get(Key);
  try {
    Main.Validate(Main.VAL_HASH, 'HSET', Value);
  } catch(err){
    Value = new Map();
    this.Database.set(Key, Value);
  }
  for(let Number = 0; Number < Request.length; Number += 2){
    let HValue = Main.NormalizeType(Request[Number + 1]);
    Value.set(Request[Number], HValue);
  }
  return {Type: 'OK'};
};<commit_msg>:new: Implement HGET<commit_after>

"use strict";
var Main = module.parent.exports;

Main.ActionHSET = function(Request){
  if(Request.length < 3){
    throw new Error(Main.MSG_ARGS_LESS);
  }
  Main.ValidateArguments(Main.ARGS_ODD, Request.length);
  let Key = Request.shift();
  let Value = this.Database.get(Key);
  try {
    Main.Validate(Main.VAL_HASH, 'HSET', Value);
  } catch(err){
    Value = new Map();
    this.Database.set(Key, Value);
  }
  for(let Number = 0; Number < Request.length; Number += 2){
    let HValue = Main.NormalizeType(Request[Number + 1]);
    Value.set(Request[Number], HValue);
  }
  return {Type: 'OK'};
};

Main.ActionHGET = function(Request){
  let Key = Request.shift();
  let Value = this.Database.get(Key);

  if(typeof Value !== 'undefined')
    Main.Validate(Main.VAL_HASH, 'HGET', Value);

  if(Request.length === 1){
    return Value && Value.get(Request[0]) || '';
  } else {
    return Request.map(function(Key){
      return Value && Value.get(Key) || '';
    });
  }
};<|endoftext|>