<commit_before>'use strict';

let cli    = require('heroku-cli-util');
let co     = require('co');
let printf = require('printf');
let _      = require('lodash');
let _table  = require('../lib/table');

let dim = cli.color.dim;
let colorize = {
    app:        cli.color.cyan,
    attachment: cli.color.green,
    addon:      cli.color.magenta,
};

function table(data, options) {
    return _table(data, _.merge(options, {
        printLine: cli.log
    }));
}

// Gets *all* attachments and add-ons and filters locally because the API
// returns *owned* items not associated items.
function* addonGetter(api, app) {
    let attachments, addons;

    if(app) { // don't disploy attachments globally
        let sudoHeaders = JSON.parse(process.env.HEROKU_HEADERS);
        if(sudoHeaders['X-Heroku-Sudo'] && !sudoHeaders['X-Heroku-Sudo-User']) {
            // because the root /addon-attachments endpoint won't include relevant
            // attachments when sudo-ing for another app, we will use the more
            // specific API call and sacrifice listing foreign attachments.
            addons = api.request({
                method:  'GET',
                path:    `/apps/${app}/addons`,
                headers: {'Accept-Expansion': 'addon_service,plan'},
            });

            attachments = api.request({
                method:  'GET',
                path:    `/apps/${app}/addon-attachments`,
            });
        } else {
            // In order to display all foreign attachments, we'll get out entire
            // attachment list
            attachments = api.addonAttachments().list();
        }
    }

    addons = addons || api.request({
        method:  'GET',
        path:    '/addons',
        headers: {'Accept-Expansion': 'addon_service,plan'}
    });

    // Get addons and attachments in parallel
    let items = yield [addons, attachments];

    function isRelevantToApp(addon) {
        return !app
            || addon.app.name == app
            || _.any(addon.attachments, function(att) { return att.app.name == app });
    }

    attachments = _.groupBy(items[1], _.property('addon.id'));

    addons = [];
    items[0].forEach(function(addon) {
        addon.attachments = attachments[addon.id];

        delete attachments[addon.id];

        if(isRelevantToApp(addon)) {
            addons.push(addon);
        }
    });

    _.values(attachments).forEach(function(atts) {
        let inaccessibleAddon = {
            app: atts[0].addon.app,
            name: atts[0].addon.name,
            plan: {name: '?', price: {cents: '?', unit: 'month'}},
            attachments: atts
        };

        if(isRelevantToApp(inaccessibleAddon)) {
            addons.push(inaccessibleAddon);
        }
    });

    return addons;
}

function formatPrice(price) {
    if(!price.cents)       { return 'free'; }
    if(price.cents == '?') { return '?'; }

    let fmt = price.cents % 100 == 0 ? '$%.0f/%s' : '$%.02f/%s'
    return printf(fmt, price.cents / 100, price.unit);
};

function displayAll(addons) {
    addons = _.sortByAll(addons, 'app.name', 'plan.name', 'addon.name')

    table(addons, {
        headerAnsi: cli.color.bold,
        columns: [{
            key:   'app.name',
            label: 'Owning App',
            ansi:  colorize.app,
        }, {
            key:   'name',
            label: 'Add-on',
            ansi:  colorize.addon,
        }, {
            key:   'plan.name',
            label: 'Plan',
            ansi:  function(s) { return _.trimRight(s) == '?' ? dim(s) : s; },
        }, {
            key:       'plan.price',
            label:     'Price',
            formatter: formatPrice,
            ansi:  function(s) { return _.trimRight(s) == '?' ? dim(s) : s; },
        }],

    });
}

function formatAttachment(attachment, showApp) {
    if(showApp === undefined) { showApp = true; }

    let attName = colorize.attachment(attachment.name);

    if(showApp) {
        return dim(colorize.app(attachment.app.name) + '::') + attName;
    } else {
        return attName;
    }
}

function renderAttachment(attachment, app, isFirst) {
    let ch = isFirst ? '└' : '├';
    let attName = formatAttachment(attachment, attachment.app.name != app);
    return printf(' %s─ %s', ch, attName);
}

function displayForApp(app, addons) {
    let nestedCalcWidther = function(path, nestedPath, fn) {
        return function(row) {
            let nestedWidth = _.max(_.get(row, nestedPath).map(_.compose(_.property('length'),
                                                                         cli.color.stripColor,
                                                                         fn)));
            return Math.max(_.get(row, path).length, nestedWidth);
        }
    };

    function isForeignApp(attOrAddon) { return attOrAddon.app.name != app }

    addons = _.sortByAll(addons,
                         isForeignApp,
                         'plan.name',
                         'addon.name');

    table(addons, {
        headerAnsi: cli.color.bold,
        columns: [{
            key:   'name',
            label: 'Add-on',
            ansi:  colorize.addon,

            // customize column width to factor in the attachment list
            // TODO: make this just be `width`, which can either be a static number or a function which returns a number
            calcWidth: nestedCalcWidther('name',
                                         'attachments',
                                         _.partial(renderAttachment, _, app)),
        }, {
            key:   'plan.name',
            label: 'Plan',
            ansi:  function(s) { return _.trimRight(s) == '?' ? dim(s) : s; }
        }, {
            label:     'Price',
            get: function(addon) {
                if(addon.app.name == app) {
                    return formatPrice(addon.plan.price);
                } else {
                    return dim(printf('(billed to %s app)', colorize.app(addon.app.name)));
                }
            },
        }],

        after: function(addon, options) {
            let atts = _.sortByAll(addon.attachments,
                                   isForeignApp,
                                   'app.name',
                                   'name');

            atts.forEach(function(attachment, idx) {
                let isFirst = (idx == addon.attachments.length - 1)
                console.log(renderAttachment(attachment, app, isFirst));
            });
        }
    })
}

let run = cli.command(function(ctx, api) {
    return co(function*() {
        if(!ctx.flags.all && ctx.app) {
            displayForApp(ctx.app, yield co(addonGetter(api, ctx.app)));
        } else {
            displayAll(yield co(addonGetter(api)));
        }
    });
});

let topic = '_addons';
module.exports = {
    topic:     topic,
    default:   true,
    needsAuth: true,
    preauth:   true,
    wantsApp:  true,
    // args:      [{name: 'addon', optional: true}],
    flags:     [{
        name:        'all',
        char:        'A',
        hasValue:    false,
        description: 'Show add-ons and attachments for all accessible apps'
    }],

    run:         run,
    usage:       `${topic} [--all|--app APP]`,
    description: 'Lists your add-ons and attachments',
    help:        `The default filter applied depends on whether you are in a Heroku app
directory. If so, the --app flag is implied. If not, the default of --all
is implied. Explicitly providing either flag overrides the default
behaviour.

Examples:

  $ heroku ${topic} --all
  $ heroku ${topic} --app acme-inc-website

Identifying specific add-ons:

  Add-ons have canonical names (ADDON_NAME in these command help texts).
  They also application-specific names called aliases or attachments. In
  many cases, these names can be used interchangeably when unambiguous.

  For example, given a fictional \`slowdb\` add-on named \`slowdb-cubed-1531\`
  attached as \`FOO_DB\` to \`app1\` and BAR_DB to \`app2\`, the following
  invocations are considered equivalent:

  $ heroku addons:upgrade slowdb             slowdb:premium
  $ heroku addons:upgrade --app app1 FOO_DB  slowdb:premium
  $ heroku addons:upgrade app1::FOO_DB       slowdb:premium
  $ heroku addons:upgrade app2::BAR_DB       slowdb:premium
  $ heroku addons:upgrade acme-inc-datastore slowdb:premium

  If the name used is ambiguous (e.g. if you used \`slowdb\` with more than
  one add-on of that type installed), the command will error due to
  ambiguity and a more specific identifier will need to be chosen.

  For more information, read https://devcenter.heroku.com/articles/add-ons.`,
};
<commit_msg>Fix case when HEROKU_HEADERS isn't present in env<commit_after>'use strict';

let cli    = require('heroku-cli-util');
let co     = require('co');
let printf = require('printf');
let _      = require('lodash');
let _table  = require('../lib/table');

let dim = cli.color.dim;
let colorize = {
    app:        cli.color.cyan,
    attachment: cli.color.green,
    addon:      cli.color.magenta,
};

function table(data, options) {
    return _table(data, _.merge(options, {
        printLine: cli.log
    }));
}

// Gets *all* attachments and add-ons and filters locally because the API
// returns *owned* items not associated items.
function* addonGetter(api, app) {
    let attachments, addons;

    if(app) { // don't disploy attachments globally
        let sudoHeaders = JSON.parse(process.env.HEROKU_HEADERS || '{}');
        if(sudoHeaders['X-Heroku-Sudo'] && !sudoHeaders['X-Heroku-Sudo-User']) {
            // because the root /addon-attachments endpoint won't include relevant
            // attachments when sudo-ing for another app, we will use the more
            // specific API call and sacrifice listing foreign attachments.
            addons = api.request({
                method:  'GET',
                path:    `/apps/${app}/addons`,
                headers: {'Accept-Expansion': 'addon_service,plan'},
            });

            attachments = api.request({
                method:  'GET',
                path:    `/apps/${app}/addon-attachments`,
            });
        } else {
            // In order to display all foreign attachments, we'll get out entire
            // attachment list
            attachments = api.addonAttachments().list();
        }
    }

    addons = addons || api.request({
        method:  'GET',
        path:    '/addons',
        headers: {'Accept-Expansion': 'addon_service,plan'}
    });

    // Get addons and attachments in parallel
    let items = yield [addons, attachments];

    function isRelevantToApp(addon) {
        return !app
            || addon.app.name == app
            || _.any(addon.attachments, function(att) { return att.app.name == app });
    }

    attachments = _.groupBy(items[1], _.property('addon.id'));

    addons = [];
    items[0].forEach(function(addon) {
        addon.attachments = attachments[addon.id];

        delete attachments[addon.id];

        if(isRelevantToApp(addon)) {
            addons.push(addon);
        }
    });

    _.values(attachments).forEach(function(atts) {
        let inaccessibleAddon = {
            app: atts[0].addon.app,
            name: atts[0].addon.name,
            plan: {name: '?', price: {cents: '?', unit: 'month'}},
            attachments: atts
        };

        if(isRelevantToApp(inaccessibleAddon)) {
            addons.push(inaccessibleAddon);
        }
    });

    return addons;
}

function formatPrice(price) {
    if(!price.cents)       { return 'free'; }
    if(price.cents == '?') { return '?'; }

    let fmt = price.cents % 100 == 0 ? '$%.0f/%s' : '$%.02f/%s'
    return printf(fmt, price.cents / 100, price.unit);
};

function displayAll(addons) {
    addons = _.sortByAll(addons, 'app.name', 'plan.name', 'addon.name')

    table(addons, {
        headerAnsi: cli.color.bold,
        columns: [{
            key:   'app.name',
            label: 'Owning App',
            ansi:  colorize.app,
        }, {
            key:   'name',
            label: 'Add-on',
            ansi:  colorize.addon,
        }, {
            key:   'plan.name',
            label: 'Plan',
            ansi:  function(s) { return _.trimRight(s) == '?' ? dim(s) : s; },
        }, {
            key:       'plan.price',
            label:     'Price',
            formatter: formatPrice,
            ansi:  function(s) { return _.trimRight(s) == '?' ? dim(s) : s; },
        }],

    });
}

