<commit_before>
function align(n, size) {
    var r = n % size;
    return r === 0 ? n : n + size - r;
}

function offsetInfo(buf, start, end) {
    if (end - start <= 0xff)
        return { size: 1, read: function (i) { return start + buf.readUInt8(end + i); } };
    else if (end - start <= 0xffff)
        return { size: 2, read: function (i) { return start + buf.readUInt16LE(end + 2 * i); } };
    else if (end - start <= 0xffffffff)
        return { size: 4, read: function (i) { return start + buf.readUInt32LE(end + 4 * i); } };
    else
        throw RangeError();
}

function nextType(signature, index) {
    switch (signature[index]) {
        case 'y':
            return {
                id: 'y',
                size: 1,
                alignment: 1,
                defaultValue: 0,
                read: function (buf, start, end) {
                    if (end - start !== 1)
                        return this.defaultValue;
                    return buf.readUInt8(start);
                }
            };

        case 'n':
            return {
                id: 'n',
                size: 2,
                alignment: 2,
                defaultValue: 0,
                read: function (buf, start, end) {
                    if (end - start !== 2)
                        return this.defaultValue;
                    return buf.readInt16LE(start);
                }
            };

        case 'q':
            return {
                id: 'q',
                size: 2,
                alignment: 2,
                defaultValue: 0,
                read: function (buf, start, end) {
                    if (end - start !== 2)
                        return this.defaultValue;
                    return buf.readUInt16LE(start);
                }
            };

        case 'i':
            return {
                id: 'i',
                size: 4,
                alignment: 4,
                defaultValue: 0,
                read: function (buf, start, end) {
                    if (end - start !== 4)
                        return this.defaultValue;
                    return buf.readInt32LE(start);
                }
            };

        case 'u':
            return {
                id: 'u',
                size: 4,
                alignment: 4,
                defaultValue: 0,
                read: function (buf, start, end) {
                    if (end - start !== 4)
                        return this.defaultValue;
                    return buf.readUInt32LE(start);
                }
            };

        case 'x':
            return {
                id: 'x',
                size: 8,
                alignment: 8,
                defaultValue: 0,
                read: function (buf, start, end) {
                    if (end - start !== 8)
                        return this.defaultValue;
                    var lo = buf.readUInt32LE(start);
                    var hi = buf.readUInt32LE(start + 4);
                    if (hi > 0x7fffffff)
                        return - ((~hi * 0x100000000) + ~lo + 1);
                    return (hi * 0x100000000) + lo;
                }
            };

        case 't':
            return {
                id: 't',
                size: 8,
                alignment: 8,
                defaultValue: 0,
                read: function (buf, start, end) {
                    if (end - start !== 8)
                        return this.defaultValue;
                    var lo = buf.readUInt32LE(start);
                    var hi = buf.readUInt32LE(start + 4);
                    return (hi * 0x100000000) + lo;
                }
            };

        case 'd':
            return {
                id: 'd',
                size: 8,
                alignment: 8,
                defaultValue: 0.0,
                read: function (buf, start, end) {
                    if (end - start !== 8)
                        return this.defaultValue;
                    return buf.readDoubleLE(start);
                }
            };

        case 'b':
            return {
                id: 'b',
                size: 1,
                alignment: 1,
                defaultValue: false,
                read: function (buf, start, end) {
                    if (end - start !== 1)
                        return this.defaultValue;
                    return !!buf.readUInt8(start);
                }
            };

        case 's':
        case 'o':
        case 'g':
            return {
                id: signature[index],
                alignment: 1,
                defaultValue: '',

                read: function (buf, start, end) {
                    if (start === end || buf.readUInt8(end - 1) !== 0)
                        return this.defaultValue;

                    var str = buf.toString('utf-8', start, end - 1); // skip \0
                    var nul = str.indexOf('\0');
                    if (nul >= 0)
                        return str.substring(0, nul);
                    return str;
                }
            };

        case 'v':
            return {
                id: 'v',
                alignment: 8,
                defaultValue: [],

                read: function (buf, start, end) {
                    var sep = end - 1;

                    while (sep >= start) {
                        if (buf.readUInt8(sep) === 0)
                            break;
                        sep -= 1;
                    }

                    return parse(buf.toString('ascii', sep + 1, end), buf.slice(start, sep));
                }
            };

        case 'm':
            var maybeElement = nextType(signature, index + 1);

            return {
                id: signature.substr(index, maybeElement.id.length + 1),
                alignment: maybeElement.alignment,
                element: maybeElement,
                defaultValue: null,

                read: function (buf, start, end) {

                    // Nothing
                    if (start === end)
                        return null;

                    // Just
                    if (this.element.size) {
                        if (end - start !== this.element.size)
                            return null;

                        return this.element.read(buf, start, end);
                    }
                    else {
                        return this.element.read(buf, start, end - 1);
                    }
                }
            };

        case '(':
            var end = index + 1;
            var elements = [];
            var size = 0;
            var alignment = 1;
            while (signature[end] !== ')') {
                var el = nextType(signature, end);
                elements.push(el);
                size = align(size, el.alignment) + el.size;
                alignment = Math.max(alignment, el.alignment);
                end += el.id.length;
            }
            if (size === 0)
                size = 1;
            return {
                id: signature.slice(index, end + 1),
                elements: elements,
                size: size,
                alignment: alignment,
                defaultValue: elements.map(function (el) { return el.defaultValue; }),

                read: function (buf, start, end) {
                    if (this.size && end - start !== this.size)
                        return this.defaultValue;

                    var offsets = offsetInfo(buf, start, end);
                    var values = [];
                    var cur = start;
                    var curOffset = 0;
                    for (var i = 0; i < this.elements.length; i++) {
                        var el = this.elements[i];
                        cur = align(cur, el.alignment);
                        var next;
                        if (el.size)
                            next = cur + el.size;
                        else if (i < this.elements.length - 1)
                            next = offsets.read(--curOffset);
                        else
                            next = end - offsets.size * -curOffset;
                        values.push(el.read(buf, cur, next));
                        cur = next;
                    }
                    return values;
                }
            };

        case '{':
            var key = nextType(signature, index + 1);
            var value = nextType(signature, index + 1 + key.id.length);

            return {
                id: signature.substr(index, key.id.length + value.id.length + 2),
                key: key,
                value: value,
                size: align(key.size, value.alignment) + value.size,
                alignment: Math.max(key.alignment, value.alignment),
                defaultValue: [ key.defaultValue, value.defaultValue ],

                read: function (buf, start, end) {
                    if (this.size && end - start !== this.size)
                        return this.defaultValue;

                    var offsets = offsetInfo(buf, start, end);
                    var keyEnd, valueEnd;

                    if (this.key.size) {
                        keyEnd = start + this.key.size;
                        valueEnd = end;
                    }
                    else {
                        keyEnd = offsets.read(-1);
                        valueEnd = end - offsets.size;
                    }
                    return [
                        this.key.read(buf, start, keyEnd),
                        this.value.read(buf, align(keyEnd, this.value.alignment), valueEnd)
                    ];
                }
            };

        case 'a':
            var element = nextType(signature, index + 1);

            return {
                id: signature.substr(index, element.id.length + 1),
                alignment: element.alignment,
                element: element,
                defaultValue: [],

                read: function (buf, start, end) {
                    if (start == end)
                        return this.element.id[0] === '{' ? {} : [];

                    var values = [];
                    var size = end - start;
                    var i, n, cur, offsets;

                    if (this.element.size) {
                        if (size % this.element.size !== 0)
                            return [];

                        n = size / this.element.size;
                        cur = start;
                        for (i = 0; i < n; i++) {
                            values.push(this.element.read(buf, cur, cur + this.element.size));
                            cur += this.element.size;
                        }
                    }
                    else {
                        offsets = offsetInfo(buf, start, end);
                        n = (end - offsets.read(-1)) / offsets.size;
                        cur = start;
                        for (i = 0; i < n; i++) {
                            var next = offsets.read(-n + i);
                            values.push(this.element.read(buf, cur, next));
                            cur = align(next, this.element.alignment);
                        }
                    }

                    if (this.element.id[0] === '{')
                        values = values.reduce(function (o, v) { o[v[0]] = v[1]; return o; }, {});

                    return values;
                }
            };
    }
}

function parse(typestr, data) {
    if (Array.isArray(data))
        data = new Buffer(data);

    var type = nextType(typestr, 0);
    if (!type || type.id.length !== typestr.length)
        throw new TypeError('invalid type string: ' + typestr);

    return type.read(data, 0, data.length);
}

exports.parse = parse;
<commit_msg>types: rename .size to .fixedSize<commit_after>
function align(n, size) {
    var r = n % size;
    return r === 0 ? n : n + size - r;
}

function offsetInfo(buf, start, end) {
    if (end - start <= 0xff)
        return { size: 1, read: function (i) { return start + buf.readUInt8(end + i); } };
    else if (end - start <= 0xffff)
        return { size: 2, read: function (i) { return start + buf.readUInt16LE(end + 2 * i); } };
    else if (end - start <= 0xffffffff)
        return { size: 4, read: function (i) { return start + buf.readUInt32LE(end + 4 * i); } };
    else
        throw RangeError();
}

