<commit_before>
'use strict';

const config = require('./config');

const computeSB = require('./holdem/get-smallblind-amount');
const assignDB = require('./holdem/assign-dealer-button');
const payBlinds = require('./holdem/pay-blinds');
const shuffleCards = require('./holdem/shuffle-cards');
const assignCards = require('./holdem/assign-player-cards');

exports = module.exports = function setup(gs){

  // prepare a poker hand, so that it can be played...

  //
  // wait a few time after an hand is completed
  // before a new one can start
  return new Promise(function(res, rej){
    setTimeout(function() {

      let hasBB = Symbol.for('hasBB');

      //
      // 0) reset initial conditions

      // the amount of chips bet by all the players
      gs.pot = 0;

      // the amount of chips each player must bet
      // to continue to be "active" in the current hand
      gs.callAmount = 0;

      // the cards on the table
      gs.community_cards = [];

      gs.players.forEach(player => { player[hasBB] = false; player.chipsBet = 0; });

      //
      // 1) compute the small blind level for the current hand
      // big blinds is always the double

      gs.sb = computeSB(gs);

      //
      // 2) assign to the player in turn the dealer button
      // only active player can receive the button

      assignDB(gs);

      //
      // 3) pay small/big blinds
      // and updates players/table's chips

      payBlinds(gs);

      //
      // 4) prepare a random sorted deck of cards
      // i'm using Fisher–Yates algorithm to achieve 'randomness'

      let deck = gs._deck = shuffleCards();

      //
      // 5) assign two cards to each active player
      // first player who receive a card is the one next the dealer button
      res(assignCards(gs, deck));

    }, config.HANDWAIT);
  });

};
<commit_msg>reset folded during setup<commit_after>
'use strict';

const config = require('./config');

const status = require('./domain/player-status');

const computeSB = require('./holdem/get-smallblind-amount');
const assignDB = require('./holdem/assign-dealer-button');
const payBlinds = require('./holdem/pay-blinds');
const shuffleCards = require('./holdem/shuffle-cards');
const assignCards = require('./holdem/assign-player-cards');

exports = module.exports = function setup(gs){

  // prepare a poker hand, so that it can be played...

  //
  // wait a few time after an hand is completed
  // before a new one can start
  return new Promise(function(res, rej){
    setTimeout(function() {

      let hasBB = Symbol.for('hasBB');

      //
      // 0) reset initial conditions

      // the amount of chips bet by all the players
      gs.pot = 0;

      // the amount of chips each player must bet
      // to continue to be "active" in the current hand
      gs.callAmount = 0;

      // the cards on the table
      gs.community_cards = [];

      // reset player conditions
      gs.players.forEach(player => {
        player[hasBB] = false;
        player.chipsBet = 0;
        player.cards = [];
        if (player.status == status.folded){
          player.status = status.active;
        }
      });

      //
      // 1) compute the small blind level for the current hand
      // big blinds is always the double

      gs.sb = computeSB(gs);

      //
      // 2) assign to the player in turn the dealer button
      // only active player can receive the button

      assignDB(gs);

      //
      // 3) pay small/big blinds
      // and updates players/table's chips

      payBlinds(gs);

      //
      // 4) prepare a random sorted deck of cards
      // i'm using Fisher–Yates algorithm to achieve 'randomness'

      let deck = gs._deck = shuffleCards();

      //
      // 5) assign two cards to each active player
      // first player who receive a card is the one next the dealer button
      res(assignCards(gs, deck));

    }, config.HANDWAIT);
  });

};
<|endoftext|>


<commit_before><commit_msg>fixed bad string concatenation as a result of a bad merge<commit_after><|endoftext|>


<commit_before>/** @jsx React.DOM */
/*
 * == BSD2 LICENSE ==
 * Copyright (c) 2014, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 * == BSD2 LICENSE ==
 */
var _ = require('lodash');
var bows = require('bows');
var React = require('react');
var sundial = require('sundial');

var utils = require('../../core/utils');

// tideline dependencies & plugins
var tidelineBlip = require('tideline/plugins/blip');
var BasicsChart = tidelineBlip.basics;

var Header = require('./header');
var Footer = require('./footer');

var Basics = React.createClass({
  chartType: 'basics',
  log: bows('Basics View'),
  propTypes: {
    bgPrefs: React.PropTypes.object.isRequired,
    chartPrefs: React.PropTypes.object.isRequired,
    timePrefs: React.PropTypes.object.isRequired,
    patientData: React.PropTypes.object.isRequired,
    onClickRefresh: React.PropTypes.func.isRequired,
    onSwitchToBasics: React.PropTypes.func.isRequired,
    onSwitchToDaily: React.PropTypes.func.isRequired,
    onSwitchToSettings: React.PropTypes.func.isRequired,
    onSwitchToWeekly: React.PropTypes.func.isRequired,
    trackMetric: React.PropTypes.func.isRequired,
    uploadUrl: React.PropTypes.string.isRequired
  },
  getInitialState: function() {
    return {
      atMostRecent: true,
      inTransition: false,
      title: this.getTitle()
    };
  },
  render: function() {

    return (

              {this.isMissingBasics() ?
                this.renderMissingBasicsMessage() : this.renderChart()}

      );

  },
  renderChart: function() {

    return (

        <BasicsChart
          bgClasses={this.props.bgPrefs.bgClasses}
          bgUnits={this.props.bgPrefs.bgUnits}
          patientData={this.props.patientData}
          timePrefs={this.props.timePrefs}
          ref="chart" />

    );

  },
  renderMissingBasicsMessage: function() {
    var self = this;
    var handleClickUpload = function() {
      self.props.trackMetric('Clicked Partial Data Upload, No Pump Data for Basics');
    };

    return (

{'Blip\'s Basics view shows a summary of your recent pump activity, but it looks like you haven\'t uploaded pump data yet.'}

{'To see your Basics in Blip,  '}
          upload
          {' your pump.'}

{'If you just uploaded, try '}
          refreshing
          {'.'}

    );

  },
  getTitle: function() {
    if (this.isMissingBasics()) {
      return '';
    }
    var timePrefs = this.props.timePrefs, timezone;
    if (!timePrefs.timezoneAware) {
      timezone = 'UTC';
    }
    else {
      timezone = timePrefs.timezoneName || 'UTC';
    }
    var basicsData = this.props.patientData.basicsData;
    var dtMask = 'MMM D, YYYY';
    return sundial.formatInTimezone(basicsData.dateRange[0], timezone, dtMask) +
      ' - ' + sundial.formatInTimezone(basicsData.dateRange[1], timezone, dtMask);
  },
  isMissingBasics: function() {
    var basicsData = this.props.patientData.basicsData;
    var data;
    if (basicsData.data) {
      data = basicsData;
    }
    else {
      return true;
    }
    // require basal, bolus, and smbg data to show The Basics
    var hasBasicsData = data.basal && data.bolus && data.smbg;
    if (hasBasicsData === false) {
      return true;
    }
    return false;
  },
  // handlers
  handleClickBasics: function(e) {
    if (e) {
      e.preventDefault();
    }
    return;
  },
  handleClickModal: function(e) {
    if (e) {
      e.preventDefault();
    }
    this.props.onSwitchToModal();
  },
  handleClickOneDay: function(e) {
    if (e) {
      e.preventDefault();
    }
    this.props.onSwitchToDaily();
  },
  handleClickTwoWeeks: function(e) {
    if (e) {
      e.preventDefault();
    }
    this.props.onSwitchToWeekly();
  }
});

module.exports = Basics;
<commit_msg>enable click-thru from basics cal days to daily view<commit_after>/** @jsx React.DOM */
/*
 * == BSD2 LICENSE ==
 * Copyright (c) 2014, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 * == BSD2 LICENSE ==
 */
var _ = require('lodash');
var bows = require('bows');
var React = require('react');
var sundial = require('sundial');

var utils = require('../../core/utils');

// tideline dependencies & plugins
var tidelineBlip = require('tideline/plugins/blip');
var BasicsChart = tidelineBlip.basics;

var Header = require('./header');
var Footer = require('./footer');

var Basics = React.createClass({
  chartType: 'basics',
  log: bows('Basics View'),
  propTypes: {
    bgPrefs: React.PropTypes.object.isRequired,
    chartPrefs: React.PropTypes.object.isRequired,
    timePrefs: React.PropTypes.object.isRequired,
    patientData: React.PropTypes.object.isRequired,
    onClickRefresh: React.PropTypes.func.isRequired,
    onSwitchToBasics: React.PropTypes.func.isRequired,
    onSwitchToDaily: React.PropTypes.func.isRequired,
    onSwitchToSettings: React.PropTypes.func.isRequired,
    onSwitchToWeekly: React.PropTypes.func.isRequired,
    trackMetric: React.PropTypes.func.isRequired,
    uploadUrl: React.PropTypes.string.isRequired
  },
  getInitialState: function() {
    return {
      atMostRecent: true,
      inTransition: false,
      title: this.getTitle()
    };
  },
  render: function() {

    return (

              {this.isMissingBasics() ?
                this.renderMissingBasicsMessage() : this.renderChart()}

      );

  },
  renderChart: function() {

    return (

        <BasicsChart
          bgClasses={this.props.bgPrefs.bgClasses}
          bgUnits={this.props.bgPrefs.bgUnits}
          onSelectDay={this.handleSelectDay}
          patientData={this.props.patientData}
          timePrefs={this.props.timePrefs}
          ref="chart" />

    );

  },
  renderMissingBasicsMessage: function() {
    var self = this;
    var handleClickUpload = function() {
      self.props.trackMetric('Clicked Partial Data Upload, No Pump Data for Basics');
    };

    return (

{'Blip\'s Basics view shows a summary of your recent pump activity, but it looks like you haven\'t uploaded pump data yet.'}

{'To see your Basics in Blip,  '}
          upload
          {' your pump.'}

{'If you just uploaded, try '}
          refreshing
          {'.'}

    );

  },
  getTitle: function() {
    if (this.isMissingBasics()) {
      return '';
    }
    var timePrefs = this.props.timePrefs, timezone;
    if (!timePrefs.timezoneAware) {
      timezone = 'UTC';
    }
    else {
      timezone = timePrefs.timezoneName || 'UTC';
    }
    var basicsData = this.props.patientData.basicsData;
    var dtMask = 'MMM D, YYYY';
    return sundial.formatInTimezone(basicsData.dateRange[0], timezone, dtMask) +
      ' - ' + sundial.formatInTimezone(basicsData.dateRange[1], timezone, dtMask);
  },
  isMissingBasics: function() {
    var basicsData = this.props.patientData.basicsData;
    var data;
    if (basicsData.data) {
      data = basicsData;
    }
    else {
      return true;
    }
    // require basal, bolus, and smbg data to show The Basics
    var hasBasicsData = data.basal && data.bolus && data.smbg;
    if (hasBasicsData === false) {
      return true;
    }
    return false;
  },
  // handlers
  handleClickBasics: function(e) {
    if (e) {
      e.preventDefault();
    }
    return;
  },
  handleClickModal: function(e) {
    if (e) {
      e.preventDefault();
    }
    this.props.onSwitchToModal();
  },
  handleClickOneDay: function(e) {
    if (e) {
      e.preventDefault();
    }
    this.props.onSwitchToDaily();
  },
  handleClickTwoWeeks: function(e) {
    if (e) {
      e.preventDefault();
    }
    this.props.onSwitchToWeekly();
  },
  handleSelectDay: function(date) {
    this.props.onSwitchToDaily(date);
  }
});