function formatAttachment(attachment, showApp) {
    if(showApp === undefined) { showApp = true; }

    let attName = colorize.attachment(attachment.name);

    if(showApp) {
        return dim(colorize.app(attachment.app.name) + '::') + attName;
    } else {
        return attName;
    }
}

function renderAttachment(attachment, app, isFirst) {
    let ch = isFirst ? '└' : '├';
    let attName = formatAttachment(attachment, attachment.app.name != app);
    return printf(' %s─ %s', ch, attName);
}

function displayForApp(app, addons) {
    let nestedCalcWidther = function(path, nestedPath, fn) {
        return function(row) {
            let nestedWidth = _.max(_.get(row, nestedPath).map(_.compose(_.property('length'),
                                                                         cli.color.stripColor,
                                                                         fn)));
            return Math.max(_.get(row, path).length, nestedWidth);
        }
    };

    function isForeignApp(attOrAddon) { return attOrAddon.app.name != app }

    addons = _.sortByAll(addons,
                         isForeignApp,
                         'plan.name',
                         'addon.name');

    table(addons, {
        headerAnsi: cli.color.bold,
        columns: [{
            key:   'name',
            label: 'Add-on',
            ansi:  colorize.addon,

            // customize column width to factor in the attachment list
            // TODO: make this just be `width`, which can either be a static number or a function which returns a number
            calcWidth: nestedCalcWidther('name',
                                         'attachments',
                                         _.partial(renderAttachment, _, app)),
        }, {
            key:   'plan.name',
            label: 'Plan',
            ansi:  function(s) { return _.trimRight(s) == '?' ? dim(s) : s; }
        }, {
            label:     'Price',
            get: function(addon) {
                if(addon.app.name == app) {
                    return formatPrice(addon.plan.price);
                } else {
                    return dim(printf('(billed to %s app)', colorize.app(addon.app.name)));
                }
            },
        }],

        after: function(addon, options) {
            let atts = _.sortByAll(addon.attachments,
                                   isForeignApp,
                                   'app.name',
                                   'name');

            atts.forEach(function(attachment, idx) {
                let isFirst = (idx == addon.attachments.length - 1)
                console.log(renderAttachment(attachment, app, isFirst));
            });
        }
    })
}

let run = cli.command(function(ctx, api) {
    return co(function*() {
        if(!ctx.flags.all && ctx.app) {
            displayForApp(ctx.app, yield co(addonGetter(api, ctx.app)));
        } else {
            displayAll(yield co(addonGetter(api)));
        }
    });
});

let topic = '_addons';
module.exports = {
    topic:     topic,
    default:   true,
    needsAuth: true,
    preauth:   true,
    wantsApp:  true,
    // args:      [{name: 'addon', optional: true}],
    flags:     [{
        name:        'all',
        char:        'A',
        hasValue:    false,
        description: 'Show add-ons and attachments for all accessible apps'
    }],

    run:         run,
    usage:       `${topic} [--all|--app APP]`,
    description: 'Lists your add-ons and attachments',
    help:        `The default filter applied depends on whether you are in a Heroku app
directory. If so, the --app flag is implied. If not, the default of --all
is implied. Explicitly providing either flag overrides the default
behaviour.

Examples:

  $ heroku ${topic} --all
  $ heroku ${topic} --app acme-inc-website

Identifying specific add-ons:

  Add-ons have canonical names (ADDON_NAME in these command help texts).
  They also application-specific names called aliases or attachments. In
  many cases, these names can be used interchangeably when unambiguous.

  For example, given a fictional \`slowdb\` add-on named \`slowdb-cubed-1531\`
  attached as \`FOO_DB\` to \`app1\` and BAR_DB to \`app2\`, the following
  invocations are considered equivalent:

  $ heroku addons:upgrade slowdb             slowdb:premium
  $ heroku addons:upgrade --app app1 FOO_DB  slowdb:premium
  $ heroku addons:upgrade app1::FOO_DB       slowdb:premium
  $ heroku addons:upgrade app2::BAR_DB       slowdb:premium
  $ heroku addons:upgrade acme-inc-datastore slowdb:premium

  If the name used is ambiguous (e.g. if you used \`slowdb\` with more than
  one add-on of that type installed), the command will error due to
  ambiguity and a more specific identifier will need to be chosen.

  For more information, read https://devcenter.heroku.com/articles/add-ons.`,
};
<|endoftext|>


<commit_before>const express = require('express')
const cors = require('cors')
const Slapp = require('slapp')
const ConvoStore = require('slapp-convo-beepboop')
const Context = require('slapp-context-beepboop')
const slack = require('slack')

const port = process.env.PORT || 3000
const token = process.env.SLACK_TOKEN

const ohsTeam = {
  U1CTUKMT9: {}, // Zoé
  // U40MZ9EL9: {}, // Tugba
  U0BU8V7N0: {}, // Trev
  // U2NC0H2BS: {}, // Temi
  U0BUEB5BK: {}, // Paolo
  U0BU8SV4K: {}, // Michele
  U1KU01R4K: {}, // Kristina
  U162CB0LC: {}, // James
  U0C160N8N: {}, // Christean
  U0BUPA30R: {}, // Chris
  U1CU5P4H0: {}, // Anna
}

const orbitTeam = {
  U2L4F0AF3: {}, // James
}

const team = ohsTeam

const slapp = Slapp({
  verify_token: process.env.SLACK_VERIFY_TOKEN,
  convo_store: ConvoStore(),
  context: Context()
})

// fetch users and store as team members

const updateMembers = () => slack.users.list({ token }, (err, { members }) => {
  if (err) throw new Error(err)

  console.log(`Fetched ${members.length} users`)
  console.log(members.map(({ id }) => id).join(', '))

  members.forEach((member) => {
    if (!team[member.id]) return
    team[member.id] = member
  })
})

updateMembers()

setInterval(updateMembers, 10000)

// commands

slapp.command('/location', '(.*)', (msg, text, location) => {
  if (!team[msg.body.user_id])
    return msg.respond(`You are not added as a team member`)

  team[msg.body.user_id].location = location

  msg.respond(`Your location has been set as _${location}_`)
})

// public api

const app = slapp.attachToExpress(express())

app.use(cors())

app.get('/', (req, res) => {
  res.send('Hello world.')
})

app.get('/team', (req, res) => {
  res.send(team)
})

// start server

app.listen(port, (err) => {
  if (err) return console.error(err)
  console.log(`Listening on port ${port}`)
})
<commit_msg>Commentout Kirstina<commit_after>const express = require('express')
const cors = require('cors')
const Slapp = require('slapp')
const ConvoStore = require('slapp-convo-beepboop')
const Context = require('slapp-context-beepboop')
const slack = require('slack')

const port = process.env.PORT || 3000
const token = process.env.SLACK_TOKEN

const ohsTeam = {
  U1CTUKMT9: {}, // Zoé
  // U40MZ9EL9: {}, // Tugba
  U0BU8V7N0: {}, // Trev
  // U2NC0H2BS: {}, // Temi
  U0BUEB5BK: {}, // Paolo
  U0BU8SV4K: {}, // Michele
  // U1KU01R4K: {}, // Kristina
  U162CB0LC: {}, // James
  U0C160N8N: {}, // Christean
  U0BUPA30R: {}, // Chris
  U1CU5P4H0: {}, // Anna
}

const orbitTeam = {
  U2L4F0AF3: {}, // James
}

const team = ohsTeam

const slapp = Slapp({
  verify_token: process.env.SLACK_VERIFY_TOKEN,
  convo_store: ConvoStore(),
  context: Context()
})

// fetch users and store as team members

const updateMembers = () => slack.users.list({ token }, (err, { members }) => {
  if (err) throw new Error(err)

  console.log(`Fetched ${members.length} users`)
  console.log(members.map(({ id }) => id).join(', '))

  members.forEach((member) => {
    if (!team[member.id]) return
    team[member.id] = member
  })
})

updateMembers()

setInterval(updateMembers, 10000)

// commands

slapp.command('/location', '(.*)', (msg, text, location) => {
  if (!team[msg.body.user_id])
    return msg.respond(`You are not added as a team member`)

  team[msg.body.user_id].location = location

  msg.respond(`Your location has been set as _${location}_`)
})

// public api

const app = slapp.attachToExpress(express())

app.use(cors())

app.get('/', (req, res) => {
  res.send('Hello world.')
})

app.get('/team', (req, res) => {
  res.send(team)
})

// start server

app.listen(port, (err) => {
  if (err) return console.error(err)
  console.log(`Listening on port ${port}`)
})
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import SelectInput from './SelectInput';
import Input from './Input';
import styled from 'styled-components';

const Fieldset = styled.fieldset`
  width: 46%;
  margin: 0 auto 1em;
  border-radius: 5px;
`;

const Legend = styled.legend` padding: 0 .75em; `;

export default class Form extends Component {
  state = {
    startVal: 15
  };

  handleCollatzChange({ target }) {
    this.setState({ startVal: target.value });
  }

  handleSubmit(e) {
    const { renderCollatz } = this.props;
    const { startVal } = this.state;

    e.preventDefault();
    renderCollatz(this.calculateCollatz(startVal));
    window.scrollTo(0, 0);
  }

  calculateCollatz(n) {
    let num = Number(n);
    const sequence = [num];

    while (num > 1) {
      if (num % 2 === 0) {
        num /= 2;
        sequence.push(num);
      } else {
        num = num * 3 + 1;
        sequence.push(num);
      }
    }

    return sequence;
  }

  animateSequence() {
    let { renderCollatz } = this.props;
    let counter = 2;

    renderCollatz(this.calculateCollatz(counter++));

    const interval = setInterval(
      () => {
        if (counter === 7) clearInterval(interval);

        renderCollatz(this.calculateCollatz(counter));
        counter++;
      },
      5500
    );
  }

  render() {
    const { selected, handleWave } = this.props;
    const waveTypes = ['sine', 'sawtooth', 'triangle', 'square'];

    return (

        <form onSubmit={this.handleSubmit.bind(this)}>
          <Fieldset>
            <Legend>
              Enter a number to calculate and listen
            </Legend>
            <SelectInput
              label="Wave type"
              selected={selected}
              waveTypes={waveTypes}
              onChange={handleWave}
            />
            <Input
              label="Start value"
              type="number"
              value={this.state.startVal}
              onChange={this.handleCollatzChange.bind(this)}
            />
            <button type="submit">
              Let's hear it!
            </button>
          </Fieldset>
        </form>

        <button onClick={this.animateSequence.bind(this)}>
          Show me 2-7
        </button>

    );
  }
}<commit_msg>keyDown handler responding<commit_after>import React, { Component } from 'react';
import SelectInput from './SelectInput';
import Input from './Input';
import styled from 'styled-components';