function nextType(signature, index) {
    switch (signature[index]) {
        case 'y':
            return {
                id: 'y',
                fixedSize: 1,
                alignment: 1,
                defaultValue: 0,
                read: function (buf, start, end) {
                    if (end - start !== 1)
                        return this.defaultValue;
                    return buf.readUInt8(start);
                }
            };

        case 'n':
            return {
                id: 'n',
                fixedSize: 2,
                alignment: 2,
                defaultValue: 0,
                read: function (buf, start, end) {
                    if (end - start !== 2)
                        return this.defaultValue;
                    return buf.readInt16LE(start);
                }
            };

        case 'q':
            return {
                id: 'q',
                fixedSize: 2,
                alignment: 2,
                defaultValue: 0,
                read: function (buf, start, end) {
                    if (end - start !== 2)
                        return this.defaultValue;
                    return buf.readUInt16LE(start);
                }
            };

        case 'i':
            return {
                id: 'i',
                fixedSize: 4,
                alignment: 4,
                defaultValue: 0,
                read: function (buf, start, end) {
                    if (end - start !== 4)
                        return this.defaultValue;
                    return buf.readInt32LE(start);
                }
            };

        case 'u':
            return {
                id: 'u',
                fixedSize: 4,
                alignment: 4,
                defaultValue: 0,
                read: function (buf, start, end) {
                    if (end - start !== 4)
                        return this.defaultValue;
                    return buf.readUInt32LE(start);
                }
            };

        case 'x':
            return {
                id: 'x',
                fixedSize: 8,
                alignment: 8,
                defaultValue: 0,
                read: function (buf, start, end) {
                    if (end - start !== 8)
                        return this.defaultValue;
                    var lo = buf.readUInt32LE(start);
                    var hi = buf.readUInt32LE(start + 4);
                    if (hi > 0x7fffffff)
                        return - ((~hi * 0x100000000) + ~lo + 1);
                    return (hi * 0x100000000) + lo;
                }
            };

        case 't':
            return {
                id: 't',
                fixedSize: 8,
                alignment: 8,
                defaultValue: 0,
                read: function (buf, start, end) {
                    if (end - start !== 8)
                        return this.defaultValue;
                    var lo = buf.readUInt32LE(start);
                    var hi = buf.readUInt32LE(start + 4);
                    return (hi * 0x100000000) + lo;
                }
            };

        case 'd':
            return {
                id: 'd',
                fixedSize: 8,
                alignment: 8,
                defaultValue: 0.0,
                read: function (buf, start, end) {
                    if (end - start !== 8)
                        return this.defaultValue;
                    return buf.readDoubleLE(start);
                }
            };

        case 'b':
            return {
                id: 'b',
                fixedSize: 1,
                alignment: 1,
                defaultValue: false,
                read: function (buf, start, end) {
                    if (end - start !== 1)
                        return this.defaultValue;
                    return !!buf.readUInt8(start);
                }
            };

        case 's':
        case 'o':
        case 'g':
            return {
                id: signature[index],
                alignment: 1,
                defaultValue: '',

                read: function (buf, start, end) {
                    if (start === end || buf.readUInt8(end - 1) !== 0)
                        return this.defaultValue;

                    var str = buf.toString('utf-8', start, end - 1); // skip \0
                    var nul = str.indexOf('\0');
                    if (nul >= 0)
                        return str.substring(0, nul);
                    return str;
                }
            };

        case 'v':
            return {
                id: 'v',
                alignment: 8,
                defaultValue: [],

                read: function (buf, start, end) {
                    var sep = end - 1;

                    while (sep >= start) {
                        if (buf.readUInt8(sep) === 0)
                            break;
                        sep -= 1;
                    }

                    return parse(buf.toString('ascii', sep + 1, end), buf.slice(start, sep));
                }
            };

        case 'm':
            var maybeElement = nextType(signature, index + 1);

            return {
                id: signature.substr(index, maybeElement.id.length + 1),
                alignment: maybeElement.alignment,
                element: maybeElement,
                defaultValue: null,

                read: function (buf, start, end) {

                    // Nothing
                    if (start === end)
                        return null;

                    // Just
                    if (this.element.fixedSize) {
                        if (end - start !== this.element.fixedSize)
                            return null;

                        return this.element.read(buf, start, end);
                    }
                    else {
                        return this.element.read(buf, start, end - 1);
                    }
                }
            };

        case '(':
            var end = index + 1;
            var elements = [];
            var size = 0;
            var alignment = 1;
            while (signature[end] !== ')') {
                var el = nextType(signature, end);
                elements.push(el);
                size = align(size, el.alignment) + el.fixedSize;
                alignment = Math.max(alignment, el.alignment);
                end += el.id.length;
            }
            if (size === 0)
                size = 1;
            return {
                id: signature.slice(index, end + 1),
                elements: elements,
                fixedSize: size,
                alignment: alignment,
                defaultValue: elements.map(function (el) { return el.defaultValue; }),

                read: function (buf, start, end) {
                    if (this.fixedSize && end - start !== this.fixedSize)
                        return this.defaultValue;

                    var offsets = offsetInfo(buf, start, end);
                    var values = [];
                    var cur = start;
                    var curOffset = 0;
                    for (var i = 0; i < this.elements.length; i++) {
                        var el = this.elements[i];
                        cur = align(cur, el.alignment);
                        var next;
                        if (el.fixedSize)
                            next = cur + el.fixedSize;
                        else if (i < this.elements.length - 1)
                            next = offsets.read(--curOffset);
                        else
                            next = end - offsets.size * -curOffset;
                        values.push(el.read(buf, cur, next));
                        cur = next;
                    }
                    return values;
                }
            };

        case '{':
            var key = nextType(signature, index + 1);
            var value = nextType(signature, index + 1 + key.id.length);

            return {
                id: signature.substr(index, key.id.length + value.id.length + 2),
                key: key,
                value: value,
                fixedSize: align(key.fixedSize, value.alignment) + value.fixedSize,
                alignment: Math.max(key.alignment, value.alignment),
                defaultValue: [ key.defaultValue, value.defaultValue ],

                read: function (buf, start, end) {
                    if (this.fixedSize && end - start !== this.fixedSize)
                        return this.defaultValue;

                    var offsets = offsetInfo(buf, start, end);
                    var keyEnd, valueEnd;

                    if (this.key.fixedSize) {
                        keyEnd = start + this.key.fixedSize;
                        valueEnd = end;
                    }
                    else {
                        keyEnd = offsets.read(-1);
                        valueEnd = end - offsets.size;
                    }
                    return [
                        this.key.read(buf, start, keyEnd),
                        this.value.read(buf, align(keyEnd, this.value.alignment), valueEnd)
                    ];
                }
            };

        case 'a':
            var element = nextType(signature, index + 1);

            return {
                id: signature.substr(index, element.id.length + 1),
                alignment: element.alignment,
                element: element,
                defaultValue: [],

                read: function (buf, start, end) {
                    if (start == end)
                        return this.element.id[0] === '{' ? {} : [];

                    var values = [];
                    var size = end - start;
                    var i, n, cur, offsets;

                    if (this.element.fixedSize) {
                        if (size % this.element.fixedSize !== 0)
                            return [];

                        n = size / this.element.fixedSize;
                        cur = start;
                        for (i = 0; i < n; i++) {
                            values.push(this.element.read(buf, cur, cur + this.element.fixedSize));
                            cur += this.element.fixedSize;
                        }
                    }
                    else {
                        offsets = offsetInfo(buf, start, end);
                        n = (end - offsets.read(-1)) / offsets.size;
                        cur = start;
                        for (i = 0; i < n; i++) {
                            var next = offsets.read(-n + i);
                            values.push(this.element.read(buf, cur, next));
                            cur = align(next, this.element.alignment);
                        }
                    }

                    if (this.element.id[0] === '{')
                        values = values.reduce(function (o, v) { o[v[0]] = v[1]; return o; }, {});

                    return values;
                }
            };
    }
}

function parse(typestr, data) {
    if (Array.isArray(data))
        data = new Buffer(data);

    var type = nextType(typestr, 0);
    if (!type || type.id.length !== typestr.length)
        throw new TypeError('invalid type string: ' + typestr);

    return type.read(data, 0, data.length);
}

