<commit_before>const BASE_ARROW_SIZE = 8;
const ARROW_NAME_SUFFIX = "-LOOSE!";
const ARROW_START = 'start';
const ARROW_END = 'end';
const ARROW_START_NAME ='ArrowheadStart';
const ARROW_END_NAME ='ArrowheadEnd';

const createArrowhead = ({
  layer,
  name,
  headPosition,
  headType,
  headScale,
}) => {
  headPosition = (typeof headPosition !== 'undefined') ?  headPosition : ARROW_END;
  headType = (typeof headType !== 'undefined') ?  headType : 'fill';
  headScale = (typeof headScale !== 'undefined') ?  headScale : 'default';

  var path = layer.bezierPathWithTransforms();
  const lineThickness = layer.style().borders().firstObject().thickness();
  const length = path.length();
  const scale = 1+(lineThickness/5);

  const position = headPosition == ARROW_END ? length : 0;
  //line end
  const endPoint = path.pointOnPathAtLength(position);
  //nextpoint on path
  const arrowBase = headPosition == ARROW_END ? position - BASE_ARROW_SIZE : position + BASE_ARROW_SIZE
  const linePoint = path.pointOnPathAtLength(arrowBase);
  const angle = 360/(2*Math.PI) * (Math.atan2(linePoint.y - endPoint.y, linePoint.x - endPoint.x));

  var headPath = NSBezierPath.bezierPath();
  headPath.moveToPoint(NSMakePoint(0,BASE_ARROW_SIZE));
  headPath.lineToPoint(NSMakePoint(-BASE_ARROW_SIZE*2,0));
  headPath.lineToPoint(NSMakePoint(0,-BASE_ARROW_SIZE));
  headPath.closePath();

  var headShape = MSShapeGroup.shapeWithBezierPath(headPath);
  headShape.frame().setWidth(Math.floor(headShape.frame().width()*scale));
  headShape.frame().setHeight(Math.floor(headShape.frame().height()*scale));

  headShape.setRotation(-1*angle);

  headShape.frame().setX(endPoint.x - headShape.frame().width()/2);
  headShape.frame().setY(endPoint.y - headShape.frame().height()/2);

  var fill = headShape.style().addStylePartOfType(0);
  fill.color = layer.style().borders().firstObject().color();
  if(!!name){
    headShape.setName(name);
  }
  return headShape;
}

const groupAndResize = (group, children) => {
  group.addLayers(children);
  group.resizeToFitChildrenWithOption(0);
  return group;
}

const createArrow = (doc, layer, arrowPosition, arrowType, arrowScale) => {
  var arrowheadStart = createArrowhead({
    layer,
    headPosition: ARROW_START,
    name: ARROW_START_NAME,
  });

  var arrowheadEnd = createArrowhead({
    layer,
    headPosition: ARROW_END,
    name: ARROW_END_NAME,
  });

  var parent = layer.parentGroup();
  var group = MSLayerGroup.new();
  parent.removeLayer(layer);
  parent.addLayers([group]);
  const name = layer.name();
  group.setName(
    name.indexOf(ARROW_NAME_SUFFIX) === -1 ?
        name + ARROW_NAME_SUFFIX
        :
        name
  );
  return groupAndResize(group, [layer, arrowheadStart, arrowheadEnd]);
}

const toggleArrows = (group) => {
  var start, end, line;
  group.layers().forEach((child) => {
    log("child="+child.name());
    if (child.name() == ARROW_START_NAME) {
      start = child;
    } else if (child.name() == ARROW_END_NAME) {
      end = child;
    } else {
      line = child;
    }
  });

  if (!!start && !!end ){
    group.removeLayer(start);
    group.removeLayer(end);
    end = createArrowhead({
      layer: line,
      headPosition: 'end',
      name: 'ArrowheadEnd',
    });
    groupAndResize(group, [end]);
  }
  if (!start && !!end ){
    group.removeLayer(start);
    group.removeLayer(end);
    start = createArrowhead({
      layer: line,
      headPosition: 'start',
      name: 'ArrowheadStart',
    });
    groupAndResize(group, [start]);
  }
  if (!!start && !end){
    group.removeLayer(start);
    group.removeLayer(end);
    start = createArrowhead({
      layer: line,
      headPosition: 'start',
      name: 'ArrowheadStart',
    });
    end = createArrowhead({
      layer: line,
      headPosition: 'end',
      name: 'ArrowheadEnd',
    });
    groupAndResize(group, [start, end]);
  }
}

const isCompletShape = (layer) =>{
  const path = layer.bezierPathWithTransforms();
  const start = path.pointOnPathAtLength(0);
  const end = path.pointOnPathAtLength(path.length());
  const startx = Math.floor(start.x);
  const starty = Math.floor(start.y);
  const endx = Math.floor(end.x);
  const endy = Math.floor(end.y);
  //lol can't math with floats for some reason.
  return startx === endx && starty === endy;
}

const onRun = (context) => {
  var doc = context.document;
  var selectedLayers = context.selection;
  var selectedCount = selectedLayers.count();

  var sketch = context.api();
  var document = sketch.selectedDocument;
  document.selectedLayers.clear();

  if (selectedCount == 0) {
    doc.showMessage('Oops, no selection.');
  } else {
    var arrows = [];
    for (var i = 0; i < selectedCount; i++) {
      var layer = selectedLayers[i];
      if (layer.isKindOfClass(MSShapeGroup)){
        if(isCompletShape(layer)){
          doc.showMessage("Skipping layer, I'll only add arrows to lines.");
        } else {
          arrows.push(createArrow(doc, layer));
        }
      } else if (layer.isKindOfClass(MSLayerGroup)){
        toggleArrows(layer);
        arrows.push(layer);
      }
    }
    //push arrows to selection so you can keep toggeling + resize
    arrows.forEach((arrow) => {
      document.layerWithID(arrow.objectID()).addToSelection();
    });
  }
}
onRun(context);
<commit_msg>Prittier!<commit_after>const BASE_ARROW_SIZE = 8;
const ARROW_NAME_SUFFIX = "-LOOSE!";
const ARROW_START = "start";
const ARROW_END = "end";
const ARROW_START_NAME = "ArrowheadStart";
const ARROW_END_NAME = "ArrowheadEnd";

const createArrowhead = ({
  layer,
  name,
  headPosition,
  headType,
  headScale
}) => {
  headPosition = typeof headPosition !== "undefined" ? headPosition : ARROW_END;
  headType = typeof headType !== "undefined" ? headType : "fill";
  headScale = typeof headScale !== "undefined" ? headScale : "default";

  var path = layer.bezierPathWithTransforms();
  const lineThickness = layer
    .style()
    .borders()
    .firstObject()
    .thickness();
  const length = path.length();
  const scale = 1 + lineThickness / 5;

  const position = headPosition == ARROW_END ? length : 0;
  //line end
  const endPoint = path.pointOnPathAtLength(position);
  //nextpoint on path
  const arrowBase =
    headPosition == ARROW_END
      ? position - BASE_ARROW_SIZE
      : position + BASE_ARROW_SIZE;
  const linePoint = path.pointOnPathAtLength(arrowBase);
  const angle =
    360 /
    (2 * Math.PI) *
    Math.atan2(linePoint.y - endPoint.y, linePoint.x - endPoint.x);

  var headPath = NSBezierPath.bezierPath();
  headPath.moveToPoint(NSMakePoint(0, BASE_ARROW_SIZE));
  headPath.lineToPoint(NSMakePoint(-BASE_ARROW_SIZE * 2, 0));
  headPath.lineToPoint(NSMakePoint(0, -BASE_ARROW_SIZE));
  headPath.closePath();

  var headShape = MSShapeGroup.shapeWithBezierPath(headPath);
  headShape.frame().setWidth(Math.floor(headShape.frame().width() * scale));
  headShape.frame().setHeight(Math.floor(headShape.frame().height() * scale));

  headShape.setRotation(-1 * angle);

  headShape.frame().setX(endPoint.x - headShape.frame().width() / 2);
  headShape.frame().setY(endPoint.y - headShape.frame().height() / 2);

  var fill = headShape.style().addStylePartOfType(0);
  fill.color = layer
    .style()
    .borders()
    .firstObject()
    .color();
  if (!!name) {
    headShape.setName(name);
  }
  return headShape;
};

const groupAndResize = (group, children) => {
  group.addLayers(children);
  group.resizeToFitChildrenWithOption(0);
  return group;
};

const createArrow = (doc, layer, arrowPosition, arrowType, arrowScale) => {
  var arrowheadStart = createArrowhead({
    layer,
    headPosition: ARROW_START,
    name: ARROW_START_NAME
  });

  var arrowheadEnd = createArrowhead({
    layer,
    headPosition: ARROW_END,
    name: ARROW_END_NAME
  });

  var parent = layer.parentGroup();
  var group = MSLayerGroup.new();
  parent.removeLayer(layer);
  parent.addLayers([group]);
  const name = layer.name();
  group.setName(
    name.indexOf(ARROW_NAME_SUFFIX) === -1 ? name + ARROW_NAME_SUFFIX : name
  );
  return groupAndResize(group, [layer, arrowheadStart, arrowheadEnd]);
};

const toggleArrows = group => {
  var start, end, line;
  group.layers().forEach(child => {
    log("child=" + child.name());
    if (child.name() == ARROW_START_NAME) {
      start = child;
    } else if (child.name() == ARROW_END_NAME) {
      end = child;
    } else {
      line = child;
    }
  });

  if (!!start && !!end) {
    group.removeLayer(start);
    group.removeLayer(end);
    end = createArrowhead({
      layer: line,
      headPosition: "end",
      name: "ArrowheadEnd"
    });
    groupAndResize(group, [end]);
  }
  if (!start && !!end) {
    group.removeLayer(start);
    group.removeLayer(end);
    start = createArrowhead({
      layer: line,
      headPosition: "start",
      name: "ArrowheadStart"
    });
    groupAndResize(group, [start]);
  }
  if (!!start && !end) {
    group.removeLayer(start);
    group.removeLayer(end);
    start = createArrowhead({
      layer: line,
      headPosition: "start",
      name: "ArrowheadStart"
    });
    end = createArrowhead({
      layer: line,
      headPosition: "end",
      name: "ArrowheadEnd"
    });
    groupAndResize(group, [start, end]);
  }
};

const isCompletShape = layer => {
  const path = layer.bezierPathWithTransforms();
  const start = path.pointOnPathAtLength(0);
  const end = path.pointOnPathAtLength(path.length());
  const startx = Math.floor(start.x);
  const starty = Math.floor(start.y);
  const endx = Math.floor(end.x);
  const endy = Math.floor(end.y);
  //lol can't math with floats for some reason.
  return startx === endx && starty === endy;
};

const onRun = context => {
  var doc = context.document;
  var selectedLayers = context.selection;
  var selectedCount = selectedLayers.count();

  var sketch = context.api();
  var document = sketch.selectedDocument;
  document.selectedLayers.clear();

  if (selectedCount == 0) {
    doc.showMessage("Oops, no selection.");
  } else {
    var arrows = [];
    for (var i = 0; i < selectedCount; i++) {
      var layer = selectedLayers[i];
      if (layer.isKindOfClass(MSShapeGroup)) {
        if (isCompletShape(layer)) {
          doc.showMessage("Skipping layer, I'll only add arrows to lines.");
        } else {
          arrows.push(createArrow(doc, layer));
        }
      } else if (layer.isKindOfClass(MSLayerGroup)) {
        toggleArrows(layer);
        arrows.push(layer);
      }
    }
    //push arrows to selection so you can keep toggeling + resize
    arrows.forEach(arrow => {
      document.layerWithID(arrow.objectID()).addToSelection();
    });
  }
};
onRun(context);
<|endoftext|>