const Fieldset = styled.fieldset`
  width: 46%;
  margin: 0 auto 1em;
  border-radius: 5px;
`;

const Legend = styled.legend` padding: 0 .75em; `;

export default class Form extends Component {
  state = {
    startVal: 15
  };

  handleCollatzChange({ target }) {
    this.setState({ startVal: target.value });
  }

  handleSubmit(e) {
    const { renderCollatz } = this.props;
    const { startVal } = this.state;

    e.preventDefault();
    renderCollatz(this.calculateCollatz(startVal));
    window.scrollTo(0, 0);
  }

  calculateCollatz(n) {
    let num = Number(n);
    const sequence = [num];

    while (num > 1) {
      if (num % 2 === 0) {
        num /= 2;
        sequence.push(num);
      } else {
        num = num * 3 + 1;
        sequence.push(num);
      }
    }

    return sequence;
  }

  animateSequence() {
    let { renderCollatz } = this.props;
    let counter = 2;

    renderCollatz(this.calculateCollatz(counter++));

    const interval = setInterval(
      () => {
        if (counter === 7) clearInterval(interval);

        renderCollatz(this.calculateCollatz(counter));
        counter++;
      },
      5500
    );
  }

  handleKeyDown(e) {
    let { renderCollatz } = this.props;
    let { startVal } = this.state;

    renderCollatz(this.calculateCollatz(startVal - 1));
    this.setState( (prevState) => ({ startVal: prevState.startVal - 1 }));
  }

  render() {
    const { selected, handleWave } = this.props;
    const waveTypes = ['sine', 'sawtooth', 'triangle', 'square'];

    return (

        <form onSubmit={this.handleSubmit.bind(this)}>
          <Fieldset>
            <Legend>
              Enter a number to calculate and listen
            </Legend>
            <SelectInput
              label="Wave type"
              selected={selected}
              waveTypes={waveTypes}
              onChange={handleWave}
            />
            <Input
              label="Start value"
              type="number"
              value={this.state.startVal}
              onChange={this.handleCollatzChange.bind(this)}
            />
            <button type="submit">
              Let's hear it!
            </button>
          </Fieldset>
        </form>

        <button onClick={this.animateSequence.bind(this)}>
          Show me 2-7
        </button>

    );
  }
}<|endoftext|>


<commit_before>import { writeFile } from 'fs';
import { basename, dirname, join, relative } from 'path';

import Plugin from 'broccoli-plugin';
import { merge } from 'lodash';
import mkdirp from 'mkdirp';
import { files as listFiles } from 'node-dir';
import { render } from 'node-sass';
import { Promise } from 'rsvp';

export default class SassDir extends Plugin {

  constructor(inputNodes, options = {}) {
    super(inputNodes, options);
    this.sassOptions = options.sassOptions || {};
  }

  build() {
    return this.renderDir(this.inputPaths[0], this.outputPath);
  }

  renderDir(inputPath, outputPath) {
    return this.readFiles(inputPath).then(
      files => this.renderFiles(
        inputPath,
        files.filter(this.filterFile.bind(this)),
        outputPath
      )
    );
  }

  readFiles(dir) {
    return new Promise((resolve, reject) => {
      listFiles(dir, (err, files) => {
        if (err) {
          reject(err);
        } else {
          resolve(files.map(absolutePath => relative(dir, absolutePath)));
        }
      });
    });
  }

  filterFile(relativePath) {
    return !basename(relativePath).startsWith('_');
  }

  renderFiles(inputPath, relativePaths, outputPath) {
    return Promise.all(relativePaths.map(
      relativePath => this.renderFile(inputPath, relativePath, outputPath)
    ));
  }

  renderFile(inputPath, relativePath, outputPath) {
    const inputFilePath = join(inputPath, relativePath);
    const outputFilePath = join(outputPath, this.getOutputCssPath(relativePath));

    return Promise.all([
      this.renderSass(inputFilePath, outputFilePath),
      this.makeDir(dirname(outputFilePath)),
    ])
    .then(([result]) => {
      const tasks = [this.writeFile(outputFilePath, result.css)];
      if (this.sassOptions.sourceMap) {
        const outputMapFilePath = join(outputPath, this.getOutputMapPath(relativePath));
        tasks.push(this.writeFile(outputMapFilePath, result.map));
      }
      return Promise.all(tasks);
    });
  }

  getOutputCssPath(relativePath) {
    return relativePath.replace(/\.[^/.]+$/, '.css');
  }

  getOutputMapPath(relativePath) {
    return this.getOutputCssPath(relativePath).replace(/\.[^/.]+$/, '.map');
  }

  renderSass(inputFilePath, outputFilePath) {
    return new Promise((resolve, reject) => {
      const options = merge({}, this.sassOptions, {
        file: inputFilePath,
        outFile: outputFilePath,
      });
      render(options, (err, result) => {
        if (err) {
          reject(err);
        } else {
          resolve(result);
        }
      });
    });
  }

  makeDir(path) {
    return new Promise((resolve, reject) => {
      mkdirp(path, err => {
        if (err) {
          reject(err);
        } else {
          resolve(path);
        }
      });
    });
  }

  writeFile(path, contents) {
    return new Promise((resolve, reject) => {
      writeFile(path, contents, err => {
        if (err) {
          reject(err);
        } else {
          resolve(contents);
        }
      });
    });
  }
}
<commit_msg>Fixed .map files being generated even when sourceMapEmbed is set<commit_after>import { writeFile } from 'fs';
import { basename, dirname, join, relative } from 'path';

import Plugin from 'broccoli-plugin';
import { merge } from 'lodash';
import mkdirp from 'mkdirp';
import { files as listFiles } from 'node-dir';
import { render } from 'node-sass';
import { Promise } from 'rsvp';

export default class SassDir extends Plugin {

  constructor(inputNodes, options = {}) {
    super(inputNodes, options);
    this.sassOptions = options.sassOptions || {};
  }

  build() {
    return this.renderDir(this.inputPaths[0], this.outputPath);
  }

  renderDir(inputPath, outputPath) {
    return this.readFiles(inputPath).then(
      files => this.renderFiles(
        inputPath,
        files.filter(this.filterFile.bind(this)),
        outputPath
      )
    );
  }

  readFiles(dir) {
    return new Promise((resolve, reject) => {
      listFiles(dir, (err, files) => {
        if (err) {
          reject(err);
        } else {
          resolve(files.map(absolutePath => relative(dir, absolutePath)));
        }
      });
    });
  }

  filterFile(relativePath) {
    return !basename(relativePath).startsWith('_');
  }

  renderFiles(inputPath, relativePaths, outputPath) {
    return Promise.all(relativePaths.map(
      relativePath => this.renderFile(inputPath, relativePath, outputPath)
    ));
  }

  renderFile(inputPath, relativePath, outputPath) {
    const inputFilePath = join(inputPath, relativePath);
    const outputFilePath = join(outputPath, this.getOutputCssPath(relativePath));

    return Promise.all([
      this.renderSass(inputFilePath, outputFilePath),
      this.makeDir(dirname(outputFilePath)),
    ])
    .then(([result]) => {
      const tasks = [this.writeFile(outputFilePath, result.css)];
      if (this.sassOptions.sourceMap && !this.sassOptions.sourceMapEmbed) {
        const outputMapFilePath = join(outputPath, this.getOutputMapPath(relativePath));
        tasks.push(this.writeFile(outputMapFilePath, result.map));
      }
      return Promise.all(tasks);
    });
  }

  getOutputCssPath(relativePath) {
    return relativePath.replace(/\.[^/.]+$/, '.css');
  }

  getOutputMapPath(relativePath) {
    return this.getOutputCssPath(relativePath).replace(/\.[^/.]+$/, '.map');
  }

  renderSass(inputFilePath, outputFilePath) {
    return new Promise((resolve, reject) => {
      const options = merge({}, this.sassOptions, {
        file: inputFilePath,
        outFile: outputFilePath,
      });
      render(options, (err, result) => {
        if (err) {
          reject(err);
        } else {
          resolve(result);
        }
      });
    });
  }

  makeDir(path) {
    return new Promise((resolve, reject) => {
      mkdirp(path, err => {
        if (err) {
          reject(err);
        } else {
          resolve(path);
        }
      });
    });
  }

  writeFile(path, contents) {
    return new Promise((resolve, reject) => {
      writeFile(path, contents, err => {
        if (err) {
          reject(err);
        } else {
          resolve(contents);
        }
      });
    });
  }
}
<|endoftext|>


<commit_before>/* eslint quote-props: "off" */

/*
 * This will hold all of our keywords information such as the hashmap that
 * holds the keywords with their tool-tip values in it.
 */
function KeywordsHashTable(obj) {
    this.length = 0;
    this.items = {};
    for (var k in obj) {
        if (obj.hasOwnProperty(k)) {
            this.items[k] = obj[k];
            this.length++;
        }
    }
    this.getTip = function (word) {
        return this.items[word];
    };
    this.hasKeyword = function (word) {
        return this.items.hasOwnProperty(word);
    };
}

/* Important keywords that need explanation with a tool-tip.
 * Only some of the keywords are displayed here because only some are used
 * and some are self-explanatory.
 */