exports.parse = parse;
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2020 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.export',
  name: 'GoogleSheetsExportDriver',
  implements: [
    'foam.nanos.export.ExportDriver',
    'foam.nanos.export.GoogleSheetsServiceConfig'
  ],

  documentation: `
    Driver retrieves data, transforms it and makes calls to googleSheetsDataExport.
    googleSheetsDataExport retrieves permission from a user to make calls to Google Sheets API on their behalf,
    creates Google Sheet, sends data to api and returns sheet id which is used for returning link to user.
  `,

  properties: [
    {
      name: 'outputter',
      factory: function() {
        return foam.nanos.export.GoogleSheetsOutputter.create();
      },
      hidden: true,
      flags: ['js']
    },
    {
      class: 'String',
      name: 'title'
    }
  ],

  methods: [
    async function exportFObject(X, obj) {
      var self = this;

      var sheetId  = '';
      var stringArray = [];
      var columnConfig = X.columnConfigToPropertyConverter;

      var props = X.filteredTableColumns ? X.filteredTableColumns : this.outputter.getAllPropertyNames(obj.cls);
      props = columnConfig.filterExportedProps(X, obj.cls_, props);

      var metadata = await self.outputter.getColumnMethadata(X, obj.cls_, props);
      stringArray.push(metadata.map(m => m.columnLabel));

      var values = [ await this.outputter.objToArrayOfStringValues(X, obj.cls_, [ obj ], metadata.map(p => p.propName)) ];
      stringArray = stringArray.concat(values);

      sheetId = await X.googleSheetsDataExport.createSheet(X, stringArray, metadata, this);
      if ( ! sheetId || sheetId.length === 0)
        return '';
      return `https://docs.google.com/spreadsheets/d/${sheetId}/edit#gid=0`;
    },
    async function exportDAO(X, dao) {
      var self = this;

      var columnConfig = X.columnConfigToPropertyConverter;

      var props = X.filteredTableColumns ? X.filteredTableColumns : this.outputter.getAllPropertyNames(dao.of);
      props = columnConfig.filterExportedProps(dao.of, props);

      var metadata = await self.outputter.getColumnMethadata(X, dao.of);

      var expr = ( foam.nanos.column.ExpressionForArrayOfNestedPropertiesBuilder.create() ).buildProjectionForPropertyNamesArray(dao.of, props);
      var sink = await dao.select(expr);

      var sheetId  = '';
      var stringArray = await self.outputter.outputTable(X, dao.of, sink.array, metadata);

      sheetId = await X.googleSheetsDataExport.createSheet(X, stringArray, metadata, this);
      if ( ! sheetId || sheetId.length == 0)
        return '';
      return `https://docs.google.com/spreadsheets/d/${sheetId}/edit#gid=0`;
    }
  ]
});<commit_msg>fixing error<commit_after>/**
 * @license
 * Copyright 2020 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.export',
  name: 'GoogleSheetsExportDriver',
  implements: [
    'foam.nanos.export.ExportDriver',
    'foam.nanos.export.GoogleSheetsServiceConfig'
  ],

  documentation: `
    Driver retrieves data, transforms it and makes calls to googleSheetsDataExport.
    googleSheetsDataExport retrieves permission from a user to make calls to Google Sheets API on their behalf,
    creates Google Sheet, sends data to api and returns sheet id which is used for returning link to user.
  `,

  properties: [
    {
      name: 'outputter',
      factory: function() {
        return foam.nanos.export.GoogleSheetsOutputter.create();
      },
      hidden: true,
      flags: ['js']
    },
    {
      class: 'String',
      name: 'title'
    }
  ],

  methods: [
    async function exportFObject(X, obj) {
      var self = this;

      var sheetId  = '';
      var stringArray = [];
      var columnConfig = X.columnConfigToPropertyConverter;

      var props = X.filteredTableColumns ? X.filteredTableColumns : this.outputter.getAllPropertyNames(obj.cls);
      props = columnConfig.filterExportedProps(X, obj.cls_, props);

      var metadata = await self.outputter.getColumnMethadata(X, obj.cls_, props);
      stringArray.push(metadata.map(m => m.columnLabel));

      var values = [ await this.outputter.objToArrayOfStringValues(X, obj.cls_, [ obj ], metadata.map(p => p.propName)) ];
      stringArray = stringArray.concat(values);

      sheetId = await X.googleSheetsDataExport.createSheet(X, stringArray, metadata, this);
      if ( ! sheetId || sheetId.length === 0)
        return '';
      return `https://docs.google.com/spreadsheets/d/${sheetId}/edit#gid=0`;
    },
    async function exportDAO(X, dao) {
      var self = this;

      var columnConfig = X.columnConfigToPropertyConverter;

      var props = X.filteredTableColumns ? X.filteredTableColumns : this.outputter.getAllPropertyNames(dao.of);
      props = columnConfig.filterExportedProps(dao.of, props);

      var metadata = await self.outputter.getColumnMethadata(X, dao.of, props);

      var expr = ( foam.nanos.column.ExpressionForArrayOfNestedPropertiesBuilder.create() ).buildProjectionForPropertyNamesArray(dao.of, props);
      var sink = await dao.select(expr);

      var sheetId  = '';
      var stringArray = await self.outputter.outputTable(X, dao.of, sink.array, metadata);

      sheetId = await X.googleSheetsDataExport.createSheet(X, stringArray, metadata, this);
      if ( ! sheetId || sheetId.length == 0)
        return '';
      return `https://docs.google.com/spreadsheets/d/${sheetId}/edit#gid=0`;
    }
  ]
});<|endoftext|>


<commit_before>import Promise from 'promise';
import path from 'path';

export function patchAsset (_owner, assets) {
  return new Promise(function (resolve, reject) {

  for (var i = 0; i < assets.length; i++) {

  var asset = assets[i]
  var _type = asset.type;
  var _name = asset.name;
  var _nameSplit = _name.split('.');
  var _asset = asset;
  var instance = _owner.instance;
  var _instanceAssets = _owner.instance.assets;
  var _mediaExtension = _owner.instance.mediaExtension;

  _asset.folder = _instanceAssets[_type]['folder'];
  _asset.backup = _instanceAssets[_type]['backup'];

  if (_type === 'Asset::Template' || _type === 'Asset::Snippet') {
    var _extension = _instanceAssets[_type]['extension'];
    if (_name.indexOf(_extension) === -1) {
      _asset['name'] = _name + _extension;
    }
  }

  if (_type === 'Asset::Media') {
    if (_asset['content-type'] === 'text/js') {
      _asset['folder'] = _mediaExtension['.js']
    }
    if (_asset['content-type'] === 'text/css') {
      _asset['folder'] = _mediaExtension['.css']
    }
    if (_asset['content-type'] === 'application/x-scss') {
      _asset['folder'] = _mediaExtension['.scss']
    }
    if (_asset['content-type'] === 'application/x-svg') {
      _asset['folder'] = _mediaExtension['.svg']
    }
    if (_asset['content-type'].indexOf('image') > -1) {
      _asset['folder'] = instance.folders['img'];
    }
    if (_asset['content-type'] === 'application/x-ico') {
      _asset['folder'] = instance.folders['img'];
    }
    if (_name.indexOf('.svg') > -1) {
      _asset['folder'] = _mediaExtension['.svg'];
    }
    if (_name.indexOf('.scss') > -1) {
      _asset['folder'] = _mediaExtension['.scss'];
    }
    if (_name.indexOf('.css') > -1) {
      _asset['folder'] = _mediaExtension['.css'];
    }
    if (_name.indexOf('.js') > -1) {
      _asset['folder'] = _mediaExtension['.js'];
    }
    if (_name.indexOf('.coffee') > -1) {
      _asset['folder'] = _mediaExtension['.coffee'];
    }
    if (_name.indexOf('.js.liquid') > -1) {
      _asset['folder'] = _mediaExtension['.js'];
    }
    if (_name.indexOf('.svg.liquid') > -1) {
      _asset['folder'] = _mediaExtension['.svg'];
    }
    if (_name.indexOf('.css.liquid') > -1) {
      _asset['folder'] = _mediaExtension['.css'];
    }
    if (_name.indexOf('.scss.liquid') > -1) {
      _asset['folder'] = _mediaExtension['.css'];
    }
    if (_asset['content-type'].indexOf('application') > -1) {
      var _ext = '.' + _nameSplit[_nameSplit.length - 1];
      if (_mediaExtension[_ext]) {
        _asset['folder'] = _mediaExtension[_ext]
      }
    }
  }

    _asset.path = path.normalize( _asset.folder + _asset['name'] );
    _asset.backupPath = _asset.backup + _asset['name'];

    if (_asset['name'].indexOf('/') > -1) {
      console.error('Недопустимое имя файла:', _asset['name'])
    }
    _owner.assets[_asset.path] = _asset;
    _owner.downloadList.push(_asset.path);
  }

    resolve()
    if (assets.length === 0) {
      reject()
    }
  })
}
<commit_msg>Update patch.js<commit_after>import Promise from 'promise';
import path from 'path';

export function patchAsset (_owner, assets) {
  return new Promise(function (resolve, reject) {

  for (var i = 0; i < assets.length; i++) {

  var asset = assets[i]
  var _type = asset.type;
  var _name = asset.name;
  var _nameSplit = _name.split('.');
  var _asset = asset;
  var instance = _owner.instance;
  var _instanceAssets = _owner.instance.assets;
  var _mediaExtension = _owner.instance.mediaExtension;

  _asset.folder = _instanceAssets[_type]['folder'];
  _asset.backup = _instanceAssets[_type]['backup'];

  if (_type === 'Asset::Template' || _type === 'Asset::Snippet') {
    var _extension = _instanceAssets[_type]['extension'];
    if (_name.indexOf(_extension) === -1) {
      _asset['name'] = _name + _extension;
    }
  }

  if (_type === 'Asset::Media') {
    if (_asset['content-type'] === 'text/js') {
      _asset['folder'] = _mediaExtension['.js']
    }
    if (_asset['content-type'] === 'text/css') {
      _asset['folder'] = _mediaExtension['.css']
    }
    if (_asset['content-type'] === 'application/x-scss') {
      _asset['folder'] = _mediaExtension['.scss']
    }
    if (_asset['content-type'] === 'application/x-svg') {
      _asset['folder'] = _mediaExtension['.svg']
    }
    if (_asset['content-type'].indexOf('image') > -1) {
      _asset['folder'] = instance.folders['img'];
    }
    if (_asset['content-type'] === 'application/x-ico') {
      _asset['folder'] = instance.folders['img'];
    }
    if (_name.indexOf('.svg') > -1) {
      _asset['folder'] = _mediaExtension['.svg'];
    }
    if (_name.indexOf('.scss') > -1) {
      _asset['folder'] = _mediaExtension['.scss'];
    }
    if (_name.indexOf('.css') > -1) {
      _asset['folder'] = _mediaExtension['.css'];
    }
    if (_name.indexOf('.js') > -1) {
      _asset['folder'] = _mediaExtension['.js'];
    }
    if (_name.indexOf('.coffee') > -1) {
      _asset['folder'] = _mediaExtension['.coffee'];
    }
    if (_name.indexOf('.js.liquid') > -1) {
      _asset['folder'] = _mediaExtension['.js'];
    }
    if (_name.indexOf('.svg.liquid') > -1) {
      _asset['folder'] = _mediaExtension['.svg'];
    }
    if (_name.indexOf('.css.liquid') > -1) {
      _asset['folder'] = _mediaExtension['.css'];
    }
    if (_name.indexOf('.scss.liquid') > -1) {
      _asset['folder'] = _mediaExtension['.css'];
    }
    if (_asset['content-type'].indexOf('application') > -1) {
      var _ext = '.' + _nameSplit[_nameSplit.length - 1];
      if (_mediaExtension[_ext]) {
        _asset['folder'] = _mediaExtension[_ext]
      }
    }
  }

    _asset.path = path.normalize( _asset.folder + _asset['name'] );
    _asset.backupPath = _asset.backup + _asset['name'];

    if (_asset['name'].indexOf('/') > -1) {
      console.error('Недопустимое имя файла:', _asset['name'])
    }
    _owner.assets[_asset.path] = _asset;
    _owner.downloadList.push(_asset);
  }

    resolve()
    if (assets.length === 0) {
      reject()
    }
  })
}
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2020 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.u2.crunch.wizardflow',
  name: 'CheckNoDataAgent',
  documentation: `
    Checks if the capabilities needed (by using crunchService.getGrantPath) all have no
    data (or capability.of == null).

    If no required capabilties have data, then the wizard is not needed to render and the
    required capabilities will be granted.

    This applies to the case where the User already has the Prerequisites to capabilit(ies/y) with no data,
    therefore thee wizard does not need to render and the user should have the capabilit(ies/y) granted
  `,

  implements: [
    'foam.core.ContextAgent',
    'foam.mlang.Expressions'
  ],

  imports: [
    'capabilities',
    'crunchService',
    'endSequence',
    'rootCapability'
  ],

  exports: [
    'submitted'
  ],

  properties: [
    {
      class: 'Boolean',
      name: 'submitted'
    }
  ],

  methods: [
    // If Property expressions ever unwrap promises this method can be blank.
    async function execute() {
      var shouldOpen = false;

      await this.crunchService.getGrantPath(null, this.rootCapability.id).then(capabilitiesNeeded => {
        capabilitiesNeeded.forEach(capa => {
          if ( capa.of ){
            shouldOpen = true;
          }
        })

        if ( ! shouldOpen ) {
          var updateJunctionPromises = capabilitiesNeeded.map(capa => {
            return this.crunchService.updateJunction(null, capa.id, null, null);
          })

          this.submitted = true;
          this.endSequence();

          return Promise.all(updateJunctionPromises);
        }
      })
    }
  ]
});

<commit_msg>More changes<commit_after>/**
 * @license
 * Copyright 2020 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.u2.crunch.wizardflow',
  name: 'CheckNoDataAgent',
  documentation: `
    Checks if the capabilities needed (by using crunchService.getGrantPath) all have no
    data (or capability.of == null).

    If no required capabilties have data, then the wizard is not needed to render and the
    required capabilities will be granted.

    This applies to the case where the User already has the Prerequisites to capabilit(ies/y) with no data,
    therefore thee wizard does not need to render and the user should have the capabilit(ies/y) granted
  `,

  implements: [
    'foam.core.ContextAgent',
    'foam.mlang.Expressions'
  ],

  imports: [
    'capabilities',
    'crunchService',
    'endSequence',
    'rootCapability'
  ],

  exports: [
    'submitted'
  ],

  properties: [
    {
      class: 'Boolean',
      name: 'submitted'
    }
  ],

  methods: [
    // If Property expressions ever unwrap promises this method can be blank.
    async function execute() {
      var shouldOpen = false;

      var capabilitiesNeeded = await this.crunchService.getGrantPath(null, this.rootCapability.id);

      capabilitiesNeeded.forEach(capa => {
        if ( capa.of ){
          shouldOpen = true;
        }
      })

      if ( ! shouldOpen ) {
        var updateJunctionPromises = capabilitiesNeeded.map(capa => {
          return this.crunchService.updateJunction(null, capa.id, null, null);
        })

        this.submitted = true;
        this.endSequence();

        return Promise.all(updateJunctionPromises);
      }
    }
  ]
});

<|endoftext|>


<commit_before>(function (module, process) {
    'use strict';
    var colors = require('colors'),
        request = require('./request/main'),
        _ = require('underscore'),
        Q = require('q'),
        events = require('events');

    colors.setTheme({
        silly:'rainbow',
        input:'grey',
        verbose:'cyan',
        prompt:'grey',
        info:'green',
        data:'grey',
        help:'cyan',
        warn:'yellow',
        debug:'blue',
        error:'red'
    });

    var translateOptions2Arguments = function (options) {
        //used to translate property to cmd line arg
        var phantomArgMap = {
            'cookiesFile':'cookies-file',
            'config': 'config',
            'debug': 'debug',
            'diskCache':'disk-cache',
            'ignoreSslErrors':'ignore-ssl-errors',
            'loadImages':'load-images',
            'localToRemoteUrlAccessEnabled':'local-to-remote-url-access',
            'maxDiskCache':'max-disk-cache-size',
            'outputEncoding':'output-encoding',
            'proxy':'proxy',
            'proxyType':'proxy-type',
            'scriptEncoding':'script-encoding',
            'version':'version',
            'webSecurity':'web-security'
        };

        //may integrate in future
        var defaultoptions = {
            'ignoreSslErrors':true,
            'localToRemoteUrlAccessEnabled':true,
            'cookiesFile':'cookies.txt',
            'diskCache':'yes',
            'loadImages':'yes',
            'localToRemoteUrlAccess':'no',
            'maxDiskCache':'50000',
            'outputEncoding':'utf8',
            'proxy':'0',
            'proxyType':'yes',
            'scriptEncoding':'yes',
            'webSecurity':'no'
        };

        //map options props to cmd line args for phantom process

        var phantomArgs = []
            , proxyArgs = [];

        for (var k in options) {
            if (options.hasOwnProperty(k)) {
                if (phantomArgMap[k]) {
                    phantomArgs.push('--' + phantomArgMap[k] + '=' + options[k]);
                } else {
                    var uncamel = k.replace(/[A-Z]/g, function(c) {
                        return '-' + c.toLowerCase();
                    });
                    proxyArgs.push('--' + uncamel + '=' + options[k]);
                }
            }
        }

        return {
            phantom: phantomArgs,
            proxy: proxyArgs
        };
    };

//    //on exit loop through process array and kill everything
//    process.on('exit', function () {
//        processArray.forEach(function (proc) {
//            proc.kill('SIGHUP');
//        });
//    });

    //creates a new phantomjs process
    var createServer = function (options, callbackFn) {
            var Webpage = require('./webpage'),
                Phantom = require('./phantom'),
                self = this,
                streamPosition = 0,

//            //pass proxy to callbackFn
//            callbackFn.call(self, self.proxy);

            //parses a line from phantoms event stream
                parseResponse = function (response) {
                    var parsedEvent;

                    self.options.debug && console.log('buffer :%s'.grey, response);

                    try {
                        parsedEvent = JSON.parse(response);
                    }
                    catch (exception) {
                        console.error(exception.toString().red.bold);
                        console.error('attempted to parse %s', response);
                        return;
                    }

                    var args = parsedEvent.args;
                    args.unshift(parsedEvent.type);

                    self.options.debug && console.log('emitting %s event on %s'.grey, parsedEvent.type, parsedEvent.source);

                    switch (parsedEvent.source) {
                        //phantomJs server module started and is listening or failed
                        case 'phantom' :
                            self.proxy.phantom.emit.apply(self.proxy.phantom, args);
                            break;
                        case 'page' :
                            self.proxy.page.emit.apply(self.proxy.page, args);
                            break;
                        case 'server' :
                            self.proxy.phantom.emit.apply(self.proxy.phantom, args);
                            break;
                        default :
                            throw new Error('unexpected eventsource:' + parsedEvent.source);

                    }

                };

            var spawnNewProcess = function () {
                var spawn = require('child_process').spawn,
                    serverPath = __dirname + '/' + require('path').normalize('./server/index.js');

                var args = translateOptions2Arguments(options);
                args.proxy.unshift(serverPath, JSON.stringify(options));
                var processArgs = args.phantom.concat(args.proxy);

                //spawn new process
                var phantomjs = spawn('phantomjs',
                    processArgs,
                    {
                        detatched:false,
                        stdio:
                            [
                                process.stdin,
                                process.stdout,
                                process.stderr
                            ]
                    });

                //  phantomjs.unref && phantomjs.unref();
            };

            var ensureServerRunning = function () {
                pingServer(options, function (result) {
                    self.options.debug && console.log('pinged server and got back %s', result);

                    if (result) {
                        self.options.debug && console.log('server already running... proxy value %s', JSON.stringify(self.proxy));
                        callbackFn(self.proxy);

                    }
                    else {
                        self.options.debug && console.log('creating a new server, waiting for servercreated event on %s', self.proxy.phantom);

                        self.proxy.phantom.on('serverCreated', function (result) {
                            self.options.debug && console.log('server created callback fired with value:%s'.yellow.bold, result);
                            callbackFn(self.proxy);
                        });

                        spawnNewProcess();
                    }
                });
            };

            //socket io implementation - credit to node-phantom
            var socketio = require('socket.io');
            var http = require('http');
            this.server = http.createServer(function (request, response) {
                response.writeHead(200, {"Content-Type":"text/html"});
                response.end('');
            }).listen();

            options.clientPort = this.server.address().port;
            var io = socketio.listen(this.server, {'log level':1});

            io.sockets.on('connection', function (socket) {
                options.debug && console.log('connection'.green);
                socket.on('res', function (response) {
                    var data = JSON.stringify(response);
                    options.debug && console.log('response: %s'.green, data);
                    parseResponse(data);
                });
            });

            //create proxy object
            self.proxy = {
                page:new Webpage(options),
                phantom:new Phantom(options),
                end:function (endCallback) {
                    self.end(function () {
                        endCallback(true);
                    });
                }
            };

            ensureServerRunning();
        },
//use to see if  phantom server already runnings
        pingServer = function (options, callbackFn) {

            var self = this;
            request.get(options.hostAndPort + '/ping',
                function (error, response) {

                    if (response && response.statusCode === 200) {    //server up

                        callbackFn && callbackFn.call(self, true);
                    }
                    else {    //server down
                        callbackFn.call(self, false);
                    }
                });
            return this;
        };

    module.exports = {
        //terminates phantomjs process
        end:function (callbackFn) {
            var self = this;
            request.post(this.options.hostAndPort + '/phantom/functions/exit', {
                    form:{
                    }
                },
                function (error, response, body) {

                    if (response && response.statusCode === 200) {    //server up
                        self.server.close();
                        callbackFn && callbackFn.call(self, true);
                    }
                    else {    //server down
                        callbackFn.call(self, false);
                    }
                });
        },
        //creates a new proxy session - creates phantomjs process and webserver module
        create:function (options, callbackFn) {
            var self = this;

            //compensate for optional options parm
            if (typeof options === 'function') {
                callbackFn = options;
                options = {};
            }

            //assign default port
            options.port = options.port || 1061;
            options.host = options.host || 'localhost';
            options.hostAndPort = 'http://' + options.host + ':' + options.port;
            options.eventStreamPath = require('path').normalize(__dirname + '/../temp/events.txt');

            options.debug && console.log('creating proxy to %s', options.hostAndPort);

            this.options = options;

            //try starting server
            createServer.call(self, options, function (proxy) {
                callbackFn.call(self, proxy);
            });

            return this;//return this to chain end
        }};
}
    (module, process)
    )
;

<commit_msg>Fix phantomjs spawn argument typo 'detatched'.<commit_after>(function (module, process) {
    'use strict';
    var colors = require('colors'),
        request = require('./request/main'),
        _ = require('underscore'),
        Q = require('q'),
        events = require('events');

    colors.setTheme({
        silly:'rainbow',
        input:'grey',
        verbose:'cyan',
        prompt:'grey',
        info:'green',
        data:'grey',
        help:'cyan',
        warn:'yellow',
        debug:'blue',
        error:'red'
    });

    var translateOptions2Arguments = function (options) {
        //used to translate property to cmd line arg
        var phantomArgMap = {
            'cookiesFile':'cookies-file',
            'config': 'config',
            'debug': 'debug',
            'diskCache':'disk-cache',
            'ignoreSslErrors':'ignore-ssl-errors',
            'loadImages':'load-images',
            'localToRemoteUrlAccessEnabled':'local-to-remote-url-access',
            'maxDiskCache':'max-disk-cache-size',
            'outputEncoding':'output-encoding',
            'proxy':'proxy',
            'proxyType':'proxy-type',
            'scriptEncoding':'script-encoding',
            'version':'version',
            'webSecurity':'web-security'
        };

        //may integrate in future
        var defaultoptions = {
            'ignoreSslErrors':true,
            'localToRemoteUrlAccessEnabled':true,
            'cookiesFile':'cookies.txt',
            'diskCache':'yes',
            'loadImages':'yes',
            'localToRemoteUrlAccess':'no',
            'maxDiskCache':'50000',
            'outputEncoding':'utf8',
            'proxy':'0',
            'proxyType':'yes',
            'scriptEncoding':'yes',
            'webSecurity':'no'
        };

        //map options props to cmd line args for phantom process

        var phantomArgs = []
            , proxyArgs = [];

        for (var k in options) {
            if (options.hasOwnProperty(k)) {
                if (phantomArgMap[k]) {
                    phantomArgs.push('--' + phantomArgMap[k] + '=' + options[k]);
                } else {
                    var uncamel = k.replace(/[A-Z]/g, function(c) {
                        return '-' + c.toLowerCase();
                    });
                    proxyArgs.push('--' + uncamel + '=' + options[k]);
                }
            }
        }

        return {
            phantom: phantomArgs,
            proxy: proxyArgs
        };
    };

//    //on exit loop through process array and kill everything
//    process.on('exit', function () {
//        processArray.forEach(function (proc) {
//            proc.kill('SIGHUP');
//        });
//    });

    //creates a new phantomjs process
    var createServer = function (options, callbackFn) {
            var Webpage = require('./webpage'),
                Phantom = require('./phantom'),
                self = this,
                streamPosition = 0,

//            //pass proxy to callbackFn
//            callbackFn.call(self, self.proxy);

            //parses a line from phantoms event stream
                parseResponse = function (response) {
                    var parsedEvent;

                    self.options.debug && console.log('buffer :%s'.grey, response);

                    try {
                        parsedEvent = JSON.parse(response);
                    }
                    catch (exception) {
                        console.error(exception.toString().red.bold);
                        console.error('attempted to parse %s', response);
                        return;
                    }

                    var args = parsedEvent.args;
                    args.unshift(parsedEvent.type);

                    self.options.debug && console.log('emitting %s event on %s'.grey, parsedEvent.type, parsedEvent.source);

                    switch (parsedEvent.source) {
                        //phantomJs server module started and is listening or failed
                        case 'phantom' :
                            self.proxy.phantom.emit.apply(self.proxy.phantom, args);
                            break;
                        case 'page' :
                            self.proxy.page.emit.apply(self.proxy.page, args);
                            break;
                        case 'server' :
                            self.proxy.phantom.emit.apply(self.proxy.phantom, args);
                            break;
                        default :
                            throw new Error('unexpected eventsource:' + parsedEvent.source);

                    }

                };

            var spawnNewProcess = function () {
                var spawn = require('child_process').spawn,
                    serverPath = __dirname + '/' + require('path').normalize('./server/index.js');

                var args = translateOptions2Arguments(options);
                args.proxy.unshift(serverPath, JSON.stringify(options));
                var processArgs = args.phantom.concat(args.proxy);

                //spawn new process
                var phantomjs = spawn('phantomjs',
                    processArgs,
                    {
                        detached:false,
                        stdio:
                            [
                                process.stdin,
                                process.stdout,
                                process.stderr
                            ]
                    });

                //  phantomjs.unref && phantomjs.unref();
            };

            var ensureServerRunning = function () {
                pingServer(options, function (result) {
                    self.options.debug && console.log('pinged server and got back %s', result);

                    if (result) {
                        self.options.debug && console.log('server already running... proxy value %s', JSON.stringify(self.proxy));
                        callbackFn(self.proxy);

                    }
                    else {
                        self.options.debug && console.log('creating a new server, waiting for servercreated event on %s', self.proxy.phantom);

                        self.proxy.phantom.on('serverCreated', function (result) {
                            self.options.debug && console.log('server created callback fired with value:%s'.yellow.bold, result);
                            callbackFn(self.proxy);
                        });

                        spawnNewProcess();
                    }
                });
            };

            //socket io implementation - credit to node-phantom
            var socketio = require('socket.io');
            var http = require('http');
            this.server = http.createServer(function (request, response) {
                response.writeHead(200, {"Content-Type":"text/html"});
                response.end('');
            }).listen();

            options.clientPort = this.server.address().port;
            var io = socketio.listen(this.server, {'log level':1});

            io.sockets.on('connection', function (socket) {
                options.debug && console.log('connection'.green);
                socket.on('res', function (response) {
                    var data = JSON.stringify(response);
                    options.debug && console.log('response: %s'.green, data);
                    parseResponse(data);
                });
            });

            //create proxy object
            self.proxy = {
                page:new Webpage(options),
                phantom:new Phantom(options),
                end:function (endCallback) {
                    self.end(function () {
                        endCallback(true);
                    });
                }
            };

            ensureServerRunning();
        },
//use to see if  phantom server already runnings
        pingServer = function (options, callbackFn) {

            var self = this;
            request.get(options.hostAndPort + '/ping',
                function (error, response) {

                    if (response && response.statusCode === 200) {    //server up

                        callbackFn && callbackFn.call(self, true);
                    }
                    else {    //server down
                        callbackFn.call(self, false);
                    }
                });
            return this;
        };

    module.exports = {
        //terminates phantomjs process
        end:function (callbackFn) {
            var self = this;
            request.post(this.options.hostAndPort + '/phantom/functions/exit', {
                    form:{
                    }
                },
                function (error, response, body) {

                    if (response && response.statusCode === 200) {    //server up
                        self.server.close();
                        callbackFn && callbackFn.call(self, true);
                    }
                    else {    //server down
                        callbackFn.call(self, false);
                    }
                });
        },
        //creates a new proxy session - creates phantomjs process and webserver module
        create:function (options, callbackFn) {
            var self = this;

            //compensate for optional options parm
            if (typeof options === 'function') {
                callbackFn = options;
                options = {};
            }

            //assign default port
            options.port = options.port || 1061;
            options.host = options.host || 'localhost';
            options.hostAndPort = 'http://' + options.host + ':' + options.port;
            options.eventStreamPath = require('path').normalize(__dirname + '/../temp/events.txt');

            options.debug && console.log('creating proxy to %s', options.hostAndPort);

            this.options = options;

            //try starting server
            createServer.call(self, options, function (proxy) {
                callbackFn.call(self, proxy);
            });

            return this;//return this to chain end
        }};
}
    (module, process)
    )
;

<|endoftext|>


<commit_before>const execa = require('execa');
const os = require('os');

if (os.platform() != "win32") {
  module.exports = getProcess;
} else {
  module.exports = getWinProcess;
}

function getWinProcess(options) {
  return new Promise((resolve, reject) => {
    execa('powershell', ['-noprofile',
      '$perf = get-wmiobject -class Win32_PerfFormattedData_PerfProc_Process;$proc = get-wmiobject -class win32_process ;$TotalMem = get-wmiobject -class win32_computersystem | select -ExpandProperty TotalPhysicalMemory;$proc | foreach {$procID = $_;$procPerf = $perf | where {$_.creatingProcessID -eq $procID.ProcessID};$procID | select Name,@{n="User"; e= {$user = $_.getOwner(); if($user.user){"{0}\\{1}" -f $user.domain, $user.user}else {"System"}}},CommandLine,ProcessID,@{n="Memory (MB)";e={"{0:N3}" -f ($_.ws / 1mb)}},@{n="Memory (%)";e={"{0:N3}" -f ($_.ws / $TotalMem)}},@{n="StartTime";e={$_.converttoDateTime($_.CreationDate)}},@{n="CPU"; e={$item = $_;$COUNT = 0;if($procPerf.percentProcessorTime){$procPerf.PercentProcessorTime | foreach {$count += $_}; $percent = $count / $procPerf.PercentProcessorTime.length;"{0:N3}" -f [double]$percent} else {"{0:N3}" -f 0}}}} | ConvertTo-Json'
    ]).then(result => {
      var processes;
      try {
        processes = JSON.parse(result.stdout);
      } catch (err) {
        processes = [];
        reject(err);
      }

      processes = processes.reduce(parseWinProcesses, []);
      processes.query = query;
      resolve(processes);
    });
  });
}

function parseWinProcesses(list, ps) {
  list.push({
    user: ps["User"],
    pid: ps["ProcessID"],
    cpu: parseFloat(ps["CPU"]),
    mem: parseFloat(ps["Memory (MB)"]),
    started: ps["StartTime"],
    command: ps["CommandLine"],
    name: ps["Name"]
  });

  return list;
}

function getProcess(options) {
  return new Promise((resolve, reject) => {
    execa('ps', ['aux']).then(result => {
      var processes = result.stdout.split('\n');

      //Remove header
      processes.shift();
      processes = processes.reduce(parseProcesses, []);

      processes.query = query;

      resolve(processes);
    });
  });
}

/**
 * Normalizes the process payload into a readable object.
 *
 * @param  {Array} list
 * @param  {Array} ps
 * @return {Array}
 */