<commit_before>class DaftJS {

  constructor (config) {
    var self = this

    self.version = {
      codename: 'apple jack',
      full: '0.1.0',
      major: '0',
      minor: '1',
      dot: '0'
    }
    self.config = config ? config : {
      logging: {
        console: true,
        file: false
      }
    }

    self.bootstrap = {
      Dom: require('domtastic'), // DOM FUNCTIONS
      Logger: require('./logger') // LOGGING
    }

    self.dom = self.bootstrap.Dom
    self.Namespace = require('./namespace')
    self.NS = {}
  }

  // LOGGING ALIAS'
  error () { new this.bootstrap.Logger(this.config.logging.console).error(arguments[0], arguments[1]) }
  info () { new this.bootstrap.Logger(this.config.logging.console).info(arguments[0], arguments[1]) }
  log () { new this.bootstrap.Logger(this.config.logging.console).log(arguments[0], arguments[1]) }
  warn () { new this.bootstrap.Logger(this.config.logging.console).warn(arguments[0], arguments[1]) }

  // READY EVENT FIRED WHEN EVERYTHING IS LOADED
  ready (cb) {
    this.dom(document).ready(function () {
      if (window.Daft) {
        cb()
      } else {
        console.error('Error:', 'Daft could not be loaded')
      }
    })
  }

}

module.exports = new DaftJS()
<commit_msg>update default config<commit_after>class DaftJS {

  constructor () {
    var self = this

    self.version = {
      codename: 'apple jack',
      full: '0.1.0',
      major: '0',
      minor: '1',
      dot: '0'
    }
    self.config = {
      logging: {
        console: true,
        file: false
      }
    }

    self.bootstrap = {
      Dom: require('domtastic'), // DOM FUNCTIONS
      Logger: require('./logger') // LOGGING
    }

    self.dom = self.bootstrap.Dom
    self.Namespace = require('./namespace')
    self.NS = {}
  }

  // LOGGING ALIAS'
  error () { new this.bootstrap.Logger(this.config.logging.console).error(arguments[0], arguments[1]) }
  info () { new this.bootstrap.Logger(this.config.logging.console).info(arguments[0], arguments[1]) }
  log () { new this.bootstrap.Logger(this.config.logging.console).log(arguments[0], arguments[1]) }
  warn () { new this.bootstrap.Logger(this.config.logging.console).warn(arguments[0], arguments[1]) }

  // READY EVENT FIRED WHEN EVERYTHING IS LOADED
  ready (cb) {
    this.dom(document).ready(function () {
      if (window.Daft) {
        cb()
      } else {
        console.error('Error:', 'Daft could not be loaded')
      }
    })
  }

}

module.exports = new DaftJS()
<|endoftext|>


<commit_before>/*jshint moz:true */
// vi: sts=2 sw=2 et
//
// accelerator setting based on
// https://github.com/ambrice/spatialnavigation-tastycactus.com/blob/master/prefs.js

const Lang = imports.lang;
const Signals = imports.signals;

const Gtk = imports.gi.Gtk;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;

const Gettext = imports.gettext.domain('gnome-shell-screenshot');
const _ = Gettext.gettext;

const Local = imports.misc.extensionUtils.getCurrentExtension();
const Path = Local.imports.path;
const Config = Local.imports.config;
const Convenience = Local.imports.convenience;

let _settings;

const buildHbox = function () {
  return new Gtk.Box({
    orientation: Gtk.Orientation.HORIZONTAL,
    margin_top: 5,
    expand: false
  });
};

const ScreenshotToolSettingsWidget = new GObject.Class({
  Name: 'ScreenshotToolSettingsWidget',
  GTypeName: 'ScreenshotToolSettingsWidget',
  Extends: Gtk.Box,

  _init: function (params) {
    this.parent(params);
    this._initLayout();
  },

  _initLayout: function () {
    this._notebook = new Gtk.Notebook();

    let label;

    this._prefsIndicator = this._makePrefsIndicator();
    label = new Gtk.Label({label: _("Indicator")});
    this._notebook.append_page(this._prefsIndicator, label);

    this._prefsKeybindings = this._makePrefsKeybindings();
    label = new Gtk.Label({label: _("Keybindings")});
    this._notebook.append_page(this._prefsKeybindings, label);

    this.add(this._notebook);
  },

  _makePrefsIndicator: function () {
    let prefs = new Gtk.Box({
      orientation: Gtk.Orientation.VERTICAL,
      margin: 20,
      margin_top: 10,
      expand: false
    });

    let hbox;

    /* Show indicator [on|off] */

    hbox = buildHbox();

    const labelShowIndicator = new Gtk.Label({
      label: _('Show indicator'),
      xalign: 0,
      expand: true
    });

    const switchShowIndicator = new Gtk.Switch();

    switchShowIndicator.connect('notify::active', (button) => {
      _settings.set_boolean(Config.KeyEnableIndicator, button.active);
    });

    switchShowIndicator.active = _settings.get_boolean(
        Config.KeyEnableIndicator
    );

    hbox.add(labelShowIndicator);
    hbox.add(switchShowIndicator);

    prefs.add(hbox, {fill: false});

    /* Default click action [dropdown] */

    hbox = buildHbox();

    const labelDefaultClickAction = new Gtk.Label({
      label: _('Default Click Action'),
      xalign: 0,
      expand: true
    });

    const clickActionOptions = [
      [_("Select Area")     , Config.ClickActions.SELECT_AREA],
      [_("Select Window")   , Config.ClickActions.SELECT_WINDOW],
      [_("Select Desktop")  , Config.ClickActions.SELECT_DESKTOP],
      [_("Show Menu")       , Config.ClickActions.SHOW_MENU]
    ];

    const currentClickAction = _settings.get_enum(Config.KeyClickAction);

    const comboBoxDefaultClickAction = this._getComboBox(
      clickActionOptions, GObject.TYPE_INT, currentClickAction,
      (value) => _settings.set_enum(Config.KeyClickAction, value)
    );

    hbox.add(labelDefaultClickAction);
    hbox.add(comboBoxDefaultClickAction);

    prefs.add(hbox, {fill: false});

    /* Clipboard Action [dropdown] */

    hbox = buildHbox();

    const labelClipboardContent = new Gtk.Label({
      label: _('Default Clipboard Content'),
      xalign: 0,
      expand: true
    });

    const comboBoxOptions = [
      [_("Unchanged")     , Config.ClipboardActions.NONE],
      [_("Image Data")    , Config.ClipboardActions.SET_IMAGE_DATA],
      // [_("Local Path")    , Config.ClipboardActions.SET_LOCAL_PATH]
      // TODO
      // [_("Remote URL")    , Config.ClipboardActions.SET_REMOTE_URL]
    ];

    const currentClipboardAction =
      _settings.get_string(Config.KeyClipboardAction);

    const comboBoxClipboardContent = this._getComboBox(
      comboBoxOptions, GObject.TYPE_STRING, currentClipboardAction,
      (value) => _settings.set_string(Config.KeyClipboardAction, value)
    );

    hbox.add(labelClipboardContent);
    hbox.add(comboBoxClipboardContent);

    prefs.add(hbox, {fill: false});

    /* Save Screenshot [on|off] */

    hbox = buildHbox();

    const labelSaveScreenshot = new Gtk.Label({
      label: _('Auto-Save Screenshot'),
      xalign: 0,
      expand: true
    });

    const switchSaveScreenshot = new Gtk.Switch();

    switchSaveScreenshot.connect('notify::active', (button) => {
      _settings.set_boolean(Config.KeySaveScreenshot, button.active);
    });

    switchSaveScreenshot.active = _settings.get_boolean(Config.KeySaveScreenshot);

    hbox.add(labelSaveScreenshot);
    hbox.add(switchSaveScreenshot);

    prefs.add(hbox, {fill: false});

    /* Save Location [filechooser] */

    hbox = buildHbox();

    const labelSaveLocation = new Gtk.Label({
      label: _('Save Location'),
      xalign: 0,
      expand: true
    });

    const chooserSaveLocation = new Gtk.FileChooserButton({
      title: _("Select"),
      local_only: true,
    });
    chooserSaveLocation.set_action(Gtk.FileChooserAction.SELECT_FOLDER);

    try {
      let saveLocation = Path.expand(
        _settings.get_string(Config.KeySaveLocation)
      );
      chooserSaveLocation.set_filename(saveLocation);
    } catch (e) {
      logError(e);
    }
    chooserSaveLocation.connect('file-set', () => {
      log("file-set");
      let dir = Path.expand(_settings.get_string(Config.KeySaveLocation));
      log("dir="+dir);
      let [filename, err] = GLib.filename_from_uri(
        chooserSaveLocation.get_uri()
      );
      if (err) {
        throw new Error("can't resolve uri");
      }
      _settings.set_string(Config.KeySaveLocation, filename);
    });

    const _setSensitivity = function () {
      var sensitive = _settings.get_boolean(Config.KeySaveScreenshot);
      labelSaveLocation.set_sensitive(sensitive);
      chooserSaveLocation.set_sensitive(sensitive);
    };

    switchSaveScreenshot.connect('notify::active', _setSensitivity);
    _setSensitivity();

    hbox.add(labelSaveLocation);
    hbox.add(chooserSaveLocation);

    prefs.add(hbox, {fill: false});

    return prefs;
  },

  _makePrefsKeybindings: function () {
    let model = new Gtk.ListStore();

    model.set_column_types([
        GObject.TYPE_STRING,
        GObject.TYPE_STRING,
        GObject.TYPE_INT,
        GObject.TYPE_INT
    ]);

    let bindings = [
      ["shortcut-select-area", _("Select area")],
      ["shortcut-select-window", _("Select window")],
      ["shortcut-select-desktop", _("Select whole desktop")]
    ];

    for (let [name, description] of bindings) {
      log("binding: " + name + " description: " + description);
      let binding = _settings.get_strv(name)[0];

      let key, mods;

      if (binding) {
        [key, mods] = Gtk.accelerator_parse(binding);
      } else {
        [key, mods] = [0, 0];
      }

      let row = model.append();

      model.set(row, [0, 1, 2, 3], [name, description, mods, key]);
    }

    let treeview = new Gtk.TreeView({
        'expand': true,
        'model': model
    });

    let cellrend = new Gtk.CellRendererText();
    let col = new Gtk.TreeViewColumn({
      'title': _('Keyboard Shortcut'),
      'expand': true
    });

    col.pack_start(cellrend, true);
    col.add_attribute(cellrend, 'text', 1);
    treeview.append_column(col);

    cellrend = new Gtk.CellRendererAccel({
      'editable': true,
      'accel-mode': Gtk.CellRendererAccelMode.GTK
    });

    cellrend.connect('accel-edited', (rend, iter, key, mods) => {
      let value = Gtk.accelerator_name(key, mods);
      let [succ, iterator] = model.get_iter_from_string(iter);

      if (!succ) {
        throw new Error("Error updating keybinding");
      }

      let name = model.get_value(iterator, 0);

      model.set(iterator, [2, 3], [mods, key]);
      _settings.set_strv(name, [value]);
    });

    cellrend.connect('accel-cleared', (rend, iter, key, mods) => {
      let [succ, iterator] = model.get_iter_from_string(iter);

      if (!succ) {
        throw new Error("Error clearing keybinding");
      }

      let name = model.get_value(iterator, 0);

      model.set(iterator, [2, 3], [0, 0]);
      _settings.set_strv(name, []);
    });

    col = new Gtk.TreeViewColumn({'title': _('Modify'), min_width: 200});

    col.pack_end(cellrend, false);
    col.add_attribute(cellrend, 'accel-mods', 2);
    col.add_attribute(cellrend, 'accel-key', 3);
    treeview.append_column(col);

    return treeview;
  },

  _getComboBox: function (options, valueType, defaultValue, callback) {
    let model = new Gtk.ListStore();

    let Columns = { LABEL: 0, VALUE: 1 };

    model.set_column_types([GObject.TYPE_STRING, valueType]);

    let comboBox = new Gtk.ComboBox({model: model});
    let renderer = new Gtk.CellRendererText();

    comboBox.pack_start(renderer, true);
    comboBox.add_attribute(renderer, 'text', 0);

    for (let [label, value] of options) {
      let iter;

      model.set(
          iter = model.append(),
          [Columns.LABEL, Columns.VALUE],
          [label, value]
      );

      if (value === defaultValue) {
          comboBox.set_active_iter(iter);
      }
    }

    comboBox.connect('changed', (entry) => {
      let [success, iter] = comboBox.get_active_iter();

      if (!success) {
          return;
      }

      let value = model.get_value(iter, Columns.VALUE);

      callback(value);
    });

    return comboBox;
  }
});