var keywordsTable = new KeywordsHashTable({
    "abs" : "",
    "ad" : "" ,
    "absurdum" : "",
    "all" : "",
    "alters" : "The implementer may leave an arbitrary value of the same type at the end of the operation. This provides the most flexibility to the implementers.",
    "alt" : "The implementer may leave an arbitrary value of the same type at the end of the operation. This provides the most flexibility to the implementers.",
    "alternative" : "",
    "and" : "",
    "Array" : "",
    "Aux_Code" : "",
    "Aux_Var" : "",
    "Aux_Vars" : "",
    "Aux" : "",
    "Auxiliary" : "",
    "Axiom" : "",
    "B" : "",
    "Base_Case" : "",
    "By" : "",
    "by" : "",
    "Cart_Prod" : "",
    "Categorical" : "",
    "Case" : "",
    "changing" : "This parameter will be changed throughout the clause.",
    "clears" : "The entry will be re-initialized to the initial value of the same type by the end of the operation.",
    "clr" : "The entry will be re-initialized to the initial value of the same type by the end of the operation.",
    "common" : "",
    "Commutativity" : "",
    "complement" : "",
    "Concatenation" : "This connects the first and second parameters into a chain of the same type. Parentheses are mandatory around Concatenation expressions",
    "concatenation" : "This connects the first and second parameters into a chain of the same type. Parentheses are mandatory around Concatenation expressions",
    "concept" : "This is similar to some object-oriented programing language's header file or class declaration. This file contains the data structure template that includes the mathematical model used to represent that type, the constraints, and a list of all operations along with their pre- and post-conditions.",
    "Concept" : "This is similar to some object-oriented programing language's header file or class declaration. This file contains the data structure template that includes the mathematical model used to represent that type, the constraints, and a list of all operations along with their pre- and post-conditions.",
    "conclusion" : "",
    "Confirm" : "",
    "conjunct" : "",
    "Constraint" : "",
    "Constraints" : "",
    "constraint" : "",
    "constraints" : "",
    "contradiction" : "",
    "convention" : "This clause contains constraints on the realization records in order to keep the implementations of all the various operations consistent. This can be singular or plural. It is also referred to as the representation invariant. ",
    "conventions" : "This clause contains constraints on the realization records in order to keep the implementations of all the various operations consistent. This can be singular or plural. It is also referred to as the representation invariant. ",
    "Convention" : "This clause contains constraints on the realization records in order to keep the implementations of all the various operations consistent. This can be singular or plural. It is also referred to as the representation invariant.",
    "Corollary" : "",
    "Correspondence" : "This clause explains how to read the value in the Contents array as the string described in conceptualization. This clause is necessary to check that the code for the procedures satisfies their respective specifications. It is also referred to as the abstraction function or abstraction relation.",
    "correspondence" : "This clause explains how to read the value in the Contents array as the string described in conceptualization. This clause is necessary to check that the code for the procedures satisfies their respective specifications. It is also referred to as the abstraction function or abstraction relation.",
    "decreasing" : "This clause specifies a progress metric that is a natural number which reduces on each pass through the loop. This loop must eventually terminate because there is not an infinite strictly decreasing sequence of natural numbers. ",
    "Deduction" : "",
    "Defines" : "",
    "defines" : "",
    "definition" : "Introducing a new mathematical function.",
    "def" : "Introducing a new mathematical function.",
    "Definition" : "Introducing a new mathematical function.",
    "Def" : "Introducing a new mathematical function.",
    "distribution" : "",
    "div" : "",
    "do" : "Perform these operations upon ensuring that the 'While' clause is true.",
    "else" : "",
    "elimination" : "",
    "end" : "This finishes whatever operation it corresponds to. You must have this to stop every operation and begin another.",
    "enhanced" : "",
    "enhancement" : "This means that the code below can use any of the information in the concept in the specification or realization of the enhancement. Also, enhancements are just a layout of different procedures that you might wish to add to a concept.",
    "Enhancement" : "This means that the code below can use any of the information in the concept in the specification or realization of the enhancement. Also, enhancements are just a layout of different procedures that you might wish to add to a concept.",
    "ensures" : "Post-conditions, or guarantees, that will happen if the requires clause is correct.",
    "equality" : "",
    "evaluates" : "Any argument passed for that parameter must be a functional expression that will be evaluated when the operation is called.",
    "eval" : "Any argument passed for that parameter must be a functional expression that will be evaluated when the operation is called.",
    "excluded" : "",
    "exemplar" : "An identifier that stands for an arbitrary value which tells the client what is true of every variable that is of this class type.",
    "existantial" : "",
    "exists" : "",
    "exit" : "",
    "Facility" : "This is similar to Java in that every file is a class, and this facility's name should be the same as the name of the file that declares it. You need this statement at the beginning to declare the name of the class and to begin writing a file. To finish the class, write 'end Facility_Name;'",
    "Facility_Finalization" : "",
    "Facility_Initialization" : "",
    "false" : "",
    "Family" : "",
    "finalization" : "",
    "for all" : "For every circumstance like this, truth will be assumed.",
    "from" : "",
    "for" : "",
    "For" : "",
    "Forget" : "",
    "generalization" : "",
    "iff" : "This is used like an 'If and only if' statement from other programming languages.",
    "if" : "An If-Then-Else statement is like most other programming languages in that we are testing a condition for truth and then moving into whichever statement sequence depending on the outcome of the if statement.",
    "If" : "An If-Then-Else statement is like most other programming languages in that we are testing a condition for truth and then moving into whichever statement sequence depending on the outcome of the if statement.",
    "Implicit" : "",
    "implies" : "",
    "Inductive" : "",
    "Inductive_case" : "",
    "initialization" : "",
    "initialization ensures" : "whenever something is declared, the client is guaranteed this statement as its initial value.",
    "instantiation" : "",
    "intersection" : "",
    "introduces" : "",
    "is" : "",
    "is_in" : "",
    "Is_Initial" : "",
    "is_not_in" : "",
    "is_not_proper_subset_of" : "",
    "is_not_subet_of" : "",
    "is_not_substring_of" : "",
    "is_proper_subset_of" : "",
    "is_subset_of" : "",
    "is_substring_of" : "",
    "Iterate" : "",
    "lambda" : "The empty string.",
    "Lemma" : "",
    "Local" : "",
    "maintaining" : "This clause describes essentially what makes the loop work. It must be true at the beginning and at the end of every iteration of the loop.",
    "Math" : "",
    "middle" : "",
    "mod" : "",
    "modeled" : "",
    "modus" : "",
    "not" : "",
    "o" : "This connects the first and second parameters into a chain of the same type. Parentheses are mandatory around Concatenation expressions.",
    "of" : "",
    "oper" : "The beginning of a function within a class. This statement needs to be concluded with an 'end Operation_Name;'. This is used to declare the facility.",
    "Oper" : "The beginning of a function within a class. This statement needs to be concluded with an 'end Operation_Name;'. This is used to declare the facility.",
    "operation" : "The beginning of a function within a class. This statement needs to be concluded with an 'end Operation_Name;'. This is used to declare the facility.",
    "Operation" : "The beginning of a function within a class. This statement needs to be concluded with an 'end Operation_Name;'. This is used to declare the facility.",
    "or" : "",
    "otherwise" : "",
    "ponens" : "",
    "Powerset" : "",
    "powerset" : "",
    "preserves" : "The value passed in will always be the same ending value,  and we are guaranteed that the value will not be changed throughout the operation.",
    "pres" : "The value passed in will always be the same ending value,  and we are guaranteed that the value will not be changed throughout the operation.",
    "Presume" : "",
    "Proc" : "This contains implementation statements within a facility.",
    "Procedure" : "This contains implementation statements within a facility.",
    "Proof" : "",
    "proof" : "",
    "Proofs_for" : "",
    "Property" : "",
    "Pty" : "",
    "QED" : "",
    "quantifier" : "",
    "realization" : "This will contain code for a procedure from the Enhancement.",
    "Realization" : "This will contain code for a procedure from the Enhancement.",
    "realized" : "",
    "reassigns" : "",
    "Record" : "",
    "Recursive" : "",
    "reductio" : "",
    "related" : "",
    "rem" : "",
    "Remember" : "",
    "repeat" : "",
    "replaces" : "The value passed in becomes irrelevant and will be replaced by the value specified in the ensures clause by the end of the operation.",
    "rpl" : "The value passed in becomes irrelevant and will be replaced by the value specified in the ensures clause by the end of the operation.",
    "represented" : "",
    "requires" : "This clause is the pre-condition that the Client (or caller) is responsible for ensuring truth.",
    "res" : "",
    "restores" : "The value passed in will always be the same ending value, but there is no guarantee that it will not be changed throughout the operation.",
    "rest" : "The value passed in will always be the same ending value, but there is no guarantee that it will not be changed throughout the operation.",
    "rules" : "",
    "SSet" : "",
    "Static" : "",
    "Subtype" : "",
    "such" : "",
    "Supposition" : "",
    "that" : "",
    "then" : "",
    "Theorem" : "",
    "Theory" : "",
    "Precis" : "",
    "There" : "",
    "there" : "",
    "times" : "",
    "true" : "",
    "Type" : "",
    "type" : "",
    "Type_Family" : "",
    "union" : "The set of elements that are in the two sets.",
    "Unique" : "",
    "unique" : "",
    "Unit" : "",
    "unit" : "",
    "universal" : "",
    "updates" : "The value passed in will have a purposeful change at the end of the operation.",
    "upd" : "The value passed in will have a purposeful change at the end of the operation.",
    "uses" : "This allows RESOLVE to handle specific data types which are defined through the concepts listed in these clauses. This is similar to header files from other programming languages.",
    "Variable" : "The declaration of a variable always begins with this. The syntax is as follows: 'Var varname:   Vartype;'. The 'Vartype' is where you determine what kind of variable we are declaring.",
    "Var" : "The declaration of a variable always begins with this. The syntax is as follows: 'Var varname:   Vartype;'. The 'Vartype' is where you determine what kind of variable we are declaring.",
    "Variables" : "The declaration of a variable always begins with this. The syntax is as follows: 'Var varname:   Vartype;'. The 'Vartype' is where you determine what kind of variable we are declaring.",
    "Vars" : "The declaration of a variable always begins with this. The syntax is as follows: 'Var varname:   Vartype;'. The 'Vartype' is where you determine what kind of variable we are declaring.",
    "when" : "",
    "where" : "",
    "While" : "The beginning of a loop where the clause following this is what the loop will be ensuring is true to be able to continue on.",
    "without" : ""
});

function checkResolveKeywords(value) {
    if (keywordsTable.hasKeyword(value) > 0) {
        return true;
    }
    else {
        return false;
    }
}

function showKeywordTooltip(pos, editor, textRange){
    var selectedWord = editor.session.getTextRange(textRange);
    if (keywordsTable.hasKeyword(selectedWord) && (keywordsTable.getTip(selectedWord) !== "")) {
        var keyword = $("#code_editor").find(".ace_keyword:contains(" + selectedWord + ")");

        var length = selectedWord.length;
        keyword.each(function () {
            var offset = $(this).offset();
            var keywordPos = editor.renderer.screenToTextCoordinates(offset.left + 3, offset.top + 3);
            if (keywordPos.row == pos.row) {
                if(keywordPos.column <= pos.column && pos.column <= keywordPos.column + length){
                    $(this).qtip({
                        content: {
                            text: keywordsTable.getTip(selectedWord),
                            title: {
                                text: selectedWord,
                                button: true
                            }
                        },
                        show: {
                            event: false, // Only show when show() is called manually
                            ready: true // Also show on page load
                        },
                        hide: "unfocus",
                        style: {
                            classes: "ui-tooltip-keywords ui-tooltip-rounded",
                            tip: {
                                corner: "top left"
                            }
                        }
                    });
                }
            }
        });
    }
}
<commit_msg>more fixes to editorUpdate<commit_after>/* eslint quote-props: "off" */

/*
 * This will hold all of our keywords information such as the hashmap that
 * holds the keywords with their tool-tip values in it.
 */
function KeywordsHashTable(obj) {
    this.length = 0;
    this.items = {};
    for (var k in obj) {
        if (obj.hasOwnProperty(k)) {
            this.items[k] = obj[k];
            this.length++;
        }
    }
    this.getTip = function (word) {
        return this.items[word];
    };
    this.hasKeyword = function (word) {
        return this.items.hasOwnProperty(word);
    };
}

/* Important keywords that need explanation with a tool-tip.
 * Only some of the keywords are displayed here because only some are used
 * and some are self-explanatory.
 */