function parseProcesses(list, ps) {
  var p = ps.split(/ +/);

  list.push({
    user: p[0],
    pid: p[1],
    cpu: parseFloat(p[2]),
    mem: parseFloat(p[3]),
    vsz: p[4],
    rss: p[5],
    tt: p[6],
    stat: p[7],
    started: p[8],
    time: p[9],
    command: p.slice(10).join(' ')
  });

  return list;
}

/**
 * Return elements that match a certain query:
 *
 * @example
 *   list.query({
 *     user: 'root',
 *     cpu: '>10',
 *     mem: '>5 <10',
 *     command: '~chrome'
 *   })
 *
 * @param  {Object} q
 * @return {Array}
 */
function query(q) {
  var filter = Object.keys(q);
  var isValid;
  var valid;
  var val;

  return this.reduce((list, ps) => {
    isValid = filter.every(key => {
      val = q[key];
      valid = true;

      if (typeof val === 'string') {
        if (val.indexOf('<') > -1) {
          valid = ps[key] < cleanValue(val, '<');
        }

        if (valid && val.indexOf('>') > -1) {
          valid = ps[key] > cleanValue(val, '>');
        }

        if (valid && val.indexOf('~') > -1) {
          valid = ps[key].indexOf(q[key].replace('~', '')) > -1;
        }
      } else {
        valid = ps[key] === val;
      }

      return valid;
    });

    if (isValid) list.push(ps);

    return list;
  }, []);
}