function init() {
  _settings = Convenience.getSettings();
  Convenience.initTranslations();
}

function buildPrefsWidget() {
  let widget = new ScreenshotToolSettingsWidget();
  widget.show_all();

  return widget;
}
<commit_msg>prefs: add saveScreenshotBindSensitivity<commit_after>/*jshint moz:true */
// vi: sts=2 sw=2 et
//
// accelerator setting based on
// https://github.com/ambrice/spatialnavigation-tastycactus.com/blob/master/prefs.js

const Lang = imports.lang;
const Signals = imports.signals;

const Gtk = imports.gi.Gtk;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;

const Gettext = imports.gettext.domain('gnome-shell-screenshot');
const _ = Gettext.gettext;

const Local = imports.misc.extensionUtils.getCurrentExtension();
const Path = Local.imports.path;
const Config = Local.imports.config;
const Convenience = Local.imports.convenience;

let _settings;

const buildHbox = function () {
  return new Gtk.Box({
    orientation: Gtk.Orientation.HORIZONTAL,
    margin_top: 5,
    expand: false
  });
};

const ScreenshotToolSettingsWidget = new GObject.Class({
  Name: 'ScreenshotToolSettingsWidget',
  GTypeName: 'ScreenshotToolSettingsWidget',
  Extends: Gtk.Box,

  _init: function (params) {
    this.parent(params);
    this._initLayout();
  },

  _initLayout: function () {
    this._notebook = new Gtk.Notebook();

    let label;

    this._prefsIndicator = this._makePrefsIndicator();
    label = new Gtk.Label({label: _("Indicator")});
    this._notebook.append_page(this._prefsIndicator, label);

    this._prefsKeybindings = this._makePrefsKeybindings();
    label = new Gtk.Label({label: _("Keybindings")});
    this._notebook.append_page(this._prefsKeybindings, label);

    this.add(this._notebook);
  },

  _makePrefsIndicator: function () {
    let prefs = new Gtk.Box({
      orientation: Gtk.Orientation.VERTICAL,
      margin: 20,
      margin_top: 10,
      expand: false
    });

    let hbox;

    /* Show indicator [on|off] */

    hbox = buildHbox();

    const labelShowIndicator = new Gtk.Label({
      label: _('Show indicator'),
      xalign: 0,
      expand: true
    });

    const switchShowIndicator = new Gtk.Switch();

    switchShowIndicator.connect('notify::active', (button) => {
      _settings.set_boolean(Config.KeyEnableIndicator, button.active);
    });

    switchShowIndicator.active = _settings.get_boolean(
        Config.KeyEnableIndicator
    );

    hbox.add(labelShowIndicator);
    hbox.add(switchShowIndicator);

    prefs.add(hbox, {fill: false});

    /* Default click action [dropdown] */

    hbox = buildHbox();

    const labelDefaultClickAction = new Gtk.Label({
      label: _('Default Click Action'),
      xalign: 0,
      expand: true
    });

    const clickActionOptions = [
      [_("Select Area")     , Config.ClickActions.SELECT_AREA],
      [_("Select Window")   , Config.ClickActions.SELECT_WINDOW],
      [_("Select Desktop")  , Config.ClickActions.SELECT_DESKTOP],
      [_("Show Menu")       , Config.ClickActions.SHOW_MENU]
    ];

    const currentClickAction = _settings.get_enum(Config.KeyClickAction);

    const comboBoxDefaultClickAction = this._getComboBox(
      clickActionOptions, GObject.TYPE_INT, currentClickAction,
      (value) => _settings.set_enum(Config.KeyClickAction, value)
    );

    hbox.add(labelDefaultClickAction);
    hbox.add(comboBoxDefaultClickAction);

    prefs.add(hbox, {fill: false});

    /* Clipboard Action [dropdown] */

    hbox = buildHbox();

    const labelClipboardContent = new Gtk.Label({
      label: _('Default Clipboard Content'),
      xalign: 0,
      expand: true
    });

    const comboBoxOptions = [
      [_("Unchanged")     , Config.ClipboardActions.NONE],
      [_("Image Data")    , Config.ClipboardActions.SET_IMAGE_DATA],
      // [_("Local Path")    , Config.ClipboardActions.SET_LOCAL_PATH]
      // TODO
      // [_("Remote URL")    , Config.ClipboardActions.SET_REMOTE_URL]
    ];

    const currentClipboardAction =
      _settings.get_string(Config.KeyClipboardAction);

    const comboBoxClipboardContent = this._getComboBox(
      comboBoxOptions, GObject.TYPE_STRING, currentClipboardAction,
      (value) => _settings.set_string(Config.KeyClipboardAction, value)
    );

    hbox.add(labelClipboardContent);
    hbox.add(comboBoxClipboardContent);

    prefs.add(hbox, {fill: false});

    /* Save Screenshot [on|off] */

    hbox = buildHbox();

    const labelSaveScreenshot = new Gtk.Label({
      label: _('Auto-Save Screenshot'),
      xalign: 0,
      expand: true
    });

    const switchSaveScreenshot = new Gtk.Switch();

    switchSaveScreenshot.connect('notify::active', (button) => {
      _settings.set_boolean(Config.KeySaveScreenshot, button.active);
    });

    switchSaveScreenshot.active = _settings.get_boolean(Config.KeySaveScreenshot);

    hbox.add(labelSaveScreenshot);
    hbox.add(switchSaveScreenshot);

    const saveScreenshotBindSensitivity = (actor) => {
      var setSensitive = () => {
        var sensitive = _settings.get_boolean(Config.KeySaveScreenshot);
        actor.set_sensitive(sensitive)
      };
      switchSaveScreenshot.connect('notify::active', setSensitive);
      setSensitive();
    };

    prefs.add(hbox, {fill: false});

    /* Save Location [filechooser] */

    hbox = buildHbox();

    const labelSaveLocation = new Gtk.Label({
      label: _('Save Location'),
      xalign: 0,
      expand: true
    });

    const chooserSaveLocation = new Gtk.FileChooserButton({
      title: _("Select"),
      local_only: true,
    });
    chooserSaveLocation.set_action(Gtk.FileChooserAction.SELECT_FOLDER);

    try {
      let saveLocation = Path.expand(
        _settings.get_string(Config.KeySaveLocation)
      );
      chooserSaveLocation.set_filename(saveLocation);
    } catch (e) {
      logError(e);
    }
    chooserSaveLocation.connect('file-set', () => {
      log("file-set");
      let dir = Path.expand(_settings.get_string(Config.KeySaveLocation));
      log("dir="+dir);
      let [filename, err] = GLib.filename_from_uri(
        chooserSaveLocation.get_uri()
      );
      if (err) {
        throw new Error("can't resolve uri");
      }
      _settings.set_string(Config.KeySaveLocation, filename);
    });

    saveScreenshotBindSensitivity(labelSaveLocation);
    saveScreenshotBindSensitivity(chooserSaveLocation);

    hbox.add(labelSaveLocation);
    hbox.add(chooserSaveLocation);

    prefs.add(hbox, {fill: false});

    return prefs;
  },

  _makePrefsKeybindings: function () {
    let model = new Gtk.ListStore();

    model.set_column_types([
        GObject.TYPE_STRING,
        GObject.TYPE_STRING,
        GObject.TYPE_INT,
        GObject.TYPE_INT
    ]);

    let bindings = [
      ["shortcut-select-area", _("Select area")],
      ["shortcut-select-window", _("Select window")],
      ["shortcut-select-desktop", _("Select whole desktop")]
    ];

    for (let [name, description] of bindings) {
      log("binding: " + name + " description: " + description);
      let binding = _settings.get_strv(name)[0];

      let key, mods;

      if (binding) {
        [key, mods] = Gtk.accelerator_parse(binding);
      } else {
        [key, mods] = [0, 0];
      }

      let row = model.append();

      model.set(row, [0, 1, 2, 3], [name, description, mods, key]);
    }

    let treeview = new Gtk.TreeView({
        'expand': true,
        'model': model
    });

    let cellrend = new Gtk.CellRendererText();
    let col = new Gtk.TreeViewColumn({
      'title': _('Keyboard Shortcut'),
      'expand': true
    });

    col.pack_start(cellrend, true);
    col.add_attribute(cellrend, 'text', 1);
    treeview.append_column(col);

    cellrend = new Gtk.CellRendererAccel({
      'editable': true,
      'accel-mode': Gtk.CellRendererAccelMode.GTK
    });

    cellrend.connect('accel-edited', (rend, iter, key, mods) => {
      let value = Gtk.accelerator_name(key, mods);
      let [succ, iterator] = model.get_iter_from_string(iter);

      if (!succ) {
        throw new Error("Error updating keybinding");
      }

      let name = model.get_value(iterator, 0);

      model.set(iterator, [2, 3], [mods, key]);
      _settings.set_strv(name, [value]);
    });

    cellrend.connect('accel-cleared', (rend, iter, key, mods) => {
      let [succ, iterator] = model.get_iter_from_string(iter);

      if (!succ) {
        throw new Error("Error clearing keybinding");
      }

      let name = model.get_value(iterator, 0);

      model.set(iterator, [2, 3], [0, 0]);
      _settings.set_strv(name, []);
    });

    col = new Gtk.TreeViewColumn({'title': _('Modify'), min_width: 200});

    col.pack_end(cellrend, false);
    col.add_attribute(cellrend, 'accel-mods', 2);
    col.add_attribute(cellrend, 'accel-key', 3);
    treeview.append_column(col);

    return treeview;
  },

  _getComboBox: function (options, valueType, defaultValue, callback) {
    let model = new Gtk.ListStore();

    let Columns = { LABEL: 0, VALUE: 1 };

    model.set_column_types([GObject.TYPE_STRING, valueType]);

    let comboBox = new Gtk.ComboBox({model: model});
    let renderer = new Gtk.CellRendererText();

    comboBox.pack_start(renderer, true);
    comboBox.add_attribute(renderer, 'text', 0);

    for (let [label, value] of options) {
      let iter;

      model.set(
          iter = model.append(),
          [Columns.LABEL, Columns.VALUE],
          [label, value]
      );

      if (value === defaultValue) {
          comboBox.set_active_iter(iter);
      }
    }

    comboBox.connect('changed', (entry) => {
      let [success, iter] = comboBox.get_active_iter();

      if (!success) {
          return;
      }

      let value = model.get_value(iter, Columns.VALUE);

      callback(value);
    });

    return comboBox;
  }
});

function init() {
  _settings = Convenience.getSettings();
  Convenience.initTranslations();
}

