<commit_before>// This is a CLI tool, using console is OK
/* eslint no-console: 0 */
const {spawn, exec} = require('child_process');
const {isAbsolute, resolve} = require('path');
const {existsSync} = require('fs');
const {version} = require('../app/package');
const pify = require('pify');
const args = require('args');
const chalk = require('chalk');
const opn = require('opn');
const columnify = require('columnify');
const got = require('got');
const ora = require('ora');
const api = require('./api');

const PLUGIN_PREFIX = 'hyper-';

let commandPromise;

const assertPluginName = pluginName => {
  if (!pluginName) {
    console.error(chalk.red('Plugin name is required'));
    process.exit(1);
  }
};

const checkConfig = () => {
  if (api.exists()) {
    return true;
  }
  let msg = chalk.red(`Error! Config file not found: ${api.configPath}\n`);
  msg += 'Please launch Hyper and retry.';
  console.error(msg);
  process.exit(1);
};

args.command(['i', 'install'], 'Install a plugin', (name, args_) => {
  checkConfig();
  const pluginName = args_[0];
  assertPluginName(pluginName);
  commandPromise = api
    .install(pluginName)
    .then(() => console.log(chalk.green(`${pluginName} installed successfully!`)))
    .catch(err => console.error(chalk.red(err)));
});

args.command(['u', 'uninstall', 'rm', 'remove'], 'Uninstall a plugin', (name, args_) => {
  checkConfig();
  const pluginName = args_[0];
  assertPluginName(pluginName);
  commandPromise = api
    .uninstall(pluginName)
    .then(() => console.log(chalk.green(`${pluginName} uninstalled successfully!`)))
    .catch(err => console.log(chalk.red(err)));
});

args.command(['ls', 'list'], 'List installed plugins', () => {
  checkConfig();
  let plugins = api.list();

  if (plugins) {
    console.log(plugins);
  } else {
    console.log(chalk.red(`No plugins installed yet.`));
  }
  process.exit(0);
});

const lsRemote = pattern => {
  // note that no errors are catched by this function
  const URL = `https://api.npms.io/v2/search?q=${(pattern && `${pattern}+`) || ''}keywords:hyper-plugin,hyper-theme`;
  return got(URL)
    .then(response => JSON.parse(response.body).results)
    .then(entries => entries.map(entry => entry.package))
    .then(entries => entries.filter(entry => entry.name.indexOf(PLUGIN_PREFIX) === 0))
    .then(entries =>
      entries.map(({name, description}) => {
        return {name, description};
      })
    )
    .then(entries =>
      entries.map(entry => {
        entry.name = chalk.green(entry.name);
        return entry;
      })
    );
};

args.command(['s', 'search'], 'Search for plugins on npm', (name, args_) => {
  const spinner = ora('Searching').start();
  const query = args_[0] ? args_[0].toLowerCase() : '';

  commandPromise = lsRemote(query)
    .then(entries => {
      if (entries.length === 0) {
        spinner.fail();
        console.error(chalk.red(`Your search '${query}' did not match any plugins`));
        console.error(`${chalk.red('Try')} ${chalk.green('hyper ls-remote')}`);
        process.exit(1);
      } else {
        let msg = columnify(entries);
        spinner.succeed();
        msg = msg.substring(msg.indexOf('\n') + 1); // remove header
        console.log(msg);
      }
    })
    .catch(err => {
      spinner.fail();
      console.error(chalk.red(err)); // TODO
    });
});

args.command(['lsr', 'list-remote', 'ls-remote'], 'List plugins available on npm', () => {
  const spinner = ora('Searching').start();

  commandPromise = lsRemote()
    .then(entries => {
      let msg = columnify(entries);

      spinner.succeed();
      msg = msg.substring(msg.indexOf('\n') + 1); // remove header
      console.log(msg);
    })
    .catch(err => {
      spinner.fail();
      console.error(chalk.red(err)); // TODO
    });
});

args.command(['d', 'docs', 'h', 'home'], 'Open the npm page of a plugin', (name, args_) => {
  const pluginName = args_[0];
  assertPluginName(pluginName);
  opn(`http://ghub.io/${pluginName}`, {wait: false});
  process.exit(0);
});

args.command(['version'], 'Show the version of hyper', () => {
  console.log(version);
  process.exit(0);
});

args.command(['<default>'], 'Launch Hyper');

args.option(['v', 'verbose'], 'Verbose mode', false);

const main = argv => {
  const flags = args.parse(argv, {
    name: 'hyper',
    version: false,
    mri: {
      boolean: ['v', 'verbose']
    }
  });

  if (commandPromise) {
    return commandPromise;
  }

  const env = Object.assign({}, process.env, {
    // this will signal Hyper that it was spawned from this module
    HYPER_CLI: '1',
    ELECTRON_NO_ATTACH_CONSOLE: '1'
  });

  delete env['ELECTRON_RUN_AS_NODE'];

  if (flags.verbose) {
    env['ELECTRON_ENABLE_LOGGING'] = '1';
  }

  const options = {
    detached: true,
    env
  };

  const args_ = args.sub.map(arg => {
    const cwd = isAbsolute(arg) ? arg : resolve(process.cwd(), arg);
    if (!existsSync(cwd)) {
      console.error(chalk.red(`Error! Directory or file does not exist: ${cwd}`));
      process.exit(1);
    }
    return cwd;
  });

  if (!flags.verbose) {
    options['stdio'] = 'ignore';
    if (process.platform === 'darwin') {
      //Use `open` to prevent multiple Hyper process
      const cmd = `open -b co.zeit.hyper ${args_}`;
      const opts = {
        env
      };
      return pify(exec)(cmd, opts);
    }
  }

  const child = spawn(process.execPath, args_, options);

  if (flags.verbose) {
    child.stdout.on('data', data => console.log(data.toString('utf8')));
    child.stderr.on('data', data => console.error(data.toString('utf8')));
  }
  if (flags.verbose) {
    return new Promise(c => child.once('exit', () => c(null)));
  }
  child.unref();
  return Promise.resolve();
};

function eventuallyExit(code) {
  setTimeout(() => process.exit(code), 100);
}

main(process.argv)
  .then(() => eventuallyExit(0))
  .catch(err => {
    console.error(err.stack ? err.stack : err);
    eventuallyExit(1);
  });
<commit_msg>fix for opn name change<commit_after>// This is a CLI tool, using console is OK
/* eslint no-console: 0 */
const {spawn, exec} = require('child_process');
const {isAbsolute, resolve} = require('path');
const {existsSync} = require('fs');
const {version} = require('../app/package');
const pify = require('pify');
const args = require('args');
const chalk = require('chalk');
const open = require('open');
const columnify = require('columnify');
const got = require('got');
const ora = require('ora');
const api = require('./api');

const PLUGIN_PREFIX = 'hyper-';

let commandPromise;

const assertPluginName = pluginName => {
  if (!pluginName) {
    console.error(chalk.red('Plugin name is required'));
    process.exit(1);
  }
};

const checkConfig = () => {
  if (api.exists()) {
    return true;
  }
  let msg = chalk.red(`Error! Config file not found: ${api.configPath}\n`);
  msg += 'Please launch Hyper and retry.';
  console.error(msg);
  process.exit(1);
};

args.command(['i', 'install'], 'Install a plugin', (name, args_) => {
  checkConfig();
  const pluginName = args_[0];
  assertPluginName(pluginName);
  commandPromise = api
    .install(pluginName)
    .then(() => console.log(chalk.green(`${pluginName} installed successfully!`)))
    .catch(err => console.error(chalk.red(err)));
});

args.command(['u', 'uninstall', 'rm', 'remove'], 'Uninstall a plugin', (name, args_) => {
  checkConfig();
  const pluginName = args_[0];
  assertPluginName(pluginName);
  commandPromise = api
    .uninstall(pluginName)
    .then(() => console.log(chalk.green(`${pluginName} uninstalled successfully!`)))
    .catch(err => console.log(chalk.red(err)));
});

args.command(['ls', 'list'], 'List installed plugins', () => {
  checkConfig();
  let plugins = api.list();

  if (plugins) {
    console.log(plugins);
  } else {
    console.log(chalk.red(`No plugins installed yet.`));
  }
  process.exit(0);
});

const lsRemote = pattern => {
  // note that no errors are catched by this function
  const URL = `https://api.npms.io/v2/search?q=${(pattern && `${pattern}+`) || ''}keywords:hyper-plugin,hyper-theme`;
  return got(URL)
    .then(response => JSON.parse(response.body).results)
    .then(entries => entries.map(entry => entry.package))
    .then(entries => entries.filter(entry => entry.name.indexOf(PLUGIN_PREFIX) === 0))
    .then(entries =>
      entries.map(({name, description}) => {
        return {name, description};
      })
    )
    .then(entries =>
      entries.map(entry => {
        entry.name = chalk.green(entry.name);
        return entry;
      })
    );
};

args.command(['s', 'search'], 'Search for plugins on npm', (name, args_) => {
  const spinner = ora('Searching').start();
  const query = args_[0] ? args_[0].toLowerCase() : '';

  commandPromise = lsRemote(query)
    .then(entries => {
      if (entries.length === 0) {
        spinner.fail();
        console.error(chalk.red(`Your search '${query}' did not match any plugins`));
        console.error(`${chalk.red('Try')} ${chalk.green('hyper ls-remote')}`);
        process.exit(1);
      } else {
        let msg = columnify(entries);
        spinner.succeed();
        msg = msg.substring(msg.indexOf('\n') + 1); // remove header
        console.log(msg);
      }
    })
    .catch(err => {
      spinner.fail();
      console.error(chalk.red(err)); // TODO
    });
});

args.command(['lsr', 'list-remote', 'ls-remote'], 'List plugins available on npm', () => {
  const spinner = ora('Searching').start();

  commandPromise = lsRemote()
    .then(entries => {
      let msg = columnify(entries);

      spinner.succeed();
      msg = msg.substring(msg.indexOf('\n') + 1); // remove header
      console.log(msg);
    })
    .catch(err => {
      spinner.fail();
      console.error(chalk.red(err)); // TODO
    });
});

args.command(['d', 'docs', 'h', 'home'], 'Open the npm page of a plugin', (name, args_) => {
  const pluginName = args_[0];
  assertPluginName(pluginName);
  open(`http://ghub.io/${pluginName}`, {wait: false, url: true});
  process.exit(0);
});

args.command(['version'], 'Show the version of hyper', () => {
  console.log(version);
  process.exit(0);
});

args.command(['<default>'], 'Launch Hyper');

args.option(['v', 'verbose'], 'Verbose mode', false);

const main = argv => {
  const flags = args.parse(argv, {
    name: 'hyper',
    version: false,
    mri: {
      boolean: ['v', 'verbose']
    }
  });

  if (commandPromise) {
    return commandPromise;
  }

  const env = Object.assign({}, process.env, {
    // this will signal Hyper that it was spawned from this module
    HYPER_CLI: '1',
    ELECTRON_NO_ATTACH_CONSOLE: '1'
  });

  delete env['ELECTRON_RUN_AS_NODE'];

  if (flags.verbose) {
    env['ELECTRON_ENABLE_LOGGING'] = '1';
  }

  const options = {
    detached: true,
    env
  };

  const args_ = args.sub.map(arg => {
    const cwd = isAbsolute(arg) ? arg : resolve(process.cwd(), arg);
    if (!existsSync(cwd)) {
      console.error(chalk.red(`Error! Directory or file does not exist: ${cwd}`));
      process.exit(1);
    }
    return cwd;
  });

  if (!flags.verbose) {
    options['stdio'] = 'ignore';
    if (process.platform === 'darwin') {
      //Use `open` to prevent multiple Hyper process
      const cmd = `open -b co.zeit.hyper ${args_}`;
      const opts = {
        env
      };
      return pify(exec)(cmd, opts);
    }
  }

  const child = spawn(process.execPath, args_, options);

  if (flags.verbose) {
    child.stdout.on('data', data => console.log(data.toString('utf8')));
    child.stderr.on('data', data => console.error(data.toString('utf8')));
  }
  if (flags.verbose) {
    return new Promise(c => child.once('exit', () => c(null)));
  }
  child.unref();
  return Promise.resolve();
};