/**
 * Return the value for a certain condition
 *
 * @example
 *   cleanValue('foo <100', '<') == 100
 *   cleanValue('>5 <1 bar', '>') == 5
 *
 * @param  {String} val
 * @param  {String} char
 * @return {Float}
 */
function cleanValue(val, char) {
  var num;
  var conditions = val.split(' ');
  var i = 0;

  while (!num && i < conditions.length) {
    if (conditions[i].indexOf(char) > -1) {
      num = conditions[i].replace(/<|>|~/g, '');
    }
    i++;
  }

  return parseFloat(num);
}<commit_msg>Add vsz, rss, tt windows support<commit_after>const execa = require('execa');
const os = require('os');

if (os.platform() != "win32") {
  module.exports = getProcess;
} else {
  module.exports = getWinProcess;
}

function getWinProcess(options) {
  return new Promise((resolve, reject) => {
    execa('powershell', ['-noprofile',
      '$perf = get-wmiobject -class Win32_PerfFormattedData_PerfProc_Process;$proc = get-wmiobject -class win32_process -Property *;$TotalMem = get-wmiobject -class win32_computersystem | select -ExpandProperty TotalPhysicalMemory; $proc | foreach {    $procID = $_;    $procPerf = $perf | where {$_.creatingProcessID -eq $procID.ProcessID};    $procID | select name,        @{n="user"; e= {$user = $_.getOwner(); if($user.user){"{0}\{1}" -f $user.domain, $user.user}else {"System"}}},        @{n="command"; e={$_.CommandLine}},        @{n="pid";e={$_.ProcessID}},        @{n="memory (MB)";e={"{0:N3}" -f ($_.ws / 1mb)}},        @{n="memory (%)";e={"{0:N3}" -f ($_.ws / $TotalMem)}},        @{n="started";e={$_.converttoDateTime($_.CreationDate)}},        @{n="cpu"; e={$item = $_;$COUNT = 0;if($procPerf.percentProcessorTime){$procPerf.PercentProcessorTime | foreach {$count += $_};$percent = $count / $procPerf.PercentProcessorTime.length;"{0:N3}" -f [double]$percent;} else {"{0:N3}" -f 0}}}, @{n="vsz"; e={$_.VirtualSize}},@{n="rss"; e={$_.WorkingSetSize}},@{n="tt"; e={$_.SessionID}},@{n="time"; e={$_.KernelModeTime+ ($_.UserModeTime *10000)}}}|convertto-json'
    ]).then(result => {
      var processes;
      try {
        processes = JSON.parse(result.stdout);
      } catch (err) {
        processes = [];
        reject(err);
      }

      processes = processes.reduce(parseWinProcesses, []);
      processes.query = query;
      resolve(processes);
    });
  });
}