var keywordsTable = new KeywordsHashTable({
    "abs" : "",
    "ad" : "",
    "absurdum" : "",
    "all" : "",
    "alters" : "The implementer may leave an arbitrary value of the same type at the end of the operation. This provides the most flexibility to the implementers.",
    "alt" : "The implementer may leave an arbitrary value of the same type at the end of the operation. This provides the most flexibility to the implementers.",
    "alternative" : "",
    "and" : "",
    "Array" : "",
    "Aux_Code" : "",
    "Aux_Var" : "",
    "Aux_Vars" : "",
    "Aux" : "",
    "Auxiliary" : "",
    "Axiom" : "",
    "B" : "",
    "Base_Case" : "",
    "By" : "",
    "by" : "",
    "Cart_Prod" : "",
    "Categorical" : "",
    "Case" : "",
    "changing" : "This parameter will be changed throughout the clause.",
    "clears" : "The entry will be re-initialized to the initial value of the same type by the end of the operation.",
    "clr" : "The entry will be re-initialized to the initial value of the same type by the end of the operation.",
    "common" : "",
    "Commutativity" : "",
    "complement" : "",
    "Concatenation" : "This connects the first and second parameters into a chain of the same type. Parentheses are mandatory around Concatenation expressions",
    "concatenation" : "This connects the first and second parameters into a chain of the same type. Parentheses are mandatory around Concatenation expressions",
    "concept" : "This is similar to some object-oriented programing language's header file or class declaration. This file contains the data structure template that includes the mathematical model used to represent that type, the constraints, and a list of all operations along with their pre- and post-conditions.",
    "Concept" : "This is similar to some object-oriented programing language's header file or class declaration. This file contains the data structure template that includes the mathematical model used to represent that type, the constraints, and a list of all operations along with their pre- and post-conditions.",
    "conclusion" : "",
    "Confirm" : "",
    "conjunct" : "",
    "Constraint" : "",
    "Constraints" : "",
    "constraint" : "",
    "constraints" : "",
    "contradiction" : "",
    "convention" : "This clause contains constraints on the realization records in order to keep the implementations of all the various operations consistent. This can be singular or plural. It is also referred to as the representation invariant. ",
    "conventions" : "This clause contains constraints on the realization records in order to keep the implementations of all the various operations consistent. This can be singular or plural. It is also referred to as the representation invariant. ",
    "Convention" : "This clause contains constraints on the realization records in order to keep the implementations of all the various operations consistent. This can be singular or plural. It is also referred to as the representation invariant.",
    "Corollary" : "",
    "Correspondence" : "This clause explains how to read the value in the Contents array as the string described in conceptualization. This clause is necessary to check that the code for the procedures satisfies their respective specifications. It is also referred to as the abstraction function or abstraction relation.",
    "correspondence" : "This clause explains how to read the value in the Contents array as the string described in conceptualization. This clause is necessary to check that the code for the procedures satisfies their respective specifications. It is also referred to as the abstraction function or abstraction relation.",
    "decreasing" : "This clause specifies a progress metric that is a natural number which reduces on each pass through the loop. This loop must eventually terminate because there is not an infinite strictly decreasing sequence of natural numbers. ",
    "Deduction" : "",
    "Defines" : "",
    "defines" : "",
    "definition" : "Introducing a new mathematical function.",
    "def" : "Introducing a new mathematical function.",
    "Definition" : "Introducing a new mathematical function.",
    "Def" : "Introducing a new mathematical function.",
    "distribution" : "",
    "div" : "",
    "do" : "Perform these operations upon ensuring that the 'While' clause is true.",
    "else" : "",
    "elimination" : "",
    "end" : "This finishes whatever operation it corresponds to. You must have this to stop every operation and begin another.",
    "enhanced" : "",
    "enhancement" : "This means that the code below can use any of the information in the concept in the specification or realization of the enhancement. Also, enhancements are just a layout of different procedures that you might wish to add to a concept.",
    "Enhancement" : "This means that the code below can use any of the information in the concept in the specification or realization of the enhancement. Also, enhancements are just a layout of different procedures that you might wish to add to a concept.",
    "ensures" : "Post-conditions, or guarantees, that will happen if the requires clause is correct.",
    "equality" : "",
    "evaluates" : "Any argument passed for that parameter must be a functional expression that will be evaluated when the operation is called.",
    "eval" : "Any argument passed for that parameter must be a functional expression that will be evaluated when the operation is called.",
    "excluded" : "",
    "exemplar" : "An identifier that stands for an arbitrary value which tells the client what is true of every variable that is of this class type.",
    "existantial" : "",
    "exists" : "",
    "exit" : "",
    "Facility" : "This is similar to Java in that every file is a class, and this facility's name should be the same as the name of the file that declares it. You need this statement at the beginning to declare the name of the class and to begin writing a file. To finish the class, write 'end Facility_Name;'",
    "Facility_Finalization" : "",
    "Facility_Initialization" : "",
    "false" : "",
    "Family" : "",
    "finalization" : "",
    "for all" : "For every circumstance like this, truth will be assumed.",
    "from" : "",
    "for" : "",
    "For" : "",
    "Forget" : "",
    "generalization" : "",
    "iff" : "This is used like an 'If and only if' statement from other programming languages.",
    "if" : "An If-Then-Else statement is like most other programming languages in that we are testing a condition for truth and then moving into whichever statement sequence depending on the outcome of the if statement.",
    "If" : "An If-Then-Else statement is like most other programming languages in that we are testing a condition for truth and then moving into whichever statement sequence depending on the outcome of the if statement.",
    "Implicit" : "",
    "implies" : "",
    "Inductive" : "",
    "Inductive_case" : "",
    "initialization" : "",
    "initialization ensures" : "whenever something is declared, the client is guaranteed this statement as its initial value.",
    "instantiation" : "",
    "intersection" : "",
    "introduces" : "",
    "is" : "",
    "is_in" : "",
    "Is_Initial" : "",
    "is_not_in" : "",
    "is_not_proper_subset_of" : "",
    "is_not_subet_of" : "",
    "is_not_substring_of" : "",
    "is_proper_subset_of" : "",
    "is_subset_of" : "",
    "is_substring_of" : "",
    "Iterate" : "",
    "lambda" : "The empty string.",
    "Lemma" : "",
    "Local" : "",
    "maintaining" : "This clause describes essentially what makes the loop work. It must be true at the beginning and at the end of every iteration of the loop.",
    "Math" : "",
    "middle" : "",
    "mod" : "",
    "modeled" : "",
    "modus" : "",
    "not" : "",
    "o" : "This connects the first and second parameters into a chain of the same type. Parentheses are mandatory around Concatenation expressions.",
    "of" : "",
    "oper" : "The beginning of a function within a class. This statement needs to be concluded with an 'end Operation_Name;'. This is used to declare the facility.",
    "Oper" : "The beginning of a function within a class. This statement needs to be concluded with an 'end Operation_Name;'. This is used to declare the facility.",
    "operation" : "The beginning of a function within a class. This statement needs to be concluded with an 'end Operation_Name;'. This is used to declare the facility.",
    "Operation" : "The beginning of a function within a class. This statement needs to be concluded with an 'end Operation_Name;'. This is used to declare the facility.",
    "or" : "",
    "otherwise" : "",
    "ponens" : "",
    "Powerset" : "",
    "powerset" : "",
    "preserves" : "The value passed in will always be the same ending value,  and we are guaranteed that the value will not be changed throughout the operation.",
    "pres" : "The value passed in will always be the same ending value,  and we are guaranteed that the value will not be changed throughout the operation.",
    "Presume" : "",
    "Proc" : "This contains implementation statements within a facility.",
    "Procedure" : "This contains implementation statements within a facility.",
    "Proof" : "",
    "proof" : "",
    "Proofs_for" : "",
    "Property" : "",
    "Pty" : "",
    "QED" : "",
    "quantifier" : "",
    "realization" : "This will contain code for a procedure from the Enhancement.",
    "Realization" : "This will contain code for a procedure from the Enhancement.",
    "realized" : "",
    "reassigns" : "",
    "Record" : "",
    "Recursive" : "",
    "reductio" : "",
    "related" : "",
    "rem" : "",
    "Remember" : "",
    "repeat" : "",
    "replaces" : "The value passed in becomes irrelevant and will be replaced by the value specified in the ensures clause by the end of the operation.",
    "rpl" : "The value passed in becomes irrelevant and will be replaced by the value specified in the ensures clause by the end of the operation.",
    "represented" : "",
    "requires" : "This clause is the pre-condition that the Client (or caller) is responsible for ensuring truth.",
    "res" : "",
    "restores" : "The value passed in will always be the same ending value, but there is no guarantee that it will not be changed throughout the operation.",
    "rest" : "The value passed in will always be the same ending value, but there is no guarantee that it will not be changed throughout the operation.",
    "rules" : "",
    "SSet" : "",
    "Static" : "",
    "Subtype" : "",
    "such" : "",
    "Supposition" : "",
    "that" : "",
    "then" : "",
    "Theorem" : "",
    "Theory" : "",
    "Precis" : "",
    "There" : "",
    "there" : "",
    "times" : "",
    "true" : "",
    "Type" : "",
    "type" : "",
    "Type_Family" : "",
    "union" : "The set of elements that are in the two sets.",
    "Unique" : "",
    "unique" : "",
    "Unit" : "",
    "unit" : "",
    "universal" : "",
    "updates" : "The value passed in will have a purposeful change at the end of the operation.",
    "upd" : "The value passed in will have a purposeful change at the end of the operation.",
    "uses" : "This allows RESOLVE to handle specific data types which are defined through the concepts listed in these clauses. This is similar to header files from other programming languages.",
    "Variable" : "The declaration of a variable always begins with this. The syntax is as follows: 'Var varname:   Vartype;'. The 'Vartype' is where you determine what kind of variable we are declaring.",
    "Var" : "The declaration of a variable always begins with this. The syntax is as follows: 'Var varname:   Vartype;'. The 'Vartype' is where you determine what kind of variable we are declaring.",
    "Variables" : "The declaration of a variable always begins with this. The syntax is as follows: 'Var varname:   Vartype;'. The 'Vartype' is where you determine what kind of variable we are declaring.",
    "Vars" : "The declaration of a variable always begins with this. The syntax is as follows: 'Var varname:   Vartype;'. The 'Vartype' is where you determine what kind of variable we are declaring.",
    "when" : "",
    "where" : "",
    "While" : "The beginning of a loop where the clause following this is what the loop will be ensuring is true to be able to continue on.",
    "without" : ""
});

function checkResolveKeywords(value) {
    if (keywordsTable.hasKeyword(value) > 0) {
        return true;
    }

    return false;
}

function showKeywordTooltip(pos, editor, textRange) {
    var selectedWord = editor.session.getTextRange(textRange);
    if (keywordsTable.hasKeyword(selectedWord) && keywordsTable.getTip(selectedWord) !== "") {
        var keyword = $("#code_editor").find(".ace_keyword:contains(" + selectedWord + ")");

        var length = selectedWord.length;
        keyword.each(function () {
            var offset = $(this).offset();
            var keywordPos = editor.renderer.screenToTextCoordinates(offset.left + 3, offset.top + 3);
            if (keywordPos.row == pos.row) {
                if (keywordPos.column <= pos.column && pos.column <= keywordPos.column + length) {
                    $(this).qtip({
                        content: {
                            text: keywordsTable.getTip(selectedWord),
                            title: {
                                text: selectedWord,
                                button: true
                            }
                        },
                        show: {
                            event: false, // Only show when show() is called manually
                            ready: true // Also show on page load
                        },
                        hide: "unfocus",
                        style: {
                            classes: "ui-tooltip-keywords ui-tooltip-rounded",
                            tip: {
                                corner: "top left"
                            }
                        }
                    });
                }
            }
        });
    }
}
<|endoftext|>