function buildPrefsWidget() {
  let widget = new ScreenshotToolSettingsWidget();
  widget.show_all();

  return widget;
}
<|endoftext|>


<commit_before>function $A(iterable) {
  if (!iterable) return [];
  if (iterable.toArray) return iterable.toArray();
  var length = iterable.length || 0, results = new Array(length);
  while (length--) results[length] = iterable[length];
  return results;
}

if (Prototype.Browser.WebKit) {
  $A = function(iterable) {
    if (!iterable) return [];
    // In Safari, only use the `toArray` method if it's not a NodeList.
    // A NodeList is a function, has an function `item` property, and a numeric
    // `length` property. Adapted from Google Doctype.
    if (!(typeof iterable === 'function' && typeof iterable.length ===
        'number' && typeof iterable.item === 'function') && iterable.toArray)
      return iterable.toArray();
    var length = iterable.length || 0, results = new Array(length);
    while (length--) results[length] = iterable[length];
    return results;
  };
}

Array.from = $A;

Object.extend(Array.prototype, Enumerable);

if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;

Object.extend(Array.prototype, {
  _each: function(iterator) {
    for (var i = 0, length = this.length; i < length; i++)
      iterator(this[i]);
  },

  clear: function() {
    this.length = 0;
    return this;
  },

  first: function() {
    return this[0];
  },

  last: function() {
    return this[this.length - 1];
  },

  compact: function() {
    return this.select(function(value) {
      return value != null;
    });
  },

  flatten: function() {
    return this.inject([], function(array, value) {
      return array.concat(Object.isArray(value) ?
        value.flatten() : [value]);
    });
  },

  without: function() {
    var values = $A(arguments);
    return this.select(function(value) {
      return !values.include(value);
    });
  },

  reverse: function(inline) {
    return (inline !== false ? this : this.toArray())._reverse();
  },

  reduce: function() {
    return this.length > 1 ? this : this[0];
  },

  uniq: function(sorted) {
    return this.inject([], function(array, value, index) {
      if (0 == index || (sorted ? array.last() != value : !array.include(value)))
        array.push(value);
      return array;
    });
  },

  intersect: function(array) {
    return this.uniq().findAll(function(item) {
      return array.detect(function(value) { return item === value });
    });
  },

  clone: function() {
    return [].concat(this);
  },

  size: function() {
    return this.length;
  },

  inspect: function() {
    return '[' + this.map(Object.inspect).join(', ') + ']';
  },

  toJSON: function() {
    var results = [];
    this.each(function(object) {
      var value = Object.toJSON(object);
      if (!Object.isUndefined(value)) results.push(value);
    });
    return '[' + results.join(', ') + ']';
  }
});

// use native browser JS 1.6 implementation if available
if (Object.isFunction(Array.prototype.forEach))
  Array.prototype._each = Array.prototype.forEach;

if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) {
  i || (i = 0);
  var length = this.length;
  if (i < 0) i = length + i;
  for (; i < length; i++)
    if (this[i] === item) return i;
  return -1;
};

if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) {
  i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
  var n = this.slice(0, i).reverse().indexOf(item);
  return (n < 0) ? n : i - n - 1;
};

Array.prototype.toArray = Array.prototype.clone;

function $w(string) {
  if (!Object.isString(string)) return [];
  string = string.strip();
  return string ? string.split(/\s+/) : [];
}

if (Prototype.Browser.Opera){
  Array.prototype.concat = function() {
    var array = [];
    for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
    for (var i = 0, length = arguments.length; i < length; i++) {
      if (Object.isArray(arguments[i])) {
        for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
          array.push(arguments[i][j]);
      } else {
        array.push(arguments[i]);
      }
    }
    return array;
  };
}
<commit_msg>Reorganizing array.js source code.<commit_after>function $A(iterable) {
  if (!iterable) return [];
  if (iterable.toArray) return iterable.toArray();
  var length = iterable.length || 0, results = new Array(length);
  while (length--) results[length] = iterable[length];
  return results;
}

if (Prototype.Browser.WebKit) {
  $A = function(iterable) {
    if (!iterable) return [];
    // In Safari, only use the `toArray` method if it's not a NodeList.
    // A NodeList is a function, has an function `item` property, and a numeric
    // `length` property. Adapted from Google Doctype.
    if (!(typeof iterable === 'function' && typeof iterable.length ===
        'number' && typeof iterable.item === 'function') && iterable.toArray)
      return iterable.toArray();
    var length = iterable.length || 0, results = new Array(length);
    while (length--) results[length] = iterable[length];
    return results;
  };
}

function $w(string) {
  if (!Object.isString(string)) return [];
  string = string.strip();
  return string ? string.split(/\s+/) : [];
}

Array.from = $A;

(function() {
  var arrayProto = Array.prototype,
      slice = arrayProto.slice,
      _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available

  function each(iterator) {
    for (var i = 0, length = this.length; i < length; i++)
      iterator(this[i]);
  }
  if (!_each) _each = each;

  function clear() {
    this.length = 0;
    return this;
  }

  function first() {
    return this[0];
  }

  function last() {
    return this[this.length - 1];
  }

  function compact() {
    return this.select(function(value) {
      return value != null;
    });
  }

  function flatten() {
    return this.inject([], function(array, value) {
      if (Object.isArray(value))
        return array.concat(value.flatten());
      array.push(value);
      return array;
    });
  }

  function without() {
    var values = slice.call(arguments, 0);
    return this.select(function(value) {
      return !values.include(value);
    });
  }

  function reverse(inline) {
    return (inline !== false ? this : this.toArray())._reverse();
  }

  function reduce() {
    return this.length > 1 ? this : this[0];
  }

  function uniq(sorted) {
    return this.inject([], function(array, value, index) {
      if (0 == index || (sorted ? array.last() != value : !array.include(value)))
        array.push(value);
      return array;
    });
  }

  function intersect(array) {
    return this.uniq().findAll(function(item) {
      return array.detect(function(value) { return item === value });
    });
  }

  function clone() {
    return slice.call(this, 0);
  }

  function size() {
    return this.length;
  }

  function inspect() {
    return '[' + this.map(Object.inspect).join(', ') + ']';
  }

  function toJSON() {
    var results = [];
    this.each(function(object) {
      var value = Object.toJSON(object);
      if (!Object.isUndefined(value)) results.push(value);
    });
    return '[' + results.join(', ') + ']';
  }

  function indexOf(item, i) {
    i || (i = 0);
    var length = this.length;
    if (i < 0) i = length + i;
    for (; i < length; i++)
      if (this[i] === item) return i;
    return -1;
  }

  function lastIndexOf(item, i) {
    i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
    var n = this.slice(0, i).reverse().indexOf(item);
    return (n < 0) ? n : i - n - 1;
  }

  function concat() {
    var array = [];
    for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
    for (var i = 0, length = arguments.length; i < length; i++) {
      if (Object.isArray(arguments[i])) {
        for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
          array.push(arguments[i][j]);
      } else {
        array.push(arguments[i]);
      }
    }
    return array;
  }

  Object.extend(arrayProto, Enumerable);

  if (!arrayProto._reverse)
    arrayProto._reverse = arrayProto.reverse;

  Object.extend(arrayProto, {
    _each:     _each,
    clear:     clear,
    first:     first,
    last:      last,
    compact:   compact,
    flatten:   flatten,
    without:   without,
    reverse:   reverse,
    reduce:    reduce,
    uniq:      uniq,
    intersect: intersect,
    clone:     clone,
    toArray:   clone,
    size:      size,
    inspect:   inspect,
    toJSON:    toJSON
  });

  // use native browser JS 1.6 implementation if available
  if (!'indexOf'     in arrayProto) arrayProto.indexOf     = indexOf;
  if (!'lastIndexOf' in arrayProto) arrayProto.lastIndexOf = lastIndexOf;
  if (!'concat'      in arrayProto) arrayProto.concat      = concat;
})();
<|endoftext|>


<commit_before>import { warn, isPromise } from './util'

let locales = Object.create(null) // locales store

export default function (Vue) {
  /**
   * Register or retrieve a global locale definition.
   *
   * @param {String} id
   * @param {Object | Function | Promise} definition
   */

  Vue.locale = (id, definition) => {
    if (definition === undefined) { // gettter
      return locales[id]
    } else { // setter
      if (definition === null) {
        locales[id] = undefined
        delete locales[id]
      } else {
        setLocale(id, definition, (locale) => {
          if (locale) {
            locales[id] = locale
          } else {
            warn('failed set `' + id + '` locale')
          }
        })
      }
    }
  }
}

function setLocale (id, definition, cb) {
  if (typeof definition === 'object') { // sync
    cb(definition)
  } else {
    let future = definition.call(this)
    if (typeof future === 'function') {
      if (future.resolved) {
        // cached
        cb(future.resolved)
      } else if (future.requested) {
        // pool callbacks
        future.pendingCallbacks.push(cb)
      } else {
        future.requested = true
        let cbs = future.pendingCallbacks = [cb]
        future((locale) => { // resolve
          future.resolved = locale
          for (let i = 0, l = cbs.length; i < l; i++) {
            cbs[i](locale)
          }
        }, () => { // reject
          cb()
        })
      }
    } else if (isPromise(future)) { // promise
      future.then((locale) => { // resolve
        cb(locale)
      }, () => { // reject
        cb()
      }).catch((err) => {
        console.error(err)
        cb()
      })
    }
  }
}
<commit_msg>chore(asset): add callback argument<commit_after>import { warn, isPromise } from './util'

let locales = Object.create(null) // locales store

export default function (Vue) {
  /**
   * Register or retrieve a global locale definition.
   *
   * @param {String} id
   * @param {Object | Function | Promise} definition
   * @param {Function} cb
   */

  Vue.locale = (id, definition, cb) => {
    if (definition === undefined) { // gettter
      return locales[id]
    } else { // setter
      if (definition === null) {
        locales[id] = undefined
        delete locales[id]
      } else {
        setLocale(id, definition, (locale) => {
          if (locale) {
            locales[id] = locale
            cb && cb()
          } else {
            warn('failed set `' + id + '` locale')
          }
        })
      }
    }
  }
}

function setLocale (id, definition, cb) {
  if (typeof definition === 'object') { // sync
    cb(definition)
  } else {
    let future = definition.call(this)
    if (typeof future === 'function') {
      if (future.resolved) {
        // cached
        cb(future.resolved)
      } else if (future.requested) {
        // pool callbacks
        future.pendingCallbacks.push(cb)
      } else {
        future.requested = true
        let cbs = future.pendingCallbacks = [cb]
        future((locale) => { // resolve
          future.resolved = locale
          for (let i = 0, l = cbs.length; i < l; i++) {
            cbs[i](locale)
          }
        }, () => { // reject
          cb()
        })
      }
    } else if (isPromise(future)) { // promise
      future.then((locale) => { // resolve
        cb(locale)
      }, () => { // reject
        cb()
      }).catch((err) => {
        console.error(err)
        cb()
      })
    }
  }
}
<|endoftext|>


<commit_before>'use strict';
var expr = require( './expr' );
var parse = require( './parse' );
var cartesian = require( 'cartesian' );

const DEFAULTS = {
    max_query_length   : 256,  // maximum string query string length
    max_term_count     : 32,   // maximum number of distinct terms allowed
    max_subquery_count : 8     // maximum number of disjunctive subqueries
};

let assert = {
    subquery_count : ( actual, allowed ) => {
        if ( actual > allowed )
            throw new Error(
                `Query too broad: produces ${actual} subqueries,`
                +  `where ${allowed} are allowed.`
            )
    },
    query_length : ( actual, allowed ) => {
        if ( actual > allowed ) {
            throw new Error(
                `Query too long: query is length ${actual}, `
                + `where ${allowed} is allowed.`
            );
        }
    }
};