function parseWinProcesses(list, ps) {
  list.push({
    user: ps["user"],
    pid: ps["pid"],
    cpu: parseFloat(ps["cpu"]),
    mem: parseFloat(ps["memory (%)"]),
    name: ps["name"],
    vsz: ps["vsz"],
    rss: ps["rss"],
    tt: ps["tt"],
    started: new Date(ps["started"].DateTime),
    time: ps["time"],
    command: ps["command"]
  });

  return list;
}

function getProcess(options) {
  return new Promise((resolve, reject) => {
    execa('ps', ['aux']).then(result => {
      var processes = result.stdout.split('\n');

      //Remove header
      processes.shift();
      processes = processes.reduce(parseProcesses, []);

      processes.query = query;

      resolve(processes);
    });
  });
}

/**
 * Normalizes the process payload into a readable object.
 *
 * @param  {Array} list
 * @param  {Array} ps
 * @return {Array}
 */
function parseProcesses(list, ps) {
  var p = ps.split(/ +/);

  list.push({
    user: p[0],
    pid: p[1],
    cpu: parseFloat(p[2]),
    mem: parseFloat(p[3]),
    vsz: p[4],
    rss: p[5],
    tt: p[6],
    stat: p[7],
    started: p[8],
    time: p[9],
    command: p.slice(10).join(' ')
  });

  return list;
}

/**
 * Return elements that match a certain query:
 *
 * @example
 *   list.query({
 *     user: 'root',
 *     cpu: '>10',
 *     mem: '>5 <10',
 *     command: '~chrome'
 *   })
 *
 * @param  {Object} q
 * @return {Array}
 */
function query(q) {
  var filter = Object.keys(q);
  var isValid;
  var valid;
  var val;

  return this.reduce((list, ps) => {
    isValid = filter.every(key => {
      val = q[key];
      valid = true;

      if (typeof val === 'string') {
        if (val.indexOf('<') > -1) {
          valid = ps[key] < cleanValue(val, '<');
        }

        if (valid && val.indexOf('>') > -1) {
          valid = ps[key] > cleanValue(val, '>');
        }

        if (valid && val.indexOf('~') > -1) {
          valid = ps[key].indexOf(q[key].replace('~', '')) > -1;
        }
      } else {
        valid = ps[key] === val;
      }

      return valid;
    });

    if (isValid) list.push(ps);

    return list;
  }, []);
}

/**
 * Return the value for a certain condition
 *
 * @example
 *   cleanValue('foo <100', '<') == 100
 *   cleanValue('>5 <1 bar', '>') == 5
 *
 * @param  {String} val
 * @param  {String} char
 * @return {Float}
 */
function cleanValue(val, char) {
  var num;
  var conditions = val.split(' ');
  var i = 0;

  while (!num && i < conditions.length) {
    if (conditions[i].indexOf(char) > -1) {
      num = conditions[i].replace(/<|>|~/g, '');
    }
    i++;
  }

  return parseFloat(num);
}<|endoftext|>


<commit_before>var constants = require('./constants.js');
var util = require('./util.js');

var getSubRoles = function(roles) {
	return [].concat.apply([], roles.map(function(role) {
		return constants.subRoles[role] || [role];
	}));
};

// candidates can be passed for performance optimization
var _getRole = function(el, candidates) {
	if (el.hasAttribute('role')) {
		return el.getAttribute('role');
	}
	for (var role in constants.extraSelectors) {
		var selector = constants.extraSelectors[role].join(',');
		if ((!candidates || candidates.indexOf(role) !== -1) && el.matches(selector)) {
			return role;
		}
	}

	if (!candidates ||
			candidates.indexOf('banner') !== -1 ||
			candidates.indexOf('contentinfo') !== -1) {
		var scoped = el.matches(constants.scoped);

		if (el.matches('header') && !scoped) {
			return 'banner';
		}
		if (el.matches('footer') && !scoped) {
			return 'contentinfo';
		}
	}
};

var getAttribute = function(el, key, _hiddenRoot) {
	if (key === 'hidden' && el === _hiddenRoot) {  // used for name calculation
		return false;
	}

	if (constants.attributeStrongMapping.hasOwnProperty(key)) {
		var value = el[constants.attributeStrongMapping[key]];
		if (value) {
			return value;
		}
	}
	if (key === 'readonly' && el.contentEditable) {
		return false;
	} else if (key === 'invalid' && el.checkValidity) {
		return !el.checkValidity();
	}

	var type = constants.attributes[key];
	var raw = el.getAttribute('aria-' + key);

	if (raw) {
		if (type === 'bool') {
			return raw === 'true';
		} else if (type === 'tristate') {
			return raw === 'true' ? true : raw === 'false' ? false : 'mixed';
		} else if (type === 'bool-undefined') {
			return raw === 'true' ? true : raw === 'false' ? false : undefined;
		} else if (type === 'id-list') {
			return raw.split(/\s+/);
		} else if (type === 'integer') {
			return parseInt(raw);
		} else if (type === 'number') {
			return parseFloat(raw);
		} else if (type === 'token-list') {
			return raw.split(/\s+/);
		} else {
			return raw;
		}
	}

	// TODO
	// autocomplete
	// contextmenu -> aria-haspopup
	// indeterminate -> aria-checked="mixed"
	// list -> aria-controls

	if (key === 'level') {
		for (var i = 1; i <= 6; i++) {
			if (el.tagName.toLowerCase() === 'h' + i) {
				return i;
			}
		}
	} else if (key === 'hidden') {
		var style = window.getComputedStyle(el);
		if (style.display === 'none' || style.visibility === 'hidden') {
			return true;
		} else if (el.clientHeight === 0) {  // rough check for performance
			return el.parentNode && getAttribute(el.parentNode, 'hidden', _hiddenRoot);
		}
	} else if (constants.attributeWeakMapping.hasOwnProperty(key)) {
		return el[constants.attributeWeakMapping[key]];
	}

	if (type === 'bool' || type === 'tristate') {
		return false;
	}
};

var matches = function(el, selector) {
	var actual;

	if (selector.substr(0, 1) === ':') {
		var attr = selector.substr(1);
		return getAttribute(el, attr);
	} else if (selector.substr(0, 1) === '[') {
		var match = /\[([a-z]+)="(.*)"\]/.exec(selector);
		actual = getAttribute(el, match[1]);
		var rawValue = match[2];
		return actual.toString() == rawValue;
	} else {
		var candidates = getSubRoles(selector.split(','));
		actual = _getRole(el, candidates);
		return candidates.indexOf(actual) !== -1;
	}
};

var _querySelector = function(all) {
	return function(root, role) {
		var results = [];
		util.walkDOM(root, function(node) {
			if (node.nodeType === node.ELEMENT_NODE) {
				// FIXME: skip hidden elements
				if (matches(node, role)) {
					results.push(node);
					if (!all) {
						return false;
					}
				}
			}
		});
		return all ? results : results[0];
	};
};

var closest = function(el, selector) {
	return util.searchUp(el, function(candidate) {
		return matches(candidate, selector);
	});
};

module.exports = {
	getRole: function(el) {
		return _getRole(el);
	},
	getAttribute: getAttribute,
	matches: matches,
	querySelector: _querySelector(),
	querySelectorAll: _querySelector(true),
	closest: closest,
};
<commit_msg>query: also treat CSS hidden as conflicting<commit_after>var constants = require('./constants.js');
var util = require('./util.js');

var getSubRoles = function(roles) {
	return [].concat.apply([], roles.map(function(role) {
		return constants.subRoles[role] || [role];
	}));
};

// candidates can be passed for performance optimization
var _getRole = function(el, candidates) {
	if (el.hasAttribute('role')) {
		return el.getAttribute('role');
	}
	for (var role in constants.extraSelectors) {
		var selector = constants.extraSelectors[role].join(',');
		if ((!candidates || candidates.indexOf(role) !== -1) && el.matches(selector)) {
			return role;
		}
	}

	if (!candidates ||
			candidates.indexOf('banner') !== -1 ||
			candidates.indexOf('contentinfo') !== -1) {
		var scoped = el.matches(constants.scoped);

		if (el.matches('header') && !scoped) {
			return 'banner';
		}
		if (el.matches('footer') && !scoped) {
			return 'contentinfo';
		}
	}
};