<commit_before>var express = require('express');
var bodyParser = require('body-parser');

var app = express();
app.use(bodyParser.json());

// Initialize the app
var server = app.listen(process.env.PORT || 8080, function() {
    var port = server.address().port;
    console.log("App now running on port", port);
});

// REST API DEFINED BELOW

// Generic error handler used by all endpoints
function handleError(res, reason, message, code) {
    console.log("ERROR: " + reason);
    res.status(code || 500).json({"error": message});
}

/*
 * "/api/charging-session"
 *   GET: find all charging sessions
 *   POST: create a new charging session
 */
app.get("/api/charging-session", function(req, res) {
    console.log("find all charging sessions");
    res.status(200).json();
});

app.post("/api/charging-session", function(req, res) {
    console.log("create new charging session");
    res.status(200).json({"response": "This is a test"});
})

/*
 * "/api/charging-session/:id"
 *   GET: find charging session by id
 *   PUT: update charging session by id
 *   DELETE: delete charging session by id
 */
app.get("/api/charging-session/:id", function(req, res) {
    console.log("find charging session by id");
    res.status(200).json();
});

app.put("/api/charging-session/:id", function(req, res) {
    console.log("update charging session by id");
    res.status(200).json();
});

app.delete("/api/charging-session/:id", function(req, res) {
    console.log("delete charging session by id");
    res.status(200).json();
});
<commit_msg>add GET request for returning a client instance url<commit_after>var express = require('express');
var bodyParser = require('body-parser');

var app = express();
app.use(bodyParser.json());

// Initialize the app
var server = app.listen(process.env.PORT || 8080, function() {
    var port = server.address().port;
    console.log("App now running on port", port);
});

// REST API DEFINED BELOW

// Generic error handler used by all endpoints
function handleError(res, reason, message, code) {
    console.log("ERROR: " + reason);
    res.status(code || 500).json({"error": message});
}

/*
 * "/api/client-instance"
 *   GET: find all charging sessions
 */
app.get("/api/client-instance", function(req, res) {
    console.log("return new client instance url");
    res.status(200).json({"data": "This is a test"});
});

/*
 * "/api/charging-session"
 *   GET: find all charging sessions
 *   POST: create a new charging session
 */
app.get("/api/charging-session", function(req, res) {
    console.log("find all charging sessions");
    res.status(200).json();
});

app.post("/api/charging-session", function(req, res) {
    console.log("create new charging session");
    res.status(200).json();
});

/*
 * "/api/charging-session/:id"
 *   GET: find charging session by id
 *   PUT: update charging session by id
 *   DELETE: delete charging session by id
 */
app.get("/api/charging-session/:id", function(req, res) {
    console.log("find charging session by id");
    res.status(200).json();
});

app.put("/api/charging-session/:id", function(req, res) {
    console.log("update charging session by id");
    res.status(200).json();
});

app.delete("/api/charging-session/:id", function(req, res) {
    console.log("delete charging session by id");
    res.status(200).json();
});
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import Switch from 'react-router-dom/Switch';
import Route from 'react-router-dom/Route';
import Link from 'react-router-dom/Link';
import NavListItem from '../NavListItem';

import Paneset from '../Paneset';
import Pane from '../Pane';
import NavList from '../NavList';
import NavListSection from '../NavListSection';
import IconButton from '../IconButton';

import css from './Settings.css';

class Settings extends React.Component {
  constructor(props) {
    super(props);
    const stripes = props.stripes;

    this.sections = props.sections;

    // if props.section was not provided, push props.pages into an array
    // so it can act like props.sections. this allows all the logic here to
    // act like we have an array of sections containing an array of
    // { label: string, pages: array } objects, which is simpler than
    // separate logic for props.sections and props.pages.
    if (!this.sections) {
      this.sections = [{
        label: '',
        pages: props.pages || [],
      }];
    }

    // this.routes contains routes from all pages across all sections
    this.routes = [];
    this.sections.forEach(section => {
      const sectionRoutes = section.pages
        .filter(p => !p.perm || stripes.hasPerm(p.perm))
        .map(page => ({
          page,
          component: stripes.connect(page.component, { dataKey: page.route }),
        }));
      this.routes = [...this.routes, ...sectionRoutes];
    });
  }

  render() {
    const props = this.props;
    const stripes = props.stripes;
    let { activeLink } = this.props;

    // links in a given section
    const navlinks = (section) => {
      const navItems = section.pages.map((p) => {
        const link = `${props.match.path}/${p.route}`;
        if (props.location.pathname.startsWith(link)) {
          activeLink = link;
        }
        if (p.perm && !stripes.hasPerm(p.perm)) return null;
        return <NavListItem key={p.route} to={link}>{p.label}</NavListItem>;
      }).filter(x => x !== null);

      return (
        <NavListSection activeLink={activeLink} label={section.label}>
          {navItems}
        </NavListSection>
      );
    };

    let Saved;
    const routes = this.routes.map((p) => {
      const Current = p.component;
      if (!Saved) Saved = Current;
      return (<Route
        key={p.page.route}
        path={`${props.match.path}/${p.page.route}`}
        render={props2 => <Current {...props2} stripes={stripes} label={p.page.label} />}
      />);
    });

    return (
      <Paneset nested defaultWidth="80%">
        <Pane
          defaultWidth="fill"
          paneTitle={props.paneTitle || 'Module Settings'}
          firstMenu={(
            <Link to="/settings" className={css.settingsBackButton}>
              <IconButton icon="left-arrow" />
            </Link>
          )}
        >
          {this.sections.map(section => (
            <NavList key={section.label}>
              {navlinks(section)}
            </NavList>
          ))}
        </Pane>
        <Switch>
          {routes}
        </Switch>
      </Paneset>
    );
  }
}

Settings.propTypes = {
  activeLink: PropTypes.string,
  location: PropTypes.shape({
    pathname: PropTypes.string,
  }),
  match: PropTypes.shape({
    path: PropTypes.string.isRequired,
  }).isRequired,
  pages: PropTypes.arrayOf(
    PropTypes.shape({
      perm: PropTypes.string,
      route: PropTypes.string.isRequired,
      label: PropTypes.string.isRequired,
      component: PropTypes.func.isRequired,
    }),
  ),
  paneTitle: PropTypes.string,
  sections: PropTypes.arrayOf(
    PropTypes.shape({
      label: PropTypes.string.isRequired,
      pages: PropTypes.arrayOf(
        PropTypes.shape({
          perm: PropTypes.string,
          route: PropTypes.string.isRequired,
          label: PropTypes.string.isRequired,
          component: PropTypes.func.isRequired,
        }),
      ).isRequired,
    }),
  ),
  stripes: PropTypes.shape({
    connect: PropTypes.func.isRequired,
    hasPerm: PropTypes.func.isRequired,
  }).isRequired,
};

export default Settings;
<commit_msg>Add missing withStripes to Settings<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import Switch from 'react-router-dom/Switch';
import Route from 'react-router-dom/Route';
import Link from 'react-router-dom/Link';
import { withStripes } from '@folio/stripes-core/src/StripesContext';

import NavListItem from '../NavListItem';
import Paneset from '../Paneset';
import Pane from '../Pane';
import NavList from '../NavList';
import NavListSection from '../NavListSection';
import IconButton from '../IconButton';

import css from './Settings.css';

class Settings extends React.Component {
  constructor(props) {
    super(props);
    const stripes = props.stripes;

    this.sections = props.sections;

    // if props.section was not provided, push props.pages into an array
    // so it can act like props.sections. this allows all the logic here to
    // act like we have an array of sections containing an array of
    // { label: string, pages: array } objects, which is simpler than
    // separate logic for props.sections and props.pages.
    if (!this.sections) {
      this.sections = [{
        label: '',
        pages: props.pages || [],
      }];
    }

    // this.routes contains routes from all pages across all sections
    this.routes = [];
    this.sections.forEach(section => {
      const sectionRoutes = section.pages
        .filter(p => !p.perm || stripes.hasPerm(p.perm))
        .map(page => ({
          page,
          component: stripes.connect(page.component, { dataKey: page.route }),
        }));
      this.routes = [...this.routes, ...sectionRoutes];
    });
  }

  render() {
    const props = this.props;
    const stripes = props.stripes;
    let { activeLink } = this.props;

    // links in a given section
    const navlinks = (section) => {
      const navItems = section.pages.map((p) => {
        const link = `${props.match.path}/${p.route}`;
        if (props.location.pathname.startsWith(link)) {
          activeLink = link;
        }
        if (p.perm && !stripes.hasPerm(p.perm)) return null;
        return <NavListItem key={p.route} to={link}>{p.label}</NavListItem>;
      }).filter(x => x !== null);

      return (
        <NavListSection activeLink={activeLink} label={section.label}>
          {navItems}
        </NavListSection>
      );
    };

    let Saved;
    const routes = this.routes.map((p) => {
      const Current = p.component;
      if (!Saved) Saved = Current;
      return (<Route
        key={p.page.route}
        path={`${props.match.path}/${p.page.route}`}
        render={props2 => <Current {...props2} stripes={stripes} label={p.page.label} />}
      />);
    });

    return (
      <Paneset nested defaultWidth="80%">
        <Pane
          defaultWidth="fill"
          paneTitle={props.paneTitle || 'Module Settings'}
          firstMenu={(
            <Link to="/settings" className={css.settingsBackButton}>
              <IconButton icon="left-arrow" />
            </Link>
          )}
        >
          {this.sections.map(section => (
            <NavList key={section.label}>
              {navlinks(section)}
            </NavList>
          ))}
        </Pane>
        <Switch>
          {routes}
        </Switch>
      </Paneset>
    );
  }
}

Settings.propTypes = {
  activeLink: PropTypes.string,
  location: PropTypes.shape({
    pathname: PropTypes.string,
  }),
  match: PropTypes.shape({
    path: PropTypes.string.isRequired,
  }).isRequired,
  pages: PropTypes.arrayOf(
    PropTypes.shape({
      perm: PropTypes.string,
      route: PropTypes.string.isRequired,
      label: PropTypes.string.isRequired,
      component: PropTypes.func.isRequired,
    }),
  ),
  paneTitle: PropTypes.string,
  sections: PropTypes.arrayOf(
    PropTypes.shape({
      label: PropTypes.string.isRequired,
      pages: PropTypes.arrayOf(
        PropTypes.shape({
          perm: PropTypes.string,
          route: PropTypes.string.isRequired,
          label: PropTypes.string.isRequired,
          component: PropTypes.func.isRequired,
        }),
      ).isRequired,
    }),
  ),
  stripes: PropTypes.shape({
    connect: PropTypes.func.isRequired,
    hasPerm: PropTypes.func.isRequired,
  }).isRequired,
};