/*
    Interface to expose to user: report syntax errors, provide constituent
      queries and answer some aggregate questions about their composition.
*/

module.exports = class query {

    constructor ( raw_query, options ) {

        options = Object.assign( DEFAULTS, options );

        assert.query_length( raw_query.length, options.max_query_length );

        this._raw = raw_query;              // original string query passed
        this._parsed = parse( raw_query );  // parse() result
        this._subqueries = [];              // dissected query, as a list

        // edge case: empty queries
        if ( !this._parsed.getChildren().length )
            return this;

        // represent all queries as a set of disjunctive subqueries
        // e.g. ( "cars" ( "trains" | "planes" ) )
        //    -> ( "cars" "trains" ) OR ( "cars" "planes" )

        if ( this._parsed.getType() === expr.type_ids.disj ) {

            // when parse() returns a disj, we can simply pick apart those terms

            this._subqueries = this._parsed.getChildren().map( ( child ) => {
                return child.isRecursive() ? child : new expr.conj([ child ]);
            } );
            assert.subquery_count(
                this._subqueries.length,
                options.max_subquery_count
            );

        } else {

            // separate the expressions which must occur in all subqueries from
            // the conditional ones

            let conjunctives = this._parsed.getChildren().filter( ( child ) => {
                return child.getType() !== expr.type_ids.disj;
            }).reduce( ( acc, child ) => {
                return acc.concat( child );
            }, [] );

            let disjunctives = this._parsed.getChildren().filter( ( child ) => {
                return child.getType() === expr.type_ids.disj;
            }).map( ( dsj ) => {
                return dsj.getChildren();
            } );

            assert.subquery_count(
                disjunctives.reduce( ( acc, dsj ) => {
                    return acc * dsj.length;
                }, 1 ),
                options.max_subquery_count
            );

            if ( !disjunctives.length ) {

                // if there are no disjunctive terms, there is just one query
                this._subqueries = [ new expr.conj( conjunctives ) ];

            } else {

                // otherwise, the subqueries are the conjunctive terms cat'ed
                // with all combinations of disjunctive terms
                // whether it is truly 'cartesian' is best left to mathematicians

                cartesian( disjunctives ).forEach( ( combo ) => {
                    this._subqueries.push( new expr.conj(
                        conjunctives.concat( combo )
                    ).normalize() );
                } );

            }

            // TODO: canonical subquery ordering?

        }

    }

    toString () {
        return this.toDisjunction().toString( 1 );
    }

    getSubqueries () {
        return this._subqueries;
    }

    toDisjunction () {
        return new expr.disj( this._subqueries );
    }

    // does this query represent all queryable items?
    isUniverse () {

        // empty query takes opposite meaning between 'expr' and 'query':
        //   - an 'expr' with no children is zero set
        //   - a 'query' with no subqueries is the universe

        return (
            !this._subqueries.length ||
            this.toDisjunction().normalize().isUniverse()
        );

    }

    // is this query unsatisfiable?
    isZeroSet () {

        return (
            !this.isUniverse() &&
            this.toDisjunction().normalize().isZeroSet()
        );

    }

};

<commit_msg>Fix: passing options incorrectly mutates defaults<commit_after>'use strict';
var expr = require( './expr' );
var parse = require( './parse' );
var cartesian = require( 'cartesian' );

const DEFAULTS = {
    max_query_length   : 256,  // maximum string query string length
    max_term_count     : 32,   // maximum number of distinct terms allowed
    max_subquery_count : 8     // maximum number of disjunctive subqueries
};

let assert = {
    subquery_count : ( actual, allowed ) => {
        if ( actual > allowed )
            throw new Error(
                `Query too broad: produces ${actual} subqueries,`
                +  `where ${allowed} are allowed.`
            )
    },
    query_length : ( actual, allowed ) => {
        if ( actual > allowed ) {
            throw new Error(
                `Query too long: query is length ${actual}, `
                + `where ${allowed} is allowed.`
            );
        }
    }
};

/*
    Interface to expose to user: report syntax errors, provide constituent
      queries and answer some aggregate questions about their composition.
*/

module.exports = class query {

    constructor ( raw_query, options ) {

        options = Object.assign( {}, DEFAULTS, options );

        assert.query_length( raw_query.length, options.max_query_length );

        this._raw = raw_query;              // original string query passed
        this._parsed = parse( raw_query );  // parse() result
        this._subqueries = [];              // dissected query, as a list

        // edge case: empty queries
        if ( !this._parsed.getChildren().length )
            return this;

        // represent all queries as a set of disjunctive subqueries
        // e.g. ( "cars" ( "trains" | "planes" ) )
        //    -> ( "cars" "trains" ) OR ( "cars" "planes" )

        if ( this._parsed.getType() === expr.type_ids.disj ) {

            // when parse() returns a disj, we can simply pick apart those terms

            this._subqueries = this._parsed.getChildren().map( ( child ) => {
                return child.isRecursive() ? child : new expr.conj([ child ]);
            } );
            assert.subquery_count(
                this._subqueries.length,
                options.max_subquery_count
            );

        } else {

            // separate the expressions which must occur in all subqueries from
            // the conditional ones

            let conjunctives = this._parsed.getChildren().filter( ( child ) => {
                return child.getType() !== expr.type_ids.disj;
            }).reduce( ( acc, child ) => {
                return acc.concat( child );
            }, [] );

            let disjunctives = this._parsed.getChildren().filter( ( child ) => {
                return child.getType() === expr.type_ids.disj;
            }).map( ( dsj ) => {
                return dsj.getChildren();
            } );

            assert.subquery_count(
                disjunctives.reduce( ( acc, dsj ) => {
                    return acc * dsj.length;
                }, 1 ),
                options.max_subquery_count
            );

            if ( !disjunctives.length ) {

                // if there are no disjunctive terms, there is just one query
                this._subqueries = [ new expr.conj( conjunctives ) ];

            } else {

                // otherwise, the subqueries are the conjunctive terms cat'ed
                // with all combinations of disjunctive terms
                // whether it is truly 'cartesian' is best left to mathematicians

                cartesian( disjunctives ).forEach( ( combo ) => {
                    this._subqueries.push( new expr.conj(
                        conjunctives.concat( combo )
                    ).normalize() );
                } );

            }

            // TODO: canonical subquery ordering?

        }

    }

    toString () {
        return this.toDisjunction().toString( 1 );
    }

    getSubqueries () {
        return this._subqueries;
    }

    toDisjunction () {
        return new expr.disj( this._subqueries );
    }

    // does this query represent all queryable items?
    isUniverse () {

        // empty query takes opposite meaning between 'expr' and 'query':
        //   - an 'expr' with no children is zero set
        //   - a 'query' with no subqueries is the universe

        return (
            !this._subqueries.length ||
            this.toDisjunction().normalize().isUniverse()
        );

    }

    // is this query unsatisfiable?
    isZeroSet () {

        return (
            !this.isUniverse() &&
            this.toDisjunction().normalize().isZeroSet()
        );

    }

};

<|endoftext|>


<commit_before>export { filterTags }

function filterTags () {

}
<commit_msg>filterTags() performs AND filter<commit_after>export { filterTags }

import every from 'lodash/collection/every'
import includes from 'lodash/collection/includes'

function filterTags (tags = [], row) {
  if (!tags) // no tags provided, filter nothing
    return true

  const docTags = row.doc.tags || []

  const found = every(tags, t => includes(docTags, t))
  return found
}
<|endoftext|>


<commit_before>jQuery(function ($) {
    $.fn.extend({
        /**
         * Triggers a custom event on an element and returns the event result
         * this is used to get around not being able to ensure callbacks are placed
         * at the end of the chain.
         *
         * TODO: deprecate with jQuery 1.4.2 release, in favor of subscribing to our
         *       own events and placing ourselves at the end of the chain.
         */
        triggerAndReturn: function (name, data) {
            var event = new jQuery.Event(name);
            this.trigger(event, data);

            return event.result !== false;
        },

        /**
         * Handles execution of remote calls firing overridable events along the way
         *
         */
        callRemote: function () {
            var el      = $(this),
                data    = [],
                method  = el.attr('method') || el.attr('data-method') || 'GET',
                url     = el.attr('action') || el.attr('href') || el.attr('data-url');

            if (el.context.tagName.toUpperCase() === 'FORM') {
                data = el.serializeArray();
            }

            // TODO: should let the developer know no url was found
            if (url !== undefined) {
                if (el.triggerAndReturn('ajax:before')) {
                    $.ajax({
                        url: url,
                        data: data,
                        type: method.toUpperCase(),
                        beforeSend: function (xhr) {
                            xhr.setRequestHeader("Accept", "text/javascript");
                            el.trigger('ajax:loading', xhr);
                        },
                        success: function (data, status, xhr) {
                            el.trigger('ajax:success', [data, status, xhr]);
                        },
                        complete: function (xhr) {
                            el.trigger('ajax:complete', xhr);
                        },
                        error: function (xhr, status, error) {
                            el.trigger('ajax:failure', [xhr, status, error]);
                        }
                    });
                }

                el.trigger('ajax:after');
            }
        }
    });

    /**
     *  confirmation handler
     */
    $('a[data-confirm],input[data-confirm]').live('click', function () {
        var el = $(this);
        if (el.triggerAndReturn('confirm')) {
            if (!confirm(el.attr('data-confirm'))) {
                return false;
            }
        }
    });

    /**
     * remote handlers
     */
    $('form[data-remote="true"]').live('submit', function (e) {
        $(this).callRemote();
        e.preventDefault();
    });

    $('a[data-remote="true"],input[data-remote="true"]').live('click', function (e) {
        $(this).callRemote();
        e.preventDefault();
    });

    /**
     * disable_with handlers
     */
    $('input[data-disable-with], form[data-remote="true"]').live('ajax:before', function () {
        var el = $(this);

        // on form submit disable submit button
        if (el.context.tagName.toUpperCase() === 'FORM') {
            el.children('input[data-disable-with]').each(function (i, el) {
                var input = $(el);
                input.data('enable_with', input.val())
                     .attr('value', input.attr('data-disable-with'))
                     .attr('disabled', 'disabled');
            });
        } else {
            el.data('enable_with', el.val())
              .attr('value', el.attr('data-disable-with'))
              .attr('disabled', 'disabled');
        }
    });

    $('input[data-disable-with], form[data-remote="true"]').live('ajax:after', function () {
        var el = $(this);

        if (el.context.tagName.toUpperCase() === 'FORM') {
            el.children('input[data-disable-with]').each(function (i, el) {
                var input = $(el);
                input.removeAttr('disabled')
                     .val(input.data('enable_with'));
            });
        } else {
            el.removeAttr('disabled')
              .val(el.data('enable_with'));
        }
    });
});
<commit_msg>simplify disable_with, and remove data-url, button_to now surrounds the button in a form<commit_after>jQuery(function ($) {
    $.fn.extend({
        /**
         * Triggers a custom event on an element and returns the event result
         * this is used to get around not being able to ensure callbacks are placed
         * at the end of the chain.
         *
         * TODO: deprecate with jQuery 1.4.2 release, in favor of subscribing to our
         *       own events and placing ourselves at the end of the chain.
         */
        triggerAndReturn: function (name, data) {
            var event = new jQuery.Event(name);
            this.trigger(event, data);

            return event.result !== false;
        },

        /**
         * Handles execution of remote calls firing overridable events along the way
         *
         */
        callRemote: function () {
            var el      = $(this),
                data    = [],
                method  = el.attr('method') || el.attr('data-method') || 'GET',
                url     = el.attr('action') || el.attr('href');

            if (el.context.tagName.toUpperCase() === 'FORM') {
                data = el.serializeArray();
            }

            // TODO: should let the developer know no url was found
            if (url !== undefined) {
                if (el.triggerAndReturn('ajax:before')) {
                    $.ajax({
                        url: url,
                        data: data,
                        type: method.toUpperCase(),
                        beforeSend: function (xhr) {
                            xhr.setRequestHeader("Accept", "text/javascript");
                            el.trigger('ajax:loading', xhr);
                        },
                        success: function (data, status, xhr) {
                            el.trigger('ajax:success', [data, status, xhr]);
                        },
                        complete: function (xhr) {
                            el.trigger('ajax:complete', xhr);
                        },
                        error: function (xhr, status, error) {
                            el.trigger('ajax:failure', [xhr, status, error]);
                        }
                    });
                }

                el.trigger('ajax:after');
            }
        }
    });

    /**
     *  confirmation handler
     */
    $('a[data-confirm],input[data-confirm]').live('click', function () {
        var el = $(this);
        if (el.triggerAndReturn('confirm')) {
            if (!confirm(el.attr('data-confirm'))) {
                return false;
            }
        }
    });

    /**
     * remote handlers
     */
    $('form[data-remote="true"]').live('submit', function (e) {
        $(this).callRemote();
        e.preventDefault();
    });

    $('a[data-remote="true"],input[data-remote="true"]').live('click', function (e) {
        $(this).callRemote();
        e.preventDefault();
    });

    /**
     * disable_with handlers
     */
    $('form[data-remote="true"]').live('ajax:before', function () {
        $(this).children('input[data-disable-with]').each(function (i, el) {
            var input = $(el);
            input.data('enable_with', input.val())
                 .attr('value', input.attr('data-disable-with'))
                 .attr('disabled', 'disabled');
        });
    });

    $('form[data-remote="true"]').live('ajax:after', function () {
        $(this).children('input[data-disable-with]').each(function (i, el) {
            var input = $(el);
            input.removeAttr('disabled')
                 .val(input.data('enable_with'));
        });
    });
});
<|endoftext|>