var getAttribute = function(el, key, _hiddenRoot) {
	if (key === 'hidden' && el === _hiddenRoot) {  // used for name calculation
		return false;
	}

	if (constants.attributeStrongMapping.hasOwnProperty(key)) {
		var value = el[constants.attributeStrongMapping[key]];
		if (value) {
			return value;
		}
	}
	if (key === 'readonly' && el.contentEditable) {
		return false;
	} else if (key === 'invalid' && el.checkValidity) {
		return !el.checkValidity();
	} else if (key === 'hidden') {
		var style = window.getComputedStyle(el);
		if (style.display === 'none' || style.visibility === 'hidden') {
			return true;
		}
	}

	var type = constants.attributes[key];
	var raw = el.getAttribute('aria-' + key);

	if (raw) {
		if (type === 'bool') {
			return raw === 'true';
		} else if (type === 'tristate') {
			return raw === 'true' ? true : raw === 'false' ? false : 'mixed';
		} else if (type === 'bool-undefined') {
			return raw === 'true' ? true : raw === 'false' ? false : undefined;
		} else if (type === 'id-list') {
			return raw.split(/\s+/);
		} else if (type === 'integer') {
			return parseInt(raw);
		} else if (type === 'number') {
			return parseFloat(raw);
		} else if (type === 'token-list') {
			return raw.split(/\s+/);
		} else {
			return raw;
		}
	}

	// TODO
	// autocomplete
	// contextmenu -> aria-haspopup
	// indeterminate -> aria-checked="mixed"
	// list -> aria-controls

	if (key === 'level') {
		for (var i = 1; i <= 6; i++) {
			if (el.tagName.toLowerCase() === 'h' + i) {
				return i;
			}
		}
	} else if (key === 'hidden') {
		if (el.clientHeight === 0) {  // rough check for performance
			return el.parentNode && getAttribute(el.parentNode, 'hidden', _hiddenRoot);
		}
	} else if (constants.attributeWeakMapping.hasOwnProperty(key)) {
		return el[constants.attributeWeakMapping[key]];
	}

	if (type === 'bool' || type === 'tristate') {
		return false;
	}
};

var matches = function(el, selector) {
	var actual;

	if (selector.substr(0, 1) === ':') {
		var attr = selector.substr(1);
		return getAttribute(el, attr);
	} else if (selector.substr(0, 1) === '[') {
		var match = /\[([a-z]+)="(.*)"\]/.exec(selector);
		actual = getAttribute(el, match[1]);
		var rawValue = match[2];
		return actual.toString() == rawValue;
	} else {
		var candidates = getSubRoles(selector.split(','));
		actual = _getRole(el, candidates);
		return candidates.indexOf(actual) !== -1;
	}
};

var _querySelector = function(all) {
	return function(root, role) {
		var results = [];
		util.walkDOM(root, function(node) {
			if (node.nodeType === node.ELEMENT_NODE) {
				// FIXME: skip hidden elements
				if (matches(node, role)) {
					results.push(node);
					if (!all) {
						return false;
					}
				}
			}
		});
		return all ? results : results[0];
	};
};

var closest = function(el, selector) {
	return util.searchUp(el, function(candidate) {
		return matches(candidate, selector);
	});
};

module.exports = {
	getRole: function(el) {
		return _getRole(el);
	},
	getAttribute: getAttribute,
	matches: matches,
	querySelector: _querySelector(),
	querySelectorAll: _querySelector(true),
	closest: closest,
};
<|endoftext|>


<commit_before>
const expect = require('chai').expect;
const RG = require('../../../client/src/battles');

const RGObjects = require('../../../client/data/battles_objects');
RG.Effects = require('../../../client/data/effects');

const downKey = {code: RG.K_MOVE_S};
const pickupKey = {code: RG.K_PICKUP};

/* AI for driving the player with commands. */
RG.PlayerDriver = function(player) {
    RG.Brain.Rogue.call(this, player);
    // const _player = player;

    this.getNextCmdOrKey = function() {
        // const seenCells = this.getSeenCells();

    };

};
RG.extend2(RG.PlayerDriver, RG.Brain.Rogue);

function findActor(level, query) {
    const actors = level.getActors();
    let found = null;
    Object.keys(query).forEach(q => {
        const val = query[q];
        const fname = q;
        actors.forEach(actor => {
            if (actor[fname]() === val) {
                found = actor;
            }
        });
    });
    return found;
}

describe('Function: All small game features', function() {
    this.timeout(60000);

    let game = null;
    let parser = null;
    let fromJSON = null;

    beforeEach(() => {
        game = new RG.Game.Main();
        parser = new RG.ObjectShellParser();
        parser.parseShellData(RG.Effects);
        parser.parseShellData(RGObjects);
        fromJSON = new RG.Game.FromJSON();
    });

    afterEach(() => {
        game = null;
        parser = null;
        fromJSON = null;
    });

    it('Devil is in the details. After a bug appears: Fix -> Verify ', () => {
        let l1 = new RG.FACT.createLevel('arena', 20, 20);
        let p1 = new RG.Actor.Rogue('Player1');
        const shopkeeper = parser.createActualObj(RG.TYPE_ACTOR, 'shopkeeper');
        const humanoid = parser.createActualObj(RG.TYPE_ACTOR, 'humanoid');
        const sword = new RG.Item.Weapon('sword');

        l1.addActor(p1, 1, 1);
        l1.addActor(shopkeeper, 3, 3);
        l1.addActor(humanoid, 15, 15);

        l1.addItem(sword, 1, 1);

        expect(shopkeeper.getBrain().getType()).to.equal('human');
        p1.setIsPlayer(true);
        game.addLevel(l1);
        game.addPlayer(p1);
        expect(p1.getCell().getX()).to.equal(1);
        expect(p1.getCell().getY()).to.equal(1);
        game.update(pickupKey);
        expect(l1.getItems(), 'l1 has no items after pickup').to.have.length(0);
        expect(p1.getInvEq().getInventory().getItems()).to.have.length(1);

        game.update(downKey);

        expect(humanoid.isEnemy(p1), 'Humanoid is enemy').to.equal(true);
        expect(shopkeeper.isEnemy(p1), 'shopkeeper not enemy').to.equal(false);

        //-------------------------------------
        // Fun starts after restoring
        //-------------------------------------
        console.log('Now restoring the game and performing checks.');

        const json = game.toJSON();
        // console.log(JSON.stringify(json, null, ' '));
        const newGame = fromJSON.createGame(json);

        // We can still update the game
        expect(newGame.update.bind(newGame, downKey)).to.not.throw(Error);

        l1 = newGame.getLevels()[0];
        // const actors = l1.getActors();

        // Verify shopkeeper's brain
        const sk = findActor(l1, {getName: 'shopkeeper'});
        p1 = findActor(l1, {getName: 'Player1'});
        const hum = findActor(l1, {getName: 'humanoid'});

        expect(sk.getBrain().getType()).to.equal('human');
        expect(hum.getBrain().getType()).to.equal('rogue');

        const inv = p1.getInvEq();
        expect(inv.getInventory().getItems(), 'Player has one item')
            .to.have.length(1);

        expect(l1.getItems(), 'Level has no items').to.have.length(0);

        expect(hum.isEnemy(p1), 'Humanoid is enemy').to.equal(true);
        expect(sk.isEnemy(p1), 'shopkeeper not enemy').to.equal(false);

    });
});
<commit_msg>Added findItem(). Added test to check that selling price is correctly restored.<commit_after>
const expect = require('chai').expect;
const RG = require('../../../client/src/battles');

const RGObjects = require('../../../client/data/battles_objects');
RG.Effects = require('../../../client/data/effects');

const downKey = {code: RG.K_MOVE_S};
const pickupKey = {code: RG.K_PICKUP};
const confirmKey = {code: RG.K_YES};

/* AI for driving the player with commands. */
RG.PlayerDriver = function(player) {
    RG.Brain.Rogue.call(this, player);
    // const _player = player;

    this.getNextCmdOrKey = function() {
        // const seenCells = this.getSeenCells();

    };

};
RG.extend2(RG.PlayerDriver, RG.Brain.Rogue);

function findActor(level, query) {
    const actors = level.getActors();
    let found = null;
    Object.keys(query).forEach(q => {
        const val = query[q];
        const fname = q;
        actors.forEach(actor => {
            if (actor[fname]() === val) {
                found = actor;
            }
        });
    });
    return found;
}

function findItem(level, query) {
    const items = level.getItems();
    let found = null;
    Object.keys(query).forEach(q => {
        const val = query[q];
        const fname = q;
        items.forEach(item => {
            if (item[fname]() === val) {
                found = item;
            }
        });
    });
    return found;
}