module.exports = Basics;
<|endoftext|>


<commit_before>/*
 * Copyright 2011 Adobe Systems Incorporated. All Rights Reserved.
 */

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, $, CodeMirror */

/*
* Displays an auto suggest popup list of files to allow the user to quickly navigate to a file.
* Uses FileIndexManger to supply the file list and registers Commands.FILE_QUICK_NAVIGATE with Brackets.
*
* TODO (issue 333) - currently jquery smart auto complete is used for the popup list. While it mostly works
* it has several issues, so it should be replace with an alternative. Issues:
* - only accepts an array of strings. A list of objects is preferred to avoid some work arounds to display
*   both the path and filename.
* - the popup position logic has flaws that require css work-arounds
* - the popup properties cannot be modified once the object is constructed
*/

define(function (require, exports, module) {
    'use strict';

    var FileIndexManager    = require("FileIndexManager"),
        DocumentManager     = require("DocumentManager"),
        CommandManager      = require("CommandManager"),
        EditorManager       = require("EditorManager"),
        Commands            = require("Commands"),
        ProjectManager      = require("ProjectManager");

    /**
    * FileLocation class
    * @constructor
    *
    */
    function FileLocation(fullPath, line, column, functionName) {
        this.fullPath = fullPath;
        this.line = line;
        this.column = column;
        this.functionName = functionName
    }

    /**
    * QuickNavigateDialog class
    * @constructor
    *
    */
    function QuickNavigateDialog(codemirror) {
        this.searchField = undefined; // defined when showDialog() is called
        this.closed = false;
        this.result = null; // $.Deferred, assigned by showShowDialog() resolved by _close()
        this.fileLocation = new FileLocation();
        this.functionList = [];

        // TODO (issue 311) - remove code mirror references
        this.codemirror = codemirror;
    }

    /**
    * Creates a dialog div floating on top of the current code mirror editor
    */
    QuickNavigateDialog.prototype._createDialogDiv = function (cm, template) {
        // TODO (issue 311) - using code mirror's wrapper element for now. Need to design a Brackets equivalent.
        var wrap = $("#editorHolder");
        this.dialog = $("
").addClass("CodeMirror-dialog")
            .html('
' + template + '
');
        wrap.before(this.dialog);
        //this.dialog = wrap.insertBefore(document.createElement("div"), wrap.firstChild);
        //this.dialog.className = "CodeMirror-dialog";
        //this.dialog.innerHTML = '
' + template + '
';
    };

    function _filenameFromPath(path) {
        return path.slice(path.lastIndexOf("/") + 1, path.length);
    }

    /**
    * Closes the search dialog and resolves the promise that showDialog returned
    */
    QuickNavigateDialog.prototype._handleItemCommit = function (value) {

        var query = this.searchField.val();

        if(this.fileLocation && !this.fileLocation.function) {
            // extract line number
            var regInfo = query.match(/(!?:)(\d+)/);
            if(regInfo) {
                this.fileLocation.line = regInfo[2] - 1;
            } else {
                regInfo = query.match(/(!?:)(\d+)/);
            }
        }

        // todo extra @function
        var regInfo = query.match(/@(.+)/);
    }

    /**
    * Closes the search dialog and resolves the promise that showDialog returned
    */
    QuickNavigateDialog.prototype._close = function (value) {
        //EditorManager.focusEditor();

        if (this.closed) {
            return;
        }
        this.closed = true;

        // remove the UI
        // $(document).unbind();
        // $(".smart_autocomplete_container").remove();
        // this.dialog.remove();

        this.result.resolve(this.fileLocation);
    };

    /**
    * Shows the search dialog and initializes the auto suggestion list with filenames from the current project
    * @returns {$.Promise} a promise that is resolved when the dialgo closes with the string value from the search field
    */
    QuickNavigateDialog.prototype.showDialog = function () {
        var that = this;
        var suggestList;
        this.result = new $.Deferred();

        FileIndexManager.getFileInfoList("all")
            .done(function (filelistResult) {
                var dialogHTML = 'Quick Open: <input type="text" autocomplete="off" id="quickFileOpenSearch" style="width: 30em">';
                that._createDialogDiv(that, dialogHTML);
                that.searchField = $('input#quickFileOpenSearch');
                var closed = false;

                // auto suggest list helper function
                function _handleResultsFormatter(item) {
                    var term = $('input#quickFileOpenSearch').val();
                    var functionSearch = term.charAt(0) === '@';
                    if (functionSearch) {
                        term = term.slice(1, term.length);
                    }

                    if (functionSearch) {
                        var boldName = item.replace(new RegExp(term, "gi"), "$&");
                        return "
" + boldName + "
";
                    } else {
                        var filename = _filenameFromPath(item);
                        var rPath = ProjectManager.makeProjectRelativeIfPossible(item);
                        var boldName = filename.replace(new RegExp(term, "gi"), "$&");
                        return "
" + boldName +
                            "
" + rPath + "
";
                    }
                }

                // auto suggest list helper function
                function _handleFilter(term, source) {
                    var functionSearch = term.charAt(0) === '@';
                    if (functionSearch) {
                        term = term.slice(1, term.length);
                    }

                    var filteredList = $.map(source, function (itemInfo) {

                        if (functionSearch && itemInfo.functionName) {
                            var functionName = itemInfo.functionName;
                            if (functionName.toLowerCase().indexOf(term.toLowerCase()) !== -1) {
                                return functionName;
                            }
                        } else if (!functionSearch && itemInfo.fullPath) {
                            // match term against filename only (not the full path)
                            var path = itemInfo.fullPath;
                            var filename = _filenameFromPath(path);
                            if (filename.toLowerCase().indexOf(term.toLowerCase()) !== -1) {
                                return path;
                            }
                        } else {
                            return null;
                        }
                    }).sort(function (a, b) {

                        if (functionSearch) {
                            return a > b;
                        } else {
                            // sort by filename
                            var filenameA = _filenameFromPath(a);
                            var filenameB = _filenameFromPath(b);
                            return filenameA > filenameB;
                        }

                    });

                    return filteredList;
                }

                // Create the auto suggest list of filenames
                that._generateFunctionList();
                suggestList = filelistResult.concat(that.functionList);

                that.searchField.smartAutoComplete({
                    source: suggestList,
                    maxResults: 10,
                    forceSelect: false,
                    typeAhead: true,
                    filter: _handleFilter,
                    resultFormatter: _handleResultsFormatter
                });

                that.searchField.bind({
                    itemSelect: function (ev, selected_item) {
                        that._handleItemCommit();
                    },

                    itemFocus: function (ev, selected_item) {
                        var fullPath = $(selected_item).attr("data-fullpath");
                        if (fullPath) {
                            that.fileLocation.fullPath = decodeURIComponent(fullPath);

                            // TODO: make function
                            CommandManager.execute(Commands.FILE_OPEN, {fullPath: that.fileLocation.fullPath, focusEditor: false});
                        } else {
                            that._setLocationFromFunctionName($(selected_item).text());

                            // TODO: make function
                            var from = {line: that.fileLocation.line, ch: that.fileLocation.column};
                            var to = {line: that.fileLocation.line, ch: that.fileLocation.column + that.fileLocation.functionName.length};
                            DocumentManager.getCurrentDocument().setSelection(from, to);
                        }
                    },

                    lostFocus: function (e) {
                        that._close();
                    },

                    keydown: function (e) {
                        // close the dialog when the ENTER (13) or ESC (27) key is pressed
                        if ((e.keyCode === 13 && !$(".smart_autocomplete_container").is(":visible")) || e.keyCode === 27) {
                            e.stopPropagation();
                            e.preventDefault();

                            // clear the query on ESC key
                            if (e.keyCode === 27) {
                                that.fileLocation = undefined;
                            }

                            that._handleItemCommit();
                            that._close();
                        }
                    }

                });

                that.searchField.focus();
            });

        return this.result;
    };

    // TODO: rename function to something better.
    QuickNavigateDialog.prototype._setLocationFromFunctionName = function (functionName) {

        var that = this;
        var i;
        for (i = 0; i < this.functionList.length; i++) {
            var functionInfo = this.functionList[i];
            if (functionInfo.functionName === functionName) {
                that.fileLocation = functionInfo;
                return;
            }
        }

        this.fileLocation.line = undefined;
    }

    QuickNavigateDialog.prototype._generateFunctionList = function () {
        var doc = DocumentManager.getCurrentDocument();
        if (!doc) {
            // TODO
        }

        var docText = doc.getText();
        this.functionList = [];
        var regex = new RegExp(/(function\b)(.+)\b\(/gi);
        var info, i, line;

        var lines = docText.split("\n");

        for (i = 0; i < lines.length; i++) {
            line = lines[i];
            info = regex.exec(line);

            if (info) {
                var funcName = $.trim(info[2]);
                this.functionList.push(new FileLocation(null, i, line.indexOf(funcName), funcName));
                //console.log(info[2]);
            }
        }
    }

    /**
    * Displays a non-modal embedded dialog above the code mirror edit that allows the user to quickly
    * navigate to different files and parts of the current file.
    * The search field lists files in the project. The user can enter ":" followed by a line
    * number to navigate to a specific line in the current file.
    */
    function doFileSearch() {

        // TODO (issue 311) - using code mirror's wrapper element for now which requires us to get the editor and the code mirror instance
        var curDoc = DocumentManager.getCurrentDocument();
        if (!curDoc) {
            return;
        }
        var cm = curDoc._editor;

        var dialog = new QuickNavigateDialog(cm);
        dialog.showDialog()
            .done(function (fileLocation) {
                if (fileLocation) {
                    if (fileLocation.fullPath) {
                        CommandManager.execute(Commands.FILE_OPEN, {fullPath: fileLocation.fullPath});
                    }

                    if (fileLocation.functionName) {
                        var from = {line: fileLocation.line, ch: fileLocation.column};
                        var to = {line: fileLocation.line, ch: fileLocation.column + fileLocation.functionName.length};
                        DocumentManager.getCurrentDocument().setSelection(from, to);
                    } else if (fileLocation.line) {
                        var from = {line: fileLocation.line, ch: 0};
                        var to = {line: fileLocation.line, ch: 0};
                        DocumentManager.getCurrentDocument().setSelection(from, to);
                    }

                    EditorManager.focusEditor();
                }
            });
    }

    CommandManager.register(Commands.FILE_QUICK_NAVIGATE, doFileSearch);
});<commit_msg>fixed the way quick find dialog is created and deleted<commit_after>/*
 * Copyright 2011 Adobe Systems Incorporated. All Rights Reserved.
 */

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, $ */

/*
* Displays an auto suggest popup list of files to allow the user to quickly navigate to a file.
* Uses FileIndexManger to supply the file list and registers Commands.FILE_QUICK_NAVIGATE with Brackets.
*
* TODO (issue 333) - currently jquery smart auto complete is used for the popup list. While it mostly works
* it has several issues, so it should be replace with an alternative. Issues:
* - only accepts an array of strings. A list of objects is preferred to avoid some work arounds to display
*   both the path and filename.
* - the popup position logic has flaws that require css work-arounds
* - the popup properties cannot be modified once the object is constructed
*/

define(function (require, exports, module) {
    'use strict';

    var FileIndexManager    = require("FileIndexManager"),
        DocumentManager     = require("DocumentManager"),
        CommandManager      = require("CommandManager"),
        EditorManager       = require("EditorManager"),
        Commands            = require("Commands"),
        ProjectManager      = require("ProjectManager");

    /**
    * FileLocation class
    * @constructor
    *
    */
    function FileLocation(fullPath, line, column, functionName) {
        this.fullPath = fullPath;
        this.line = line;
        this.column = column;
        this.functionName = functionName
    }

    /**
    * QuickNavigateDialog class
    * @constructor
    *
    */
    function QuickNavigateDialog() {
        this.searchField = undefined; // defined when showDialog() is called
        this.closed = false;
        this.result = null; // $.Deferred, assigned by showShowDialog() resolved by _close()
        this.fileLocation = new FileLocation();
        this.functionList = [];
    }

    /**
    * Creates a dialog div floating on top of the current code mirror editor
    */
    QuickNavigateDialog.prototype._createDialogDiv = function (template) {
        var wrap = $("#editorHolder")[0];
        this.dialog = wrap.insertBefore(document.createElement("div"), wrap.firstChild);
        this.dialog.className = "CodeMirror-dialog";
        this.dialog.innerHTML = '
' + template + '
';
    };

    function _filenameFromPath(path) {
        return path.slice(path.lastIndexOf("/") + 1, path.length);
    }

    /**
    * Closes the search dialog and resolves the promise that showDialog returned
    */
    QuickNavigateDialog.prototype._handleItemCommit = function (value) {

        var query = this.searchField.val();

        if(this.fileLocation && !this.fileLocation.function) {
            // extract line number
            var regInfo = query.match(/(!?:)(\d+)/);
            if(regInfo) {
                this.fileLocation.line = regInfo[2] - 1;
            } else {
                regInfo = query.match(/(!?:)(\d+)/);
            }
        }

        // todo extra @function
        var regInfo = query.match(/@(.+)/);
    }

    /**
    * Closes the search dialog and resolves the promise that showDialog returned
    */
    QuickNavigateDialog.prototype._close = function (value) {
        //EditorManager.focusEditor();

        if (this.closed) {
            return;
        }
        this.closed = true;

        this.dialog.parentNode.removeChild(this.dialog);
        $(".smart_autocomplete_container").remove();

        this.result.resolve(this.fileLocation);
    };

    /**
    * Shows the search dialog and initializes the auto suggestion list with filenames from the current project
    * @returns {$.Promise} a promise that is resolved when the dialgo closes with the string value from the search field
    */
    QuickNavigateDialog.prototype.showDialog = function () {
        var that = this;
        var suggestList;
        this.result = new $.Deferred();

        FileIndexManager.getFileInfoList("all")
            .done(function (filelistResult) {
                var dialogHTML = 'Quick Open: <input type="text" autocomplete="off" id="quickFileOpenSearch" style="width: 30em">';
                that._createDialogDiv(dialogHTML);
                that.searchField = $('input#quickFileOpenSearch');
                var closed = false;

                // auto suggest list helper function
                function _handleResultsFormatter(item) {
                    var term = $('input#quickFileOpenSearch').val();
                    var functionSearch = term.charAt(0) === '@';
                    if (functionSearch) {
                        term = term.slice(1, term.length);
                    }

                    if (functionSearch) {
                        var boldName = item.replace(new RegExp(term, "gi"), "$&");
                        return "
" + boldName + "
";
                    } else {
                        var filename = _filenameFromPath(item);
                        var rPath = ProjectManager.makeProjectRelativeIfPossible(item);
                        var boldName = filename.replace(new RegExp(term, "gi"), "$&");
                        return "
" + boldName +
                            "
" + rPath + "
";
                    }
                }

                // auto suggest list helper function
                function _handleFilter(term, source) {
                    var functionSearch = term.charAt(0) === '@';
                    if (functionSearch) {
                        term = term.slice(1, term.length);
                    }

                    var filteredList = $.map(source, function (itemInfo) {

                        if (functionSearch && itemInfo.functionName) {
                            var functionName = itemInfo.functionName;
                            if (functionName.toLowerCase().indexOf(term.toLowerCase()) !== -1) {
                                return functionName;
                            }
                        } else if (!functionSearch && itemInfo.fullPath) {
                            // match term against filename only (not the full path)
                            var path = itemInfo.fullPath;
                            var filename = _filenameFromPath(path);
                            if (filename.toLowerCase().indexOf(term.toLowerCase()) !== -1) {
                                return path;
                            }
                        } else {
                            return null;
                        }
                    }).sort(function (a, b) {

                        if (functionSearch) {
                            return a > b;
                        } else {
                            // sort by filename
                            var filenameA = _filenameFromPath(a);
                            var filenameB = _filenameFromPath(b);
                            if(filenameA > filenameB) {
                                return -1
                            } else if(filenameA < filenameB) {
                                return 1
                            } else {
                                return 0;
                            }
                        }

                    });

                    return filteredList;
                }

                // Create the auto suggest list of filenames
                that._generateFunctionList();
                suggestList = filelistResult.concat(that.functionList);

                that.searchField.smartAutoComplete({
                    source: suggestList,
                    maxResults: 10,
                    forceSelect: false,
                    typeAhead: true,
                    filter: _handleFilter,
                    resultFormatter: _handleResultsFormatter
                });

                that.searchField.bind({
                    itemSelect: function (ev, selected_item) {
                        that._handleItemCommit();
                    },

                    itemFocus: function (ev, selected_item) {
                        var fullPath = $(selected_item).attr("data-fullpath");
                        if (fullPath) {
                            that.fileLocation.fullPath = decodeURIComponent(fullPath);

                            // TODO: make function
                            CommandManager.execute(Commands.FILE_OPEN, {fullPath: that.fileLocation.fullPath, focusEditor: false});
                        } else {
                            that._setLocationFromFunctionName($(selected_item).text());

                            // TODO: make function
                            var from = {line: that.fileLocation.line, ch: that.fileLocation.column};
                            var to = {line: that.fileLocation.line, ch: that.fileLocation.column + that.fileLocation.functionName.length};
                            DocumentManager.getCurrentDocument().setSelection(from, to);
                        }
                    },

                    lostFocus: function (e) {
                        that._close();
                    },

                    keydown: function (e) {
                        // close the dialog when the ENTER (13) or ESC (27) key is pressed
                        if ((e.keyCode === 13 && !$(".smart_autocomplete_container").is(":visible")) || e.keyCode === 27) {
                            e.stopPropagation();
                            e.preventDefault();

                            // clear the query on ESC key
                            if (e.keyCode === 27) {
                                that.fileLocation = undefined;
                            }

                            that._handleItemCommit();
                            that._close();
                        }
                    }

                });

                that.searchField.focus();
            });

        return this.result;
    };

    // TODO: rename function to something better.
    QuickNavigateDialog.prototype._setLocationFromFunctionName = function (functionName) {

        var that = this;
        var i;
        for (i = 0; i < this.functionList.length; i++) {
            var functionInfo = this.functionList[i];
            if (functionInfo.functionName === functionName) {
                that.fileLocation = functionInfo;
                return;
            }
        }

        this.fileLocation.line = undefined;
    }

    QuickNavigateDialog.prototype._generateFunctionList = function () {
        this.functionList = [];

        var doc = DocumentManager.getCurrentDocument();
        if (!doc) {
            return;
        }

        var docText = doc.getText();

        var regex = new RegExp(/(function\b)(.+)\b\(/gi);
        var info, i, line;

        var lines = docText.split("\n");

        for (i = 0; i < lines.length; i++) {
            line = lines[i];
            info = regex.exec(line);

            if (info) {
                var funcName = $.trim(info[2]);
                this.functionList.push(new FileLocation(null, i, line.indexOf(funcName), funcName));
                //console.log(info[2]);
            }
        }
    }

    /**
    * Displays a non-modal embedded dialog above the code mirror edit that allows the user to quickly
    * navigate to different files and parts of the current file.
    * The search field lists files in the project. The user can enter ":" followed by a line
    * number to navigate to a specific line in the current file.
    */
    function doFileSearch() {

        var curDoc = DocumentManager.getCurrentDocument();

        var dialog = new QuickNavigateDialog();
        dialog.showDialog()
            .done(function (fileLocation) {
                if (fileLocation) {
                    if (fileLocation.fullPath) {
                        CommandManager.execute(Commands.FILE_OPEN, {fullPath: fileLocation.fullPath});
                    }

                    if (fileLocation.functionName) {
                        var from = {line: fileLocation.line, ch: fileLocation.column};
                        var to = {line: fileLocation.line, ch: fileLocation.column + fileLocation.functionName.length};
                        DocumentManager.getCurrentDocument().setSelection(from, to);
                    } else if (fileLocation.line) {
                        var from = {line: fileLocation.line, ch: 0};
                        var to = {line: fileLocation.line, ch: 0};
                        DocumentManager.getCurrentDocument().setSelection(from, to);
                    }

                    EditorManager.focusEditor();
                }
            });
    }

    CommandManager.register(Commands.FILE_QUICK_NAVIGATE, doFileSearch);
});<|endoftext|>


<commit_before><commit_msg>removed missing console.log<commit_after><|endoftext|>


<commit_before>import React, { PropTypes } from 'react';
import GregorianCalendar from 'gregorian-calendar';
import classnames from 'classnames';
import CalendarPart from './range-calendar/CalendarPart';
import { syncTime, getTodayTime } from './util/';
import TodayButton from './calendar/TodayButton';
import OkButton from './calendar/OkButton';
import CommonMixin from './mixin/CommonMixin';

function noop() {
}

function getNow() {
  const selectedValue = new GregorianCalendar();
  selectedValue.setTime(Date.now());
  return selectedValue;
}

function onValueChange(direction, current) {
  let value;
  value = current;
  if (direction === 'right') {
    value.addMonth(-1);
  }
  this.fireValueChange(value);
}

function normalizeAnchor(props, init) {
  const selectedValue = props.selectedValue || init && props.defaultSelectedValue || [];
  let value = props.value;
  if (Array.isArray(value)) {
    value = value[0];
  }
  let defaultValue = props.defaultValue;
  if (Array.isArray(defaultValue)) {
    defaultValue = defaultValue[0];
  }
  return value || init && defaultValue || selectedValue[0] || init && getNow();
}

function onInputSelect(direction, value) {
  if (!value) {
    return;
  }
  const originalValue = this.state.selectedValue;
  const selectedValue = originalValue.concat();
  const index = direction === 'left' ? 0 : 1;
  selectedValue[index] = value;
  if (selectedValue[0] && selectedValue[1]) {
    if (this.compare(selectedValue[0], selectedValue[1]) > 0) {
      selectedValue[1 - index] = undefined;
    }
  }
  this.fireSelectValueChange(selectedValue);
}

const RangeCalendar = React.createClass({
  propTypes: {
    prefixCls: PropTypes.string,
    dateInputPlaceholder: PropTypes.any,
    defaultValue: PropTypes.any,
    timePicker: PropTypes.any,
    value: PropTypes.any,
    showOk: PropTypes.bool,
    selectedValue: PropTypes.array,
    defaultSelectedValue: PropTypes.array,
    onOk: PropTypes.func,
    locale: PropTypes.object,
    onChange: PropTypes.func,
    onSelect: PropTypes.func,
    onValueChange: PropTypes.func,
    formatter: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
    onClear: PropTypes.func,
  },

  mixins: [CommonMixin],

  getDefaultProps() {
    return {
      defaultSelectedValue: [],
      onValueChange: noop,
    };
  },

  getInitialState() {
    const props = this.props;
    const selectedValue = props.selectedValue || props.defaultSelectedValue;
    const value = normalizeAnchor(props, 1);
    return {
      selectedValue,
      value,
    };
  },

  componentWillReceiveProps(nextProps) {
    const newState = {};
    if ('value' in nextProps) {
      if (nextProps.value) {
        newState.value = nextProps.value;
      } else {
        newState.value = normalizeAnchor(nextProps, 0);
      }
      this.setState(newState);
    }
    if ('selectedValue' in nextProps) {
      newState.selectedValue = nextProps.selectedValue;
      this.setState(newState);
    }
  },

  onSelect(value) {
    const originalValue = this.state.selectedValue;
    const selectedValue = originalValue.concat();
    let changed = false;
    if (!selectedValue.length || selectedValue.length === 2 && !originalValue.hovering) {
      selectedValue.length = 1;
      selectedValue[0] = value;
      changed = true;
    } else if (this.compare(selectedValue[0], value) <= 0) {
      selectedValue[1] = value;
      changed = true;
    } else if (this.compare(selectedValue[0], value) > 0) {
      selectedValue.length = 1;
      selectedValue[0] = value;
      changed = true;
    }
    if (changed) {
      this.fireSelectValueChange(selectedValue);
    }
  },

  onDayHover(hoverValue) {
    let selectedValue = this.state.selectedValue;
    if (!selectedValue.length || selectedValue.length === 2 && !selectedValue.hovering) {
      return;
    }
    if (this.compare(hoverValue, selectedValue[0]) < 0) {
      return;
    }
    selectedValue = selectedValue.concat();
    selectedValue[1] = hoverValue;
    selectedValue.hovering = 1;
    this.fireSelectValueChange(selectedValue);
  },

  onToday() {
    this.setState({
      value: getTodayTime(this.state.value),
    });
  },

  onOk() {
    this.props.onOk(this.state.selectedValue);
  },

  getStartValue() {
    let value = this.state.value;
    const selectedValue = this.state.selectedValue;
    // keep selectedTime when select date
    if (selectedValue[0] && this.props.timePicker) {
      value = value.clone();
      syncTime(selectedValue[0], value);
    }
    return value;
  },

  getEndValue() {
    const endValue = this.state.value.clone();
    endValue.addMonth(1);
    const selectedValue = this.state.selectedValue;
    // keep selectedTime when select date
    if (selectedValue[1] && this.props.timePicker) {
      syncTime(selectedValue[1], endValue);
    }
    return endValue;
  },

  compare(v1, v2) {
    if (this.props.timePicker) {
      return v1.getTime() - v2.getTime();
    }
    return v1.compareToDay(v2);
  },

  fireSelectValueChange(selectedValue, direct) {
    if (!('selectedValue' in this.props)) {
      this.setState({
        selectedValue,
      });
    }
    this.props.onChange(selectedValue);
    if (direct || selectedValue[0] && selectedValue[1] && !selectedValue.hovering) {
      this.props.onSelect(selectedValue);
    }
  },

  fireValueChange(value) {
    const props = this.props;
    if (!('value' in props)) {
      this.setState({
        value,
      });
    }
    props.onValueChange(value);
  },

  clear() {
    this.fireSelectValueChange([], true);
    this.props.onClear();
  },

  render() {
    const props = this.props;
    const state = this.state;
    const { prefixCls, dateInputPlaceholder, timePicker, showOk, locale } = props;
    const className = {
      [props.className]: !!props.className,
      [prefixCls]: 1,
      [`${prefixCls}-hidden`]: !props.visible,
      [`${prefixCls}-range`]: 1,
      [`${prefixCls}-week-number`]: props.showWeekNumber,
    };
    const classes = classnames(className);
    const newProps = {
      selectedValue: state.selectedValue,
      onSelect: this.onSelect,
      onDayHover: this.onDayHover,
    };

    let placeholder1;
    let placeholder2;

    if (dateInputPlaceholder) {
      if (Array.isArray(dateInputPlaceholder)) {
        [placeholder1, placeholder2] = dateInputPlaceholder;
      } else {
        placeholder1 = placeholder2 = dateInputPlaceholder;
      }
    }
    return (

      <a
        className={`${prefixCls}-clear-btn`}
        role="button"
        title={locale.clear}
        onClick={this.clear}
      />
      <CalendarPart
        {...props}
        {...newProps}
        direction="left"
        formatter={this.getFormatter()}
        value={this.getStartValue()}
        placeholder={placeholder1}
        onInputSelect={onInputSelect.bind(this, 'left')}
        onValueChange={onValueChange.bind(this, 'left')}
      />
      <span className={`${prefixCls}-range-middle`}>~
      <CalendarPart
        {...props}
        {...newProps}
        direction="right"
        formatter={this.getFormatter()}
        placeholder={placeholder2}
        value={this.getEndValue()}
        onInputSelect={onInputSelect.bind(this, 'right')}
        onValueChange={onValueChange.bind(this, 'right')}
      />
      <div className={`${prefixCls}-range-bottom`}>
        <TodayButton
          {...props}
          value={state.value}
          onToday={this.onToday}
          text={locale.backToToday}
        />
        {showOk === true || showOk !== false && !!timePicker ?
          <OkButton
            {...props}
            value={state.value}
            onOk={this.onOk}
            okDisabled={state.selectedValue.length !== 2 || state.selectedValue.hovering}
          /> : null}

);
  },
});

export default RangeCalendar;
<commit_msg>Fix RangePicker focus error<commit_after>import React, { PropTypes } from 'react';
import { findDOMNode } from 'react-dom';
import GregorianCalendar from 'gregorian-calendar';
import classnames from 'classnames';
import CalendarPart from './range-calendar/CalendarPart';
import { syncTime, getTodayTime } from './util/';
import TodayButton from './calendar/TodayButton';
import OkButton from './calendar/OkButton';
import CommonMixin from './mixin/CommonMixin';

function noop() {
}

function getNow() {
  const selectedValue = new GregorianCalendar();
  selectedValue.setTime(Date.now());
  return selectedValue;
}

function onValueChange(direction, current) {
  let value;
  value = current;
  if (direction === 'right') {
    value.addMonth(-1);
  }
  this.fireValueChange(value);
}

function normalizeAnchor(props, init) {
  const selectedValue = props.selectedValue || init && props.defaultSelectedValue || [];
  let value = props.value;
  if (Array.isArray(value)) {
    value = value[0];
  }
  let defaultValue = props.defaultValue;
  if (Array.isArray(defaultValue)) {
    defaultValue = defaultValue[0];
  }
  return value || init && defaultValue || selectedValue[0] || init && getNow();
}

function onInputSelect(direction, value) {
  if (!value) {
    return;
  }
  const originalValue = this.state.selectedValue;
  const selectedValue = originalValue.concat();
  const index = direction === 'left' ? 0 : 1;
  selectedValue[index] = value;
  if (selectedValue[0] && selectedValue[1]) {
    if (this.compare(selectedValue[0], selectedValue[1]) > 0) {
      selectedValue[1 - index] = undefined;
    }
  }
  this.fireSelectValueChange(selectedValue);
}

const RangeCalendar = React.createClass({
  propTypes: {
    prefixCls: PropTypes.string,
    dateInputPlaceholder: PropTypes.any,
    defaultValue: PropTypes.any,
    timePicker: PropTypes.any,
    value: PropTypes.any,
    showOk: PropTypes.bool,
    selectedValue: PropTypes.array,
    defaultSelectedValue: PropTypes.array,
    onOk: PropTypes.func,
    locale: PropTypes.object,
    onChange: PropTypes.func,
    onSelect: PropTypes.func,
    onValueChange: PropTypes.func,
    formatter: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
    onClear: PropTypes.func,
  },

  mixins: [CommonMixin],

  getDefaultProps() {
    return {
      defaultSelectedValue: [],
      onValueChange: noop,
    };
  },

  getInitialState() {
    const props = this.props;
    const selectedValue = props.selectedValue || props.defaultSelectedValue;
    const value = normalizeAnchor(props, 1);
    return {
      selectedValue,
      value,
    };
  },

  componentWillReceiveProps(nextProps) {
    const newState = {};
    if ('value' in nextProps) {
      if (nextProps.value) {
        newState.value = nextProps.value;
      } else {
        newState.value = normalizeAnchor(nextProps, 0);
      }
      this.setState(newState);
    }
    if ('selectedValue' in nextProps) {
      newState.selectedValue = nextProps.selectedValue;
      this.setState(newState);
    }
  },

  onSelect(value) {
    const originalValue = this.state.selectedValue;
    const selectedValue = originalValue.concat();
    let changed = false;
    if (!selectedValue.length || selectedValue.length === 2 && !originalValue.hovering) {
      selectedValue.length = 1;
      selectedValue[0] = value;
      changed = true;
    } else if (this.compare(selectedValue[0], value) <= 0) {
      selectedValue[1] = value;
      changed = true;
    } else if (this.compare(selectedValue[0], value) > 0) {
      selectedValue.length = 1;
      selectedValue[0] = value;
      changed = true;
    }
    if (changed) {
      this.fireSelectValueChange(selectedValue);
    }
  },

  onDayHover(hoverValue) {
    let selectedValue = this.state.selectedValue;
    if (!selectedValue.length || selectedValue.length === 2 && !selectedValue.hovering) {
      return;
    }
    if (this.compare(hoverValue, selectedValue[0]) < 0) {
      return;
    }
    selectedValue = selectedValue.concat();
    selectedValue[1] = hoverValue;
    selectedValue.hovering = 1;
    this.fireSelectValueChange(selectedValue);
  },

  onToday() {
    this.setState({
      value: getTodayTime(this.state.value),
    });
  },

  onOk() {
    this.props.onOk(this.state.selectedValue);
  },

  getStartValue() {
    let value = this.state.value;
    const selectedValue = this.state.selectedValue;
    // keep selectedTime when select date
    if (selectedValue[0] && this.props.timePicker) {
      value = value.clone();
      syncTime(selectedValue[0], value);
    }
    return value;
  },

  getEndValue() {
    const endValue = this.state.value.clone();
    endValue.addMonth(1);
    const selectedValue = this.state.selectedValue;
    // keep selectedTime when select date
    if (selectedValue[1] && this.props.timePicker) {
      syncTime(selectedValue[1], endValue);
    }
    return endValue;
  },

  compare(v1, v2) {
    if (this.props.timePicker) {
      return v1.getTime() - v2.getTime();
    }
    return v1.compareToDay(v2);
  },

  fireSelectValueChange(selectedValue, direct) {
    if (!('selectedValue' in this.props)) {
      this.setState({
        selectedValue,
      });
    }
    this.props.onChange(selectedValue);
    if (direct || selectedValue[0] && selectedValue[1] && !selectedValue.hovering) {
      this.props.onSelect(selectedValue);
    }
  },

  fireValueChange(value) {
    const props = this.props;
    if (!('value' in props)) {
      this.setState({
        value,
      });
    }
    props.onValueChange(value);
  },

  focus() {
    findDOMNode(this).focus();
  },

  clear() {
    this.fireSelectValueChange([], true);
    this.props.onClear();
  },

  render() {
    const props = this.props;
    const state = this.state;
    const { prefixCls, dateInputPlaceholder, timePicker, showOk, locale } = props;
    const className = {
      [props.className]: !!props.className,
      [prefixCls]: 1,
      [`${prefixCls}-hidden`]: !props.visible,
      [`${prefixCls}-range`]: 1,
      [`${prefixCls}-week-number`]: props.showWeekNumber,
    };
    const classes = classnames(className);
    const newProps = {
      selectedValue: state.selectedValue,
      onSelect: this.onSelect,
      onDayHover: this.onDayHover,
    };

    let placeholder1;
    let placeholder2;

    if (dateInputPlaceholder) {
      if (Array.isArray(dateInputPlaceholder)) {
        [placeholder1, placeholder2] = dateInputPlaceholder;
      } else {
        placeholder1 = placeholder2 = dateInputPlaceholder;
      }
    }
    return (

      <a
        className={`${prefixCls}-clear-btn`}
        role="button"
        title={locale.clear}
        onClick={this.clear}
      />
      <CalendarPart
        {...props}
        {...newProps}
        direction="left"
        formatter={this.getFormatter()}
        value={this.getStartValue()}
        placeholder={placeholder1}
        onInputSelect={onInputSelect.bind(this, 'left')}
        onValueChange={onValueChange.bind(this, 'left')}
      />
      <span className={`${prefixCls}-range-middle`}>~
      <CalendarPart
        {...props}
        {...newProps}
        direction="right"
        formatter={this.getFormatter()}
        placeholder={placeholder2}
        value={this.getEndValue()}
        onInputSelect={onInputSelect.bind(this, 'right')}
        onValueChange={onValueChange.bind(this, 'right')}
      />
      <div className={`${prefixCls}-range-bottom`}>
        <TodayButton
          {...props}
          value={state.value}
          onToday={this.onToday}
          text={locale.backToToday}
        />
        {showOk === true || showOk !== false && !!timePicker ?
          <OkButton
            {...props}
            value={state.value}
            onOk={this.onOk}
            okDisabled={state.selectedValue.length !== 2 || state.selectedValue.hovering}
          /> : null}

);
  },
});

export default RangeCalendar;
<|endoftext|>


<commit_before>/* @flow */

import type { Metadata } from '../metadata'
import type {
  ChokidarAdd,
  ChokidarAddDir,
  ChokidarChange,
  ChokidarUnlink,
  ChokidarUnlinkDir
} from './chokidar_event'

export type LocalDirAdded = ChokidarAddDir & {wip?: true}
export type LocalDirUnlinked = ChokidarUnlinkDir & {old: ?Metadata}
export type LocalFileAdded = ChokidarAdd & {md5sum: string, wip?: true}
export type LocalFileUnlinked = ChokidarUnlink & {old: ?Metadata}
type LocalFileUpdated = ChokidarChange & {md5sum: string, wip?: true}

export type LocalEvent =
  | LocalDirAdded
  | LocalDirUnlinked
  | LocalFileAdded
  | LocalFileUnlinked
  | LocalFileUpdated

module.exports = {
  getInode
}

function getInode (e: LocalEvent): ?number {
  switch (e.type) {
    case 'add':
    case 'addDir':
    case 'change':
      return e.stats.ino
    case 'unlink':
    case 'unlinkDir':
      if (e.old != null) return e.old.ino
  }
}
<commit_msg>core/local/event: Export LocalFileUpdated type<commit_after>/* @flow */

import type { Metadata } from '../metadata'
import type {
  ChokidarAdd,
  ChokidarAddDir,
  ChokidarChange,
  ChokidarUnlink,
  ChokidarUnlinkDir
} from './chokidar_event'

export type LocalDirAdded = ChokidarAddDir & {wip?: true}
export type LocalDirUnlinked = ChokidarUnlinkDir & {old: ?Metadata}
export type LocalFileAdded = ChokidarAdd & {md5sum: string, wip?: true}
export type LocalFileUnlinked = ChokidarUnlink & {old: ?Metadata}
export type LocalFileUpdated = ChokidarChange & {md5sum: string, wip?: true}

export type LocalEvent =
  | LocalDirAdded
  | LocalDirUnlinked
  | LocalFileAdded
  | LocalFileUnlinked
  | LocalFileUpdated

module.exports = {
  getInode
}

function getInode (e: LocalEvent): ?number {
  switch (e.type) {
    case 'add':
    case 'addDir':
    case 'change':
      return e.stats.ino
    case 'unlink':
    case 'unlinkDir':
      if (e.old != null) return e.old.ino
  }
}
<|endoftext|>


<commit_before>/* global mhaStrings */
/* exported Other */

var Other = (function () {
    var row = function (_number, _header, _url, _value) {
        var number = _number;
        var header = _header;
        var url = _url;
        var value = _value;

        return {
            number: number,
            header: header,
            url: url,
            value: value
        }
    };

    var otherRows = [];
    var sortColumn = "number";
    var sortOrder = 1;

    function doSort(col) {
        if (sortColumn === col) {
            sortOrder *= -1;
        } else {
            sortColumn = col;
            sortOrder = 1;
        }

        if (sortColumn + "Sort" in otherRows[0]) {
            col = col + "Sort";
        }

        var that = this;
        otherRows.sort(function (a, b) {
            return that.sortOrder * (a[col] < b[col] ? -1 : 1);
        });
    }

    function init(otherHeader) {
        otherRows.push(new row(
            otherRows.length + 1,
            otherHeader.header,
            mhaStrings.mapHeaderToURL(otherHeader.header, null),
            row.value = otherHeader.value));
    }

    function exists() { return otherRows.length > 0; }

    return {
        init: init,
        exists: exists,
        get otherRows() { return otherRows; },
        doSort: doSort,
        get sortColumn() { return sortColumn; },
        get sortOrder() { return sortOrder; }
    }
});<commit_msg>simplify<commit_after>/* global mhaStrings */
/* exported Other */

var Other = (function () {
    var row = function (number, header, url, value) {
        return {
            number: number,
            header: header,
            url: url,
            value: value
        }
    };

    var otherRows = [];
    var sortColumn = "number";
    var sortOrder = 1;

    function doSort(col) {
        if (sortColumn === col) {
            sortOrder *= -1;
        } else {
            sortColumn = col;
            sortOrder = 1;
        }

        if (sortColumn + "Sort" in otherRows[0]) {
            col = col + "Sort";
        }

        var that = this;
        otherRows.sort(function (a, b) {
            return that.sortOrder * (a[col] < b[col] ? -1 : 1);
        });
    }

    function init(otherHeader) {
        otherRows.push(new row(
            otherRows.length + 1,
            otherHeader.header,
            mhaStrings.mapHeaderToURL(otherHeader.header, null),
            row.value = otherHeader.value));
    }

    function exists() { return otherRows.length > 0; }

    return {
        init: init,
        exists: exists,
        get otherRows() { return otherRows; },
        doSort: doSort,
        get sortColumn() { return sortColumn; },
        get sortOrder() { return sortOrder; }
    }
});<|endoftext|>


<commit_before>this.addEventListener('install', event => {
    console.log('Service worker установлен');
    event.waitUntil(caches.open('MY_CACHE')
        .then(cache => {
            // загружаем в наш cache необходимые файлы
            return cache.addAll([
                '/',
                '/built/main.css',
                '/built/main.js',

                '/built/halloween.css',
                '/built/halloween.js',

                '/static/img/icons/pumpkin.png',
                '/static/img/results/1.png',
                '/static/img/results/2.png',
                '/static/img/results/3.png',
                '/static/img/results/4.png',
                '/static/img/results/5.png',

                '/static/video/win.mp4'
            ]);
        }));
});
<commit_msg>Fix service worker<commit_after>this.addEventListener('install', event => {
    console.log('Service worker установлен');
    event.waitUntil(caches.open('MY_CACHE')
        .then(cache => {
            // загружаем в наш cache необходимые файлы
            return cache.addAll([
                '/',
                '/built/main.css',
                '/built/main.js',

                '/built/halloween.css',
                '/built/halloween.js',

                '/static/img/icons/pumpkin.png',
                '/static/img/results/1.png',
                '/static/img/results/2.png',
                '/static/img/results/3.png',
                '/static/img/results/4.png',
                '/static/img/results/5.png',

                '/static/video/win.mp4'
            ]);
        }));
});

this.addEventListener('fetch', event => {
    // console.log(event);
    event.respondWith(caches.match(event.request)
        .then(cachedResponse => {

            // выдаём кэш, если он есть
            if (cachedResponse) {
                return cachedResponse;
            }

            // иначе запрашиваем из сети как обычно
            return fetch(event.request);
        }));
});
<|endoftext|>


<commit_before>"use strict";

const RemoteCallable = require("conductor-chord").RemoteCallable,
	EventEmitter2 = require("eventemitter2").EventEmitter2,
	sha3 = require("js-sha3"),
	ID = require("conductor-chord").ID,
	pki = require("node-forge").pki,
	random = require("node-forge").random,
	cipher = require("node-forge").cipher,
	forgeUtil = require("node-forge").util,
	md = require("node-forge").md,
	u = require("./UtilFunctions.js"),
	Session = require("./Session.js"),
	RecvSession = require("./RecvSession.js");

//EVENTS
//	.on("receiveConnection", recvSession)

class ShallotModule extends RemoteCallable {
	static get defaultConfig () {
		return {
			routeLength: 3,
			callTimeout: 666,
			maxCallRetries: 3,
			rcCacheDuration: 5000
		};
	};

	constructor (chord, config) {
		super(chord, "shallot");

		this.config = u.mergeConfig(ShallotModule.defaultConfig, config);

		this._rcTimeout = this.config.callTimeout;
		this._rcRetries = this.config.maxCallRetries;
		this._rcCacheDuration = this.config.rcCacheDuration;

		this._evts = new EventEmitter2({
			maxListeners: 20
		});

		this.keyStore = {};
		this.sessions = {};
		this.circuits = {};

		chord.registerModule(this);
	}

	get emit () {
		return this._evts.emit.bind(this._evts);
	}

	get on () {
		return this._evts.on.bind(this._evts);
	}

	get off () {
		return this._evts.off.bind(this._evts);
	}

	delegate (message) {
		if(super.delegate(message))
			return;

		switch (message.handler) {
			case "r":
				//RELAY
				this._parseRelay(message.data.params[0])
					.then(
						response => this.answer(message, response)
					)
					.catch(
						reason => this.error(message, reason)
					);
				break;
			case "b":
				//BUILD
				this._parseBuild(message.data.params[0])
					.then(
						response => this.answer(message, response)
					)
					.catch(
						reason => this.error(message, reason)
					);
				break;
		}
	}

	createRouteTo (id) {
		//Generate a route.
		//This is routeLength * randomIDs, + destination.
		let routeProms = [];

		for (let i = 0; i < this.config.routeLength; i++) {
			(i=>{
				let plannedId = new ID(
					forgeUtil.encode64(random.getBytesSync(this.chord.config.idWidth/8))
				);

				// Find what key our random id maps to.
				// Lookup its public key.
				// Fail if it does not exist.
				routeProms[i] = this.chord.node.findSuccessor(plannedId)
					.then(
						node => {return this._lookupKey(node.id);}
					);
			})(i)
		}

		routeProms[this.config.routeLength] = this.chord.node.findSuccessor(id)
			.then(
				node => {
					if (ID.compare(node.id, id) !== 0)
						return Promise.reject(`Destination node ${ID.coerceString(id)} could not be found!`);

					return this._lookupKey(id);
				}
			)

		// Now await all promise resolutions.
		// Afterwards, propagate the chain to build a session.

		return Promise.all(routeProms);
	}

	connectTo (id) {
		//First, get our route.
		return this.createRouteTo(id)
			.then(
				route => {
					//Generate an AES key for each hop.
					let aesKeys = [];
					for (let i =0; i < route.length; i++)
						aesKeys.push(random.getBytesSync(16));

					//Create the first circuitID
					let firstCirc = random.getBytesSync(8);

					let propagateLink = index => {
						//End recursive promise chain.
						if(index === route.length) {
							let data = {
								f: ID.coerceString(this.chord.id)
							};

							return this._sendOnion(aesKeys, route[0], firstCirc, data)
								.then(()=> {
									return Promise.resolve(new Session(this, route, aesKeys, firstCirc));
								})
						}

						//Package the aes key for each node along the chain.
						let internal = {
							k: route[index].encrypt(aesKeys[index])
						};

						//Our promise for both paths.
						let a;

						//If sending to the first node, we have to send a full build message instead
						//of a relay.
						if (index===0) {
							internal.c = route[0].encrypt(firstCirc+ID.coerceString(this.chord.id));
							internal.v = this.rsaSign(internal.k+internal.c);

							a = this._sendBuild(route[0], internal);
						} else {
							//We need to inform the end of the route about the next hop.
							//Encrypt this information just for it.
							internal.d = route[index-1].encrypt(ID.coerceString(route[index].id));

							//Now wrap with as many layers as we can, and put our circuit id
							//(secured, with the iv) in the message.
							a = this._sendOnion(aesKeys, route[0], firstCirc, internal, index-1);
						}

						return a.then(() => {return propagateLink(index+1);})
					};

					//Begin propagation.
					return propagateLink(0);
				}
			);
	}

	_lookupKey (id) {
		let idStr = ID.coerceString(id);

		//If we have it, return it.
		if(this.keyStore[idStr])
			return Promise.resolve(this.keyStore[idStr]);
		else {
			//Perform network lookup.
			return new Promise ( (resolve, reject) => {
				this.chord.lookupItem(idStr)
					.then( pubKey => {
						//If it wasn't in the network, reject the original call.
						//Also reject if the pubkey does not match the target.
						if (pubKey===null)
							reject("[Shallot] - couldn't find pubKey for "+idStr);
						else {
							let hash = sha3["sha3_"+this.chord.config.idWidth].buffer(pubKey),
								hashStr = ID.coerceString(new ID(hash));

							if (ID.compare(hashStr, id)!==0) {
								reject("[Shallot] - mismatch of obtained pubKey for "+idStr);
							} else {
								//Build a new item for future lookups, and then resolve the original call.
								let item = {
									id,
									pubKey,
									cryptor: pki.publicKeyFromPem(pubKey),
									encrypt (msg) {
										return this.cryptor.encrypt(msg, "RSA-OAEP");
									},
									verify (digest, signature) {
										return this.cryptor.verify(digest, signature);
									}
								};

								this.keyStore[idStr] = item;
								resolve(item);
							}
						}
					} )
			} )
		}
	}

	_sendOnion (aesKeys, firstHop, circ, data, index) {
		let i = (index===undefined) ? aesKeys.length-1 : index,
			iv = random.getBytesSync(16),
			out = JSON.stringify(data);

		while (i>=0) {
			out = ShallotModule.aes_encrypt(out, aesKeys[i], iv);
			i--;
		}

		let internal = {
			d: out,
			s: firstHop.encrypt(circ+iv)
		};

		return this.call(firstHop.id, "r", [internal]);
	}

	_sendBuild (firstHop, data) {
		return this.call(firstHop.id, "b", [data]);
	}

	_parseRelay (content) {
		//PACKET FORMAT
		//d: encrypted data for us to decode.
		//s: secured circuit

		//Can contain:
		//	relay - data cannot be JSON parsed, circuit has a next hop.
		//	build - data can be parsed, we must take the d field and add
		//			c and v fields (circuit+this id, signature).
		//	finish - JSON message dictating that the given circuit is an exit point.
		//			contains f: entry point's id.
		//	content - data can be JSON parsed - ouput at session attached
		//			to circuit.

		return new Promise( (resolve, reject) => {
			//Parse "s" - decrypt, then first 8 bytes are circuit, next 16 are iv for AES.
			let decS = this.rsaDecrypt(content.s),
				circ = decS.substr(0, 8),
				iv = decS.substr(8, 16);

			//We can now decrypt d.
			let packetRaw = ShallotModule.aes_decrypt(content.d, this.circuits[circ].aes, iv),
				packet = ShallotModule.determinePacket(packetRaw);

			let circData = this.circuits[circ],
				nextHop, nextCirc;

			switch (packet.type) {
				case "relay":
					//Lookup the circuit we are switching to.
					nextHop = circData.nextHop;
					nextCirc = circData.nextCirc;

					this._lookupKey(nextHop)
						.then( key => {
							//Modify the packet with c, v fields.
							let out = {s: key.encrypt(nextCirc+iv), d:packet.data}

							//Send to next hop.
							return this.call(nextHop, "r", [out])
								.then(res => resolve(res));

						})
						.catch(reason => reject(reason));
					break;
				case "build":
					//Parse the d field - this contains our next hop.
					if(circData.nextHop && circData.nextCirc){
						nextHop = circData.nextHop;
						nextCirc = circData.nextCirc;
					} else {
						nextHop = this.rsaDecrypt(packet.data.d);
						nextCirc = random.getBytesSync(8);
					}

					//Lookup next hop's public key.
					delete packet.data.d;
					this._lookupKey(nextHop)
						.then( key => {
							//Modify the packet with c, v fields.
							packet.data.c = key.encrypt(nextCirc+ID.coerceString(nextHop));
							packet.data.v = this.rsaSign(packet.data.k+packet.data.c);

							//Augment our circuit.
							this.circuits[circ].nextHop = nextHop;
							this.circuits[circ].nextCirc = nextCirc;

							//Send to next hop.
							return this._sendBuild(key, packet.data)
								.then(res => resolve(res));

						})
						.catch(reason => reject(reason));
					break;
				case "finish":
					//Read the data's f field - this is the link owner's ID.
					let startId = packet.data.f;

					//Create a new RecvSession for this circuit.
					this.circuits[circ].session = new RecvSession(this, startId);
					resolve(true);
					break;
				case "content":
					//Fire onmessage events of RecvSession attached to this circuit.
					this.circuits[circ].session.content(packet.data.c);
					resolve(true);
					break;
			}
		} );
	}

	_parseBuild (content) {
		//PACKET FORMAT
		//k: our aes key for this circuit segment
		//c: pub encypted circuit code, + last hop's ID
		//v: signature, signed by last hop.

		//First, read in AES key, circuit and last hop.
		return new Promise( (resolve, reject) => {
			let aesKey = this.rsaDecrypt(content.k),
				decC = this.rsaDecrypt(content.c),
				circ = decC.substr(0,8),
				lastHopId = decC.slice(8);

			//Now, verify the hash to ensure origin is correct.
			this._lookupKey(lastHopId)
				.then(
					key => {
						let ver = this.rsaVerify(content.k+content.c, content.v, key);

						if (!ver)
							reject("Could not verify build packet!");

						//Now, place the circuit in the internal tables.
						this.circuits[circ] = {
							aes: aesKey,
							lastHop: lastHopId,
							nextHop: null,
							nextCirc: null
						};

						resolve(true);
					},

					err => reject(err)
				)
		} );
	}

	rsaDecrypt (data) {
		return this.chord.key.privateKey.decrypt(data, "RSA-OAEP");
	}

	rsaSign (data) {
		let digestor = md.sha256.create();
		digestor.update(data);

		return this.chord.key.privateKey.sign(digestor);
	}

	rsaVerify (data, signature, key) {
		let digestor = md.sha256.create();
		digestor.update(data);

		return key.verify(digestor.digest().bytes(), signature);
	}

	static determinePacket (packetRaw) {
		//Get a packet from the inside of an onion layer.
		//Can contain:
		//	relay - data cannot be JSON parsed, circuit has a next hop.
		//	build - data can be parsed, has d,k.
		//	finish - JSON message, has f.
		//	content - data can be JSON parsed, has c

		let out = {
			type: null,
			data: null
		},
		inter;

		try {
			inter = JSON.parse(packetRaw);
		} catch (e) {
			out.type = "relay";
			out.data = packetRaw;

			return out;
		}

		if (inter.d !== undefined && inter.k !== undefined)
			out.type = "build";
		else if (inter.f !== undefined)
			out.type = "finish";
		else if (inter.c !== undefined)
			out.type = "content";
		else
			throw new Error("Illegal packet content: "+packetRaw);

		out.data = inter;

		return out;
	}

	static aes_encrypt (data, aesKey, iv) {
		let cipherObj = cipher.createCipher('AES-CBC', aesKey);

		cipherObj.start({
			iv,
			additionalData: 'binary-encoded string'
		});

		cipherObj.update(forgeUtil.createBuffer(data));
		cipherObj.finish();

		return cipherObj.output.data;
	}

	static aes_decrypt (cipherText, aesKey, iv) {
		let decipher = cipher.createDecipher('AES-CBC', aesKey);

		decipher.start({
			iv,
			additionalData: 'binary-encoded string'
		});

		decipher.update(forgeUtil.createBuffer(cipherText));
		let success = decipher.finish();

		return (success) ? decipher.output.data : null;
	}
}

module.exports = ShallotModule;<commit_msg>[Module] Fixing verification, refactoring.<commit_after>"use strict";

const RemoteCallable = require("conductor-chord").RemoteCallable,
	EventEmitter2 = require("eventemitter2").EventEmitter2,
	sha3 = require("js-sha3"),
	ID = require("conductor-chord").ID,
	pki = require("node-forge").pki,
	random = require("node-forge").random,
	cipher = require("node-forge").cipher,
	forgeUtil = require("node-forge").util,
	md = require("node-forge").md,
	u = require("./UtilFunctions.js"),
	Session = require("./Session.js"),
	RecvSession = require("./RecvSession.js");

//EVENTS
//	.on("receiveConnection", recvSession)

class ShallotModule extends RemoteCallable {
	static get defaultConfig () {
		return {
			routeLength: 3,
			callTimeout: 666,
			maxCallRetries: 3,
			rcCacheDuration: 5000
		};
	};

	constructor (chord, config) {
		super(chord, "shallot");

		this.config = u.mergeConfig(ShallotModule.defaultConfig, config);

		this._rcTimeout = this.config.callTimeout;
		this._rcRetries = this.config.maxCallRetries;
		this._rcCacheDuration = this.config.rcCacheDuration;

		this._evts = new EventEmitter2({
			maxListeners: 20
		});

		this.keyStore = {};
		this.sessions = {};
		this.circuits = {};

		chord.registerModule(this);
	}

	get emit () {
		return this._evts.emit.bind(this._evts);
	}

	get on () {
		return this._evts.on.bind(this._evts);
	}

	get off () {
		return this._evts.off.bind(this._evts);
	}

	delegate (message) {
		if(super.delegate(message))
			return;

		switch (message.handler) {
			case "r":
				//RELAY
				this._parseRelay(message.data.params[0])
					.then(
						response => this.answer(message, response)
					)
					.catch(
						reason => this.error(message, reason)
					);
				break;
			case "b":
				//BUILD
				this._parseBuild(message.data.params[0])
					.then(
						response => this.answer(message, response)
					)
					.catch(
						reason => this.error(message, reason)
					);
				break;
		}
	}

	createRouteTo (id) {
		//Generate a route.
		//This is routeLength * randomIDs, + destination.
		let routeProms = [];

		for (let i = 0; i < this.config.routeLength; i++) {
			(i=>{
				let plannedId = new ID(
					forgeUtil.encode64(random.getBytesSync(this.chord.config.idWidth/8))
				);

				// Find what key our random id maps to.
				// Lookup its public key.
				// Fail if it does not exist.
				routeProms[i] = this.chord.node.findSuccessor(plannedId)
					.then(
						node => {return this._lookupKey(node.id);}
					);
			})(i)
		}

		routeProms[this.config.routeLength] = this.chord.node.findSuccessor(id)
			.then(
				node => {
					if (ID.compare(node.id, id) !== 0)
						return Promise.reject(`Destination node ${ID.coerceString(id)} could not be found!`);

					return this._lookupKey(id);
				}
			)

		// Now await all promise resolutions.
		// Afterwards, propagate the chain to build a session.

		return Promise.all(routeProms);
	}

	connectTo (id) {
		//First, get our route.
		return this.createRouteTo(id)
			.then(
				route => {
					//Generate an AES key for each hop.
					let aesKeys = [];
					for (let i =0; i < route.length; i++)
						aesKeys.push(random.getBytesSync(16));

					//Create the first circuitID
					let firstCirc = random.getBytesSync(8);

					let propagateLink = index => {
						//End recursive promise chain.
						if(index === route.length) {
							let data = {
								f: ID.coerceString(this.chord.id)
							};

							return this._sendOnion(aesKeys, route[0], firstCirc, data)
								.then(()=> {
									return Promise.resolve(new Session(this, route, aesKeys, firstCirc));
								})
						}

						//Package the aes key for each node along the chain.
						let internal = {
							k: route[index].encrypt(aesKeys[index])
						};

						//Our promise for both paths.
						let a;

						//If sending to the first node, we have to send a full build message instead
						//of a relay.
						if (index===0) {
							this._augmentBuild(internal, route[0], firstCirc);

							a = this._sendBuild(route[0], internal);
						} else {
							//We need to inform the end of the route about the next hop.
							//Encrypt this information just for it.
							internal.d = route[index-1].encrypt(ID.coerceString(route[index].id));

							//Now wrap with as many layers as we can, and put our circuit id
							//(secured, with the iv) in the message.
							a = this._sendOnion(aesKeys, route[0], firstCirc, internal, index-1);
						}

						return a.then(() => {return propagateLink(index+1);})
					};

					//Begin propagation.
					return propagateLink(0);
				}
			);
	}

	_lookupKey (id) {
		let idStr = ID.coerceString(id);

		//If we have it, return it.
		if(this.keyStore[idStr])
			return Promise.resolve(this.keyStore[idStr]);
		else {
			//Perform network lookup.
			return new Promise ( (resolve, reject) => {
				this.chord.lookupItem(idStr)
					.then( pubKey => {
						//If it wasn't in the network, reject the original call.
						//Also reject if the pubkey does not match the target.
						if (pubKey===null)
							reject("[Shallot] - couldn't find pubKey for "+idStr);
						else {
							let hash = sha3["sha3_"+this.chord.config.idWidth].buffer(pubKey),
								hashStr = ID.coerceString(new ID(hash));

							if (ID.compare(hashStr, id)!==0) {
								reject("[Shallot] - mismatch of obtained pubKey for "+idStr);
							} else {
								//Build a new item for future lookups, and then resolve the original call.
								let item = {
									id,
									pubKey,
									cryptor: pki.publicKeyFromPem(pubKey),
									encrypt (msg) {
										return this.cryptor.encrypt(msg, "RSA-OAEP");
									},
									verify (digest, signature) {
										return this.cryptor.verify(digest, signature);
									}
								};

								this.keyStore[idStr] = item;
								resolve(item);
							}
						}
					} )
			} )
		}
	}

	_sendOnion (aesKeys, firstHop, circ, data, index) {
		let i = (index===undefined) ? aesKeys.length-1 : index,
			iv = random.getBytesSync(16),
			out = JSON.stringify(data);

		while (i>=0) {
			out = ShallotModule.aes_encrypt(out, aesKeys[i], iv);
			i--;
		}

		let internal = {
			d: out,
			s: firstHop.encrypt(circ+iv)
		};

		return this.call(firstHop.id, "r", [internal]);
	}

	_sendBuild (firstHop, data) {
		return this.call(firstHop.id, "b", [data]);
	}

	_parseRelay (content) {
		//PACKET FORMAT
		//d: encrypted data for us to decode.
		//s: secured circuit

		//Can contain:
		//	relay - data cannot be JSON parsed, circuit has a next hop.
		//	build - data can be parsed, we must take the d field and add
		//			c and v fields (circuit+this id, signature).
		//	finish - JSON message dictating that the given circuit is an exit point.
		//			contains f: entry point's id.
		//	content - data can be JSON parsed - ouput at session attached
		//			to circuit.

		return new Promise( (resolve, reject) => {
			//Parse "s" - decrypt, then first 8 bytes are circuit, next 16 are iv for AES.
			let decS = this.rsaDecrypt(content.s),
				circ = decS.substr(0, 8),
				iv = decS.substr(8, 16);

			//We can now decrypt d.
			let packetRaw = ShallotModule.aes_decrypt(content.d, this.circuits[circ].aes, iv),
				packet = ShallotModule.determinePacket(packetRaw);

			let circData = this.circuits[circ],
				nextHop, nextCirc;

			switch (packet.type) {
				case "relay":
					//Lookup the circuit we are switching to.
					nextHop = circData.nextHop;
					nextCirc = circData.nextCirc;

					this._lookupKey(nextHop)
						.then( key => {
							//Modify the packet with c, v fields.
							let out = {s: key.encrypt(nextCirc+iv), d:packet.data}

							//Send to next hop.
							return this.call(nextHop, "r", [out])
								.then(res => resolve(res));

						})
						.catch(reason => reject(reason));
					break;
				case "build":
					//Parse the d field - this contains our next hop.
					if(circData.nextHop && circData.nextCirc){
						nextHop = circData.nextHop;
						nextCirc = circData.nextCirc;
					} else {
						nextHop = this.rsaDecrypt(packet.data.d);
						nextCirc = random.getBytesSync(8);
					}

					//Lookup next hop's public key.
					this._lookupKey(nextHop)
						.then( key => {
							//Modify the packet with c, v fields.
							this._augmentBuild(packet.data, key, circ);

							//Augment our circuit.
							this.circuits[circ].nextHop = nextHop;
							this.circuits[circ].nextCirc = nextCirc;

							//Send to next hop.
							return this._sendBuild(key, packet.data)
								.then(res => resolve(res));

						})
						.catch(reason => reject(reason));
					break;
				case "finish":
					//Read the data's f field - this is the link owner's ID.
					let startId = packet.data.f;

					//Create a new RecvSession for this circuit.
					this.circuits[circ].session = new RecvSession(this, startId);
					resolve(true);
					break;
				case "content":
					//Fire onmessage events of RecvSession attached to this circuit.
					this.circuits[circ].session.content(packet.data.c);
					resolve(true);
					break;
			}
		} );
	}

	_augmentBuild (object, nexthopKey, nextCirc) {
		if (object.d)
			delete object.d;

		object.c = nexthopKey.encrypt(nextCirc+ID.coerceString(this.chord.id));
		object.v = this.rsaSign(object.k+object.c);
	}

	_parseBuild (content) {
		//PACKET FORMAT
		//k: our aes key for this circuit segment
		//c: pub encypted circuit code, + last hop's ID
		//v: signature, signed by last hop.

		//First, read in AES key, circuit and last hop.
		return new Promise( (resolve, reject) => {
			let aesKey = this.rsaDecrypt(content.k),
				decC = this.rsaDecrypt(content.c),
				circ = decC.substr(0,8),
				lastHopId = decC.slice(8);

			//Now, verify the hash to ensure origin is correct.
			this._lookupKey(lastHopId)
				.then(
					key => {
						let ver = this.rsaVerify(content.k+content.c, content.v, key);

						if (!ver)
							reject("Could not verify build packet!");

						//Now, place the circuit in the internal tables.
						this.circuits[circ] = {
							aes: aesKey,
							lastHop: lastHopId,
							nextHop: null,
							nextCirc: null
						};

						resolve(true);
					},

					err => reject(err)
				)
		} );
	}

	rsaDecrypt (data) {
		return this.chord.key.privateKey.decrypt(data, "RSA-OAEP");
	}

	rsaSign (data) {
		let digestor = md.sha256.create();
		digestor.update(data);

		return this.chord.key.privateKey.sign(digestor);
	}

	rsaVerify (data, signature, key) {
		let digestor = md.sha256.create();
		digestor.update(data);

		return key.verify(digestor.digest().bytes(), signature);
	}

	static determinePacket (packetRaw) {
		//Get a packet from the inside of an onion layer.
		//Can contain:
		//	relay - data cannot be JSON parsed, circuit has a next hop.
		//	build - data can be parsed, has d,k.
		//	finish - JSON message, has f.
		//	content - data can be JSON parsed, has c

		let out = {
			type: null,
			data: null
		},
		inter;

		try {
			inter = JSON.parse(packetRaw);
		} catch (e) {
			out.type = "relay";
			out.data = packetRaw;

			return out;
		}

		if (inter.d !== undefined && inter.k !== undefined)
			out.type = "build";
		else if (inter.f !== undefined)
			out.type = "finish";
		else if (inter.c !== undefined)
			out.type = "content";
		else
			throw new Error("Illegal packet content: "+packetRaw);

		out.data = inter;

		return out;
	}

	static aes_encrypt (data, aesKey, iv) {
		let cipherObj = cipher.createCipher('AES-CBC', aesKey);

		cipherObj.start({
			iv,
			additionalData: 'binary-encoded string'
		});

		cipherObj.update(forgeUtil.createBuffer(data));
		cipherObj.finish();

		return cipherObj.output.data;
	}

	static aes_decrypt (cipherText, aesKey, iv) {
		let decipher = cipher.createDecipher('AES-CBC', aesKey);

		decipher.start({
			iv,
			additionalData: 'binary-encoded string'
		});

		decipher.update(forgeUtil.createBuffer(cipherText));
		let success = decipher.finish();

		return (success) ? decipher.output.data : null;
	}
}

module.exports = ShallotModule;<|endoftext|>


<commit_before>// ----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// ----------------------------------------------------------------------------
var errors = require('../../utilities/errors'),
    express = require('express'),
    path = require('path');

module.exports = function(configuration) {
    var swaggerPath = resolveSwaggerUi(),
        middleware = swaggerPath && express.static(swaggerPath);

    return function (req, res, next) {
        if(swaggerPath) {
            if(!req.query.url)
                res.redirect('?url=' + swaggerUrl());
            else
                middleware(req, res, next);
        } else {
            next(errors.notFound());
        }

        function swaggerUrl() {
            // this is a bit of a hack and assumes swagger metadata is exposed in the parent directory
            var swaggerPath = path.join(req.originalUrl, '..').replace(/\\/g, '/');
            return req.protocol + '://' + req.get('host') + swaggerPath;
        }
    };

    function resolveSwaggerUi() {
        try {
            return path.dirname(require.resolve('swagger-ui'));
        } catch(error) { }
    }
};
<commit_msg>swagger ui https fix<commit_after>// ----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// ----------------------------------------------------------------------------
var errors = require('../../utilities/errors'),
    express = require('express'),
    path = require('path');

module.exports = function(configuration) {
    var swaggerPath = resolveSwaggerUi(),
        middleware = swaggerPath && express.static(swaggerPath);

    return function (req, res, next) {
        if(swaggerPath) {
            if(!req.query.url)
                res.redirect('?url=' + swaggerUrl());
            else
                middleware(req, res, next);
        } else {
            next(errors.notFound());
        }

        function swaggerUrl() {
            // this is a bit of a hack and assumes swagger metadata is exposed in the parent directory
            var swaggerPath = path.join(req.originalUrl, '..').replace(/\\/g, '/'),
                // requests are always http from the Azure Web Apps front end to the worker - detect using headers that ARR attaches
                protocol = (req.headers['x-forwarded-proto'] === 'https' || req.headers['x-arr-ssl']) ? 'https' : 'http';
            return protocol + '://' + req.get('host') + swaggerPath;
        }
    };

    function resolveSwaggerUi() {
        try {
            return path.dirname(require.resolve('swagger-ui'));
        } catch(error) { }
    }
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import unionClassNames from 'union-class-names';
import { Map } from 'immutable';

// The component we render when we encounter a hyperlink in the text
export default class Link extends Component {
  render() {
    /* eslint-disable no-use-before-define */
    const {
      decoratedText = '',
      theme = Map(),
      prefix,
      target,
      className,
      ...props,
      } = this.props;
    /* eslint-enable */
    const combinedClassName = unionClassNames(theme.get('link'), className);
    const href = decoratedText.startsWith(prefix) ? decoratedText : prefix + decoratedText;
    return (
      <a
        { ...props }
        href={ href }
        className={ combinedClassName }
        target={ target }
      />
    );
  }
}
<commit_msg>changed startsWith to indexOf check<commit_after>import React, { Component } from 'react';
import unionClassNames from 'union-class-names';
import { Map } from 'immutable';

// The component we render when we encounter a hyperlink in the text
export default class Link extends Component {
  render() {
    /* eslint-disable no-use-before-define */
    const {
      decoratedText = '',
      theme = Map(),
      prefix,
      target,
      className,
      ...props,
      } = this.props;
    /* eslint-enable */
    const combinedClassName = unionClassNames(theme.get('link'), className);
    const href = decoratedText.indexOf(prefix) === 0 ? decoratedText : prefix + decoratedText;
    return (
      <a
        { ...props }
        href={ href }
        className={ combinedClassName }
        target={ target }
      />
    );
  }
}
<|endoftext|>