<commit_before>'use strict';

// First, check for JSON support
// If there is no JSON, we no-op the core features of Raven
// since JSON is required to encode the payload
var _Raven = window.Raven,
    hasJSON = !!(window.JSON && window.JSON.stringify),
    globalServer,
    globalUser,
    globalKey,
    globalProject,
    globalOptions = {
        logger: 'javascript',
        ignoreErrors: [],
        ignoreUrls: [],
        whitelistUrls: [],
        includePaths: [],
        tags: {}
    };

var TK = TraceKit.noConflict();

// Disable Tracekit's remote fetching by default
TK.remoteFetching = false;

/*
 * The core Raven singleton
 *
 * @this {Raven}
 */
var Raven = {
    VERSION: '@VERSION',

    /*
     * Allow Raven to be configured as soon as it is loaded
     * It uses a global RavenConfig = {dsn: '...', config: {}}
     *
     * @return undefined
     */
    afterLoad: function() {
        var globalConfig = window.RavenConfig;
        if (globalConfig) {
            this.config(globalConfig.dsn, globalConfig.config).install();
        }
    },

    /*
     * Allow multiple versions of Raven to be installed.
     * Strip Raven from the global context and returns the instance.
     *
     * @return {Raven}
     */
    noConflict: function() {
        window.Raven = _Raven;
        return Raven;
    },

    /*
     * Configure Raven with a DSN and extra options
     *
     * @param {string} dsn The public Sentry DSN
     * @param {object} options Optional set of of global options [optional]
     * @return {Raven}
     */
    config: function(dsn, options) {
        var uri = parseUri(dsn),
            lastSlash = uri.path.lastIndexOf('/'),
            path = uri.path.substr(1, lastSlash);

        // merge in options
        if (options) {
            each(options, function(key, value){
                globalOptions[key] = value;
            });
        }

        // join regexp rules into one big rule
        globalOptions.ignoreUrls = globalOptions.ignoreUrls.length ? joinRegExp(globalOptions.ignoreUrls) : false;
        globalOptions.whitelistUrls = globalOptions.whitelistUrls.length ? joinRegExp(globalOptions.whitelistUrls) : false;
        globalOptions.includePaths = joinRegExp(globalOptions.includePaths);

        // "Script error." is hard coded into browsers for errors that it can't read.
        // this is the result of a script being pulled in from an external domain and CORS.
        globalOptions.ignoreErrors.push('Script error.');

        globalKey = uri.user;
        globalProject = ~~uri.path.substr(lastSlash + 1);

        // assemble the endpoint from the uri pieces
        globalServer = '//' + uri.host +
                      (uri.port ? ':' + uri.port : '') +
                      '/' + path + 'api/' + globalProject + '/store/';

        if (uri.protocol) {
            globalServer = uri.protocol + ':' + globalServer;
        }

        if (globalOptions.fetchContext) {
            TK.remoteFetching = true;
        }

        // return for chaining
        return Raven;
    },

    /*
     * Installs a global window.onerror error handler
     * to capture and report uncaught exceptions.
     * At this point, install() is required to be called due
     * to the way TraceKit is set up.
     *
     * @return {Raven}
     */
    install: function() {
        if (!isSetup()) return;

        TK.report.subscribe(handleStackInfo);

        return Raven;
    },

    /*
     * Wrap code within a context so Raven can capture errors
     * reliably across domains that is executed immediately.
     *
     * @param {object} options A specific set of options for this context [optional]
     * @param {function} func The callback to be immediately executed within the context
     * @param {array} args An array of arguments to be called with the callback [optional]
     */
    context: function(options, func, args) {
        if (isFunction(options)) {
            args = func || [];
            func = options;
            options = undefined;
        }

        Raven.wrap(options, func).apply(this, args);
    },

    /*
     * Wrap code within a context and returns back a new function to be executed
     *
     * @param {object} options A specific set of options for this context [optional]
     * @param {function} func The function to be wrapped in a new context
     * @return {function} The newly wrapped functions with a context
     */
    wrap: function(options, func) {
        // options is optional
        if (isFunction(options)) {
            func = options;
            options = undefined;
        }

        return function() {
            try {
                return func.apply(this, arguments);
            } catch(e) {
                Raven.captureException(e, options);
                throw e;
            }
        };
    },

    /*
     * Uninstalls the global error handler.
     *
     * @return {Raven}
     */
    uninstall: function() {
        TK.report.unsubscribe(handleStackInfo);

        return Raven;
    },

    /*
     * Manually capture an exception and send it over to Sentry
     *
     * @param {error} ex An exception to be logged
     * @param {object} options A specific set of options for this error [optional]
     * @return {Raven}
     */
    captureException: function(ex, options) {
        // If a string is passed through, recall as a message
        if (typeof ex === 'string') {
            return Raven.captureMessage(ex, options);
        }

        // TraceKit.report will re-raise any exception passed to it,
        // which means you have to wrap it in try/catch. Instead, we
        // can wrap it here and only re-raise if TraceKit.report
        // raises an exception different from the one we asked to
        // report on.
        try {
            TK.report(ex, options);
        } catch(ex1) {
            if(ex !== ex1) {
                throw ex1;
            }
        }

        return Raven;
    },

    /*
     * Manually send a message to Sentry
     *
     * @param {string} msg A plain message to be captured in Sentry
     * @param {object} options A specific set of options for this message [optional]
     * @return {Raven}
     */
    captureMessage: function(msg, options) {
        // Fire away!
        send(
            arrayMerge({
                message: msg
            }, options)
        );

        return Raven;
    },

    /*
     * Set/clear a user to be sent along with the payload.
     *
     * @param {object} user An object representing user data [optional]
     * @return {Raven}
     */
    setUser: function(user) {
       globalUser = user;

       return Raven;
    }
};

function triggerEvent(eventType, options) {
    var event, key;

    eventType = 'raven' + eventType[0].toUpperCase() + eventType.substr(1);

    if (document.createEvent) {
        event = document.createEvent('HTMLEvents');
        event.initEvent(eventType, true, true);
    } else {
        event = document.createEventObject();
        event.eventType = eventType;
    }

    if (typeof options !== 'object') {
        options = {};
    }

    for (key in options) if (options.hasOwnProperty(key)) {
        event[key] = options[key];
    }

    if (document.createEvent) {
        document.dispatchEvent(event);
    } else {
        document.fireEvent('on' + event.eventType.toLowerCase(), event);
    }
}

var uriKeys = 'source protocol authority userInfo user password host port relative path directory file query anchor'.split(' '),
    uriPattern = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;

/**** Private functions ****/
function parseUri(str) {
    var m = uriPattern.exec(str),
        uri = {},
        i = 14;

    while (i--) uri[uriKeys[i]] = m[i] || '';

    return uri;
}

function isUndefined(what) {
    return typeof what === 'undefined';
}

function isFunction(what) {
    return typeof what === 'function';
}

function each(obj, callback) {
    var i, j;

    if (isUndefined(obj.length)) {
        for (i in obj) {
            if (obj.hasOwnProperty(i)) {
                callback.call(null, i, obj[i]);
            }
        }
    } else {
        j = obj.length;
        if (j) {
            for (i = 0; i < j; i++) {
                callback.call(null, i, obj[i]);
            }
        }
    }
}

var cachedAuth;

function getAuthQueryString() {
    if (cachedAuth) return cachedAuth;

    var qs = [
        'sentry_version=3',
        'sentry_client=raven-js/' + Raven.VERSION
    ];
    if (globalKey) {
        qs.push('sentry_key=' + globalKey);
    }

    cachedAuth = '?' + qs.join('&');
    return cachedAuth;
}

function handleStackInfo(stackInfo, options) {
    var frames = [];

    if (stackInfo.stack && stackInfo.stack.length) {
        each(stackInfo.stack, function(i, stack) {
            var frame = normalizeFrame(stack);
            if (frame) {
                frames.push(frame);
            }
        });
    }

    triggerEvent('handle', {
        stackInfo: stackInfo,
        options: options
    });

    processException(
        stackInfo.name,
        stackInfo.message,
        stackInfo.url,
        stackInfo.lineno,
        frames,
        options
    );
}

function normalizeFrame(frame) {
    if (!frame.url) return;

    // normalize the frames data
    var normalized = {
        filename:   frame.url,
        lineno:     frame.line,
        colno:      frame.column,
        'function': frame.func || '?'
    }, context = extractContextFromFrame(frame), i;

    if (context) {
        var keys = ['pre_context', 'context_line', 'post_context'];
        i = 3;
        while (i--) normalized[keys[i]] = context[i];
    }

    normalized.in_app = !( // determine if an exception came from outside of our app
        // first we check the global includePaths list.
        !globalOptions.includePaths.test(normalized.filename) ||
        // Now we check for fun, if the function name is Raven or TraceKit
        /(Raven|TraceKit)\./.test(normalized['function']) ||
        // finally, we do a last ditch effort and check for raven.min.js
        /raven\.(min\.)js$/.test(normalized.filename)
    );

    return normalized;
}

function extractContextFromFrame(frame) {
    // immediately check if we should even attempt to parse a context
    if (!frame.context || !globalOptions.fetchContext) return;

    var context = frame.context,
        pivot = ~~(context.length / 2),
        i = context.length, isMinified = false;

    while (i--) {
        // We're making a guess to see if the source is minified or not.
        // To do that, we make the assumption if *any* of the lines passed
        // in are greater than 300 characters long, we bail.
        // Sentry will see that there isn't a context
        if (context[i].length > 300) {
            isMinified = true;
            break;
        }
    }

    if (isMinified) {
        // The source is minified and we don't know which column. Fuck it.
        if (isUndefined(frame.column)) return;

        // If the source is minified and has a frame column
        // we take a chunk of the offending line to hopefully shed some light
        return [
            [],  // no pre_context
            context[pivot].substr(frame.column, 50), // grab 50 characters, starting at the offending column
            []   // no post_context
        ];
    }

    return [
        context.slice(0, pivot),    // pre_context
        context[pivot],             // context_line
        context.slice(pivot + 1)    // post_context
    ];
}