describe('Function: All small game features', function() {
    this.timeout(60000);

    let game = null;
    let parser = null;
    let fromJSON = null;

    beforeEach(() => {
        game = new RG.Game.Main();
        parser = new RG.ObjectShellParser();
        parser.parseShellData(RG.Effects);
        parser.parseShellData(RGObjects);
        fromJSON = new RG.Game.FromJSON();
    });

    afterEach(() => {
        game = null;
        parser = null;
        fromJSON = null;
    });

    it('Devil is in the details. After a bug appears: Fix -> Verify ', () => {
        let l1 = new RG.FACT.createLevel('arena', 20, 20);
        let p1 = new RG.Actor.Rogue('Player1');
        const p1Inv = p1.getInvEq().getInventory();
        const shopkeeper = parser.createActualObj(RG.TYPE_ACTOR, 'shopkeeper');
        const humanoid = parser.createActualObj(RG.TYPE_ACTOR, 'humanoid');
        const sword = new RG.Item.Weapon('sword');

        l1.addActor(p1, 1, 1);
        l1.addActor(shopkeeper, 3, 3);
        l1.addActor(humanoid, 15, 15);

        l1.addItem(sword, 1, 1);

        expect(shopkeeper.getBrain().getType()).to.equal('human');
        p1.setIsPlayer(true);
        game.addLevel(l1);
        game.addPlayer(p1);
        expect(p1.getCell().getX()).to.equal(1);
        expect(p1.getCell().getY()).to.equal(1);
        game.update(pickupKey);
        expect(l1.getItems(), 'l1 has no items after pickup').to.have.length(0);
        expect(p1Inv.getItems()).to.have.length(1);

        game.update(downKey);

        expect(humanoid.isEnemy(p1), 'Humanoid is enemy').to.equal(true);
        expect(shopkeeper.isEnemy(p1), 'shopkeeper not enemy').to.equal(false);

        // Test selling of items
        const p1X = p1.getX();
        const p1Y = p1.getY();
        const magicSword = parser.createActualObj(RG.TYPE_ITEM, 'Magic sword');
        p1Inv.addItem(magicSword);

        const dagger = parser.createActualObj(RG.TYPE_ITEM, 'Magic dagger');
        dagger.add('Unpaid', new RG.Component.Unpaid());
        l1.addItem(dagger, p1X, p1Y);

        expect(p1Inv.getItems()).to.have.length(2);
        const shopElem = new RG.Element.Shop();
        shopElem.setShopkeeper(shopkeeper);
        l1.addElement(shopElem, p1X, p1Y);
        const dropCmd = {cmd: 'drop', item: magicSword};
        game.update(dropCmd);
        game.update(confirmKey);
        expect(p1Inv.getItems(), 'Two items after selling').to.have.length(2);

        //-------------------------------------
        // Fun starts after restoring
        //-------------------------------------
        console.log('Now restoring the game and performing checks.');

        const json = game.toJSON();
        // console.log(JSON.stringify(json, null, ' '));
        const newGame = fromJSON.createGame(json);

        // We can still update the game
        expect(newGame.update.bind(newGame, downKey)).to.not.throw(Error);

        l1 = newGame.getLevels()[0];
        // const actors = l1.getActors();

        // Verify shopkeeper's brain
        const sk = findActor(l1, {getName: 'shopkeeper'});
        p1 = findActor(l1, {getName: 'Player1'});
        const hum = findActor(l1, {getName: 'humanoid'});

        expect(sk.getBrain().getType()).to.equal('human');
        expect(hum.getBrain().getType()).to.equal('rogue');

        const inv = p1.getInvEq();
        expect(inv.getInventory().getItems(), 'Player has one item')
            .to.have.length(2);

        expect(l1.getItems(), 'Level has 2 items').to.have.length(2);

        expect(hum.isEnemy(p1), 'Humanoid is enemy').to.equal(true);
        expect(sk.isEnemy(p1), 'shopkeeper not enemy').to.equal(false);

        const newShop = l1.getElements().find(
            elem => elem.getType() === 'shop');
        expect(newShop.getShopkeeper().getID()).to.equal(shopkeeper.getID());
        const newDagger = findItem(l1, {getName: 'Magic dagger'});
        const price = newShop.getItemPriceForSelling(newDagger);
        expect(price).to.be.above(0);

    });
});
<|endoftext|>


<commit_before>// Load modules

var Request = require('request');
var Utils = require('./utils');
var Boom = require('boom');

// Declare internals

var internals = {};

// Create and configure server instance

exports = module.exports = internals.Proxy = function (options, route) {

    Utils.assert(options, 'Missing options');
    Utils.assert(!!options.host ^ !!options.mapUri, 'Must have either options.host or options.mapUri');
    Utils.assert(!options.passThrough || !route.cache.isMode('server'), 'Cannot use pass-through proxy mode with caching');
    Utils.assert(!options.mapUri || typeof options.mapUri === 'function', 'options.mapUri must be a function');
    Utils.assert(!options.postResponse || typeof options.postResponse === 'function', 'options.postResponse must be a function');
    Utils.assert(!options.hasOwnProperty('isCustomPostResponse'), 'Cannot manually set options.isCustomPostResponse');

    this.settings = {};
    this.settings.mapUri = options.mapUri || internals.mapUri(options.protocol, options.host, options.port);
    this.settings.xforward = options.xforward || false;
    this.settings.passThrough = options.passThrough || false;
    this.settings.isCustomPostResponse = !!options.postResponse;
    this.settings.postResponse = options.postResponse || internals.postResponse;     // function (request, settings, response, payload)

    return this;
};

internals.Proxy.prototype.httpClient = Request;

internals.Proxy.prototype.handler = function () {

    var self = this;

    return function (request) {

        self.settings.mapUri(request, function (err, uri) {

            if (err) {
                return request.reply(err);
            }

            var req = request.raw.req;

            var options = {
                uri: uri,
                method: request.method,
                headers: {}
            };

            if (self.settings.passThrough) {                        // Never set with cache
                options.headers = Utils.clone(req.headers);
                delete options.headers.host;
            }

            if (self.settings.xforward) {
                options.headers['x-forwarded-for'] = (options.headers['x-forwarded-for'] ? options.headers['x-forwarded-for'] + ',' : '') + req.connection.remoteAddress || req.socket.remoteAddress;
                options.headers['x-forwarded-port'] = (options.headers['x-forwarded-port'] ? options.headers['x-forwarded-port'] + ',' : '') + req.connection.remotePort || req.socket.remotePort;
                options.headers['x-forwarded-proto'] = (options.headers['x-forwarded-proto'] ? options.headers['x-forwarded-proto'] + ',' : '') + self.settings.protocol;
            }

            var isGet = (request.method === 'get' || request.method === 'head');

            if (self.settings.isCustomPostResponse ||                                       // Custom response method
                (isGet && request._route.cache.isMode('server'))) {       // GET/HEAD with Cache

                // Callback interface

                self.httpClient(options, function (err, response, payload) {

                    // Request handles all redirect responses (3xx) and will return an err if redirection fails

                    if (err) {
                        return request.reply(Boom.internal('Proxy error', err));
                    }

                    return self.settings.postResponse(request, self.settings, response, payload);
                });
            }
            else {

                // Stream interface

                if (!isGet &&
                    request.rawBody) {

                    options.headers['Content-Type'] = req.headers['content-type'];
                    options.body = request.rawBody;
                }

                var reqStream = self.httpClient(options);

                reqStream.on('response', function (resStream) {

                    request.reply(resStream);                   // Request._respond will pass-through headers and status code
                });

                if (!isGet &&
                    request.route.payload === 'stream') {

                    request.raw.req.pipe(reqStream);
                    request.raw.req.resume();
                }
            }
        });
    };
};

internals.mapUri = function (protocol, host, port) {

    protocol = protocol || 'http';
    port = port || (protocol === 'http' ? 80 : 443);
    var baseUrl = protocol + '://' + host + ':' + port;

    return function (request, callback) {

        return callback(null, baseUrl + request.path + (request.query ? '?' + request.query : ''));
    };
};

internals.postResponse = function (request, settings, response, payload) {

    var contentType = response.headers['content-type'];
    var statusCode = response.statusCode;

    if (statusCode >= 400) {
        return request.reply(Boom.passThrough(statusCode, payload, contentType));
    }

    var response = request.reply.payload(payload);
    if (contentType) {
        response.type(contentType);
    }

    return response.send();
};<commit_msg>Fix proxy mapUri query bug<commit_after>// Load modules

var Request = require('request');
var Utils = require('./utils');
var Boom = require('boom');

// Declare internals

var internals = {};

// Create and configure server instance

exports = module.exports = internals.Proxy = function (options, route) {

    Utils.assert(options, 'Missing options');
    Utils.assert(!!options.host ^ !!options.mapUri, 'Must have either options.host or options.mapUri');
    Utils.assert(!options.passThrough || !route.cache.isMode('server'), 'Cannot use pass-through proxy mode with caching');
    Utils.assert(!options.mapUri || typeof options.mapUri === 'function', 'options.mapUri must be a function');
    Utils.assert(!options.postResponse || typeof options.postResponse === 'function', 'options.postResponse must be a function');
    Utils.assert(!options.hasOwnProperty('isCustomPostResponse'), 'Cannot manually set options.isCustomPostResponse');

    this.settings = {};
    this.settings.mapUri = options.mapUri || internals.mapUri(options.protocol, options.host, options.port);
    this.settings.xforward = options.xforward || false;
    this.settings.passThrough = options.passThrough || false;
    this.settings.isCustomPostResponse = !!options.postResponse;
    this.settings.postResponse = options.postResponse || internals.postResponse;     // function (request, settings, response, payload)

    return this;
};

internals.Proxy.prototype.httpClient = Request;

internals.Proxy.prototype.handler = function () {

    var self = this;

    return function (request) {

        self.settings.mapUri(request, function (err, uri) {

            if (err) {
                return request.reply(err);
            }

            var req = request.raw.req;

            var options = {
                uri: uri,
                method: request.method,
                headers: {}
            };

            if (self.settings.passThrough) {                        // Never set with cache
                options.headers = Utils.clone(req.headers);
                delete options.headers.host;
            }

            if (self.settings.xforward) {
                options.headers['x-forwarded-for'] = (options.headers['x-forwarded-for'] ? options.headers['x-forwarded-for'] + ',' : '') + req.connection.remoteAddress || req.socket.remoteAddress;
                options.headers['x-forwarded-port'] = (options.headers['x-forwarded-port'] ? options.headers['x-forwarded-port'] + ',' : '') + req.connection.remotePort || req.socket.remotePort;
                options.headers['x-forwarded-proto'] = (options.headers['x-forwarded-proto'] ? options.headers['x-forwarded-proto'] + ',' : '') + self.settings.protocol;
            }

            var isGet = (request.method === 'get' || request.method === 'head');

            if (self.settings.isCustomPostResponse ||                                       // Custom response method
                (isGet && request._route.cache.isMode('server'))) {       // GET/HEAD with Cache

                // Callback interface

                self.httpClient(options, function (err, response, payload) {

                    // Request handles all redirect responses (3xx) and will return an err if redirection fails

                    if (err) {
                        return request.reply(Boom.internal('Proxy error', err));
                    }

                    return self.settings.postResponse(request, self.settings, response, payload);
                });
            }
            else {

                // Stream interface

                if (!isGet &&
                    request.rawBody) {

                    options.headers['Content-Type'] = req.headers['content-type'];
                    options.body = request.rawBody;
                }

                var reqStream = self.httpClient(options);

                reqStream.on('response', function (resStream) {

                    request.reply(resStream);                   // Request._respond will pass-through headers and status code
                });

                if (!isGet &&
                    request.route.payload === 'stream') {

                    request.raw.req.pipe(reqStream);
                    request.raw.req.resume();
                }
            }
        });
    };
};

internals.mapUri = function (protocol, host, port) {

    protocol = protocol || 'http';
    port = port || (protocol === 'http' ? 80 : 443);
    var baseUrl = protocol + '://' + host + ':' + port;

    return function (request, callback) {

        return callback(null, baseUrl + request.path + (request.url.search || ''));
    };
};

internals.postResponse = function (request, settings, response, payload) {

    var contentType = response.headers['content-type'];
    var statusCode = response.statusCode;

    if (statusCode >= 400) {
        return request.reply(Boom.passThrough(statusCode, payload, contentType));
    }

    var response = request.reply.payload(payload);
    if (contentType) {
        response.type(contentType);
    }

    return response.send();
};<|endoftext|>