function eventuallyExit(code) {
  setTimeout(() => process.exit(code), 100);
}

main(process.argv)
  .then(() => eventuallyExit(0))
  .catch(err => {
    console.error(err.stack ? err.stack : err);
    eventuallyExit(1);
  });
<|endoftext|>


<commit_before>/* extra stuff */

'use strict';

window.addEventListener('DOMContentLoaded', function () {
    angular.module('swiftBrowserE2E').run(function (swiftSim) {
        var text = [
            'Hey, this is some text. Have fun editing it!',
            '',
            '--Sincerely, the Swift Browser developers'
        ];
        var python = [
            'import math',
            '',
            'def primes(n):',
            '    """',
            '    Find all primes less than n.',
            '',
            '    >>> primes(3)',
            '    [2]',
            '    >>> primes(15)',
            '    [2, 3, 5, 7, 11, 13]',
            '    """',
            '    candidates = [True] * n',
            '    candidates[0] = candidates[1] = False',
            '    stop = int(math.sqrt(n))',
            '    for i in range(2, stop + 1):',
            '        if candidates[i]:',
            '            for j in range(2 * i, n, i):',
            '                candidates[j] = False',
            '    return [i for (i, c) in enumerate(candidates) if c]',
            '',
            'print "Primes below 20:", ", ".join(map(str, primes(20)))'
        ];
        var html = [
            '<!DOCTYPE html>',
            '',
            '  ',
            '    <meta charset="utf-8">',
            '    <title>Test Page</title>',
            '  ',
            '',
            '  ',
            '
Welcome!
',
            '
Pretty cool!
',
            '  ',
            ''
        ];

        swiftSim.addContainer('empty container');
        swiftSim.setObjects('foo', {
            'x.txt': {headers: {
                'Last-Modified': 'Sat, 16 Aug 2014 13:33:21 GMT',
                'Content-Type': 'text/plain'
            }, content: text.join('\n')},
            'primes.py': {headers: {
                'Last-Modified': 'Sat, 16 Aug 2014 13:33:21 GMT',
                'Content-Type': 'text/x-python'
            }, content: python.join('\n')},
            'nested/z.html': {headers: {
                'Last-Modified': 'Sat, 16 Aug 2014 13:33:21 GMT',
                'Content-Type': 'text/html'
            }, content: html.join('\n')}
        });

        /* Simple linear congruential random generator */
        var rand = (function () {
            var state = 1;
            var a = 31;
            var c = 11;
            var m = 50;
            return function () {
                state = (a * state + c) % m;
                return state;
            };
        })();

        var large = {};
        for (var i = 0; i < 1234; i++) {
            var r = rand();
            var xs = new Array(r + 1).join('x');
            var content = [
                'This is object ' + i + '.',
                '',
                'Here are: ' + r + " x's: " + xs + '.'
            ];
            large['o-' + i] = {
                headers: {
                    'Last-Modified': 'Sat, 16 Aug 2014 13:33:21 GMT',
                    'Content-Type': 'text/plain'
                }, content: content.join('\n')
            };
        }
        swiftSim.setObjects('large', large);
    });
    angular.resumeBootstrap(['swiftBrowserE2E']);
});
<commit_msg>mock-env: test for #94<commit_after>/* extra stuff */

'use strict';

window.addEventListener('DOMContentLoaded', function () {
    angular.module('swiftBrowserE2E').run(function (swiftSim) {
        var text = [
            'Hey, this is some text. Have fun editing it!',
            '',
            '--Sincerely, the Swift Browser developers'
        ];
        var python = [
            'import math',
            '',
            'def primes(n):',
            '    """',
            '    Find all primes less than n.',
            '',
            '    >>> primes(3)',
            '    [2]',
            '    >>> primes(15)',
            '    [2, 3, 5, 7, 11, 13]',
            '    """',
            '    candidates = [True] * n',
            '    candidates[0] = candidates[1] = False',
            '    stop = int(math.sqrt(n))',
            '    for i in range(2, stop + 1):',
            '        if candidates[i]:',
            '            for j in range(2 * i, n, i):',
            '                candidates[j] = False',
            '    return [i for (i, c) in enumerate(candidates) if c]',
            '',
            'print "Primes below 20:", ", ".join(map(str, primes(20)))'
        ];
        var html = [
            '<!DOCTYPE html>',
            '',
            '  ',
            '    <meta charset="utf-8">',
            '    <title>Test Page</title>',
            '  ',
            '',
            '  ',
            '
Welcome!
',
            '
Pretty cool!
',
            '  ',
            ''
        ];

        swiftSim.addContainer('empty container');
        swiftSim.setObjects('foo', {
            'x.txt': {headers: {
                'Last-Modified': 'Sat, 16 Aug 2014 13:33:21 GMT',
                'Content-Type': 'text/plain'
            }, content: text.join('\n')},
            'primes.py': {headers: {
                'Last-Modified': 'Sat, 16 Aug 2014 13:33:21 GMT',
                'Content-Type': 'text/x-python'
            }, content: python.join('\n')},
            'nested/z.html': {headers: {
                'Last-Modified': 'Sat, 16 Aug 2014 13:33:21 GMT',
                'Content-Type': 'text/html'
            }, content: html.join('\n')}
        });

        /* Simple linear congruential random generator */
        var rand = (function () {
            var state = 1;
            var a = 31;
            var c = 11;
            var m = 50;
            return function () {
                state = (a * state + c) % m;
                return state;
            };
        })();

        var large = {};
        for (var i = 0; i < 1234; i++) {
            var r = rand();
            var xs = new Array(r + 1).join('x');
            var content = [
                'This is object ' + i + '.',
                '',
                'Here are: ' + r + " x's: " + xs + '.'
            ];
            large['o-' + i] = {
                headers: {
                    'Last-Modified': 'Sat, 16 Aug 2014 13:33:21 GMT',
                    'Content-Type': 'text/plain'
                }, content: content.join('\n')
            };
        }
        swiftSim.setObjects('large', large);

        swiftSim.setObjects('deep', {
            'this/is/a/deeply/nested/object.txt': {headers: {
                'Last-Modified': 'Sat, 16 Aug 2014 13:33:21 GMT',
                'Content-Type': 'text/plain'
            }, content: 'Maybe we could short-circuit the directories?\n'}
        });
    });
    angular.resumeBootstrap(['swiftBrowserE2E']);
});
<|endoftext|>


<commit_before>ContactManager.Views.Contact = Backbone.View.extend({
  tagName: 'li',
  className: 'media col-md-6 col-lg-4',
  template: _.template($('#tpl-contact').html()),

  events: {
    'click .delete-contract': 'onClickDelete'
  },

  initialize: function() {
    this.listenTo(this.model, 'remove', this.remove);
  },

  render: function() {
    var html = this.template(this.model.toJSON());
    this.$el.append(html);
    return this;
  },

  onClickDelete: function(e) {
    e.preventDefault();
    this.model.collection.remove(this.model);
  }
});
<commit_msg>Use ItemView in contact view<commit_after>ContactManager.Views.Contact = Marionette.ItemView.extend({
  tagName: 'li',
  className: 'media col-md-6 col-lg-4',
  template: '#tpl-contact',

  events: {
    'click .delete-contract': 'onClickDelete'
  },

  modelEvents: {
    'remove': 'close'
  },

  onClickDelete: function(e) {
    e.preventDefault();
    this.model.collection.remove(this.model);
  }
});
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2016 - present Instructure, Inc.
 *
 * This file is part of Canvas.
 *
 * Canvas is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation, version 3 of the License.
 *
 * Canvas 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 GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

import canvasBaseTheme from '@instructure/canvas-theme'
import canvasHighContrastTheme from '@instructure/canvas-high-contrast-theme'
import moment from 'moment'
import tz from 'timezone_core'
import './fakeRequireJSFallback'

// we already put a <script> tag for the locale corresponding ENV.MOMENT_LOCALE
// on the page from rails, so this should not cause a new network request.
moment().locale(ENV.MOMENT_LOCALE)

// These timezones and locales should already be put on the page as <script>
// tags from rails. this block should not create any network requests.
if (typeof ENV !== 'undefined') {
  if (ENV.TIMEZONE) tz.changeZone(ENV.TIMEZONE)
  if (ENV.CONTEXT_TIMEZONE) tz.preload(ENV.CONTEXT_TIMEZONE)
  if (ENV.BIGEASY_LOCALE) tz.changeLocale(ENV.BIGEASY_LOCALE, ENV.MOMENT_LOCALE)
}

// This will inject and set up sentry for deprecation reporting.  It should be
// stripped out and be a no-op in production.
if (process.env.NODE_ENV !== 'production' && process.env.DEPRECATION_SENTRY_DSN) {
  const Raven = require('raven-js')
  Raven.config(process.env.DEPRECATION_SENTRY_DSN, {
    ignoreErrors: ['renderIntoDiv', 'renderSidebarIntoDiv'], // silence the `Cannot read property 'renderIntoDiv' of null` errors we get from the pre- rce_enhancements old rce code
    release: process.env.GIT_COMMIT
  }).install()

  const setupRavenConsoleLoggingPlugin = require('../jsx/shared/helpers/setupRavenConsoleLoggingPlugin')
    .default
  setupRavenConsoleLoggingPlugin(Raven, {loggerName: 'console'})
}

if (process.env.NODE_ENV !== 'production') {
  const {
    filterUselessConsoleMessages
  } = require('@instructure/js-utils/lib/filterUselessConsoleMessages')
  filterUselessConsoleMessages(console)
}

// setup the inst-ui default theme
if (ENV.use_high_contrast) {
  canvasHighContrastTheme.use()
} else {
  const brandvars = window.CANVAS_ACTIVE_BRAND_VARIABLES || {}

  // Set CSS transitions to 0ms in Selenium and JS tests
  let transitionOverride = {}
  if (process.env.NODE_ENV === 'test' || window.INST.environment === 'test') {
    transitionOverride = {
      transitions: {
        duration: '0ms'
      }
    }
  }

  canvasBaseTheme.use({
    overrides: {...transitionOverride, ...brandvars}
  })
}