function processException(type, message, fileurl, lineno, frames, options) {
    var stacktrace, label, i;

    // IE8 really doesn't have Array.prototype.indexOf
    // Filter out a message that matches our ignore list
    i = globalOptions.ignoreErrors.length;
    while (i--) {
        if (message === globalOptions.ignoreErrors[i]) {
            return;
        }
    }

    if (frames && frames.length) {
        stacktrace = {frames: frames};
        fileurl = fileurl || frames[0].filename;
    } else if (fileurl) {
        stacktrace = {
            frames: [{
                filename: fileurl,
                lineno: lineno
            }]
        };
    }

    if (globalOptions.ignoreUrls && globalOptions.ignoreUrls.test(fileurl)) return;
    if (globalOptions.whitelistUrls && !globalOptions.whitelistUrls.test(fileurl)) return;

    label = lineno ? message + ' at ' + lineno : message;

    // Fire away!
    send(
        arrayMerge({
            'sentry.interfaces.Exception': {
                type: type,
                value: message
            },
            'sentry.interfaces.Stacktrace': stacktrace,
            culprit: fileurl,
            message: label
        }, options)
    );
}

function arrayMerge(arr1, arr2) {
    if (!arr2) {
        return arr1;
    }
    each(arr2, function(key, value){
        arr1[key] = value;
    });
    return arr1;
}

function getHttpData() {
    var http = {
        url: document.location.href,
        headers: {
            'User-Agent': navigator.userAgent
        }
    };

    if (document.referrer) {
        http.headers.Referer = document.referrer;
    }

    return http;
}

function send(data) {
    if (!isSetup()) return;

    data = arrayMerge({
        project: globalProject,
        logger: globalOptions.logger,
        site: globalOptions.site,
        platform: 'javascript',
        'sentry.interfaces.Http': getHttpData()
    }, data);

    // Merge in the tags separately since arrayMerge doesn't handle a deep merge
    data.tags = arrayMerge(globalOptions.tags, data.tags);

    // If there are no tags, strip the key from the payload alltogther.
    if (!data.tags) delete data.tags;

    if (globalUser) data['sentry.interfaces.User'] = globalUser;

    if (isFunction(globalOptions.dataCallback)) {
        data = globalOptions.dataCallback(data);
    }

    // Check if the request should be filtered or not
    if (isFunction(globalOptions.shouldSendCallback) && !globalOptions.shouldSendCallback(data)) {
        return;
    }

    makeRequest(data);
}

function makeRequest(data) {
    var img, src;

    function success() {
        triggerEvent('success', {
            data: data,
            src: src
        });
    }

    function failure() {
        triggerEvent('failure', {
            data: data,
            src: src
        });
    }

    src = globalServer + getAuthQueryString() + '&sentry_data=' + encodeURIComponent(JSON.stringify(data));
    img = new Image();
    img.onload = success;
    img.onerror = failure;
    img.onabort = failure;
    img.src = src;
}

function isSetup() {
    if (!hasJSON) return false;  // needs JSON support
    if (!globalServer) {
        if (window.console && console.error) {
            console.error("Error: Raven has not been configured.");
        }
        return false;
    }
    return true;
}

function wrapArguments(what) {
    if (!isFunction(what)) return what;

    function wrapped() {
        var args = [], i = arguments.length, arg;
        while(i--) {
            arg = arguments[i];
            args[i] = isFunction(arg) ? Raven.wrap(arg) : arg;
        }
        what.apply(null, args);
    }
    // copy over properties of the old function
    for (var k in what) wrapped[k] = what[k];
    return wrapped;
}

function joinRegExp(patterns) {
    // Combine an array of regular expressions into one large regexp
    var sources = [], i = patterns.length;
    // lol, map
    while (i--) sources[i] = patterns[i].source;
    return new RegExp(sources.join('|'), 'i');
}

Raven.afterLoad();
<commit_msg>handle some quirks mode issues IE8 and 9 do not support array-style string parsing in quirks mode: "abcdef"[0] returns "" whereas "abcdef".substr(0,1) returns "a" document.fireEvent() returns "Invalid argument" regardless of the parameters sent to it. This happens in IE8 and IE9 in quirks mode.<commit_after>'use strict';

// First, check for JSON support
// If there is no JSON, we no-op the core features of Raven
// since JSON is required to encode the payload
var _Raven = window.Raven,
    hasJSON = !!(window.JSON && window.JSON.stringify),
    globalServer,
    globalUser,
    globalKey,
    globalProject,
    globalOptions = {
        logger: 'javascript',
        ignoreErrors: [],
        ignoreUrls: [],
        whitelistUrls: [],
        includePaths: [],
        tags: {}
    };

var TK = TraceKit.noConflict();

// Disable Tracekit's remote fetching by default
TK.remoteFetching = false;

/*
 * The core Raven singleton
 *
 * @this {Raven}
 */
var Raven = {
    VERSION: '@VERSION',

    /*
     * Allow Raven to be configured as soon as it is loaded
     * It uses a global RavenConfig = {dsn: '...', config: {}}
     *
     * @return undefined
     */
    afterLoad: function() {
        var globalConfig = window.RavenConfig;
        if (globalConfig) {
            this.config(globalConfig.dsn, globalConfig.config).install();
        }
    },

    /*
     * Allow multiple versions of Raven to be installed.
     * Strip Raven from the global context and returns the instance.
     *
     * @return {Raven}
     */
    noConflict: function() {
        window.Raven = _Raven;
        return Raven;
    },

    /*
     * Configure Raven with a DSN and extra options
     *
     * @param {string} dsn The public Sentry DSN
     * @param {object} options Optional set of of global options [optional]
     * @return {Raven}
     */
    config: function(dsn, options) {
        var uri = parseUri(dsn),
            lastSlash = uri.path.lastIndexOf('/'),
            path = uri.path.substr(1, lastSlash);

        // merge in options
        if (options) {
            each(options, function(key, value){
                globalOptions[key] = value;
            });
        }

        // join regexp rules into one big rule
        globalOptions.ignoreUrls = globalOptions.ignoreUrls.length ? joinRegExp(globalOptions.ignoreUrls) : false;
        globalOptions.whitelistUrls = globalOptions.whitelistUrls.length ? joinRegExp(globalOptions.whitelistUrls) : false;
        globalOptions.includePaths = joinRegExp(globalOptions.includePaths);

        // "Script error." is hard coded into browsers for errors that it can't read.
        // this is the result of a script being pulled in from an external domain and CORS.
        globalOptions.ignoreErrors.push('Script error.');

        globalKey = uri.user;
        globalProject = ~~uri.path.substr(lastSlash + 1);

        // assemble the endpoint from the uri pieces
        globalServer = '//' + uri.host +
                      (uri.port ? ':' + uri.port : '') +
                      '/' + path + 'api/' + globalProject + '/store/';

        if (uri.protocol) {
            globalServer = uri.protocol + ':' + globalServer;
        }

        if (globalOptions.fetchContext) {
            TK.remoteFetching = true;
        }

        // return for chaining
        return Raven;
    },

    /*
     * Installs a global window.onerror error handler
     * to capture and report uncaught exceptions.
     * At this point, install() is required to be called due
     * to the way TraceKit is set up.
     *
     * @return {Raven}
     */
    install: function() {
        if (!isSetup()) return;

        TK.report.subscribe(handleStackInfo);

        return Raven;
    },

    /*
     * Wrap code within a context so Raven can capture errors
     * reliably across domains that is executed immediately.
     *
     * @param {object} options A specific set of options for this context [optional]
     * @param {function} func The callback to be immediately executed within the context
     * @param {array} args An array of arguments to be called with the callback [optional]
     */
    context: function(options, func, args) {
        if (isFunction(options)) {
            args = func || [];
            func = options;
            options = undefined;
        }

        Raven.wrap(options, func).apply(this, args);
    },

    /*
     * Wrap code within a context and returns back a new function to be executed
     *
     * @param {object} options A specific set of options for this context [optional]
     * @param {function} func The function to be wrapped in a new context
     * @return {function} The newly wrapped functions with a context
     */
    wrap: function(options, func) {
        // options is optional
        if (isFunction(options)) {
            func = options;
            options = undefined;
        }

        return function() {
            try {
                return func.apply(this, arguments);
            } catch(e) {
                Raven.captureException(e, options);
                throw e;
            }
        };
    },

    /*
     * Uninstalls the global error handler.
     *
     * @return {Raven}
     */
    uninstall: function() {
        TK.report.unsubscribe(handleStackInfo);

        return Raven;
    },

    /*
     * Manually capture an exception and send it over to Sentry
     *
     * @param {error} ex An exception to be logged
     * @param {object} options A specific set of options for this error [optional]
     * @return {Raven}
     */
    captureException: function(ex, options) {
        // If a string is passed through, recall as a message
        if (typeof ex === 'string') {
            return Raven.captureMessage(ex, options);
        }

        // TraceKit.report will re-raise any exception passed to it,
        // which means you have to wrap it in try/catch. Instead, we
        // can wrap it here and only re-raise if TraceKit.report
        // raises an exception different from the one we asked to
        // report on.
        try {
            TK.report(ex, options);
        } catch(ex1) {
            if(ex !== ex1) {
                throw ex1;
            }
        }

        return Raven;
    },

    /*
     * Manually send a message to Sentry
     *
     * @param {string} msg A plain message to be captured in Sentry
     * @param {object} options A specific set of options for this message [optional]
     * @return {Raven}
     */
    captureMessage: function(msg, options) {
        // Fire away!
        send(
            arrayMerge({
                message: msg
            }, options)
        );

        return Raven;
    },

    /*
     * Set/clear a user to be sent along with the payload.
     *
     * @param {object} user An object representing user data [optional]
     * @return {Raven}
     */
    setUser: function(user) {
       globalUser = user;

       return Raven;
    }
};

function triggerEvent(eventType, options) {
    var event, key;

    eventType = 'raven' + eventType.substr(0,1).toUpperCase() + eventType.substr(1);

    if (document.createEvent) {
        event = document.createEvent('HTMLEvents');
        event.initEvent(eventType, true, true);
    } else {
        event = document.createEventObject();
        event.eventType = eventType;
    }

    if (typeof options !== 'object') {
        options = {};
    }

    for (key in options) if (options.hasOwnProperty(key)) {
        event[key] = options[key];
    }

    if (document.createEvent) {
        // IE9 if standards
        document.dispatchEvent(event);
    } else {
        // IE8 regardless of Quirks or Standards
        // IE9 if quirks
        try {
            document.fireEvent('on' + event.eventType.toLowerCase(), event);
        } catch(e) {}
    }
}

var uriKeys = 'source protocol authority userInfo user password host port relative path directory file query anchor'.split(' '),
    uriPattern = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;

/**** Private functions ****/
function parseUri(str) {
    var m = uriPattern.exec(str),
        uri = {},
        i = 14;

    while (i--) uri[uriKeys[i]] = m[i] || '';

    return uri;
}

function isUndefined(what) {
    return typeof what === 'undefined';
}

function isFunction(what) {
    return typeof what === 'function';
}