export default withStripes(Settings);
<|endoftext|>


<commit_before>import React from "react";
//import {Icon} from "../../icon/index.js";
import * as helpers from "../../helpers.js";

//Import toolbar styles
import "./style.scss";

//Base class
let baseClass = "neutrine-toolbar";

//Export toolbar wrapper component
export const ToolbarWrapper = function (props) {
    //Toolbar class styles
    let classList = [baseClass + "-wrapper"];
    //Check if toolbar is collapsed
    if (props.collapsed === true) {
        classList.push(baseClass + "-wrapper--collapsed");
    }
    //Return the toolbar element
    return React.createElement("div", {"className": classList.join(" ")}, props.children);
};

//Toolbar wrapper default props
ToolbarWrapper.defaultProps = {
    "collapsed": true
};

//Export toolbar component
export const Toolbar = function (props) {
    //Sidebar base class styles
    let classList = [baseClass];
    //Check the toolbar color
    if (props.color === "light" || props.color === "dark") {
        classList.push(baseClass + "--" + props.color);
    }
    //Build toolbar props
    let toolbarProps = {
        "className": helpers.classNames(classList, props.className),
        "style": props.style
    };
    //Return the toolbar component
    return React.createElement("div", toolbarProps, props.children);
};

//Toolbar default props
Toolbar.defaultProps = {
    "color": "light"
};

//Toolbar toggle
export const ToolbarToggle = function (props) {
    //Build the sidebar toggle props
    let toggleProps = {
        "align": "center",
        "onClick": props.onClick,
        "className": baseClass + "-toggle"
    };
    //Build the toggle icon
    let toggleIcon = React.createElement(Icon, {
        "icon": "chevron-left",
        "className": baseClass + "-toggle-icon"
    });
    //Build the toggle element
    return React.createElement("div", toggleProps, toggleIcon);
};

//Toolbar item
export const ToolbarItem = function (props) {
    //Initialize the button props
    let itemProps = {
        "className": [baseClass + "-item"],
        "onClick": props.onClick
    };
    //Add the button icon
    let icon = null;
    if (props.icon !== null) {
        icon = React.createElement(Icon, {
            "icon": props["icon"],
            "className": baseClass + "-item-icon"
        });
    }
    //itemProps.className.push(baseClass + "-link-" + key);
    //Check if this link is active
    if (typeof props.active === "boolean" && props.active === true) {
        itemProps.className.push(baseClass + "-item--active");
    }
    //Merge the classnames
    itemProps.className = itemProps.className.join(" ");
    //Return the toolbar item element
    return React.createElement("div", itemProps, icon, props.text);
};

//Toolbar item default props
ToolbarItem.defaultProps = {
    "text": "",
    "icon": null,
    "active": false,
    "onClick": null,
};

//Toolbar separator
export const ToolbarSeparator = function (props) {
    return React.createElement("div", {
        "className": baseClass + "-separator"
    });
};

//Toolbar group
export const ToolbarGroup = function (props) {
    //Toolbar group default props
    let groupProps = {
        "className": baseClass + "-group"
    };
    //Return the toolbar group element
    return React.createElement("div", groupProps, props.text);
};

//Toolbar group default props
ToolbarGroup.defaultProps = {
    "text": null
};

<commit_msg>Fixed icon component import<commit_after>import React from "react";
import {Icon} from "../../icon/index.js";
import * as helpers from "../../helpers.js";

//Import toolbar styles
import "./style.scss";

//Base class
let baseClass = "neutrine-toolbar";

//Export toolbar wrapper component
export const ToolbarWrapper = function (props) {
    //Toolbar class styles
    let classList = [baseClass + "-wrapper"];
    //Check if toolbar is collapsed
    if (props.collapsed === true) {
        classList.push(baseClass + "-wrapper--collapsed");
    }
    //Return the toolbar element
    return React.createElement("div", {"className": classList.join(" ")}, props.children);
};

//Toolbar wrapper default props
ToolbarWrapper.defaultProps = {
    "collapsed": true
};

//Export toolbar component
export const Toolbar = function (props) {
    //Sidebar base class styles
    let classList = [baseClass];
    //Check the toolbar color
    if (props.color === "light" || props.color === "dark") {
        classList.push(baseClass + "--" + props.color);
    }
    //Build toolbar props
    let toolbarProps = {
        "className": helpers.classNames(classList, props.className),
        "style": props.style
    };
    //Return the toolbar component
    return React.createElement("div", toolbarProps, props.children);
};

//Toolbar default props
Toolbar.defaultProps = {
    "color": "light"
};

//Toolbar toggle
export const ToolbarToggle = function (props) {
    //Build the sidebar toggle props
    let toggleProps = {
        "align": "center",
        "onClick": props.onClick,
        "className": baseClass + "-toggle"
    };
    //Build the toggle icon
    let toggleIcon = React.createElement(Icon, {
        "icon": "chevron-left",
        "className": baseClass + "-toggle-icon"
    });
    //Build the toggle element
    return React.createElement("div", toggleProps, toggleIcon);
};

//Toolbar item
export const ToolbarItem = function (props) {
    //Initialize the button props
    let itemProps = {
        "className": [baseClass + "-item"],
        "onClick": props.onClick
    };
    //Add the button icon
    let icon = null;
    if (props.icon !== null) {
        icon = React.createElement(Icon, {
            "icon": props["icon"],
            "className": baseClass + "-item-icon"
        });
    }
    //itemProps.className.push(baseClass + "-link-" + key);
    //Check if this link is active
    if (typeof props.active === "boolean" && props.active === true) {
        itemProps.className.push(baseClass + "-item--active");
    }
    //Merge the classnames
    itemProps.className = itemProps.className.join(" ");
    //Return the toolbar item element
    return React.createElement("div", itemProps, icon, props.text);
};

//Toolbar item default props
ToolbarItem.defaultProps = {
    "text": "",
    "icon": null,
    "active": false,
    "onClick": null,
};

//Toolbar separator
export const ToolbarSeparator = function (props) {
    return React.createElement("div", {
        "className": baseClass + "-separator"
    });
};

//Toolbar group
export const ToolbarGroup = function (props) {
    //Toolbar group default props
    let groupProps = {
        "className": baseClass + "-group"
    };
    //Return the toolbar group element
    return React.createElement("div", groupProps, props.text);
};

//Toolbar group default props
ToolbarGroup.defaultProps = {
    "text": null
};

<|endoftext|>


<commit_before>(function(module) {
    module.component('mcDir', {
        templateUrl: 'project/files/components/dir/mc-dir.html',
        controller: 'MCDirComponentController'
    });

    module.controller('MCDirComponentController', MCDirComponentController);
    MCDirComponentController.$inject = ["$stateParams", "project", "gridFiles"];
    function MCDirComponentController($stateParams, project, gridFiles) {
        var ctrl = this;
        ctrl.project = project.get();

        var entry = gridFiles.findEntry(ctrl.project.files[0], $stateParams.dir_id);
        if (entry) {
            ctrl.dir = entry.model;
            console.dir(ctrl.dir);
        }
    }
}(angular.module('materialscommons')));
<commit_msg>Remove console statement.<commit_after>(function(module) {
    module.component('mcDir', {
        templateUrl: 'project/files/components/dir/mc-dir.html',
        controller: 'MCDirComponentController'
    });

    module.controller('MCDirComponentController', MCDirComponentController);
    MCDirComponentController.$inject = ["$stateParams", "project", "gridFiles"];
    function MCDirComponentController($stateParams, project, gridFiles) {
        var ctrl = this;
        ctrl.project = project.get();

        var entry = gridFiles.findEntry(ctrl.project.files[0], $stateParams.dir_id);
        if (entry) {
            ctrl.dir = entry.model;
        }
    }
}(angular.module('materialscommons')));
<|endoftext|>


<commit_before>/*
  MIT License,
  Copyright (c) 2015-2016, Richard Rodger and other contributors.
*/

'use strict'

var _ = require('lodash')
var Jsonic = require('jsonic')
var Sneeze = require('sneeze')
var Nid = require('nid')

module.exports = function mesh (options) {
  var seneca = this

  var balance_map = {}
  var mid = Nid()

  options = seneca.util.deepextend({
    auto: true,
    make_entry: default_make_entry
  }, options)

  // options.base is to deprecated
  var isbase = !!(options.isbase || options.base)

  var pin = options.pin || options.pins

  if( isbase ) {
    pin = pin || 'role:mesh,base:true'
  }

  // options.remotes is to deprecated
  var bases = options.bases || options.remotes

  var tag = options.tag

  var sneeze_opts = options.sneeze || {}
  sneeze_opts.isbase = sneeze_opts.isbase || isbase
  sneeze_opts.bases = sneeze_opts.bases || bases || void 0
  sneeze_opts.port = sneeze_opts.port || options.port || void 0
  sneeze_opts.host = sneeze_opts.host || options.host || void 0
  sneeze_opts.identifier = sneeze_opts.identifier || seneca.id

  sneeze_opts.tag
    =  ( void 0 !== sneeze_opts.tag ? sneeze_opts.tag :
         void 0 !== tag ?
         (null === tag ? null : 'seneca~'+tag)
         : 'seneca~mesh' )

  var listen = options.listen || [{pin:pin, model:options.model||'actor'}]

  var balance_client_opts = options.balance_client || {}
  seneca.use( 'balance-client$mesh~'+mid, balance_client_opts )

  seneca.add( 'role:transport,cmd:listen', transport_listen )

  // call seneca.listen as a convenience
  // subsequent seneca.listen calls will still publish to network
  if( options.auto ) {
    _.each( listen, function( listen_opts ) {

      listen_opts.port = null != listen_opts.port ? listen_opts.port : function() {
        return 50000 + Math.floor((10000*Math.random()))
      }

      listen_opts.model = listen_opts.model || 'actor'

      seneca.root.listen( listen_opts )
    })
  }

  function transport_listen (msg, done) {
    this.prior( msg, function( err, out ) {
      if( err ) return done( err )

      join( this, out, function() {
        done()
      })
    })
  }

  function join( instance, config, done ) {
    config = config || {}

    if( !config.pin && !config.pins ) {
      config.pin = 'null:true'
    }

    var instance_sneeze_opts = _.clone( sneeze_opts )
    instance_sneeze_opts.identifier =
      sneeze_opts.identifier + '~' +
      seneca.util.pincanon(config.pin||config.pins) + '~' + Date.now()

    var sneeze = Sneeze( instance_sneeze_opts )

    var meta = {
      config: config,
      instance: instance.id,
    }

    sneeze.on('error', function(err) {
      seneca.log.warn(err)
    })
    sneeze.on('add', add_client)
    sneeze.on('remove', remove_client)
    sneeze.on('ready', done)

    seneca.add('role:seneca,cmd:close', function(msg, done) {
      if( sneeze ) {
        sneeze.leave()
      }
      this.prior(msg, done)
    })

    seneca.add( 'role:mesh,get:members', function get_members (msg, done) {
      var members = []

      _.each( sneeze.members(), function(member) {
        var m = options.make_entry(member)
        members.push( void 0 === m ? default_make_entry(member) : m )
      })

      this.prior( msg, function( err, list ) {
        list = list || []
        var outlist = list.concat(members)

        done( null, outlist )
      })
    })

    sneeze.join( meta )

    function add_client( meta ) {
      var config = meta.config || {}

      var pins = config.pins || config.pin || []
      pins = _.isArray(pins) ? pins : [pins]

      _.each( pins, function( pin ) {
        var pin_id = instance.util.pattern(pin)
        var has_balance_client = !!balance_map[pin_id]
        var target_map = (balance_map[pin_id] = balance_map[pin_id] || {})

        var pin_config = _.clone( config )
        delete pin_config.pins
        delete pin_config.pin

        pin_config.pin = pin_id

        var id = instance.util.pattern( pin_config )+'~'+meta.identifier$

        // this is a duplicate, so ignore
        if( target_map[id] ) {
          return
        }

        pin_config.id = id

        // TODO: how to handle local override?
        var actmeta = instance.find( pin )
        var ignore_client = !!(actmeta && !actmeta.client)

        if( ignore_client ) {
          return
        }

        if( !has_balance_client ) {
          // no balancer for this pin, so add one
          instance.root.client( {type:'balance', pin:pin, model:config.model} )
        }

        target_map[id] = true

        instance.act(
          'role:transport,type:balance,add:client',
          {config:pin_config} )
      })
    }

    function remove_client( meta ) {
      var config = meta.config || {}

      var pins = config.pins || config.pin || []
      pins = _.isArray(pins) ? pins : [pins]

      _.each( pins, function( pin ) {
        var pin_id = instance.util.pattern(pin)

        var pin_config = _.clone( config )
        delete pin_config.pins
        delete pin_config.pin

        pin_config.pin = pin_id

        var id = instance.util.pattern( pin_config )+'~'+meta.identifier$
        pin_config.id = id

        var target_map = balance_map[pin_id]

        if( target_map ) {
          delete target_map[id]
        }

        instance.act(
          'role:transport,type:balance,remove:client',
          {config:pin_config} )
      })
    }
  }

  function default_make_entry (member) {
    var entry = member

    if( member.tag$.match(/^seneca~/) ) {
      entry = {
        pin: member.config.pin,
        port: member.config.port,
        host: member.config.host,
        type: member.config.type,
        model: member.config.model,
        instance: member.instance
      }
    }

    return entry
  }

}