/* #__PURE__ */ if (process.env.NODE_ENV === 'test' || window.INST.environment === 'test') {
  // This is for the `wait_for_ajax_requests` method in selenium
  window.__CANVAS_IN_FLIGHT_XHR_REQUESTS__ = 0
  const send = XMLHttpRequest.prototype.send
  XMLHttpRequest.prototype.send = function() {
    window.__CANVAS_IN_FLIGHT_XHR_REQUESTS__++
    // 'loadend' gets fired after both successful and errored requests
    this.addEventListener('loadend', () => {
      window.__CANVAS_IN_FLIGHT_XHR_REQUESTS__--
      window.dispatchEvent(new CustomEvent('canvasXHRComplete'))
    })
    return send.apply(this, arguments)
  }

  // and this so it also tracks `fetch` requests
  const fetch = window.fetch
  window.fetch = function() {
    window.__CANVAS_IN_FLIGHT_XHR_REQUESTS__++
    const promise = fetch.apply(this, arguments)
    promise.finally(() => window.__CANVAS_IN_FLIGHT_XHR_REQUESTS__--)
    return promise
  }
}
<commit_msg>Override canvas theme to use Lato Extended font<commit_after>/*
 * Copyright (C) 2016 - present Instructure, Inc.
 *
 * This file is part of Canvas.
 *
 * Canvas is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation, version 3 of the License.
 *
 * Canvas 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 GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

import canvasBaseTheme from '@instructure/canvas-theme'
import canvasHighContrastTheme from '@instructure/canvas-high-contrast-theme'
import moment from 'moment'
import tz from 'timezone_core'
import './fakeRequireJSFallback'

// we already put a <script> tag for the locale corresponding ENV.MOMENT_LOCALE
// on the page from rails, so this should not cause a new network request.
moment().locale(ENV.MOMENT_LOCALE)

// These timezones and locales should already be put on the page as <script>
// tags from rails. this block should not create any network requests.
if (typeof ENV !== 'undefined') {
  if (ENV.TIMEZONE) tz.changeZone(ENV.TIMEZONE)
  if (ENV.CONTEXT_TIMEZONE) tz.preload(ENV.CONTEXT_TIMEZONE)
  if (ENV.BIGEASY_LOCALE) tz.changeLocale(ENV.BIGEASY_LOCALE, ENV.MOMENT_LOCALE)
}

// This will inject and set up sentry for deprecation reporting.  It should be
// stripped out and be a no-op in production.
if (process.env.NODE_ENV !== 'production' && process.env.DEPRECATION_SENTRY_DSN) {
  const Raven = require('raven-js')
  Raven.config(process.env.DEPRECATION_SENTRY_DSN, {
    ignoreErrors: ['renderIntoDiv', 'renderSidebarIntoDiv'], // silence the `Cannot read property 'renderIntoDiv' of null` errors we get from the pre- rce_enhancements old rce code
    release: process.env.GIT_COMMIT
  }).install()

  const setupRavenConsoleLoggingPlugin = require('../jsx/shared/helpers/setupRavenConsoleLoggingPlugin')
    .default
  setupRavenConsoleLoggingPlugin(Raven, {loggerName: 'console'})
}

if (process.env.NODE_ENV !== 'production') {
  const {
    filterUselessConsoleMessages
  } = require('@instructure/js-utils/lib/filterUselessConsoleMessages')
  filterUselessConsoleMessages(console)
}

// setup the inst-ui default theme
// override the fontFamily to include "Lato Extended", which we prefer
// to load over plain Lato (see LS-1559)
if (ENV.use_high_contrast) {
  canvasHighContrastTheme.use({
    overrides: {
      typography: {
        fontFamily: 'LatoWeb, "Lato Extended", Lato, "Helvetica Neue", Helvetica, Arial, sans-serif'
      }
    }
  })
} else {
  const brandvars = window.CANVAS_ACTIVE_BRAND_VARIABLES || {}

  // Set CSS transitions to 0ms in Selenium and JS tests
  let transitionOverride = {}
  if (process.env.NODE_ENV === 'test' || window.INST.environment === 'test') {
    transitionOverride = {
      transitions: {
        duration: '0ms'
      }
    }
  }

  canvasBaseTheme.use({
    overrides: {
      ...transitionOverride,
      ...brandvars,
      typography: {
        fontFamily: 'LatoWeb, "Lato Extended", Lato, "Helvetica Neue", Helvetica, Arial, sans-serif'
      }
    }
  })
}

/* #__PURE__ */ if (process.env.NODE_ENV === 'test' || window.INST.environment === 'test') {
  // This is for the `wait_for_ajax_requests` method in selenium
  window.__CANVAS_IN_FLIGHT_XHR_REQUESTS__ = 0
  const send = XMLHttpRequest.prototype.send
  XMLHttpRequest.prototype.send = function() {
    window.__CANVAS_IN_FLIGHT_XHR_REQUESTS__++
    // 'loadend' gets fired after both successful and errored requests
    this.addEventListener('loadend', () => {
      window.__CANVAS_IN_FLIGHT_XHR_REQUESTS__--
      window.dispatchEvent(new CustomEvent('canvasXHRComplete'))
    })
    return send.apply(this, arguments)
  }

  // and this so it also tracks `fetch` requests
  const fetch = window.fetch
  window.fetch = function() {
    window.__CANVAS_IN_FLIGHT_XHR_REQUESTS__++
    const promise = fetch.apply(this, arguments)
    promise.finally(() => window.__CANVAS_IN_FLIGHT_XHR_REQUESTS__--)
    return promise
  }
}
<|endoftext|>


<commit_before>const Promise = require('bluebird');
const fsExtra = Promise.promisifyAll(require('fs-extra'));
const fs   = Promise.promisifyAll(require('fs'));
const uuid = require('uuid');
const exec = require('child_process').exec;

class Disassembler {

  constructor(options={logger, guid}) {
    this.logger = options.logger;
    this.guid = options.guid;
  }

  run(code, done, tmpDir="/tmp/javabytes") {
    this.findUniqueDir(tmpDir)
    .then((args) => {
      return this.makeDir({dirName: args.dirName, code});
    })
    .then((args) => {
      return this.compileJavaFile(args);
    })
    .then((args) => {
      return this.disassemble(args);
    })
    .then((args) => {
      return this.cleanup(args);
    })
    .then((obj) => {
      done(obj);
    })
    .catch((obj) => {
      done(obj);
    });
  }

  // make a tmp dir where work can happen
  makeDir(obj) {
    const dirName = obj.dirName;
    const code = obj.code;
    return new Promise((resolve, reject) => {
      fsExtra.mkdirs(dirName, function(err) {
        if (err) {
          reject(err);
        } else {
          resolve({dirName, code});
        }
      });
    });
  }

  // creates and compiles the java source
  compileJavaFile(obj) {
    const dirName = obj.dirName;
    const code = obj.code;
    return new Promise((resolve, reject) => {
      const classname = this.extractClass(code);
      const fileLocation = `${dirName}/${classname}.java`;

      fsExtra.outputFile(fileLocation, code, (err) => {
        if (err) {
          this.logger.error(err);
          reject({
            errors: "Unable to create file"
          });
        }

        exec(`javac ${fileLocation}`, {shell: '/bin/bash'}, (error, stdout, stderr) => {
          if (error) {
            this.logger.error(`${this.guid}: Error -> ${error}`);
            reject({ errors: error });
          } else if (stderr) {
            this.logger.error(`${this.guid}: Stderr-> ${stderr}`);
            reject({ errors: this.cleanseOutput(stderr, `${dirName}/`) });
          } else {
            this.logger.verbose(`${this.guid}: Disassembling successful`);
            resolve({dirName, classname});
          }
        });
      });
    });
  }

  // disassembles the given source class file
  disassemble(obj) {
    const dirName = obj.dirName;
    const classname = obj.classname;
    return new Promise( (resolve, reject) => {
      const cmd = `javap -c ${dirName}/${classname}.class`;
      exec(cmd, (error, stdout, stderr) => {
        if (stderr) {
          this.logger.error(stderr);
          reject({
            errors: this.cleanseOutput(stderr, `${dirName}/`)
          });
        } else {
          resolve({
            result: stdout,
            dirName
          });
        }
      });
    });
  }

  // delete tmp files
  cleanup(obj) {
    const dirName = obj.dirName;
    const result = obj.result;
    return new Promise((resolve, reject) => {
      fsExtra.remove(dirName, function(){});
      resolve({result});
    });
  }

  // find a unique directory name
  findUniqueDir(tmpDir) {
    const guid = uuid.v4().replace(/-/g, '');
    const dirName = `${tmpDir}/${guid}`;
    return new Promise((resolve, reject) => {
      fs.stat(dirName, (err, stats) => {
        if (err) {
          resolve({dirName});
        } else {
          findUniqueDir();
        }
      });
    });
  }