function each(obj, callback) {
    var i, j;

    if (isUndefined(obj.length)) {
        for (i in obj) {
            if (obj.hasOwnProperty(i)) {
                callback.call(null, i, obj[i]);
            }
        }
    } else {
        j = obj.length;
        if (j) {
            for (i = 0; i < j; i++) {
                callback.call(null, i, obj[i]);
            }
        }
    }
}

var cachedAuth;

function getAuthQueryString() {
    if (cachedAuth) return cachedAuth;

    var qs = [
        'sentry_version=3',
        'sentry_client=raven-js/' + Raven.VERSION
    ];
    if (globalKey) {
        qs.push('sentry_key=' + globalKey);
    }

    cachedAuth = '?' + qs.join('&');
    return cachedAuth;
}

function handleStackInfo(stackInfo, options) {
    var frames = [];

    if (stackInfo.stack && stackInfo.stack.length) {
        each(stackInfo.stack, function(i, stack) {
            var frame = normalizeFrame(stack);
            if (frame) {
                frames.push(frame);
            }
        });
    }

    triggerEvent('handle', {
        stackInfo: stackInfo,
        options: options
    });

    processException(
        stackInfo.name,
        stackInfo.message,
        stackInfo.url,
        stackInfo.lineno,
        frames,
        options
    );
}

function normalizeFrame(frame) {
    if (!frame.url) return;

    // normalize the frames data
    var normalized = {
        filename:   frame.url,
        lineno:     frame.line,
        colno:      frame.column,
        'function': frame.func || '?'
    }, context = extractContextFromFrame(frame), i;

    if (context) {
        var keys = ['pre_context', 'context_line', 'post_context'];
        i = 3;
        while (i--) normalized[keys[i]] = context[i];
    }

    normalized.in_app = !( // determine if an exception came from outside of our app
        // first we check the global includePaths list.
        !globalOptions.includePaths.test(normalized.filename) ||
        // Now we check for fun, if the function name is Raven or TraceKit
        /(Raven|TraceKit)\./.test(normalized['function']) ||
        // finally, we do a last ditch effort and check for raven.min.js
        /raven\.(min\.)js$/.test(normalized.filename)
    );

    return normalized;
}

function extractContextFromFrame(frame) {
    // immediately check if we should even attempt to parse a context
    if (!frame.context || !globalOptions.fetchContext) return;

    var context = frame.context,
        pivot = ~~(context.length / 2),
        i = context.length, isMinified = false;

    while (i--) {
        // We're making a guess to see if the source is minified or not.
        // To do that, we make the assumption if *any* of the lines passed
        // in are greater than 300 characters long, we bail.
        // Sentry will see that there isn't a context
        if (context[i].length > 300) {
            isMinified = true;
            break;
        }
    }

    if (isMinified) {
        // The source is minified and we don't know which column. Fuck it.
        if (isUndefined(frame.column)) return;

        // If the source is minified and has a frame column
        // we take a chunk of the offending line to hopefully shed some light
        return [
            [],  // no pre_context
            context[pivot].substr(frame.column, 50), // grab 50 characters, starting at the offending column
            []   // no post_context
        ];
    }

    return [
        context.slice(0, pivot),    // pre_context
        context[pivot],             // context_line
        context.slice(pivot + 1)    // post_context
    ];
}

function processException(type, message, fileurl, lineno, frames, options) {
    var stacktrace, label, i;

    // IE8 really doesn't have Array.prototype.indexOf
    // Filter out a message that matches our ignore list
    i = globalOptions.ignoreErrors.length;
    while (i--) {
        if (message === globalOptions.ignoreErrors[i]) {
            return;
        }
    }

    if (frames && frames.length) {
        stacktrace = {frames: frames};
        fileurl = fileurl || frames[0].filename;
    } else if (fileurl) {
        stacktrace = {
            frames: [{
                filename: fileurl,
                lineno: lineno
            }]
        };
    }

    if (globalOptions.ignoreUrls && globalOptions.ignoreUrls.test(fileurl)) return;
    if (globalOptions.whitelistUrls && !globalOptions.whitelistUrls.test(fileurl)) return;

    label = lineno ? message + ' at ' + lineno : message;

    // Fire away!
    send(
        arrayMerge({
            'sentry.interfaces.Exception': {
                type: type,
                value: message
            },
            'sentry.interfaces.Stacktrace': stacktrace,
            culprit: fileurl,
            message: label
        }, options)
    );
}

function arrayMerge(arr1, arr2) {
    if (!arr2) {
        return arr1;
    }
    each(arr2, function(key, value){
        arr1[key] = value;
    });
    return arr1;
}

function getHttpData() {
    var http = {
        url: document.location.href,
        headers: {
            'User-Agent': navigator.userAgent
        }
    };

    if (document.referrer) {
        http.headers.Referer = document.referrer;
    }

    return http;
}

function send(data) {
    if (!isSetup()) return;

    data = arrayMerge({
        project: globalProject,
        logger: globalOptions.logger,
        site: globalOptions.site,
        platform: 'javascript',
        'sentry.interfaces.Http': getHttpData()
    }, data);

    // Merge in the tags separately since arrayMerge doesn't handle a deep merge
    data.tags = arrayMerge(globalOptions.tags, data.tags);

    // If there are no tags, strip the key from the payload alltogther.
    if (!data.tags) delete data.tags;

    if (globalUser) data['sentry.interfaces.User'] = globalUser;

    if (isFunction(globalOptions.dataCallback)) {
        data = globalOptions.dataCallback(data);
    }

    // Check if the request should be filtered or not
    if (isFunction(globalOptions.shouldSendCallback) && !globalOptions.shouldSendCallback(data)) {
        return;
    }

    makeRequest(data);
}

function makeRequest(data) {
    var img, src;

    function success() {
        triggerEvent('success', {
            data: data,
            src: src
        });
    }

    function failure() {
        triggerEvent('failure', {
            data: data,
            src: src
        });
    }

    src = globalServer + getAuthQueryString() + '&sentry_data=' + encodeURIComponent(JSON.stringify(data));
    img = new Image();
    img.onload = success;
    img.onerror = failure;
    img.onabort = failure;
    img.src = src;
}

function isSetup() {
    if (!hasJSON) return false;  // needs JSON support
    if (!globalServer) {
        if (window.console && console.error) {
            console.error("Error: Raven has not been configured.");
        }
        return false;
    }
    return true;
}

function wrapArguments(what) {
    if (!isFunction(what)) return what;

    function wrapped() {
        var args = [], i = arguments.length, arg;
        while(i--) {
            arg = arguments[i];
            args[i] = isFunction(arg) ? Raven.wrap(arg) : arg;
        }
        what.apply(null, args);
    }
    // copy over properties of the old function
    for (var k in what) wrapped[k] = what[k];
    return wrapped;
}

function joinRegExp(patterns) {
    // Combine an array of regular expressions into one large regexp
    var sources = [], i = patterns.length;
    // lol, map
    while (i--) sources[i] = patterns[i].source;
    return new RegExp(sources.join('|'), 'i');
}

Raven.afterLoad();
<|endoftext|>


<commit_before>// ngaro module
var ngaro = require('./ngaro.js');
// node modules
var fs = require('fs');
var path = require('path');

//ngaro.setImage(); -will need to add this to ngaro
//ngaro.rxProcessImage();

// start retro.js
if (require.main === module) {
    run();
}

function getInputs(inputs){

    var a = 0;
    if(inputs[-1] != 0){
    }

    return a;
}

function dump(){

    var vmImage = convertArray(ngaro.ram.image);
    console.log(vmImage.join("|"));
    var addressArray = convertArray(ngaro.address.data);
    console.log(addressArray.join("|"));
    var dataArray = convertArray(ngaro.data.data);
    console.log(dataArray.join("|"));
}

function convertArray(typedArray){
    var newArray = [];
    for(var i = 0; i < typedArray.length; i++){
        newArray.push(typedArray[i]);
    }
    return newArray;
}

function run(){

    var imageFile;
    var imageFileCheck;
    var dump_after = false;

    var list = new Array();

    var num = 2;
    while (num < process.argv.length){
        var args = process.argv[num];
        if (args === '--with') {
            num++;
            //list.append( //file );
        } else if (args === '--dump'){
            dump_after = true;
        } else if (args === '--image'){
            num++;
            args = process.argv[num];
            imageFileCheck = fs.existsSync(args,function(exists){});
            if(imageFileCheck){
                imageFile = args;
            } else {
                console.log('File not found');
                process.exit(2);
            }
        }
        num++;
    }

    if(!imageFile) {
        imageFile = path.resolve(__dirname,'retro-11.5.img');
    }

    var fileInfo = fs.statSync(imageFile);
    var cells = Math.ceil(fileInfo.size/4);

    var imageArray = new Array();
    var fd = fs.openSync(imageFile,'r');
    if (!fd) {
        console.log('Unable to open file');
    } else {
        var bufsize = cells*4;
        var buffer = new Buffer(bufsize);
        fs.readSync(fd,buffer,0,bufsize,0);
        for (var i = 0; i < cells; i++) {
            imageArray[i] = buffer.readInt32LE(i*4);
        }
        fs.close(fd);
        //ngaro.image = imageArray;

        ngaro.setImage(imageArray);
        ngaro.rxProcessImage();
    }

    if(!dump_after){
       //stuff
    } else {
       // need to pass arrays to dump
       dump();
    }
}
<commit_msg>removed placeholder comments. cleaned up code layout.<commit_after>// ngaro module
var ngaro = require('./ngaro.js');
// node modules
var fs = require('fs');
var path = require('path');

// start retro.js
if (require.main === module) {
    run();
}

function dump(){

    var dumpArray = convertArray(ngaro.ram.image);
    console.log(dumpArray.join("|"));
    dumpArray = convertArray(ngaro.address.data);
    console.log(dumpArray.join("|"));
    dumpArray = convertArray(ngaro.data.data);
    console.log(dumpArray.join("|"));
}

function convertArray(typedArray){

    var newArray = [];
    for(var i = 0; i < typedArray.length; i++){
        newArray.push(typedArray[i]);
    }
    return newArray;
}

function run(){

    var imageFile;
    var imageFileCheck;
    var dump_after = false;
    var num = 2;

    while (num < process.argv.length){
        var args = process.argv[num];
        if (args === '--with') {
            //needs implementation
        } else if (args === '--dump'){
            dump_after = true;
        } else if (args === '--image'){
            num++;
            args = process.argv[num];
            imageFileCheck = fs.existsSync(args,function(exists){});
            if(imageFileCheck){
                imageFile = args;
            } else {
                console.log('File not found');
                process.exit(2);
            }
        }
        num++;
    }

    if(!imageFile) {
        imageFile = path.resolve(__dirname,'retro-11.5.img');
    }

    var fileInfo = fs.statSync(imageFile);
    var cells = Math.ceil(fileInfo.size/4);
    var imageArray = new Array();
    var fd = fs.openSync(imageFile,'r');

    if (!fd) {
        console.log('Unable to open file');
    } else {
        var bufsize = cells*4;
        var buffer = new Buffer(bufsize);
        fs.readSync(fd,buffer,0,bufsize,0);
        for (var i = 0; i < cells; i++) {
            imageArray[i] = buffer.readInt32LE(i*4);
        }
        fs.close(fd);
        ngaro.setImage(imageArray);
        ngaro.rxProcessImage();
    }

    if(!dump_after){
       //do other stuff
    } else {
       dump();
    }
}
<|endoftext|>


<commit_before>function Board() {
}

Board.prototype.width= function() {
    return 10;
}
<commit_msg>Added Board.height()<commit_after>function Board() {
}

Board.prototype.width= function() {
    return 10;
}

Board.prototype.height= function() {
    return 10;
}
<|endoftext|>