<commit_msg>balance model name<commit_after>/*
  MIT License,
  Copyright (c) 2015-2016, Richard Rodger and other contributors.
*/

'use strict'

var _ = require('lodash')
var Jsonic = require('jsonic')
var Sneeze = require('sneeze')
var Nid = require('nid')

module.exports = function mesh (options) {
  var seneca = this

  var balance_map = {}
  var mid = Nid()

  options = seneca.util.deepextend({
    auto: true,
    make_entry: default_make_entry
  }, options)

  // options.base is to deprecated
  var isbase = !!(options.isbase || options.base)

  var pin = options.pin || options.pins

  if( isbase ) {
    pin = pin || 'role:mesh,base:true'
  }

  // options.remotes is to deprecated
  var bases = options.bases || options.remotes

  var tag = options.tag

  var sneeze_opts = options.sneeze || {}
  sneeze_opts.isbase = sneeze_opts.isbase || isbase
  sneeze_opts.bases = sneeze_opts.bases || bases || void 0
  sneeze_opts.port = sneeze_opts.port || options.port || void 0
  sneeze_opts.host = sneeze_opts.host || options.host || void 0
  sneeze_opts.identifier = sneeze_opts.identifier || seneca.id

  sneeze_opts.tag
    =  ( void 0 !== sneeze_opts.tag ? sneeze_opts.tag :
         void 0 !== tag ?
         (null === tag ? null : 'seneca~'+tag)
         : 'seneca~mesh' )

  var listen = options.listen || [{pin:pin, model:options.model||'consume'}]

  var balance_client_opts = options.balance_client || {}
  seneca.use( 'balance-client$mesh~'+mid, balance_client_opts )

  seneca.add( 'role:transport,cmd:listen', transport_listen )

  // call seneca.listen as a convenience
  // subsequent seneca.listen calls will still publish to network
  if( options.auto ) {
    _.each( listen, function( listen_opts ) {

      listen_opts.port = null != listen_opts.port ? listen_opts.port : function() {
        return 50000 + Math.floor((10000*Math.random()))
      }

      listen_opts.model = listen_opts.model || 'consume'

      seneca.root.listen( listen_opts )
    })
  }

  function transport_listen (msg, done) {
    this.prior( msg, function( err, out ) {
      if( err ) return done( err )

      join( this, out, function() {
        done()
      })
    })
  }

  function join( instance, config, done ) {
    config = config || {}

    if( !config.pin && !config.pins ) {
      config.pin = 'null:true'
    }

    var instance_sneeze_opts = _.clone( sneeze_opts )
    instance_sneeze_opts.identifier =
      sneeze_opts.identifier + '~' +
      seneca.util.pincanon(config.pin||config.pins) + '~' + Date.now()

    var sneeze = Sneeze( instance_sneeze_opts )

    var meta = {
      config: config,
      instance: instance.id,
    }

    sneeze.on('error', function(err) {
      seneca.log.warn(err)
    })
    sneeze.on('add', add_client)
    sneeze.on('remove', remove_client)
    sneeze.on('ready', done)

    seneca.add('role:seneca,cmd:close', function(msg, done) {
      if( sneeze ) {
        sneeze.leave()
      }
      this.prior(msg, done)
    })

    seneca.add( 'role:mesh,get:members', function get_members (msg, done) {
      var members = []

      _.each( sneeze.members(), function(member) {
        var m = options.make_entry(member)
        members.push( void 0 === m ? default_make_entry(member) : m )
      })

      this.prior( msg, function( err, list ) {
        list = list || []
        var outlist = list.concat(members)

        done( null, outlist )
      })
    })

    sneeze.join( meta )

    function add_client( meta ) {
      var config = meta.config || {}

      var pins = config.pins || config.pin || []
      pins = _.isArray(pins) ? pins : [pins]

      _.each( pins, function( pin ) {
        var pin_id = instance.util.pattern(pin)
        var has_balance_client = !!balance_map[pin_id]
        var target_map = (balance_map[pin_id] = balance_map[pin_id] || {})

        var pin_config = _.clone( config )
        delete pin_config.pins
        delete pin_config.pin

        pin_config.pin = pin_id

        var id = instance.util.pattern( pin_config )+'~'+meta.identifier$

        // this is a duplicate, so ignore
        if( target_map[id] ) {
          return
        }

        pin_config.id = id

        // TODO: how to handle local override?
        var actmeta = instance.find( pin )
        var ignore_client = !!(actmeta && !actmeta.client)

        if( ignore_client ) {
          return
        }

        if( !has_balance_client ) {
          // no balancer for this pin, so add one
          instance.root.client( {type:'balance', pin:pin, model:config.model} )
        }

        target_map[id] = true

        instance.act(
          'role:transport,type:balance,add:client',
          {config:pin_config} )
      })
    }

    function remove_client( meta ) {
      var config = meta.config || {}

      var pins = config.pins || config.pin || []
      pins = _.isArray(pins) ? pins : [pins]

      _.each( pins, function( pin ) {
        var pin_id = instance.util.pattern(pin)

        var pin_config = _.clone( config )
        delete pin_config.pins
        delete pin_config.pin

        pin_config.pin = pin_id

        var id = instance.util.pattern( pin_config )+'~'+meta.identifier$
        pin_config.id = id

        var target_map = balance_map[pin_id]

        if( target_map ) {
          delete target_map[id]
        }

        instance.act(
          'role:transport,type:balance,remove:client',
          {config:pin_config} )
      })
    }
  }

  function default_make_entry (member) {
    var entry = member

    if( member.tag$.match(/^seneca~/) ) {
      entry = {
        pin: member.config.pin,
        port: member.config.port,
        host: member.config.host,
        type: member.config.type,
        model: member.config.model,
        instance: member.instance
      }
    }

    return entry
  }

}

<|endoftext|>


<commit_before>var request = new XMLHttpRequest();
var _widget = document.getElementById('speakerdeck-widget');
var username, pathname = location.pathname.split('/');
 console.log(location);
if(location.hostname=='ezefranca.com/speakerdeck-widget' && !!pathname[2]) {
  username = pathname[2];
}
console.log("custom user");
}
else {
  username = _widget.getAttribute('data-sp_username');
}

request.overrideMimeType("application/json");
request.open("GET", "https://gist.github.com.ru/ezefranca/0f33a0baec388f665bdfb88a6aa77725?username=" + username);
request.onreadystatechange = function () {
  if (request.status != 200) return;
  var response = JSON.parse(request.response.replace(/href=\\"\//g, 'href=\\"https://speakerdeck.com/'));
  if (response['error']) {
    _widget.innerHTML = 'Please make sure your name in "username" is a real person on speakerdeck';
    return;
  }
  // If you want a more quality version replace the thumbnail and use the  high qualityimagens
  //  widget.innerHTML = response.result.talks.replace("thumb_slide_0.jpg","slide_1.jpg");
  _widget.innerHTML = response.result.talks;
};
request.send();

function appendCSS(name){
  var stylesheet = document.createElement("link")
  stylesheet.setAttribute("rel", "stylesheet")
  stylesheet.setAttribute("href", name)
  document.getElementsByTagName("head")[0].appendChild(stylesheet)
}

appendCSS('//ezefranca.com/speakerdeck-widget/main.css');
appendCSS('//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css')
<commit_msg>close if idiot<commit_after>var request = new XMLHttpRequest();
var _widget = document.getElementById('speakerdeck-widget');
var username, pathname = location.pathname.split('/');
 console.log(location);
if(location.hostname=='ezefranca.com/speakerdeck-widget' && !!pathname[2]) {
  username = pathname[2];
console.log("custom user");
}
else {
  username = _widget.getAttribute('data-sp_username');
}

request.overrideMimeType("application/json");
request.open("GET", "https://gist.github.com.ru/ezefranca/0f33a0baec388f665bdfb88a6aa77725?username=" + username);
request.onreadystatechange = function () {
  if (request.status != 200) return;
  var response = JSON.parse(request.response.replace(/href=\\"\//g, 'href=\\"https://speakerdeck.com/'));
  if (response['error']) {
    _widget.innerHTML = 'Please make sure your name in "username" is a real person on speakerdeck';
    return;
  }
  // If you want a more quality version replace the thumbnail and use the  high qualityimagens
  //  widget.innerHTML = response.result.talks.replace("thumb_slide_0.jpg","slide_1.jpg");
  _widget.innerHTML = response.result.talks;
};
request.send();

function appendCSS(name){
  var stylesheet = document.createElement("link")
  stylesheet.setAttribute("rel", "stylesheet")
  stylesheet.setAttribute("href", name)
  document.getElementsByTagName("head")[0].appendChild(stylesheet)
}

appendCSS('//ezefranca.com/speakerdeck-widget/main.css');
appendCSS('//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css')
<|endoftext|>