  // extract class name
  extractClass(code) {
    const pattern = /\s*(public|private)\s+class\s+(\w+)\s+((extends\s+\w+)|(implements\s+\w+( ,\w+)*))?\s*\{/;
    const matches = pattern.exec(code);
    if (matches) {
      return matches[2];
    } else {
      return uuid.v4();
    }
  }

  // remove the randomly generated dir names and make it into a valid json obj
  cleanseOutput(output, location) {
    const re = new RegExp(location, "g");
    return output.replace(re, '').replace(/"/g, '\\"');
  }
}

module.exports = Disassembler;
<commit_msg>cleaned up exec and used execfile<commit_after>const Promise = require('bluebird');
const fsExtra = Promise.promisifyAll(require('fs-extra'));
const fs   = Promise.promisifyAll(require('fs'));
const uuid = require('uuid');
const exec = require('child_process').execFile;

class Disassembler {

  constructor(options={logger, guid}) {
    this.logger = options.logger;
    this.guid = options.guid;
  }

  run(code, done, tmpDir="/tmp/javabytes") {
    this.findUniqueDir(tmpDir)
    .then((args) => {
      return this.makeDir({dirName: args.dirName, code});
    })
    .then((args) => {
      return this.compileJavaFile(args);
    })
    .then((args) => {
      return this.disassemble(args);
    })
    .then((args) => {
      return this.cleanup(args);
    })
    .then((obj) => {
      done(obj);
    })
    .catch((obj) => {
      done(obj);
    });
  }

  // make a tmp dir where work can happen
  makeDir(obj) {
    const dirName = obj.dirName;
    const code = obj.code;
    return new Promise((resolve, reject) => {
      fsExtra.mkdirs(dirName, function(err) {
        if (err) {
          reject(err);
        } else {
          resolve({dirName, code});
        }
      });
    });
  }

  // creates and compiles the java source
  compileJavaFile(obj) {
    const dirName = obj.dirName;
    const code = obj.code;
    return new Promise((resolve, reject) => {
      const classname = this.extractClass(code);
      const fileLocation = `${dirName}/${classname}.java`;

      fsExtra.outputFile(fileLocation, code, (err) => {
        if (err) {
          this.logger.error(err);
          reject({
            errors: "Unable to create file"
          });
        }

        exec(`javac ${fileLocation}`, {shell: '/bin/bash'}, (error, stdout, stderr) => {
          if (stderr) {
            this.logger.error(`${this.guid}: Stderr-> ${stderr}`);
            reject({ errors: this.cleanseOutput(stderr, `${dirName}/`) });
          } else {
            this.logger.verbose(`${this.guid}: Disassembling successful`);
            resolve({dirName, classname});
          }
        });
      });
    });
  }

  // disassembles the given source class file
  disassemble(obj) {
    const dirName = obj.dirName;
    const classname = obj.classname;
    return new Promise( (resolve, reject) => {
      exec(`javap -c ${dirName}/${classname}.class`, {shell: '/bin/bash'}, (error, stdout, stderr) => {
        if (stderr) {
          this.logger.error(stderr);
          reject({
            errors: this.cleanseOutput(stderr, `${dirName}/`)
          });
        } else {
          resolve({
            result: stdout,
            dirName
          });
        }
      });
    });
  }

  // delete tmp files
  cleanup(obj) {
    const dirName = obj.dirName;
    const result = obj.result;
    return new Promise((resolve, reject) => {
      fsExtra.remove(dirName, function(){});
      resolve({result});
    });
  }

  // find a unique directory name
  findUniqueDir(tmpDir) {
    const guid = uuid.v4().replace(/-/g, '');
    const dirName = `${tmpDir}/${guid}`;
    return new Promise((resolve, reject) => {
      fs.stat(dirName, (err, stats) => {
        if (err) {
          resolve({dirName});
        } else {
          findUniqueDir();
        }
      });
    });
  }

  // extract class name
  extractClass(code) {
    const pattern = /\s*(public|private)\s+class\s+(\w+)\s+((extends\s+\w+)|(implements\s+\w+( ,\w+)*))?\s*\{/;
    const matches = pattern.exec(code);
    if (matches) {
      return matches[2];
    } else {
      return uuid.v4();
    }
  }

  // remove the randomly generated dir names and make it into a valid json obj
  cleanseOutput(output, location) {
    const re = new RegExp(location, "g");
    return output.replace(re, '').replace(/"/g, '\\"');
  }
}

module.exports = Disassembler;
<|endoftext|>


<commit_before>// @flow

import split2 from 'split2'
import { spawn } from 'child_process'
import EventEmitter from 'events'
import getPort from 'get-port'
import isDev from 'electron-is-dev'
import { mainLog, lndLog, lndLogGetLevel } from '../utils/log'
import { fetchBlockHeight } from './util'
import LndConfig from './config'

// Sync statuses
const CHAIN_SYNC_PENDING = 'chain-sync-pending'
const CHAIN_SYNC_WAITING = 'chain-sync-waiting'
const CHAIN_SYNC_IN_PROGRESS = 'chain-sync-started'
const CHAIN_SYNC_COMPLETE = 'chain-sync-finished'

// Events
const ERROR = 'error'
const EXIT = 'exit'
const WALLET_UNLOCKER_GRPC_ACTIVE = 'wallet-unlocker-grpc-active'
const LIGHTNING_GRPC_ACTIVE = 'lightning-grpc-active'
const GOT_CURRENT_BLOCK_HEIGHT = 'got-current-block-height'
const GOT_LND_BLOCK_HEIGHT = 'got-lnd-block-height'
const GOT_LND_CFILTER_HEIGHT = 'got-lnd-cfilter-height'

// Settings
const DEFAULT_RPC_PORT = 11009
const DEFAULT_REST_PORT = 8180

/**
 * Wrapper class for Lnd to run and monitor it in Neutrino mode.
 * @extends EventEmitter
 */
class Neutrino extends EventEmitter {
  lndConfig: LndConfig
  process: any
  isWalletUnlockerGrpcActive: boolean
  isLightningGrpcActive: boolean
  chainSyncStatus: string
  currentBlockHeight: number
  lndBlockHeight: number
  lndCfilterHeight: number
  lastError: ?string

  constructor(lndConfig: LndConfig) {
    super()
    this.lndConfig = lndConfig
    this.process = null
    this.isWalletUnlockerGrpcActive = false
    this.isLightningGrpcActive = false
    this.chainSyncStatus = CHAIN_SYNC_PENDING
    this.currentBlockHeight = 0
    this.lndBlockHeight = 0
    this.lndCfilterHeight = 0
    this.lastError = null
  }

  static incrementIfHigher = (context: any, property: string, newVal: any): boolean => {
    const { [property]: oldVal } = context
    if (newVal > oldVal) {
      context[property] = newVal
      return true
    }
    return false
  }

  /**
   * Start the Lnd process in Neutrino mode.
   * @return {Number} PID of the Lnd process that was started.
   */
  async start() {
    if (this.process) {
      return Promise.reject(
        new Error('Neutrino process with PID ${this.process.pid} already exists.')
      )
    }

    // The height returned from the LND log output may not be the actual current block height (this is the case
    // when BTCD is still in the middle of syncing the blockchain) so try to fetch thhe current height from from
    // some block explorers so that we have a good starting point.
    try {
      const blockHeight = await fetchBlockHeight(this.lndConfig.chain, this.lndConfig.network)
      this.setCurrentBlockHeight(blockHeight)
    } catch (err) {
      mainLog.warn(`Unable to fetch block height: ${err.message}`)
    }

    mainLog.info('Starting lnd in neutrino mode')
    mainLog.info(' > binaryPath', this.lndConfig.binaryPath)
    mainLog.info(' > chain', this.lndConfig.chain)
    mainLog.info(' > network', this.lndConfig.network)
    mainLog.info(' > host:', this.lndConfig.host)
    mainLog.info(' > cert:', this.lndConfig.cert)
    mainLog.info(' > macaroon:', this.lndConfig.macaroon)

    // Get a free port to use as the rpc listen address.
    const rpcListen = isDev
      ? await getPort({
          host: 'localhost',
          port: [10009, 10008, 10007, 10006, 10005, 10004, 10003, 10002, 10001],
        })
      : DEFAULT_RPC_PORT
    this.lndConfig.host = `localhost:${rpcListen}`

    // Get a free port to use as the rest listen address.
    const restListen = isDev
      ? await getPort({
          host: 'localhost',
          port: [8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087, 8088, 8089],
        })
      : DEFAULT_REST_PORT

    // Get a free port to use as the p2p listen address.
    const p2pListen = await getPort({
      host: '0.0.0.0',
      port: [9735, 9734, 9733, 9732, 9731, 9736, 9737, 9738, 9739],
    })

    // Genreate autopilot config.
    const autopilotArgMap: Object = {
      autopilotAllocation: '--autopilot.allocation',
      autopilotMaxchannels: '--autopilot.maxchannels',
      autopilotMinchansize: '--autopilot.minchansize',
      autopilotMaxchansize: '--autopilot.maxchansize',
      autopilotMinconfs: '--autopilot.minconfs',
    }
    const autopilotConf = []
    Object.entries(this.lndConfig).forEach(([key, value]) => {
      if (Object.keys(autopilotArgMap).includes(key)) {
        autopilotConf.push(`${autopilotArgMap[key]}=${String(value)}`)
      }
    })

    // Configure lnd.
    const neutrinoArgs = [
      `--configfile=${this.lndConfig.configPath}`,
      `--lnddir=${this.lndConfig.lndDir}`,
      `--listen=0.0.0.0:${p2pListen}`,
      `--rpclisten=localhost:${rpcListen}`,
      `--restlisten=localhost:${restListen}`,
      `${this.lndConfig.alias ? `--alias=${this.lndConfig.alias}` : ''}`,
      `${this.lndConfig.autopilot ? '--autopilot.active' : ''}`,
      `${this.lndConfig.autopilotPrivate ? '--autopilot.private' : ''}`,
      ...autopilotConf,
    ]

    // Configure neutrino backend.
    neutrinoArgs.push(`--${this.lndConfig.chain}.${this.lndConfig.network}`)
    global.CONFIG.neutrino.connect[this.lndConfig.network].forEach(node =>
      neutrinoArgs.push(`--neutrino.connect=${node}`)
    )

    // When not on mainnet, enable the experimental assumechanvalid flag.
    if (this.lndConfig.network !== 'mainnet') {
      neutrinoArgs.push(`--routing.assumechanvalid`)
    }

    // Log the final config.
    mainLog.info(
      'Spawning Neutrino process: %s %s',
      this.lndConfig.binaryPath,
      neutrinoArgs.filter(v => v != '').join(' ')
    )

    // Spawn lnd process.
    this.process = spawn(this.lndConfig.binaryPath, neutrinoArgs)
      .on('error', error => {
        mainLog.debug('Neutrino process received "error" event with error: %s', error)
        this.emit(ERROR, error, this.lastError)
      })
      .on('exit', (code, signal) => {
        mainLog.debug(
          'Neutrino process received "exit" event with code %s and signal %s',
          code,
          signal
        )
        this.emit(EXIT, code, signal, this.lastError)
        this.process = null
      })

    // Listen for when neutrino prints data to stderr.
    this.process.stderr.pipe(split2()).on('data', line => {
      lndLog.error(line)
      if (line.startsWith('panic:')) {
        this.lastError = line
      }
    })

    // Listen for when neutrino prints data to stdout.
    this.process.stdout.pipe(split2()).on('data', line => {
      const level = lndLogGetLevel(line)
      lndLog[level](line)
      if (level === 'error') {
        this.lastError = line.split('[ERR] LTND:')[1]
      }

      // password RPC server listening (wallet unlocker started).
      if (!this.isWalletUnlockerGrpcActive && !this.isLightningGrpcActive) {
        if (line.includes('RPC server listening on') && line.includes('password')) {
          this.isWalletUnlockerGrpcActive = true
          this.emit(WALLET_UNLOCKER_GRPC_ACTIVE)
        }
      }

      // RPC server listening (wallet unlocked).
      if (!this.isLightningGrpcActive) {
        if (line.includes('RPC server listening on') && !line.includes('password')) {
          this.isLightningGrpcActive = true
          this.emit(LIGHTNING_GRPC_ACTIVE)
        }
      }

      // If the sync has already completed then we don't need to do anything else.
      if (this.is(CHAIN_SYNC_COMPLETE)) {
        return
      }

      if (this.is(CHAIN_SYNC_PENDING) || this.is(CHAIN_SYNC_IN_PROGRESS)) {
        // If we can't get a connectionn to the backend.
        if (
          line.includes('Waiting for chain backend to finish sync') ||
          line.includes('Waiting for block headers to sync, then will start cfheaders sync')
        ) {
          this.setState(CHAIN_SYNC_WAITING)
        }
        // If we are still waiting for the back end to finish synncing.
        if (line.includes('No sync peer candidates available')) {
          this.setState(CHAIN_SYNC_WAITING)
        }
      }

      // Lnd syncing has started or resumed.
      if (this.is(CHAIN_SYNC_PENDING) || this.is(CHAIN_SYNC_WAITING)) {
        const match =
          line.match(/Syncing to block height (\d+)/) ||
          line.match(/Starting cfilters sync at block_height=(\d+)/)

        if (match) {
          // Notify that chhain syncronisation has now started.
          this.setState(CHAIN_SYNC_IN_PROGRESS)

          // This is the latest block that BTCd is aware of.
          const btcdHeight = match[1]
          this.setCurrentBlockHeight(btcdHeight)
        }
      }

      // Lnd as received some updated block data.
      if (this.is(CHAIN_SYNC_WAITING) || this.is(CHAIN_SYNC_IN_PROGRESS)) {
        let height
        let cfilter
        let match

        if ((match = line.match(/Caught up to height (\d+)/))) {
          height = match[1]
        } else if ((match = line.match(/Processed \d* blocks? in the last.+\(height (\d+)/))) {
          height = match[1]
        } else if ((match = line.match(/Difficulty retarget at block height (\d+)/))) {
          height = match[1]
        } else if ((match = line.match(/Fetching set of headers from tip \(height=(\d+)/))) {
          height = match[1]
        } else if ((match = line.match(/Waiting for filter headers \(height=(\d+)\) to catch/))) {
          height = match[1]
        } else if ((match = line.match(/Writing filter headers up to height=(\d+)/))) {
          height = match[1]
        } else if ((match = line.match(/Starting cfheaders sync at block_height=(\d+)/))) {
          height = match[1]
        } else if ((match = line.match(/Got cfheaders from height=(\d*) to height=(\d+)/))) {
          cfilter = match[2]
        } else if ((match = line.match(/Writing filter headers up to height=(\d*)/))) {
          cfilter = match[1]
        } else if ((match = line.match(/Verified \d* filter headers? in the.+\(height (\d+)/))) {
          cfilter = match[1]
        } else if ((match = line.match(/Fetching filter for height=(\d+)/))) {
          cfilter = match[1]
        }

        if (height) {
          this.setState(CHAIN_SYNC_IN_PROGRESS)
          this.setLndBlockHeight(height)
        }

        if (cfilter) {
          this.setState(CHAIN_SYNC_IN_PROGRESS)
          this.setLndCfilterHeight(cfilter)
        }

        // Lnd syncing has completed.
        if (line.includes('Chain backend is fully synced')) {
          this.setState(CHAIN_SYNC_COMPLETE)
        }
      }
    })

    return this.process
  }

  /**
   * Stop the Lnd process.
   */
  kill(signalName: string = 'SIGINT') {
    if (this.process) {
      mainLog.info('Killing Neutrino process...')
      this.process.kill(signalName)
    }
  }

  /**
   * Check if the current state matches the pasted in state.
   * @param  {String} state State to compare against the current state.
   * @return {Boolean} Boolean indicating if the current state matches the passed in state.
   */
  is(state: string) {
    return this.chainSyncStatus === state
  }

  /**
   * Set the current state and emit an event to notify others if the state as changed.
   * @param {String} state Target state.
   */
  setState(state: string) {
    if (state !== this.chainSyncStatus) {
      this.chainSyncStatus = state
      this.emit(state)
    }
  }

  /**
   * Set the current block height and emit an event to notify others if it has changed.
   * @param {String|Number} height Block height
   */
  setCurrentBlockHeight(height: number | string) {
    const heightAsNumber = Number(height)
    const changed = Neutrino.incrementIfHigher(this, 'currentBlockHeight', heightAsNumber)
    if (changed) {
      this.emit(GOT_CURRENT_BLOCK_HEIGHT, heightAsNumber)
    }
  }

  /**
   * Set the lnd block height and emit an event to notify others if it has changed.
   * @param {String|Number} height Block height
   */
  setLndBlockHeight(height: number | string) {
    const heightAsNumber = Number(height)
    const changed = Neutrino.incrementIfHigher(this, 'lndBlockHeight', heightAsNumber)
    if (changed) {
      this.emit(GOT_LND_BLOCK_HEIGHT, heightAsNumber)
      this.setCurrentBlockHeight(heightAsNumber)
    }
  }

  /**
   * Set the lnd cfilter height and emit an event to notify others if it has changed.
   * @param {String|Number} height Block height
   */
  setLndCfilterHeight(height: number | string) {
    const heightAsNumber = Number(height)
    const changed = Neutrino.incrementIfHigher(this, 'lndCfilterHeight', heightAsNumber)
    if (changed) {
      this.emit(GOT_LND_CFILTER_HEIGHT, heightAsNumber)
      this.setCurrentBlockHeight(heightAsNumber)
    }
  }
}

export default Neutrino
<commit_msg>fix(lnd): enable assumechanvalid on mainnet<commit_after>// @flow

import split2 from 'split2'
import { spawn } from 'child_process'
import EventEmitter from 'events'
import getPort from 'get-port'
import isDev from 'electron-is-dev'
import { mainLog, lndLog, lndLogGetLevel } from '../utils/log'
import { fetchBlockHeight } from './util'
import LndConfig from './config'

// Sync statuses
const CHAIN_SYNC_PENDING = 'chain-sync-pending'
const CHAIN_SYNC_WAITING = 'chain-sync-waiting'
const CHAIN_SYNC_IN_PROGRESS = 'chain-sync-started'
const CHAIN_SYNC_COMPLETE = 'chain-sync-finished'

// Events
const ERROR = 'error'
const EXIT = 'exit'
const WALLET_UNLOCKER_GRPC_ACTIVE = 'wallet-unlocker-grpc-active'
const LIGHTNING_GRPC_ACTIVE = 'lightning-grpc-active'
const GOT_CURRENT_BLOCK_HEIGHT = 'got-current-block-height'
const GOT_LND_BLOCK_HEIGHT = 'got-lnd-block-height'
const GOT_LND_CFILTER_HEIGHT = 'got-lnd-cfilter-height'

// Settings
const DEFAULT_RPC_PORT = 11009
const DEFAULT_REST_PORT = 8180

/**
 * Wrapper class for Lnd to run and monitor it in Neutrino mode.
 * @extends EventEmitter
 */
class Neutrino extends EventEmitter {
  lndConfig: LndConfig
  process: any
  isWalletUnlockerGrpcActive: boolean
  isLightningGrpcActive: boolean
  chainSyncStatus: string
  currentBlockHeight: number
  lndBlockHeight: number
  lndCfilterHeight: number
  lastError: ?string

  constructor(lndConfig: LndConfig) {
    super()
    this.lndConfig = lndConfig
    this.process = null
    this.isWalletUnlockerGrpcActive = false
    this.isLightningGrpcActive = false
    this.chainSyncStatus = CHAIN_SYNC_PENDING
    this.currentBlockHeight = 0
    this.lndBlockHeight = 0
    this.lndCfilterHeight = 0
    this.lastError = null
  }

  static incrementIfHigher = (context: any, property: string, newVal: any): boolean => {
    const { [property]: oldVal } = context
    if (newVal > oldVal) {
      context[property] = newVal
      return true
    }
    return false
  }

  /**
   * Start the Lnd process in Neutrino mode.
   * @return {Number} PID of the Lnd process that was started.
   */
  async start() {
    if (this.process) {
      return Promise.reject(
        new Error('Neutrino process with PID ${this.process.pid} already exists.')
      )
    }

    // The height returned from the LND log output may not be the actual current block height (this is the case
    // when BTCD is still in the middle of syncing the blockchain) so try to fetch thhe current height from from
    // some block explorers so that we have a good starting point.
    try {
      const blockHeight = await fetchBlockHeight(this.lndConfig.chain, this.lndConfig.network)
      this.setCurrentBlockHeight(blockHeight)
    } catch (err) {
      mainLog.warn(`Unable to fetch block height: ${err.message}`)
    }

    mainLog.info('Starting lnd in neutrino mode')
    mainLog.info(' > binaryPath', this.lndConfig.binaryPath)
    mainLog.info(' > chain', this.lndConfig.chain)
    mainLog.info(' > network', this.lndConfig.network)
    mainLog.info(' > host:', this.lndConfig.host)
    mainLog.info(' > cert:', this.lndConfig.cert)
    mainLog.info(' > macaroon:', this.lndConfig.macaroon)

    // Get a free port to use as the rpc listen address.
    const rpcListen = isDev
      ? await getPort({
          host: 'localhost',
          port: [10009, 10008, 10007, 10006, 10005, 10004, 10003, 10002, 10001],
        })
      : DEFAULT_RPC_PORT
    this.lndConfig.host = `localhost:${rpcListen}`

    // Get a free port to use as the rest listen address.
    const restListen = isDev
      ? await getPort({
          host: 'localhost',
          port: [8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087, 8088, 8089],
        })
      : DEFAULT_REST_PORT

    // Get a free port to use as the p2p listen address.
    const p2pListen = await getPort({
      host: '0.0.0.0',
      port: [9735, 9734, 9733, 9732, 9731, 9736, 9737, 9738, 9739],
    })

    // Genreate autopilot config.
    const autopilotArgMap: Object = {
      autopilotAllocation: '--autopilot.allocation',
      autopilotMaxchannels: '--autopilot.maxchannels',
      autopilotMinchansize: '--autopilot.minchansize',
      autopilotMaxchansize: '--autopilot.maxchansize',
      autopilotMinconfs: '--autopilot.minconfs',
    }
    const autopilotConf = []
    Object.entries(this.lndConfig).forEach(([key, value]) => {
      if (Object.keys(autopilotArgMap).includes(key)) {
        autopilotConf.push(`${autopilotArgMap[key]}=${String(value)}`)
      }
    })

    // Configure lnd.
    const neutrinoArgs = [
      `--routing.assumechanvalid`,
      `--configfile=${this.lndConfig.configPath}`,
      `--lnddir=${this.lndConfig.lndDir}`,
      `--listen=0.0.0.0:${p2pListen}`,
      `--rpclisten=localhost:${rpcListen}`,
      `--restlisten=localhost:${restListen}`,
      `${this.lndConfig.alias ? `--alias=${this.lndConfig.alias}` : ''}`,
      `${this.lndConfig.autopilot ? '--autopilot.active' : ''}`,
      `${this.lndConfig.autopilotPrivate ? '--autopilot.private' : ''}`,
      ...autopilotConf,
    ]

    // Configure neutrino backend.
    neutrinoArgs.push(`--${this.lndConfig.chain}.${this.lndConfig.network}`)
    global.CONFIG.neutrino.connect[this.lndConfig.network].forEach(node =>
      neutrinoArgs.push(`--neutrino.connect=${node}`)
    )

    // Log the final config.
    mainLog.info(
      'Spawning Neutrino process: %s %s',
      this.lndConfig.binaryPath,
      neutrinoArgs.filter(v => v != '').join(' ')
    )

    // Spawn lnd process.
    this.process = spawn(this.lndConfig.binaryPath, neutrinoArgs)
      .on('error', error => {
        mainLog.debug('Neutrino process received "error" event with error: %s', error)
        this.emit(ERROR, error, this.lastError)
      })
      .on('exit', (code, signal) => {
        mainLog.debug(
          'Neutrino process received "exit" event with code %s and signal %s',
          code,
          signal
        )
        this.emit(EXIT, code, signal, this.lastError)
        this.process = null
      })

    // Listen for when neutrino prints data to stderr.
    this.process.stderr.pipe(split2()).on('data', line => {
      lndLog.error(line)
      if (line.startsWith('panic:')) {
        this.lastError = line
      }
    })

    // Listen for when neutrino prints data to stdout.
    this.process.stdout.pipe(split2()).on('data', line => {
      const level = lndLogGetLevel(line)
      lndLog[level](line)
      if (level === 'error') {
        this.lastError = line.split('[ERR] LTND:')[1]
      }

      // password RPC server listening (wallet unlocker started).
      if (!this.isWalletUnlockerGrpcActive && !this.isLightningGrpcActive) {
        if (line.includes('RPC server listening on') && line.includes('password')) {
          this.isWalletUnlockerGrpcActive = true
          this.emit(WALLET_UNLOCKER_GRPC_ACTIVE)
        }
      }

      // RPC server listening (wallet unlocked).
      if (!this.isLightningGrpcActive) {
        if (line.includes('RPC server listening on') && !line.includes('password')) {
          this.isLightningGrpcActive = true
          this.emit(LIGHTNING_GRPC_ACTIVE)
        }
      }

      // If the sync has already completed then we don't need to do anything else.
      if (this.is(CHAIN_SYNC_COMPLETE)) {
        return
      }

      if (this.is(CHAIN_SYNC_PENDING) || this.is(CHAIN_SYNC_IN_PROGRESS)) {
        // If we can't get a connectionn to the backend.
        if (
          line.includes('Waiting for chain backend to finish sync') ||
          line.includes('Waiting for block headers to sync, then will start cfheaders sync')
        ) {
          this.setState(CHAIN_SYNC_WAITING)
        }
        // If we are still waiting for the back end to finish synncing.
        if (line.includes('No sync peer candidates available')) {
          this.setState(CHAIN_SYNC_WAITING)
        }
      }

      // Lnd syncing has started or resumed.
      if (this.is(CHAIN_SYNC_PENDING) || this.is(CHAIN_SYNC_WAITING)) {
        const match =
          line.match(/Syncing to block height (\d+)/) ||
          line.match(/Starting cfilters sync at block_height=(\d+)/)

        if (match) {
          // Notify that chhain syncronisation has now started.
          this.setState(CHAIN_SYNC_IN_PROGRESS)

          // This is the latest block that BTCd is aware of.
          const btcdHeight = match[1]
          this.setCurrentBlockHeight(btcdHeight)
        }
      }

      // Lnd as received some updated block data.
      if (this.is(CHAIN_SYNC_WAITING) || this.is(CHAIN_SYNC_IN_PROGRESS)) {
        let height
        let cfilter
        let match

        if ((match = line.match(/Caught up to height (\d+)/))) {
          height = match[1]
        } else if ((match = line.match(/Processed \d* blocks? in the last.+\(height (\d+)/))) {
          height = match[1]
        } else if ((match = line.match(/Difficulty retarget at block height (\d+)/))) {
          height = match[1]
        } else if ((match = line.match(/Fetching set of headers from tip \(height=(\d+)/))) {
          height = match[1]
        } else if ((match = line.match(/Waiting for filter headers \(height=(\d+)\) to catch/))) {
          height = match[1]
        } else if ((match = line.match(/Writing filter headers up to height=(\d+)/))) {
          height = match[1]
        } else if ((match = line.match(/Starting cfheaders sync at block_height=(\d+)/))) {
          height = match[1]
        } else if ((match = line.match(/Got cfheaders from height=(\d*) to height=(\d+)/))) {
          cfilter = match[2]
        } else if ((match = line.match(/Writing filter headers up to height=(\d*)/))) {
          cfilter = match[1]
        } else if ((match = line.match(/Verified \d* filter headers? in the.+\(height (\d+)/))) {
          cfilter = match[1]
        } else if ((match = line.match(/Fetching filter for height=(\d+)/))) {
          cfilter = match[1]
        }

        if (height) {
          this.setState(CHAIN_SYNC_IN_PROGRESS)
          this.setLndBlockHeight(height)
        }

        if (cfilter) {
          this.setState(CHAIN_SYNC_IN_PROGRESS)
          this.setLndCfilterHeight(cfilter)
        }

        // Lnd syncing has completed.
        if (line.includes('Chain backend is fully synced')) {
          this.setState(CHAIN_SYNC_COMPLETE)
        }
      }
    })

    return this.process
  }

  /**
   * Stop the Lnd process.
   */
  kill(signalName: string = 'SIGINT') {
    if (this.process) {
      mainLog.info('Killing Neutrino process...')
      this.process.kill(signalName)
    }
  }

  /**
   * Check if the current state matches the pasted in state.
   * @param  {String} state State to compare against the current state.
   * @return {Boolean} Boolean indicating if the current state matches the passed in state.
   */
  is(state: string) {
    return this.chainSyncStatus === state
  }

  /**
   * Set the current state and emit an event to notify others if the state as changed.
   * @param {String} state Target state.
   */
  setState(state: string) {
    if (state !== this.chainSyncStatus) {
      this.chainSyncStatus = state
      this.emit(state)
    }
  }

  /**
   * Set the current block height and emit an event to notify others if it has changed.
   * @param {String|Number} height Block height
   */
  setCurrentBlockHeight(height: number | string) {
    const heightAsNumber = Number(height)
    const changed = Neutrino.incrementIfHigher(this, 'currentBlockHeight', heightAsNumber)
    if (changed) {
      this.emit(GOT_CURRENT_BLOCK_HEIGHT, heightAsNumber)
    }
  }

  /**
   * Set the lnd block height and emit an event to notify others if it has changed.
   * @param {String|Number} height Block height
   */
  setLndBlockHeight(height: number | string) {
    const heightAsNumber = Number(height)
    const changed = Neutrino.incrementIfHigher(this, 'lndBlockHeight', heightAsNumber)
    if (changed) {
      this.emit(GOT_LND_BLOCK_HEIGHT, heightAsNumber)
      this.setCurrentBlockHeight(heightAsNumber)
    }
  }

  /**
   * Set the lnd cfilter height and emit an event to notify others if it has changed.
   * @param {String|Number} height Block height
   */
  setLndCfilterHeight(height: number | string) {
    const heightAsNumber = Number(height)
    const changed = Neutrino.incrementIfHigher(this, 'lndCfilterHeight', heightAsNumber)
    if (changed) {
      this.emit(GOT_LND_CFILTER_HEIGHT, heightAsNumber)
      this.setCurrentBlockHeight(heightAsNumber)
    }
  }
}

export default Neutrino
<|endoftext|>


<commit_before>function Hevristika(tockovanje, sirina, visina, v_vrsto) {
    this.tockovanje = tockovanje;
    this.sirina = sirina;
    this.visina = visina;
    this.v_vrsto = v_vrsto;
}

Hevristika.iz_shranjene = function (podatki) {

    return new Hevristika(podatki.tockovanje, podatki.sirina, podatki.visina, podatki.v_vrsto);

};

Hevristika.prototype.kaznuj_globino = function (globina, maximiziramo) {
    // Neumni nacin, linearno
    if(maximiziramo){
        return this.tockovanje.KAZEN_NA_GLOBINO_MAX * 2;
    }else{
        return this.kaznuj_globino(globina, !maximiziramo);
    }
};

Hevristika.prototype.tockuj_zmago = function() {
    return HEVRISTIKA.TOCKOVANJE.ZMAGA;
};

Hevristika.prototype.tockuj_poraz = function() {
    return HEVRISTIKA.TOCKOVANJE.PORAZ;
};

Hevristika.prototype.tockuj_remi = function() {
    return HEVRISTIKA.TOCKOVANJE.REMI;
};

// Pustimo si v razmisleku, da nekoc dodamo, ali je igralec clovek,
// mogoce bi v tem primeru lahko ocenjevali kako drugace (clovek nekatere poteze "ceni" bolj).
Hevristika.prototype.oceni_plosco = function (plosca, trenutni_igralec) {
    var vrednost = 0;
    var ocene = [];
    //združimo ocene od diagonal, vrstic in stolpcov
    ocene = ocene.concat(this.preveri_vrstice(plosca), this.preveri_desno_diagonalo(plosca), this.preveri_levo_diagonalo(plosca), this.preveri_navzdol(plosca));
    for(var i = 0; i < ocene.length; i++){
        if(ocene[i].igralec == trenutni_igralec){//če je ocena od trenutnega igralca prištejemo
            vrednost += ocene[i].dobi_vrednost();
        }
        else{//drugače odštejemo
            vrednost -= ocene[i].dobi_vrednost();
        }
    }

    return vrednost;
};

Hevristika.prototype.preveri_vrstice = function(plosca) {
    var ocene = [];
    for(var vrstica = 0; vrstica<this.visina; vrstica++){
        var prejsni = null;
        var trenutni = null;
        var dolzina = 0;
        var dolzina_vmes = 0;
        for(var i=0; i < this.sirina; i++){
            if(trenutni == IGRALCI.NE_ODIGRANO && plosca[i][vrstica] == IGRALCI.NE_ODIGRANO){
                continue;
            }
            if(trenutni == null){
                if(plosca[i][vrstica] == IGRALCI.NE_ODIGRANO){
                    continue;
                }
                else{
                    trenutni = plosca[i][vrstica];
                    dolzina = 1;
                    if(i > 0){
                        prejsni = IGRALCI.NE_ODIGRANO;
                    }
                }
            }
            else{
                if(plosca[i][vrstica] != trenutni &&  (plosca[i][vrstica] != IGRALCI.NE_ODIGRANO || i == this.sirina - 1)){//zaustavitveni pogoj
                        if(prejsni == IGRALCI.NE_ODIGRANO  && dolzina_vmes <= 1){
                            ocene.push(new OcenaHevristika(trenutni, this.v_vrsto - 1));
                        }
                    }
                    else{
                        //ni dovolj v vrsto
                    }
                    prejsni = trenutni;//na novo nastavimo začetne vrednosti
                    trenutni = plosca[i][vrstica];
                    dolzina = 1;
                    dolzina_vmes = 0;
                }
                else{
                    if(plosca[i][vrstica] == IGRALCI.NE_ODIGRANO){
                        prejsni = IGRALCI.NE_ODIGRANO;
                        dolzina_vmes += 1;

                    }
                    else{
                        dolzina += 1;
                    }
                }
            }
            if(dolzina >=this.v_vrsto - 1){
                if(prejsni == IGRALCI.NE_ODIGRANO && dolzina_vmes <= 1){
                    ocene.push(new OcenaHevristika(trenutni, this.v_vrsto - 1));
                }
            }
        }
    }
    return ocene;
};

Hevristika.prototype.preveri_desno_diagonalo = function(plosca) {
    //funkcija deluje tako da se sprehodi po število vseh diagonal ki so dolžine vsaj
    //v_vrsto. Za vsako to diagonalo določi začetni in končni stolpec glede na obliko
    //mreže(lahko je pokončna ali vodoravna) ter nato preveri za proste v_vrsto - 1 "verige"
    //na tej diagonali
    //preverja diagonale ki potekajo desno - dol
    var ocene = [];
    var dolzina_vmes = 0;
    for(var skupno = this.v_vrsto - 1; skupno < this.sirina + this.visina - this.v_vrsto; skupno++){
        if(skupno >= this.visina){
            var zacetna_vrstica = this.visina - 1;
            if(skupno >= this.sirina){
                var koncna_vrstica = skupno - this.sirina + 1;
            }
            else{
                koncna_vrstica = 0;
            }
        }
        else{
            zacetna_vrstica = skupno;
            koncna_vrstica = 0
        }
        var prejsni = null;
        var trenutni = null;
        var dolzina = 0;
        for(var vrstica = zacetna_vrstica; vrstica >= koncna_vrstica; vrstica--){
            var i = skupno - vrstica;
            if(trenutni == IGRALCI.NE_ODIGRANO && plosca[i][vrstica] == IGRALCI.NE_ODIGRANO){
                continue;
            }
            if(trenutni == null){
                if(plosca[i][vrstica] == IGRALCI.NE_ODIGRANO){
                    prejsni = IGRALCI.NE_ODIGRANO;
                    // Nadaljujemo z zanko
                }
                else{

                    trenutni = plosca[i][vrstica];
                    dolzina = 1;
                }
            }
            else{
                if(plosca[i][vrstica] != trenutni &&  (plosca[i][vrstica] != IGRALCI.NE_ODIGRANO || vrstica == koncna_vrstica)){//zaustavitveni pogoj
                    if(dolzina >=this.v_vrsto - 1){
                        if(prejsni == IGRALCI.NE_ODIGRANO && dolzina_vmes <= 1){
                            ocene.push(new OcenaHevristika(trenutni, this.v_vrsto - 1));
                        }
                    }
                    else{
                        //ni dovolj v vrsto
                    }
                    prejsni = trenutni;//na novo nastavimo zacetne vrednosti
                    trenutni = plosca[i][vrstica];
                    dolzina = 1;
                    dolzina_vmes = 0;
                }
                else{
                    if(plosca[i][vrstica] == IGRALCI.NE_ODIGRANO){
                        prejsni = IGRALCI.NE_ODIGRANO;
                        dolzina_vmes += 1;
                    }
                    else{
                        dolzina += 1;
                    }
                }
            }

            if(vrstica == koncna_vrstica && (dolzina >=this.v_vrsto - 1)){
                if(prejsni == IGRALCI.NE_ODIGRANO && dolzina_vmes <= 1){
                    ocene.push(new OcenaHevristika(trenutni, this.v_vrsto - 1));
                }
            }

        }
    }
    return ocene;

};

Hevristika.prototype.preveri_levo_diagonalo = function(plosca) {
    //deluje podobno kot preveri_desno_diagonalo le da preverja diagonale
    //ki potekajo v smeri levo - gor
    var ocene = [];
    var zacetek = 0;
    if(this.sirina > this.visina){
        var tip_igre = 1;
        var prva_meja = this.visina - 1 -  (this.v_vrsto - 1); //zadanemo v zgornji levi  kot
        var druga_meja = this.sirina - 1 - (this.v_vrsto - 1); //zadanemo v spodnji desni  kot
    }
    else{
        prva_meja = this.sirina - 1 - (this._vrsto - 1); //zadanemo v spodnji desni  kot
        druga_meja = this.visina - 1 - (this.v_vrsto - 1);
        tip_igre = -1;
    }

    for(var skupno = zacetek; skupno < this.sirina + this.visina - 1 - 2*(this.v_vrsto - 1); skupno++){
        if(tip_igre == 1){ //sirina > visina
            if(skupno <= prva_meja){
                var zacetni_stolpec = 0;
                var koncni_stolpec = this.v_vrsto - 1 + skupno;
            }
            else if(skupno > prva_meja && skupno < druga_meja){
                zacetni_stolpec = skupno - (this.visina - 1) + this.v_vrsto - 1;
                koncni_stolpec = zacetni_stolpec + this.visina - 1;
            }
            else if(skupno >= druga_meja){
                zacetni_stolpec = skupno - (this.visina - 1) + this.v_vrsto - 1;
                koncni_stolpec = this.sirina - 1;
            }
        }
        else{
            if(skupno <= prva_meja){
                zacetni_stolpec = 0;
                koncni_stolpec = this.v_vrsto - 1 + skupno;
            }
            else if(skupno <= druga_meja){
                zacetni_stolpec = 0;
                koncni_stolpec = this.sirina - 1;
            }
            else{
                zacetni_stolpec = skupno - (this.visina - 1 - this.v_vrsto - 1);
                koncni_stolpec = this.sirina - 1;
            }

        }
        var prejsni = null;
        var trenutni = null;
        var dolzina = 0;
        var dolzina_vmes = 0;
        for(var i = zacetni_stolpec; i <= koncni_stolpec; i++){
            var vrstica = Math.max(this.visina - this.v_vrsto  - skupno + i, 0); //dolocimo vrstico glede na trenutni stolpec

            if(trenutni == IGRALCI.NE_ODIGRANO && plosca[i][vrstica] == IGRALCI.NE_ODIGRANO){
                continue;
            }
            if(trenutni == null){
                if(plosca[i][vrstica] == IGRALCI.NE_ODIGRANO){
                    prejsni = IGRALCI.NE_ODIGRANO;
                    // Nadaljujemo z zanko
                }
                else{

                    trenutni = plosca[i][vrstica];
                    dolzina = 1;
                }
            }
            else{
                if(plosca[i][vrstica] != trenutni &&  (plosca[i][vrstica] != IGRALCI.NE_ODIGRANO || i == koncni_stolpec)){//zaustavitveni pogoj
                        if(prejsni == IGRALCI.NE_ODIGRANO && dolzina_vmes <= 1){
                            ocene.push(new OcenaHevristika(trenutni, this.v_vrsto - 1));
                        }
                    }
                    else{
                        //ni dovolj v vrsto
                    }
                    prejsni = trenutni; //na novo nastavimo zacetne vrednosti
                    trenutni = plosca[i][vrstica];
                    dolzina = 1;
                    dolzina_vmes = 0;
                }
                else{
                    if(plosca[i][vrstica] == IGRALCI.NE_ODIGRANO){
                        prejsni = IGRALCI.NE_ODIGRANO;
                        dolzina_vmes += 1;
                    }
                    else{
                        dolzina += 1;
                    }
                }
            }

            if(dolzina >=this.v_vrsto - 1){
                if(prejsni == IGRALCI.NE_ODIGRANO && dolzina_vmes <= 1){
                    ocene.push(new OcenaHevristika(trenutni, this.v_vrsto - 1));
                }
            }
        }
    }

    return ocene;

};

Hevristika.prototype.preveri_navzdol = function(plosca) {
    //preveri po stolpcu navzdol za vzorce( v_vrsto - 1 dolge verige)
    var ocene = [];
    for(var stolpec = 0; stolpec < this.sirina; stolpec++){
        var prvi = IGRALCI.NE_ODIGRANO;
        var dolzina = 0;
        if(plosca[stolpec][0] != IGRALCI.NE_ODIGRANO){
            continue; //stolpec je poln
        }
        for(var vrstica = 1; vrstica < this.visina; vrstica++){
            if(plosca[stolpec][vrstica] == IGRALCI.NE_ODIGRANO){
                continue;
            }
            prvi = plosca[stolpec][vrstica];
            for(var i = 0; i<this.v_vrsto; i++){
                if(plosca[stolpec][vrstica + i] == prvi){
                    dolzina += 1;
                }
                else{
                    break;
                }
            }
            if(dolzina == this.v_vrsto - 1){
                ocene.push(new OcenaHevristika(prvi, dolzina));
            }
            break;
        }
    }
    return ocene;
};<commit_msg>Zbrisan odvečni oklepaj.<commit_after>function Hevristika(tockovanje, sirina, visina, v_vrsto) {
    this.tockovanje = tockovanje;
    this.sirina = sirina;
    this.visina = visina;
    this.v_vrsto = v_vrsto;
}

Hevristika.iz_shranjene = function (podatki) {

    return new Hevristika(podatki.tockovanje, podatki.sirina, podatki.visina, podatki.v_vrsto);

};

Hevristika.prototype.kaznuj_globino = function (globina, maximiziramo) {
    // Neumni nacin, linearno
    if(maximiziramo){
        return this.tockovanje.KAZEN_NA_GLOBINO_MAX * 2;
    }else{
        return this.kaznuj_globino(globina, !maximiziramo);
    }
};

Hevristika.prototype.tockuj_zmago = function() {
    return HEVRISTIKA.TOCKOVANJE.ZMAGA;
};

Hevristika.prototype.tockuj_poraz = function() {
    return HEVRISTIKA.TOCKOVANJE.PORAZ;
};

Hevristika.prototype.tockuj_remi = function() {
    return HEVRISTIKA.TOCKOVANJE.REMI;
};

// Pustimo si v razmisleku, da nekoc dodamo, ali je igralec clovek,
// mogoce bi v tem primeru lahko ocenjevali kako drugace (clovek nekatere poteze "ceni" bolj).
Hevristika.prototype.oceni_plosco = function (plosca, trenutni_igralec) {
    var vrednost = 0;
    var ocene = [];
    //združimo ocene od diagonal, vrstic in stolpcov
    ocene = ocene.concat(this.preveri_vrstice(plosca), this.preveri_desno_diagonalo(plosca), this.preveri_levo_diagonalo(plosca), this.preveri_navzdol(plosca));
    for(var i = 0; i < ocene.length; i++){
        if(ocene[i].igralec == trenutni_igralec){//če je ocena od trenutnega igralca prištejemo
            vrednost += ocene[i].dobi_vrednost();
        }
        else{//drugače odštejemo
            vrednost -= ocene[i].dobi_vrednost();
        }
    }

    return vrednost;
};

Hevristika.prototype.preveri_vrstice = function(plosca) {
    var ocene = [];
    for(var vrstica = 0; vrstica<this.visina; vrstica++){
        var prejsni = null;
        var trenutni = null;
        var dolzina = 0;
        var dolzina_vmes = 0;
        for(var i=0; i < this.sirina; i++){
            if(trenutni == IGRALCI.NE_ODIGRANO && plosca[i][vrstica] == IGRALCI.NE_ODIGRANO){
                continue;
            }
            if(trenutni == null){
                if(plosca[i][vrstica] == IGRALCI.NE_ODIGRANO){
                    continue;
                }
                else{
                    trenutni = plosca[i][vrstica];
                    dolzina = 1;
                    if(i > 0){
                        prejsni = IGRALCI.NE_ODIGRANO;
                    }
                }
            }
            else{
                if(plosca[i][vrstica] != trenutni &&  (plosca[i][vrstica] != IGRALCI.NE_ODIGRANO || i == this.sirina - 1)){//zaustavitveni pogoj
                    if(prejsni == IGRALCI.NE_ODIGRANO  && dolzina_vmes <= 1){
                        ocene.push(new OcenaHevristika(trenutni, this.v_vrsto - 1));
                    }

                    else{
                        //ni dovolj v vrsto
                    }
                    prejsni = trenutni;//na novo nastavimo začetne vrednosti
                    trenutni = plosca[i][vrstica];
                    dolzina = 1;
                    dolzina_vmes = 0;
                }
                else{
                    if(plosca[i][vrstica] == IGRALCI.NE_ODIGRANO){
                        prejsni = IGRALCI.NE_ODIGRANO;
                        dolzina_vmes += 1;

                    }
                    else{
                        dolzina += 1;
                    }
                }
            }
            if(dolzina >=this.v_vrsto - 1){
                if(prejsni == IGRALCI.NE_ODIGRANO && dolzina_vmes <= 1){
                    ocene.push(new OcenaHevristika(trenutni, this.v_vrsto - 1));
                }
            }
        }
    }
    return ocene;
};

Hevristika.prototype.preveri_desno_diagonalo = function(plosca) {
    //funkcija deluje tako da se sprehodi po število vseh diagonal ki so dolžine vsaj
    //v_vrsto. Za vsako to diagonalo določi začetni in končni stolpec glede na obliko
    //mreže(lahko je pokončna ali vodoravna) ter nato preveri za proste v_vrsto - 1 "verige"
    //na tej diagonali
    //preverja diagonale ki potekajo desno - dol
    var ocene = [];
    var dolzina_vmes = 0;
    for(var skupno = this.v_vrsto - 1; skupno < this.sirina + this.visina - this.v_vrsto; skupno++){
        if(skupno >= this.visina){
            var zacetna_vrstica = this.visina - 1;
            if(skupno >= this.sirina){
                var koncna_vrstica = skupno - this.sirina + 1;
            }
            else{
                koncna_vrstica = 0;
            }
        }
        else{
            zacetna_vrstica = skupno;
            koncna_vrstica = 0
        }
        var prejsni = null;
        var trenutni = null;
        var dolzina = 0;
        for(var vrstica = zacetna_vrstica; vrstica >= koncna_vrstica; vrstica--){
            var i = skupno - vrstica;
            if(trenutni == IGRALCI.NE_ODIGRANO && plosca[i][vrstica] == IGRALCI.NE_ODIGRANO){
                continue;
            }
            if(trenutni == null){
                if(plosca[i][vrstica] == IGRALCI.NE_ODIGRANO){
                    prejsni = IGRALCI.NE_ODIGRANO;
                    // Nadaljujemo z zanko
                }
                else{

                    trenutni = plosca[i][vrstica];
                    dolzina = 1;
                }
            }
            else{
                if(plosca[i][vrstica] != trenutni &&  (plosca[i][vrstica] != IGRALCI.NE_ODIGRANO || vrstica == koncna_vrstica)){//zaustavitveni pogoj
                    if(dolzina >=this.v_vrsto - 1){
                        if(prejsni == IGRALCI.NE_ODIGRANO && dolzina_vmes <= 1){
                            ocene.push(new OcenaHevristika(trenutni, this.v_vrsto - 1));
                        }
                    }
                    else{
                        //ni dovolj v vrsto
                    }
                    prejsni = trenutni;//na novo nastavimo zacetne vrednosti
                    trenutni = plosca[i][vrstica];
                    dolzina = 1;
                    dolzina_vmes = 0;
                }
                else{
                    if(plosca[i][vrstica] == IGRALCI.NE_ODIGRANO){
                        prejsni = IGRALCI.NE_ODIGRANO;
                        dolzina_vmes += 1;
                    }
                    else{
                        dolzina += 1;
                    }
                }
            }

            if(vrstica == koncna_vrstica && (dolzina >=this.v_vrsto - 1)){
                if(prejsni == IGRALCI.NE_ODIGRANO && dolzina_vmes <= 1){
                    ocene.push(new OcenaHevristika(trenutni, this.v_vrsto - 1));
                }
            }

        }
    }
    return ocene;

};

Hevristika.prototype.preveri_levo_diagonalo = function(plosca) {
    //deluje podobno kot preveri_desno_diagonalo le da preverja diagonale
    //ki potekajo v smeri levo - gor
    var ocene = [];
    var zacetek = 0;
    if(this.sirina > this.visina){
        var tip_igre = 1;
        var prva_meja = this.visina - 1 -  (this.v_vrsto - 1); //zadanemo v zgornji levi  kot
        var druga_meja = this.sirina - 1 - (this.v_vrsto - 1); //zadanemo v spodnji desni  kot
    }
    else{
        prva_meja = this.sirina - 1 - (this._vrsto - 1); //zadanemo v spodnji desni  kot
        druga_meja = this.visina - 1 - (this.v_vrsto - 1);
        tip_igre = -1;
    }

    for(var skupno = zacetek; skupno < this.sirina + this.visina - 1 - 2*(this.v_vrsto - 1); skupno++){
        if(tip_igre == 1){ //sirina > visina
            if(skupno <= prva_meja){
                var zacetni_stolpec = 0;
                var koncni_stolpec = this.v_vrsto - 1 + skupno;
            }
            else if(skupno > prva_meja && skupno < druga_meja){
                zacetni_stolpec = skupno - (this.visina - 1) + this.v_vrsto - 1;
                koncni_stolpec = zacetni_stolpec + this.visina - 1;
            }
            else if(skupno >= druga_meja){
                zacetni_stolpec = skupno - (this.visina - 1) + this.v_vrsto - 1;
                koncni_stolpec = this.sirina - 1;
            }
        }
        else{
            if(skupno <= prva_meja){
                zacetni_stolpec = 0;
                koncni_stolpec = this.v_vrsto - 1 + skupno;
            }
            else if(skupno <= druga_meja){
                zacetni_stolpec = 0;
                koncni_stolpec = this.sirina - 1;
            }
            else{
                zacetni_stolpec = skupno - (this.visina - 1 - this.v_vrsto - 1);
                koncni_stolpec = this.sirina - 1;
            }

        }
        var prejsni = null;
        var trenutni = null;
        var dolzina = 0;
        var dolzina_vmes = 0;
        for(var i = zacetni_stolpec; i <= koncni_stolpec; i++){
            var vrstica = Math.max(this.visina - this.v_vrsto  - skupno + i, 0); //dolocimo vrstico glede na trenutni stolpec

            if(trenutni == IGRALCI.NE_ODIGRANO && plosca[i][vrstica] == IGRALCI.NE_ODIGRANO){
                continue;
            }
            if(trenutni == null){
                if(plosca[i][vrstica] == IGRALCI.NE_ODIGRANO){
                    prejsni = IGRALCI.NE_ODIGRANO;
                    // Nadaljujemo z zanko
                }
                else{

                    trenutni = plosca[i][vrstica];
                    dolzina = 1;
                }
            }
            else{
                if(plosca[i][vrstica] != trenutni &&  (plosca[i][vrstica] != IGRALCI.NE_ODIGRANO || i == koncni_stolpec)){//zaustavitveni pogoj
                    if(prejsni == IGRALCI.NE_ODIGRANO && dolzina_vmes <= 1){
                        ocene.push(new OcenaHevristika(trenutni, this.v_vrsto - 1));
                    }
                    else{
                        //ni dovolj v vrsto
                    }
                    prejsni = trenutni; //na novo nastavimo zacetne vrednosti
                    trenutni = plosca[i][vrstica];
                    dolzina = 1;
                    dolzina_vmes = 0;
                }
                else{
                    if(plosca[i][vrstica] == IGRALCI.NE_ODIGRANO){
                        prejsni = IGRALCI.NE_ODIGRANO;
                        dolzina_vmes += 1;
                    }
                    else{
                        dolzina += 1;
                    }
                }
            }

            if(dolzina >=this.v_vrsto - 1){
                if(prejsni == IGRALCI.NE_ODIGRANO && dolzina_vmes <= 1){
                    ocene.push(new OcenaHevristika(trenutni, this.v_vrsto - 1));
                }
            }
        }
    }

    return ocene;

};

Hevristika.prototype.preveri_navzdol = function(plosca) {
    //preveri po stolpcu navzdol za vzorce( v_vrsto - 1 dolge verige)
    var ocene = [];
    for(var stolpec = 0; stolpec < this.sirina; stolpec++){
        var prvi = IGRALCI.NE_ODIGRANO;
        var dolzina = 0;
        if(plosca[stolpec][0] != IGRALCI.NE_ODIGRANO){
            continue; //stolpec je poln
        }
        for(var vrstica = 1; vrstica < this.visina; vrstica++){
            if(plosca[stolpec][vrstica] == IGRALCI.NE_ODIGRANO){
                continue;
            }
            prvi = plosca[stolpec][vrstica];
            for(var i = 0; i<this.v_vrsto; i++){
                if(plosca[stolpec][vrstica + i] == prvi){
                    dolzina += 1;
                }
                else{
                    break;
                }
            }
            if(dolzina == this.v_vrsto - 1){
                ocene.push(new OcenaHevristika(prvi, dolzina));
            }
            break;
        }
    }
    return ocene;
};<|endoftext|>


<commit_before>define(["./rendering/animation", "./rendering/animationsheet"], function Gui(Animation, AnimationSheet) {
    var Gui = function(world, input, player, viewport) {

        this.input = input;
        this.player = player;

        var deltaBlue = new DBPlanner();
        var spriteSheet = new AnimationSheet("target.png", 52, 52);
        var crossHairsAnimation = new Animation(spriteSheet, 100, [0]);
        var bubbleAnimation = new Animation(spriteSheet, 100, [1]);

        this.bubbles = [0.2, 0.4, 0.6, 0.8, 1.0].map(function(t, i) {
            var bubble = new Gui.Bubble(t == 1.0 ? crossHairsAnimation : bubbleAnimation, t, world, input, player, viewport);
            // constraint idea:
            // keep targeting graphics in sync with mouse and player position
            // TODO: add constraints here
            // old formula variant, fast
            bbb.always({
                solver: deltaBlue,
                ctx: {
                    bubble: bubble,
                    player: player,
                    input: input,
                    t: t,
                    viewport: viewport
                },
                methods: function() {
                    bubble.position.formula([input.mouse, input.mouse.x, input.mouse.y, player.position, player.position.x, player.position.y], function(mouse, mouseX, mouseY, srcPosition, srcPositionX, srcPositionY) {
                        return mouse.mulFloat(t).add(
                            viewport.worldToScreenCoordinates(srcPosition).mulFloat(1-t)
                        );
                    });
                } }, function() {
                var r = bubble.position.equals(input.mouse.mulFloat(t).add(
                    viewport.worldToScreenCoordinates(player.position).mulFloat(1-t)
                ));
                return r;
            });
/*
            // new version with implicit formula, convenient but slow
            always: {
                solver: deltaBlue
                bubble.position.equals(input.mouse.mulFloat(t).add(viewport.worldToScreenCoordinates(player.position).mulFloat(1-t)))
            }
*/

            return bubble;
        });

    };

    Gui.prototype.update = function(dt) {
        this.bubbles.forEach(function(bubble) {
            bubble.update(dt);
        });
    };

    Gui.prototype.draw = function(renderer) {
        this.bubbles.forEach(function(bubble) {
            bubble.draw(renderer);
        });
    };

    Gui.Bubble = function(animation, t, world, input, player, viewport) {
        this.animation = animation;
        this.position = Vector2.Zero.copy();

        this.t = t;
        this.input = input;
        this.viewport = viewport;
        this.player = player;
    };

    Gui.Bubble.prototype.update = function(dt) {
        this.animation.update(dt);
    };

    Gui.Bubble.prototype.draw = function(renderer) {
        var halfSize = new Vector2(13, 13);
        this.animation.draw(renderer, new AABB(
            this.position.sub(halfSize),
            this.position.add(halfSize)
        ));
    };

    return Gui;
});
<commit_msg>added transparency to gui overlay<commit_after>define(["./rendering/animation", "./rendering/animationsheet"], function Gui(Animation, AnimationSheet) {
    var Gui = function(world, input, player, viewport) {

        this.input = input;
        this.player = player;

        var deltaBlue = new DBPlanner();
        var spriteSheet = new AnimationSheet("target.png", 52, 52);
        var crossHairsAnimation = new Animation(spriteSheet, 100, [0]);
        var bubbleAnimation = new Animation(spriteSheet, 100, [1]);

        this.bubbles = [0.2, 0.4, 0.6, 0.8, 1.0].map(function(t, i) {
            var bubble = new Gui.Bubble(t == 1.0 ? crossHairsAnimation : bubbleAnimation, t, world, input, player, viewport);
            // constraint idea:
            // keep targeting graphics in sync with mouse and player position
            // TODO: add constraints here
            // old formula variant, fast
            bbb.always({
                solver: deltaBlue,
                ctx: {
                    bubble: bubble,
                    player: player,
                    input: input,
                    t: t,
                    viewport: viewport
                },
                methods: function() {
                    bubble.position.formula([input.mouse, input.mouse.x, input.mouse.y, player.position, player.position.x, player.position.y], function(mouse, mouseX, mouseY, srcPosition, srcPositionX, srcPositionY) {
                        return mouse.mulFloat(t).add(
                            viewport.worldToScreenCoordinates(srcPosition).mulFloat(1-t)
                        );
                    });
                } }, function() {
                var r = bubble.position.equals(input.mouse.mulFloat(t).add(
                    viewport.worldToScreenCoordinates(player.position).mulFloat(1-t)
                ));
                return r;
            });
/*
            // new version with implicit formula, convenient but slow
            always: {
                solver: deltaBlue
                bubble.position.equals(input.mouse.mulFloat(t).add(viewport.worldToScreenCoordinates(player.position).mulFloat(1-t)))
            }
*/

            return bubble;
        });

    };

    Gui.prototype.update = function(dt) {
        this.bubbles.forEach(function(bubble) {
            bubble.update(dt);
        });
    };

    Gui.prototype.draw = function(renderer) {
        renderer.configuration.setGlobalAlpha(0.7);
        this.bubbles.forEach(function(bubble) {
            bubble.draw(renderer);
        });
        renderer.configuration.setGlobalAlpha(1.0);
    };

    Gui.Bubble = function(animation, t, world, input, player, viewport) {
        this.animation = animation;
        this.position = Vector2.Zero.copy();

        this.t = t;
        this.input = input;
        this.viewport = viewport;
        this.player = player;
    };

    Gui.Bubble.prototype.update = function(dt) {
        this.animation.update(dt);
    };

    Gui.Bubble.prototype.draw = function(renderer) {
        var halfSize = new Vector2(13, 13);
        this.animation.draw(renderer, new AABB(
            this.position.sub(halfSize),
            this.position.add(halfSize)
        ));
    };

    return Gui;
});
<|endoftext|>