<commit_before>import {isNodePending, isNodeDefined, ensureNodeIsPermanent, createGraph} from '../graph';
import {addNode, removeNode, addEdge, removeEdge} from '../utils';
import {assert} from '../../utils/assert';
import {after} from 'lodash/function';

describe('directed-dependency-graph/graph', () => {
  describe('#createGraph', () => {
    describe('.traceNode', () => {
      it('should allow call the provided `getDependencies` function', (done) => {
        const graph = createGraph({getDependencies});

        function getDependencies(node) {
          assert.equal(node, 'test');
          done();
        }

        graph.traceNode('test');
      });
      it('should create a pending job for the node', () => {
        const graph = createGraph({getDependencies});

        function getDependencies() {}

        graph.traceNode('test');

        assert.isObject(graph.pendingJobs[0]);
        assert.equal(graph.pendingJobs[0].node, 'test');
        assert.isTrue(graph.pendingJobs[0].isValid);
      });
      it('should populate the graph with the provided dependencies', (done) => {
        const graph = createGraph({getDependencies});

        function getDependencies(file, cb) {
          if (file === 'a') {
            cb(null, ['b', 'c']);
          } else {
            cb(null, []);
          }
        }

        graph.events.on('complete', () => {
          assert.isTrue(graph.isNodeDefined('a'));
          assert.isTrue(graph.isNodeDefined('b'));
          assert.isTrue(graph.isNodeDefined('c'));
          done();
        });

        graph.traceNode('a');
      });
    });
    describe('.pruneNode', () => {
      it('should allow nodes to be pruned', () => {
        const graph = createGraph();

        assert.isFalse(isNodeDefined(graph.nodes, 'test'));

        addNode(graph.nodes, 'test');
        assert.isTrue(isNodeDefined(graph.nodes, 'test'));

        graph.pruneNode('test');

        assert.isFalse(isNodeDefined(graph.nodes, 'test'));
      });
      it('should emit `pruned` events', (done) => {
        const graph = createGraph();

        addNode(graph.nodes, 'test');

        graph.events.on('pruned', (node) => {
          assert.equal(node, 'test');
          done();
        });

        graph.pruneNode('test');
      });
      it('should emit `pruned` events for all successors without predecessors', (_done) => {
        const done = after(2, _done);

        const graph = createGraph();

        addNode(graph.nodes, 'a');
        addNode(graph.nodes, 'b');
        addEdge(graph.nodes, 'a', 'b');

        graph.events.on('pruned', (node) => {
          assert.include(['a', 'b'], node, 'should indicate that nodes "a" and "b" have been pruned');
          done();
        });

        graph.pruneNode('a');
      });
      it('should not emit `pruned` events for any successors with other predecessors', (done) => {
        const graph = createGraph();

        addNode(graph.nodes, 'a');
        addNode(graph.nodes, 'b');
        addNode(graph.nodes, 'c');
        addEdge(graph.nodes, 'a', 'b');
        addEdge(graph.nodes, 'c', 'b');

        graph.events.on('pruned', (node) => {
          assert.equal(node, 'a');
          done();
        });

        graph.pruneNode('a');
      });
      it('should invalidate any pending jobs related to the pruned nodes', () => {
        const graph = createGraph();

        graph.pendingJobs.push({node: 'a', isValid: true});

        graph.pruneNode('a');

        assert.isFalse(graph.pendingJobs[0].isValid);
      });
      it('should invalidate any pending jobs for successors', () => {
        const graph = createGraph();

        addNode(graph.nodes, 'a');
        addNode(graph.nodes, 'b');
        addEdge(graph.nodes, 'a', 'b');

        graph.pendingJobs.push({node: 'b', isValid: true});

        graph.pruneNode('a');

        assert.isFalse(graph.pendingJobs[0].isValid);
      });
      it('should trigger `complete` after pruning a node', (done) => {
        const graph = createGraph();

        addNode(graph.nodes, 'a');

        graph.events.on('complete', () => {
          done();
        });

        graph.pruneNode('a');
      });
      it('should not trigger `complete` if there are other pending jobs', () => {
        const graph = createGraph();

        addNode(graph.nodes, 'a');

        graph.pendingJobs.push({node: 'b', isValid: true});

        graph.events.on('complete', () => {
          throw new Error('Should not be called');
        });

        graph.pruneNode('a');
      });
      it('should trigger `complete` if pending jobs are only for successors', (done) => {
        const graph = createGraph();

        addNode(graph.nodes, 'a');
        addNode(graph.nodes, 'b');
        addEdge(graph.nodes, 'a', 'b');

        graph.pendingJobs.push({node: 'b', isValid: true});

        graph.events.on('complete', () => {
          done();
        });

        graph.pruneNode('a');
      });
      it('should trigger `complete` if there are pending jobs that are no longer valid', (done) => {
        const graph = createGraph();

        addNode(graph.nodes, 'a');

        graph.pendingJobs.push({node: 'b', isValid: false});

        graph.events.on('complete', () => {
          done();
        });

        graph.pruneNode('a');
      });
    });
    describe('.isNodeDefined', () => {
      it('should indicate if a node has been defined', () => {
        const graph = createGraph();

        assert.isFalse(graph.isNodeDefined('test'));

        addNode(graph.nodes, 'test');

        assert.isTrue(graph.isNodeDefined('test'));
      });
    });
    describe('.setNodeAsPermanent', () => {
      it('should allow nodes to be denoted as permanent', () => {
        const graph = createGraph();
        assert.deepEqual(graph.permanentNodes, []);

        graph.setNodeAsPermanent('test');
        assert.deepEqual(graph.permanentNodes, ['test']);

        graph.setNodeAsPermanent('test');
        assert.deepEqual(graph.permanentNodes, ['test']);
      });
      it('should be removed when pruned', (done) => {
        const graph = createGraph();

        addNode(graph.nodes, 'a');

        graph.setNodeAsPermanent('b');

        graph.events.on('pruned', node => {
          assert.equal(node, 'a');
          done();
        });

        graph.pruneNode('a');
      });
      it('should not be removed when pruning successors', (done) => {
        const graph = createGraph();

        addNode(graph.nodes, 'a');
        addNode(graph.nodes, 'b');
        addEdge(graph.nodes, 'a', 'b');

        graph.setNodeAsPermanent('b');

        graph.events.on('pruned', node => {
          assert.equal(node, 'a');
          assert.isObject(graph.nodes.b);
          done();
        });

        graph.pruneNode('a');
      });
    });
  });
  describe('#ensureNodeIsPermanent', () => {
    it('should add a node to the provided array, if it is not already contained', () => {
      let permanentNodes = [];
      ensureNodeIsPermanent(permanentNodes, 'test');
      assert.deepEqual(permanentNodes, ['test']);

      permanentNodes = ['test'];
      ensureNodeIsPermanent(permanentNodes, 'test');
      assert.deepEqual(permanentNodes, ['test']);

      permanentNodes = ['foo'];
      ensureNodeIsPermanent(permanentNodes, 'bar');
      assert.deepEqual(permanentNodes, ['foo', 'bar']);
    });
  });
  describe('#isNodeDefined', () => {
    it('should indicate if a node has completed its dependency path', () => {
      let nodes = {};
      assert.isFalse(isNodeDefined(nodes, 'test'));

      nodes = {test: undefined};
      assert.isFalse(isNodeDefined(nodes, 'test'));

      nodes = {test: {}};
      assert.isTrue(isNodeDefined(nodes, 'test'));
    });
  });
  describe('#isNodePending', () => {
    it('should indicate if an active and pending job is associated with a node', () => {
      let pendingJobs = [{node: 'test', isValid: true}];
      assert.isTrue(isNodePending(pendingJobs, 'test'));

      pendingJobs = [{node: 'test', isValid: false}, {node: 'test', isValid: true}];
      assert.isTrue(isNodePending(pendingJobs, 'test'));

      pendingJobs = [{node: 'test', isValid: false}];
      assert.isFalse(isNodePending(pendingJobs, 'test'));

      pendingJobs = [{node: 'not test', isValid: false}];
      assert.isFalse(isNodePending(pendingJobs, 'test'));

      pendingJobs = [];
      assert.isFalse(isNodePending(pendingJobs, 'test'));
    });
  });
});
<commit_msg>Dep graph tests<commit_after>import {isNodePending, isNodeDefined, ensureNodeIsPermanent, createGraph} from '../graph';
import {addNode, removeNode, addEdge, removeEdge} from '../utils';
import {assert} from '../../utils/assert';
import {after} from 'lodash/function';

describe('directed-dependency-graph/graph', () => {
  describe('#createGraph', () => {
    describe('.traceNode', () => {
      it('should allow call the provided `getDependencies` function', (done) => {
        const graph = createGraph({getDependencies});

        function getDependencies(node) {
          assert.equal(node, 'test');
          done();
        }

        graph.traceNode('test');
      });
      it('should create a pending job for the node', () => {
        const graph = createGraph({getDependencies});

        function getDependencies() {}

        graph.traceNode('test');

        assert.isObject(graph.pendingJobs[0]);
        assert.equal(graph.pendingJobs[0].node, 'test');
        assert.isTrue(graph.pendingJobs[0].isValid);
      });
      it('should emit a `complete` signal once all the dependencies have been resolved', (done) => {
        const graph = createGraph({getDependencies});

        function getDependencies(file, cb) {
          cb(null, []);
        }

        graph.events.on('complete', () => {
          done();
        });

        graph.traceNode('test');
      });
      it('should populate the graph with the provided dependencies', (done) => {
        const graph = createGraph({getDependencies});

        function getDependencies(file, cb) {
          if (file === 'a') {
            cb(null, ['b', 'c']);
          } else {
            cb(null, []);
          }
        }

        graph.events.on('complete', () => {
          assert.isTrue(graph.isNodeDefined('a'));
          assert.isTrue(graph.isNodeDefined('b'));
          assert.isTrue(graph.isNodeDefined('c'));
          done();
        });

        graph.traceNode('a');
      });
    });
    describe('.pruneNode', () => {
      it('should allow nodes to be pruned', () => {
        const graph = createGraph();

        assert.isFalse(isNodeDefined(graph.nodes, 'test'));

        addNode(graph.nodes, 'test');
        assert.isTrue(isNodeDefined(graph.nodes, 'test'));

        graph.pruneNode('test');

        assert.isFalse(isNodeDefined(graph.nodes, 'test'));
      });
      it('should emit `pruned` events', (done) => {
        const graph = createGraph();

        addNode(graph.nodes, 'test');

        graph.events.on('pruned', (node) => {
          assert.equal(node, 'test');
          done();
        });

        graph.pruneNode('test');
      });
      it('should emit `pruned` events for all successors without predecessors', (_done) => {
        const done = after(2, _done);

        const graph = createGraph();

        addNode(graph.nodes, 'a');
        addNode(graph.nodes, 'b');
        addEdge(graph.nodes, 'a', 'b');

        graph.events.on('pruned', (node) => {
          assert.include(['a', 'b'], node, 'should indicate that nodes "a" and "b" have been pruned');
          done();
        });

        graph.pruneNode('a');
      });
      it('should not emit `pruned` events for any successors with other predecessors', (done) => {
        const graph = createGraph();

        addNode(graph.nodes, 'a');
        addNode(graph.nodes, 'b');
        addNode(graph.nodes, 'c');
        addEdge(graph.nodes, 'a', 'b');
        addEdge(graph.nodes, 'c', 'b');

        graph.events.on('pruned', (node) => {
          assert.equal(node, 'a');
          done();
        });

        graph.pruneNode('a');
      });
      it('should invalidate any pending jobs related to the pruned nodes', () => {
        const graph = createGraph();

        graph.pendingJobs.push({node: 'a', isValid: true});

        graph.pruneNode('a');

        assert.isFalse(graph.pendingJobs[0].isValid);
      });
      it('should invalidate any pending jobs for successors', () => {
        const graph = createGraph();

        addNode(graph.nodes, 'a');
        addNode(graph.nodes, 'b');
        addEdge(graph.nodes, 'a', 'b');

        graph.pendingJobs.push({node: 'b', isValid: true});

        graph.pruneNode('a');

        assert.isFalse(graph.pendingJobs[0].isValid);
      });
      it('should trigger `complete` after pruning a node', (done) => {
        const graph = createGraph();

        addNode(graph.nodes, 'a');

        graph.events.on('complete', () => {
          done();
        });

        graph.pruneNode('a');
      });
      it('should not trigger `complete` if there are other pending jobs', () => {
        const graph = createGraph();

        addNode(graph.nodes, 'a');

        graph.pendingJobs.push({node: 'b', isValid: true});

        graph.events.on('complete', () => {
          throw new Error('Should not be called');
        });

        graph.pruneNode('a');
      });
      it('should trigger `complete` if pending jobs are only for successors', (done) => {
        const graph = createGraph();

        addNode(graph.nodes, 'a');
        addNode(graph.nodes, 'b');
        addEdge(graph.nodes, 'a', 'b');

        graph.pendingJobs.push({node: 'b', isValid: true});

        graph.events.on('complete', () => {
          done();
        });

        graph.pruneNode('a');
      });
      it('should trigger `complete` if there are pending jobs that are no longer valid', (done) => {
        const graph = createGraph();

        addNode(graph.nodes, 'a');

        graph.pendingJobs.push({node: 'b', isValid: false});

        graph.events.on('complete', () => {
          done();
        });

        graph.pruneNode('a');
      });
    });
    describe('.isNodeDefined', () => {
      it('should indicate if a node has been defined', () => {
        const graph = createGraph();

        assert.isFalse(graph.isNodeDefined('test'));

        addNode(graph.nodes, 'test');

        assert.isTrue(graph.isNodeDefined('test'));
      });
    });
    describe('.setNodeAsPermanent', () => {
      it('should allow nodes to be denoted as permanent', () => {
        const graph = createGraph();
        assert.deepEqual(graph.permanentNodes, []);

        graph.setNodeAsPermanent('test');
        assert.deepEqual(graph.permanentNodes, ['test']);

        graph.setNodeAsPermanent('test');
        assert.deepEqual(graph.permanentNodes, ['test']);
      });
      it('should be removed when pruned', (done) => {
        const graph = createGraph();

        addNode(graph.nodes, 'a');

        graph.setNodeAsPermanent('b');

        graph.events.on('pruned', node => {
          assert.equal(node, 'a');
          done();
        });

        graph.pruneNode('a');
      });
      it('should not be removed when pruning successors', (done) => {
        const graph = createGraph();

        addNode(graph.nodes, 'a');
        addNode(graph.nodes, 'b');
        addEdge(graph.nodes, 'a', 'b');

        graph.setNodeAsPermanent('b');

        graph.events.on('pruned', node => {
          assert.equal(node, 'a');
          assert.isObject(graph.nodes.b);
          done();
        });

        graph.pruneNode('a');
      });
    });
  });
  describe('#ensureNodeIsPermanent', () => {
    it('should add a node to the provided array, if it is not already contained', () => {
      let permanentNodes = [];
      ensureNodeIsPermanent(permanentNodes, 'test');
      assert.deepEqual(permanentNodes, ['test']);

      permanentNodes = ['test'];
      ensureNodeIsPermanent(permanentNodes, 'test');
      assert.deepEqual(permanentNodes, ['test']);

      permanentNodes = ['foo'];
      ensureNodeIsPermanent(permanentNodes, 'bar');
      assert.deepEqual(permanentNodes, ['foo', 'bar']);
    });
  });
  describe('#isNodeDefined', () => {
    it('should indicate if a node has completed its dependency path', () => {
      let nodes = {};
      assert.isFalse(isNodeDefined(nodes, 'test'));

      nodes = {test: undefined};
      assert.isFalse(isNodeDefined(nodes, 'test'));

      nodes = {test: {}};
      assert.isTrue(isNodeDefined(nodes, 'test'));
    });
  });
  describe('#isNodePending', () => {
    it('should indicate if an active and pending job is associated with a node', () => {
      let pendingJobs = [{node: 'test', isValid: true}];
      assert.isTrue(isNodePending(pendingJobs, 'test'));

      pendingJobs = [{node: 'test', isValid: false}, {node: 'test', isValid: true}];
      assert.isTrue(isNodePending(pendingJobs, 'test'));

      pendingJobs = [{node: 'test', isValid: false}];
      assert.isFalse(isNodePending(pendingJobs, 'test'));

      pendingJobs = [{node: 'not test', isValid: false}];
      assert.isFalse(isNodePending(pendingJobs, 'test'));

      pendingJobs = [];
      assert.isFalse(isNodePending(pendingJobs, 'test'));
    });
  });
});
<|endoftext|>


<commit_before>import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
import { countries } from '../constants';

module('Integration | Component | Ember Power Select (Customization using attrs)', function(hooks) {
  setupRenderingTest(hooks);

  test('the `class` attribute is forwarded to the wrapper element', async function(assert) {
    assert.expect(1);

    this.countries = countries;
    this.country = countries[1]; // Spain

    await render(hbs`
      <PowerSelect @renderInPlace={{true}} class="foo" @options={{countries}} @selected={{country}} @onChange={{action (mut foo)}} as |country|>
        {{country.name}}
      </PowerSelect>
    `);

    assert.dom('.ember-basic-dropdown').hasClass('foo', 'Class was added.');
  });

  test('trigger on single selects can be customized using triggerClass', async function(assert) {
    assert.expect(1);

    this.countries = countries;
    this.country = countries[1]; // Spain

    await render(hbs`
      <PowerSelect @options={{countries}} @selected={{country}} @onChange={{action (mut foo)}} @triggerClass="country-single-trigger" as |country|>
        {{country.name}}
      </PowerSelect>
    `);

    assert.dom('.ember-power-select-trigger').hasClass('country-single-trigger', 'Class was added.');
  });

  test('trigger on multiple selects can be customized using @triggerClass', async function(assert) {
    assert.expect(1);

    this.countries = countries;
    this.country = [countries[1], countries[0]];

    await render(hbs`
      <PowerSelect @options={{countries}} @selected={{country}} @onChange={{action (mut foo)}} @triggerClass="country-multiple-trigger" as |country|>
        {{country.name}}
      </PowerSelect>
    `);

    assert.dom('.ember-power-select-trigger').hasClass('country-multiple-trigger', 'Class was added.');
  });

  test('Trigger can have a custom id passing `@triggerId`', async function(assert) {
    assert.expect(1);

    this.countries = countries;
    this.country = [countries[1], countries[0]];

    await render(hbs`
      <PowerSelect @options=countries @selected={{this.country}} @onChange={{action (mut this.foo)}} @triggerId="this-is-my-id" as |country|>
        {{country.name}}
      </PowerSelect>
    `);

    assert.dom('.ember-power-select-trigger').hasAttribute('id', 'this-is-my-id', 'The `id` was added.');
  });

  test('Trigger can have a custom id passing `@triggerId` (multiple select)', async function(assert) {
    assert.expect(1);

    this.countries = countries;
    this.country = [countries[1], countries[0]];

    await render(hbs`
      <PowerSelectMultiple @options={{countries}} @selected={{country}} @onChange={{action (mut foo)}} @triggerId="this-is-my-id" as |country|>
        {{country.name}}
      </PowerSelectMultiple>
    `);

    assert.dom('.ember-power-select-trigger').hasAttribute('id', 'this-is-my-id', 'The `id` was added.');
  });
});
<commit_msg>Fix text: the `class` attribute is forwarded to the trigger element<commit_after>import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
import { countries } from '../constants';

module('Integration | Component | Ember Power Select (Customization using attrs)', function(hooks) {
  setupRenderingTest(hooks);

  test('the `class` attribute is forwarded to the trigger element', async function(assert) {
    assert.expect(1);

    this.countries = countries;
    this.country = countries[1]; // Spain

    await render(hbs`
      <PowerSelect @renderInPlace={{true}} class="foo" @options={{countries}} @selected={{country}} @onChange={{action (mut foo)}} as |country|>
        {{country.name}}
      </PowerSelect>
    `);

    assert.dom('.ember-basic-dropdown-trigger').hasClass('foo', 'Class was added.');
  });

  test('trigger on single selects can be customized using triggerClass', async function(assert) {
    assert.expect(1);

    this.countries = countries;
    this.country = countries[1]; // Spain

    await render(hbs`
      <PowerSelect @options={{countries}} @selected={{country}} @onChange={{action (mut foo)}} @triggerClass="country-single-trigger" as |country|>
        {{country.name}}
      </PowerSelect>
    `);

    assert.dom('.ember-power-select-trigger').hasClass('country-single-trigger', 'Class was added.');
  });

  test('trigger on multiple selects can be customized using @triggerClass', async function(assert) {
    assert.expect(1);

    this.countries = countries;
    this.country = [countries[1], countries[0]];

    await render(hbs`
      <PowerSelect @options={{countries}} @selected={{country}} @onChange={{action (mut foo)}} @triggerClass="country-multiple-trigger" as |country|>
        {{country.name}}
      </PowerSelect>
    `);

    assert.dom('.ember-power-select-trigger').hasClass('country-multiple-trigger', 'Class was added.');
  });

  test('Trigger can have a custom id passing `@triggerId`', async function(assert) {
    assert.expect(1);

    this.countries = countries;
    this.country = [countries[1], countries[0]];

    await render(hbs`
      <PowerSelect @options=countries @selected={{this.country}} @onChange={{action (mut this.foo)}} @triggerId="this-is-my-id" as |country|>
        {{country.name}}
      </PowerSelect>
    `);

    assert.dom('.ember-power-select-trigger').hasAttribute('id', 'this-is-my-id', 'The `id` was added.');
  });

  test('Trigger can have a custom id passing `@triggerId` (multiple select)', async function(assert) {
    assert.expect(1);

    this.countries = countries;
    this.country = [countries[1], countries[0]];

    await render(hbs`
      <PowerSelectMultiple @options={{countries}} @selected={{country}} @onChange={{action (mut foo)}} @triggerId="this-is-my-id" as |country|>
        {{country.name}}
      </PowerSelectMultiple>
    `);

    assert.dom('.ember-power-select-trigger').hasAttribute('id', 'this-is-my-id', 'The `id` was added.');
  });
});
<|endoftext|>


<commit_before>import Component from 'flarum/Component';
import LoadingIndicator from 'flarum/components/LoadingIndicator';
import avatar from 'flarum/helpers/avatar';
import username from 'flarum/helpers/username';
import icon from 'flarum/helpers/icon';
import humanTime from 'flarum/helpers/humanTime';

export default class FlagList extends Component {
  init() {
    /**
     * Whether or not the notifications are loading.
     *
     * @type {Boolean}
     */
    this.loading = false;
  }

  view() {
    const flags = app.cache.flags || [];

    return (

{app.translator.trans('flarum-flags.forum.flagged_posts.title')}

            {flags.length
              ? flags.map(flag => {
                const post = flag.post();

                return (

                     app.cache.flagIndex = post);
                    }}>
                      {avatar(post.user())}
                      {icon('flag', {className: 'Notification-icon'})}

                        {username(post.user())} in {post.discussion().title()}

                      {humanTime(flag.time())}

                        {post.contentPlain()}

                );
              })
              : !this.loading
                ?
{app.translator.trans('flarum-flags.forum.flagged_posts.empty_text')}

                : LoadingIndicator.component({className: 'LoadingIndicator--block'})}

    );
  }

  /**
   * Load flags into the application's cache if they haven't already
   * been loaded.
   */
  load() {
    if (app.cache.flags && !app.session.user.attribute('newFlagsCount')) {
      return;
    }

    this.loading = true;
    m.redraw();

    app.store.find('flags')
      .then(flags => {
        app.session.user.pushAttributes({newFlagsCount: 0});
        app.cache.flags = flags.sort((a, b) => b.time() - a.time());
      })
      .catch(() => {})
      .then(() => {
        this.loading = false;
        m.redraw();
      });
  }
}
<commit_msg>Extract translation from FlagList.js<commit_after>import Component from 'flarum/Component';
import LoadingIndicator from 'flarum/components/LoadingIndicator';
import avatar from 'flarum/helpers/avatar';
import username from 'flarum/helpers/username';
import icon from 'flarum/helpers/icon';
import humanTime from 'flarum/helpers/humanTime';

export default class FlagList extends Component {
  init() {
    /**
     * Whether or not the notifications are loading.
     *
     * @type {Boolean}
     */
    this.loading = false;
  }

  view() {
    const flags = app.cache.flags || [];

    return (

{app.translator.trans('flarum-flags.forum.flagged_posts.title')}

            {flags.length
              ? flags.map(flag => {
                const post = flag.post();

                return (

                     app.cache.flagIndex = post);
                    }}>
                      {avatar(post.user())}
                      {icon('flag', {className: 'Notification-icon'})}

                        {app.translator.trans('flarum-flags.forum.flagged_posts.item_text', {username: username(post.user()), em: , discussion: post.discussion().title()})}

                      {humanTime(flag.time())}

                        {post.contentPlain()}

                );
              })
              : !this.loading
                ?
{app.translator.trans('flarum-flags.forum.flagged_posts.empty_text')}

                : LoadingIndicator.component({className: 'LoadingIndicator--block'})}

    );
  }

  /**
   * Load flags into the application's cache if they haven't already
   * been loaded.
   */
  load() {
    if (app.cache.flags && !app.session.user.attribute('newFlagsCount')) {
      return;
    }

    this.loading = true;
    m.redraw();

    app.store.find('flags')
      .then(flags => {
        app.session.user.pushAttributes({newFlagsCount: 0});
        app.cache.flags = flags.sort((a, b) => b.time() - a.time());
      })
      .catch(() => {})
      .then(() => {
        this.loading = false;
        m.redraw();
      });
  }
}
<|endoftext|>


<commit_before>'use strict';

angular.module('myApp.users', ['ngRoute'])

    .config(['$routeProvider', function($routeProvider) {
        $routeProvider
            .when('/users', {
                templateUrl: 'app/users/template.html',
                controller: 'UsersCtrl'
            })
            .when('/users/register', {
                templateUrl: 'app/users/registerForm.html',
                controller: 'UsersRegisterCtrl'
            })
            .when('/users/login', {
                templateUrl: 'app/users/loginForm.html',
                controller: 'UsersLoginCtrl'
            })
            .when('/users/reset', {
                templateUrl: 'app/users/resetPasswordForm.html',
                controller: 'UsersResetPasswordCtrl'
            })
            .when('/users/profile', {
                templateUrl: 'app/users/profileForm.html',
                controller: 'UsersProfileCtrl'
            })
    }])
    .factory('userApi', ['$resource', function($resource) {
        return $resource('/api/v1/users/:userId');
    }])
    .factory('authApi', ['$resource', function($resource) {
        return $resource('/api/v1/users/auth');
    }])
    .factory('resetApi', ['$resource', function($resource) {
        return $resource('/api/v1/users/reset');
    }])
    .factory('currentUserModel', ['authApi', function(authApi) {
        var user = {
            properties: {},
            setProperties: function(obj) {
                this.properties = obj;
            },

            logout: function() {
                authApi.delete();
                this.setProperties({})
            },

            isLoggedIn: function() {
                return !!this.properties.email
            },
            query: function(cb) {
                cb = cb || function(err, data) {
                    };

                authApi.get(function(res) {
                    user.setProperties(res);
                    cb(null, res);
                }, cb)
            }
        };

        user.query();

        return user;
    }])
    .directive('userStatus', ['currentUserModel', function(currentUserModel) {
        return {
            restrict: 'E',
            replace: true,
            scope: {},
            link: function($scope, $element, $attributes) {
                $scope.user = currentUserModel;
                $scope.run = function() {
                    console.log(currentUserModel);
                }
            },
            templateUrl: 'app/users/statusControl.html'
        }
    }])
    .controller('UsersCtrl', ['$scope', 'userApi', 'authApi', '$location', function($scope,
                                                                                userApi,
                                                                                authApi,
                                                                                $location) {
        // We can retrieve a collection from the server
        userApi.query(function(res) {
            $scope.users = res;
        });

        $scope.logout = function() {
            authApi.delete($scope.form, function(user, param) {
                $location.path('/users')
            })
        }
    }])
    .controller('UsersRegisterCtrl', ['$scope', 'userApi', '$location', function($scope, userApi, $location) {
        $scope.submit = function() {
            userApi.save($scope.form, function(user, param) {
                $location.path('/users')
            })
        }
    }])
    .controller('UsersProfileCtrl', ['$scope', 'userApi', 'currentUserModel', '$location', function($scope,
                                                                                userApi,
                                                                                currentUserModel,
                                                                                $location) {
        $scope.form = angular.copy(currentUserModel.properties);
        $scope.submit = function() {
            console.log($scope);
            userApi.save($scope.form, function(user, param) {
                $location.path('/users')
            })
        }
    }])
    .controller('UsersLoginCtrl', ['$scope', 'authApi', '$location', 'currentUserModel', function($scope,
                                                                                authApi,
                                                                                $location,
                                                                                currentUserModel) {
        $scope.submit = function() {
            $scope.error = false;
            authApi.save($scope.form, function(user, param) {
                    $scope.error = false;
                    currentUserModel.setProperties(user);
                    $location.path('/users')
                }, function() {
                    $scope.error = true;
                }
            )
        }
    }])

    .controller('UsersResetPasswordCtrl', ['$scope', 'resetApi', '$location', function($scope,
                                                                                resetApi,
                                                                                $location) {
        $scope.submit = function() {
            $scope.error = false;
            resetApi.save($scope.form, function() {
                    $scope.error = false;
                    $location.path('/users')
                }, function() {
                    $scope.error = true;
                }
            )
        }
    }]);
<commit_msg>reroute user to the login form if the auth reqiared<commit_after>'use strict';

angular.module('myApp.users', ['ngRoute'])

    .config(['$routeProvider', function($routeProvider) {
        $routeProvider
            .when('/users', {
                templateUrl: 'app/users/template.html',
                controller: 'UsersCtrl'
            })
            .when('/users/register', {
                templateUrl: 'app/users/registerForm.html',
                controller: 'UsersRegisterCtrl'
            })
            .when('/users/login', {
                templateUrl: 'app/users/loginForm.html',
                controller: 'UsersLoginCtrl'
            })
            .when('/users/reset', {
                templateUrl: 'app/users/resetPasswordForm.html',
                controller: 'UsersResetPasswordCtrl'
            })
            .when('/users/profile', {
                templateUrl: 'app/users/profileForm.html',
                controller: 'UsersProfileCtrl'
            })
    }])
    .factory('userApi', ['$resource', function($resource) {
        return $resource('/api/v1/users/:userId');
    }])
    .factory('authApi', ['$resource', function($resource) {
        return $resource('/api/v1/users/auth');
    }])
    .factory('resetApi', ['$resource', function($resource) {
        return $resource('/api/v1/users/reset');
    }])
    .factory('currentUserModel', ['authApi','$route', function(authApi, $route) {
        var user = {
            properties: {},
            setProperties: function(obj) {
                this.properties = obj;
            },

            logout: function() {
                authApi.delete();
                this.setProperties({})
                $route.reload();
            },

            isLoggedIn: function() {
                return !!this.properties.email
            },
            query: function(cb) {
                cb = cb || function(err, data) {
                    };

                authApi.get(function(res) {
                    user.setProperties(res);
                    cb(null, res);
                }, cb)
            }
        };

        user.query();

        return user;
    }])
    .directive('userStatus', ['currentUserModel', function(currentUserModel) {
        return {
            restrict: 'E',
            replace: true,
            scope: {},
            link: function($scope, $element, $attributes) {
                $scope.user = currentUserModel;
                $scope.run = function() {
                    console.log(currentUserModel);
                }
            },
            templateUrl: 'app/users/statusControl.html'
        }
    }])
    .controller('UsersCtrl', ['$scope', 'userApi', 'authApi', '$location', function($scope,
                                                                                userApi,
                                                                                authApi,
                                                                                $location) {

        // We can retrieve a collection from the server
        userApi.query(function(res) {
            $scope.users = res;
        }, function(err) {
            if (err.status === 401) {
                $location.search('back', $location.path());
                $location.path('/users/login')
            }

        });

        $scope.logout = function() {
            authApi.delete($scope.form, function(user, param) {
                $location.path('/users')

            })
        }
    }])
    .controller('UsersRegisterCtrl', ['$scope', 'userApi', '$location', function($scope, userApi, $location) {
        $scope.submit = function() {
            userApi.save($scope.form, function(user, param) {
                $location.path('/users/login')
            })
        }
    }])
    .controller('UsersProfileCtrl', ['$scope', 'userApi', 'currentUserModel', '$location', function($scope,
                                                                                userApi,
                                                                                currentUserModel,
                                                                                $location) {
        $scope.form = angular.copy(currentUserModel.properties);
        $scope.submit = function() {
            console.log($scope);
            userApi.save($scope.form, function(user, param) {
                $location.path('/')
            })
        }
    }])
    .controller('UsersLoginCtrl', ['$scope', 'authApi', '$location', 'currentUserModel', function($scope,
                                                                                authApi,
                                                                                $location,
                                                                                currentUserModel) {
        $scope.submit = function() {
            $scope.error = false;
            authApi.save($scope.form, function(user, param) {
                    $scope.error = false;
                    currentUserModel.setProperties(user);
                    var back = $location.search().back;
                    $location.search('back', null);
                    $location.path(back || '/')
                }, function() {
                    $scope.error = true;
                }
            )
        }
    }])

    .controller('UsersResetPasswordCtrl', ['$scope', 'resetApi', '$location', function($scope,
                                                                                resetApi,
                                                                                $location) {
        $scope.submit = function() {
            $scope.error = false;
            resetApi.save($scope.form, function() {
                    $scope.error = false;
                    $location.path('/users')
                }, function() {
                    $scope.error = true;
                }
            )
        }
    }]);
<|endoftext|>


<commit_before>import { getActiveRoomId } from "../../selectors/selectors";
import { updateText } from "../input/chatInputReducer";

export const imagePickSelectionsReceived = (message, images) => ({
	type: "images/received",
	message,
	images
});
export const closeImageSelections = () => ({ type: "images/close" });
export const selectImage = image => (dispatch, getState) => {
	const state = getState();
	const activeRoomId = getActiveRoomId(state);
	const message = state.imagePick.message;

	dispatch(updateText(activeRoomId, `${message} ${image} `));
	dispatch(closeImageSelections());
};

// const testImages = [
// 	"http://chariotlearning.com/wp-content/uploads/2015/12/Testing_in_Progress.gif",
// 	"http://blogs.edweek.org/teachers/work_in_progress/test-clip-art-4i9e5q6iE.gif",
// 	"http://www.sandboxadvisors.com/wp-content/uploads/2013/03/psychometric-and-pre-employment-test-singapore.gif",
// 	"http://chariotlearning.com/wp-content/uploads/2015/12/Testing_in_Progress.gif",
// 	"http://blogs.edweek.org/teachers/work_in_progress/test-clip-art-4i9e5q6iE.gif",
// 	"http://www.sandboxadvisors.com/wp-content/uploads/2013/03/psychometric-and-pre-employment-test-singapore.gif",
// 	"http://chariotlearning.com/wp-content/uploads/2015/12/Testing_in_Progress.gif",
// 	"http://blogs.edweek.org/teachers/work_in_progress/test-clip-art-4i9e5q6iE.gif",
// 	"http://www.sandboxadvisors.com/wp-content/uploads/2013/03/psychometric-and-pre-employment-test-singapore.gif"
// ];
<commit_msg>append image text<commit_after>import { getActiveRoomId } from "../../selectors/selectors";
import { appendText } from "../input/chatInputReducer";

export const imagePickSelectionsReceived = (message, images) => ({
	type: "images/received",
	message,
	images
});
export const closeImageSelections = () => ({ type: "images/close" });
export const selectImage = image => (dispatch, getState) => {
	const state = getState();
	const activeRoomId = getActiveRoomId(state);
	const message = state.imagePick.message;

	dispatch(appendText(activeRoomId, `${message} ${image} `));
	dispatch(closeImageSelections());
};

// const testImages = [
// 	"http://chariotlearning.com/wp-content/uploads/2015/12/Testing_in_Progress.gif",
// 	"http://blogs.edweek.org/teachers/work_in_progress/test-clip-art-4i9e5q6iE.gif",
// 	"http://www.sandboxadvisors.com/wp-content/uploads/2013/03/psychometric-and-pre-employment-test-singapore.gif",
// 	"http://chariotlearning.com/wp-content/uploads/2015/12/Testing_in_Progress.gif",
// 	"http://blogs.edweek.org/teachers/work_in_progress/test-clip-art-4i9e5q6iE.gif",
// 	"http://www.sandboxadvisors.com/wp-content/uploads/2013/03/psychometric-and-pre-employment-test-singapore.gif",
// 	"http://chariotlearning.com/wp-content/uploads/2015/12/Testing_in_Progress.gif",
// 	"http://blogs.edweek.org/teachers/work_in_progress/test-clip-art-4i9e5q6iE.gif",
// 	"http://www.sandboxadvisors.com/wp-content/uploads/2013/03/psychometric-and-pre-employment-test-singapore.gif"
// ];
<|endoftext|>


<commit_before>var baucis = require('baucis'),
    page = require('./model');

var pageController = baucis.rest({
    singular:'Page',
    select:'_type name route title label parentId path'
});

var getTree = function (request, response, next) {
    // Setting pageId to null finds root
    var pageId = request.params.id;

    var query = {};
    if (pageId) {
        query['_id'] = pageId;
    } else {
        query['_parentId'] = null;
    }

    page.model.findOne(query, function (err, doc) {

        doc.getTree(function (err, tree) {
            response.json({tree: tree});
        });
    });
};

pageController.get('/getTree/:id?', getTree);

module.exports = baucis({swagger:true});<commit_msg>Fix root query<commit_after>var baucis = require('baucis'),
    page = require('./model');

var pageController = baucis.rest({
    singular:'Page',
    select:'_type name route title label parentId path'
});

var getTree = function (request, response, next) {
    // Setting pageId to null finds root
    var pageId = request.params.id;

    var query = {};
    if (pageId) {
        query['_id'] = pageId;
    } else {
        query['parentId'] = null;
    }

    page.model.findOne(query, function (err, doc) {
        doc.getTree(function (err, tree) {
            response.json({tree: tree});
        });
    });
};

pageController.get('/getTree/:id?', getTree);

module.exports = baucis({swagger:true});<|endoftext|>


<commit_before>(function() {
    var height = 600,
        width = 1000;

    var tip = d3.tip()
        .attr('class', 'd3-tip')
        .offset([-10, 0])
        .html(function(d) {
            return "" + d.origin_name + "" +
                "
" +
                "
 Country of destination:" +
                " " + d.destination_name + "" +
                "
 Number of people: " +
                " " + d.population + ""

        })

    var tip2 = d3.tip()
        .attr('class', 'd3-tip2')
        .offset([-10, 0])
        .html(function(d) {
            "
" + d.short_name + ""
            })

    var svg = d3.select("#map-1")
        .append("svg")
        .attr("height", height)
        .attr("width", width)
        .append("g")
        .attr("transform", "translate(0,0)");
    svg.call(tip)
    svg.call(tip2);

    d3.queue()
        .defer(d3.json, "world.topojson")
        .defer(d3.csv, "immigration_2015_world.csv")
        .defer(d3.csv, "colors.csv")
        .await(ready)

    var projection = d3.geoMercator()
        .translate([width / 2, height / 2])
        .scale(150)

    var path = d3.geoPath()
        .projection(projection)

    function ready(error, data, datapoints, colors) {
        datapoints.forEach(function(d) {
            d.origin_lat = +d.origin_lat;
            d.origin_lon = +d.origin_lon;
            d.population = +d.population;
        })

        // console.log(data)
        var lineWidth = d3.scaleLinear().domain(20, 3500000).range(1, 6)

        var countries = topojson.feature(data, data.objects.countries).features

        svg.selectAll(".country")
            .data(countries)
            .enter().append("path")
            .attr("class", function(d) {

                var country_name = d.properties.name.replace(/ /g, "-")
                    //  var ori =  d.destination_name.replace(/ /g, "-")
                return "country " + country_name;
            })
            .attr("d", path)
            .attr("fill", "#EBEBEB")
            .attr("stroke", "white")

        //
        .on("click", function(d) {

                d3.select(this)
                    .attr("fill", "#ABABAB")
                origin_name = "." + d.properties.name.replace(/ /g, "-")

                svg.selectAll(".arcs" + origin_name)
                    .style('stroke-width', function(d){
                      return lineWidth(d.population)
                    })
                    .style('stroke', function(d) {
                        if (d.population > 1) {
                            return "red"
                        } else {
                            return 'none'
                        }
                    })
                svg.selectAll(".circle" + origin_name)
                    .attr("fill", "red")
                    .attr("opacity", 0.4)

            })

            //
            // .on("mouseout", function(d){
            //   d3.select(this)
            //     .attr("fill", "#EBEBEB")
            //     .attr("stroke", "white" )
            //   svg.selectAll(".arcs")
            //     .attr("fill", "none")
            //   svg.selectAll(".circle" + clean_name )
            //     .attr("fill", "none")
            // })

        svg.selectAll(".arcs")
            .data(datapoints)
            .enter()
            .append("path")
            .attr("class", "arcs")
            .attr("fill", "none")
            .attr("class", function(d) {
                var origin = d.origin_name.replace(/ /g, "-")
                    //  var destination =  d.destination_name.replace(/ /g, "-")
                return "arcs " + origin;
            })

        .attr('d', function(d) {
                return lngLatToArc(d, 1); // A bend of 5 looks nice and subtle, but this will depend on the length of your arcs and the visual look your visualization requires. Higher number equals less bend.
            })
            .attr("opacity", 0.4)
            .on('mouseover', function(d) {
                d3.select(this)
                    .attr("stroke", "black")
                tip.show(d)
                var destination = "." + d.destination_name.replace(/ /g, "-")

                svg.selectAll(".country" + destination)
                    .attr("fill", "red")
                    .attr("opacity", 0.4)

                svg.selectAll(".circle" + destination)
                    .attr("fill", "red")
                    .attr("opacity", 0.4)

            })
            .on('mouseout', function(d) {
                d3.select(this)
                    .attr("stroke", "red")
                tip.hide(d)
                var destination = "." + d.destination_name.replace(/ /g, "-")
                svg.selectAll(".country" + destination)
                    .attr("fill", "#EBEBEB")
                    .attr("opacity", 1)
                svg.selectAll(".circle" + destination)
                    .attr("fill", "none")
                    .attr("opacity", 0.4)

            })

        svg.selectAll(".circle")
            .data(datapoints)
            .enter().append("circle")
            .attr("class", function(d) {
                var origin = d.origin_name.replace(/ /g, "-")
                    // var destination =  d.destination_name.replace(/ /g, "-")
                return "circle " + origin;
            })

            .attr('r', 3)
            .attr("cx", function(d) {
                var coords = projection([d.origin_lon, d.origin_lat])
                    // console.log(coords)
                return coords[0];
            })
            .attr("cy", function(d) {
                var coords = projection([d.origin_lon, d.origin_lat])
                return coords[1];
            })
            .attr("fill", "none")
            .attr("stroke", "#00688B")
            .attr("stroke-width", "none")
            .attr("opacity", 0.7)
            .on('mouseover', function(d) {
                d3.select(this)
                .attr("fill", "black")
                tip2.show(d)
              })
            .on('mouseout', function(d) {
                d3.select(this)
                  .attr("fill", "none")
                tip2.hide(d)
              })

        // This function takes an object, the key names where it will find an array of lng/lat pairs, e.g. `[-74, 40]`
        // And a bend parameter for how much bend you want in your arcs, the higher the number, the less bend.
        function lngLatToArc(d, bend) {
            // If no bend is supplied, then do the plain square root
            bend = bend || 1;
            // `d[sourceName]` and `d[targetname]` are arrays of `[lng, lat]`
            // Note, people often put these in lat then lng, but mathematically we want x then y which is `lng,lat`

            var sourceLngLat = [d.origin_lon, d.origin_lat],
                targetLngLat = [d.destination_lon, d.destination_lat];

            if (targetLngLat && sourceLngLat) {
                var sourceXY = projection(sourceLngLat),
                    targetXY = projection(targetLngLat);

                // Uncomment this for testing, useful to see if you have any null lng/lat values
                // if (!targetXY) console.log(d, targetLngLat, targetXY)
                var sourceX = sourceXY[0],
                    sourceY = sourceXY[1];

                var targetX = targetXY[0],
                    targetY = targetXY[1];

                var dx = targetX - sourceX,
                    dy = targetY - sourceY
                dr = Math.sqrt(dx * dx + dy * dy) * bend;

                // To avoid a whirlpool effect, make the bend direction consistent regardless of whether the source is east or west of the target
                var west_of_source = (targetX - sourceX) < 0;
                if (west_of_source) return "M" + targetX + "," + targetY + "A" + dr + "," + dr + " 0 0,1 " + sourceX + "," + sourceY;
                return "M" + sourceX + "," + sourceY + "A" + dr + "," + dr + " 0 0,1 " + targetX + "," + targetY;

            } else {
                return "M0,0,l0,0z";
            }
        }

    }
})();
<commit_msg>Delete project5.js<commit_after><|endoftext|>


<commit_before>/*

Azure search provisioning

 */

var async = require('async');
var request = require('request');
var util = require('util');

module.exports = {

    provisionSearch: function (token, params, callback) {

        // provision storage
        var schKey = null;

        async.series(
            [
                function (cb) {
                    createSearchService(token, params, function (err, result, res, req) {
                        if (err) {
                            return cb(err);
                        }
                        cb(null, result);
                    });
                },
                function (cb) {
                    configSearchService(token, params, function (err, result, res, req) {
                        if (err) {
                            return cb(err);
                        }

                        schKey = res;

                        cb(null, result);
                    });
                }
            ],
            function (err, results) {
                console.log('search provision completed');
                if (err) {
                    console.log(err);
                }

                callback(err, results, schKey);
            }
        );

    },

    provisionSearch2: function (schKey, params, callback) {

        async.series(
            [
                // configSearchIndex
                function (cb) {
                    configSearchIndex(schKey, params, function (error, result) {
                        if (!error) {
                            cb(null, result);
                        }
                    });
                }
            ],
            function (err, results) {
                console.log('search provision completed');
                if (err) {
                    console.log(err);
                }

                callback(err, results, schKey);
            }
        );

    },

    configDR: function (schKey, params, callback) {

        async.series(
            [
                function (cb) {
                    configSearchDS(schKey, params, function (error, result) {
                        if (!error) {
                            cb(null, result);
                        }
                    });
                },
                function (cb) {
                    configSearchIndexer(schKey, params, function (error, result) {
                        if (!error) {
                            cb(null, result);
                        }
                    });
                }
            ],
            function (err, results) {
                console.log('search config completed');
                if (err) {
                    console.log(err);
                }

                callback(err, results, schKey);
            }
        );

    }
};

function createSearchService(token, params, callback) {

    var _params = {
        uri: util.format("https://management.azure.com/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Search/searchServices/%s?api-version=2015-08-19",
            params.subscription, params.resourceGroupName, params.searchServiceName),
        method: 'PUT',
        json: true,
        headers: {
            'Authorization': 'Bearer ' + token,
            'Content-Type': 'application/json;charset=utf-8'
        },
        body: {
            "properties": {
                "replicaCount": 1,
                "partitionCount": 1,
                "hostingMode": "Default"
            },
            "sku": {
                "name": "basic"
            },
            "location": params.schlocation,
            "tags": {
                "costcenter": params.tags
            }
        }
    };

    request(_params, function (error, result, response) {
        if (!error) {
            console.log("\nCreating search account: " + params.searchServiceName);
            //console.log(result);
            callback(null, result);
        }

    });
}

function configSearchService(token, params, callback) {

    var schKey = null;

    async.series([
        function (cb) {
            getSearchSeviceKey(token, params, function (error, result, res) {
                if (!error) {

                    schKey = res;
                    console.log("search key: ", schKey);
                    cb(null, result);
                } else {
                    cb(error);
                }

            });
        },
        // configSearchIndex
        function (cb) {
            // DNS Error
            retryConfigSearchIndex(schKey, params, 10, 30000, function (error, result) {
                if (!error) {
                    console.log("search index created");
                    cb(null, result);
                } else {
                    cb(error);
                }
            });

            /*configSearchIndex(schKey, params, function (error, result) {
                if (!error) {
                    cb(null, result);
                } else {
                    cb(error);
                }
            });*/
        }
    ], function (err, results) {
        if (!err) {
            callback(null, results, schKey);
        } else {
            callback(err);
        }
    });

}

function getSearchSeviceKey(token, paramsSearch, callback) {
    var params = {
        uri: util.format("https://management.azure.com/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Search/searchServices/%s/listAdminKeys?api-version=2015-08-19",
            paramsSearch.subscription, paramsSearch.resourceGroupName, paramsSearch.searchServiceName),
        method: 'POST',
        json: true,
        headers: {
            'Authorization': 'Bearer ' + token,
            'Content-Type': 'application/json;charset=utf-8'
        }
    };

    console.log("Get searchservice key: ", paramsSearch.searchServiceName);
    request(params, function (error, result, response) {
        if (!error) {
            //console.log(result);
            var schkey = result.body.primaryKey; // result.body.secondaryKey

            callback(null, result, schkey);
        } else {
            callback(error);
        }

    });
}

var retryConfigSearchIndex = (function () {
    var count = 0;

    return function (schkey, params, max, timeout, next) {

        var body = {
            "name": params.searchIndex,
            "fields": [
                { "name": "id", "type": "Edm.String", "key": true, "searchable": false, "filterable": false, "sortable": false, "facetable": false },
                { "name": "uri", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
                { "name": "uri2", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
                { "name": "thumbnail", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
                { "name": "thumbnail2", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
                { "name": "tags", "type": "Collection(Edm.String)", "searchable": true, "filterable": true, "sortable": false, "facetable": true },
                { "name": "caption", "type": "Edm.String", "searchable": true, "filterable": false, "sortable": false, "facetable": false }
            ]
        };

        var _params = {
            uri: "https://" + params.searchServiceName + ".search.windows.net/indexes?api-version=2016-09-01",
            method: 'POST',
            json: true,
            headers: {
                "Content-Type": "application/json",
                "api-key": schkey
            },
            body: body
        };

        request(_params, function (error, response) {

            if (error || response.statusCode != 201) {
                if (error) {
                    console.log('count, err code:', count, (error.code) ? error.code : error);
                }
                if (response) {
                    console.log('count, statuscode:', count, (response.statusCode) ? response.statusCode : response);
                }

                if (count++ < max) {
                    return setTimeout(function () {
                        retryConfigSearchIndex(schkey, params, max, timeout, next);
                    }, timeout);
                } else {
                    return next('max retries reached');
                }
            }
            console.log('statuscode:', (response.statusCode) ? response.statusCode : response);
            next(null, response);
        });
    };
})();

function configSearchIndex(schkey, paramsSearch, callback) {

    var body = {
        "name": paramsSearch.searchIndex,
        "fields": [
            { "name": "id", "type": "Edm.String", "key": true, "searchable": false, "filterable": false, "sortable": false, "facetable": false },
            { "name": "uri", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
            { "name": "uri2", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
            { "name": "thumbnail", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
            { "name": "thumbnail2", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
            { "name": "tags", "type": "Collection(Edm.String)", "searchable": true, "filterable": true, "sortable": false, "facetable": true },
            { "name": "caption", "type": "Edm.String", "searchable": true, "filterable": false, "sortable": false, "facetable": false }
        ]
    };

    var params = {
        uri: "https://" + paramsSearch.searchServiceName + ".search.windows.net/indexes?api-version=2016-09-01",
        method: 'POST',
        json: true,
        headers: {
            "Content-Type": "application/json",
            "api-key": schkey
        },
        body: body
    };

    console.log("Config search index: ", body.name);
    request(params, function (error, response) {
        // TODO: status 503, DNS not found issue
        if (!error) {
            callback(null, response);
        } else {
            callback(error);
        }
    });

}

function configSearchDS(schkey, paramsSearch, callback) {

    var params = {
        uri: "https://" + paramsSearch.searchServiceName + ".search.windows.net/datasources?api-version=2015-02-28-Preview",
        method: 'POST',
        json: true,
        headers: {
            "Content-Type": "application/json",
            "api-key": schkey
        },
        body: {
            "name": paramsSearch.searchDataSource,
            "type": "azureblob",
            "credentials": { "connectionString": paramsSearch.storageConnString },
            "container": { "name": paramsSearch.containerName, "query": "log" }
        }
    };

    console.log("Config search datasource: ", params.body.name);
    request(params, function (error, result) {
        if (!error) {
            //console.log(result);
            callback(null, result);
        }
    });
}

// this is for DR index
function configSearchIndexer(schkey, paramsSearch, callback) {

    var params = {
        uri: "https://" + paramsSearch.searchServiceName + ".search.windows.net/indexers?api-version=2015-02-28-Preview",
        method: 'POST',
        json: true,
        headers: {
            "Content-Type": "application/json",
            "api-key": schkey
        },
        body: {
            "name": paramsSearch.searchIndexer,
            "dataSourceName": paramsSearch.searchDataSource,
            "targetIndexName": paramsSearch.searchIndex,
            "parameters": { "configuration": { "parsingMode": "json" } },
            "schedule": { "interval": "PT30M" } // 30 min
        }
    };

    console.log("Config search indexer: ", params.body.name);

    request(params, function (error, result) {
        if (!error) {
            //console.log(result);
            callback(null, result);
        }
    });
}
<commit_msg>search api version updated<commit_after>/*

Azure search provisioning

 */

var async = require('async');
var request = require('request');
var util = require('util');

module.exports = {

    provisionSearch: function (token, params, callback) {

        // provision storage
        var schKey = null;

        async.series(
            [
                function (cb) {
                    createSearchService(token, params, function (err, result, res, req) {
                        if (err) {
                            return cb(err);
                        }
                        cb(null, result);
                    });
                },
                function (cb) {
                    configSearchService(token, params, function (err, result, res, req) {
                        if (err) {
                            return cb(err);
                        }

                        schKey = res;

                        cb(null, result);
                    });
                }
            ],
            function (err, results) {
                console.log('search provision completed');
                if (err) {
                    console.log(err);
                }

                callback(err, results, schKey);
            }
        );

    },

    provisionSearch2: function (schKey, params, callback) {

        async.series(
            [
                // configSearchIndex
                function (cb) {
                    configSearchIndex(schKey, params, function (error, result) {
                        if (!error) {
                            cb(null, result);
                        }
                    });
                }
            ],
            function (err, results) {
                console.log('search provision completed');
                if (err) {
                    console.log(err);
                }

                callback(err, results, schKey);
            }
        );

    },

    configDR: function (schKey, params, callback) {

        async.series(
            [
                function (cb) {
                    configSearchDS(schKey, params, function (error, result) {
                        if (!error) {
                            cb(null, result);
                        }
                    });
                },
                function (cb) {
                    configSearchIndexer(schKey, params, function (error, result) {
                        if (!error) {
                            cb(null, result);
                        }
                    });
                }
            ],
            function (err, results) {
                console.log('search config completed');
                if (err) {
                    console.log(err);
                }

                callback(err, results, schKey);
            }
        );

    }
};

function createSearchService(token, params, callback) {

    var _params = {
        uri: util.format("https://management.azure.com/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Search/searchServices/%s?api-version=2015-08-19",
            params.subscription, params.resourceGroupName, params.searchServiceName),
        method: 'PUT',
        json: true,
        headers: {
            'Authorization': 'Bearer ' + token,
            'Content-Type': 'application/json;charset=utf-8'
        },
        body: {
            "properties": {
                "replicaCount": 1,
                "partitionCount": 1,
                "hostingMode": "Default"
            },
            "sku": {
                "name": "basic"
            },
            "location": params.schlocation,
            "tags": {
                "costcenter": params.tags
            }
        }
    };

    request(_params, function (error, result, response) {
        if (!error) {
            console.log("\nCreating search account: " + params.searchServiceName);
            //console.log(result);
            callback(null, result);
        }

    });
}

function configSearchService(token, params, callback) {

    var schKey = null;

    async.series([
        function (cb) {
            getSearchSeviceKey(token, params, function (error, result, res) {
                if (!error) {

                    schKey = res;
                    console.log("search key: ", schKey);
                    cb(null, result);
                } else {
                    cb(error);
                }

            });
        },
        // configSearchIndex
        function (cb) {
            // DNS Error
            retryConfigSearchIndex(schKey, params, 10, 30000, function (error, result) {
                if (!error) {
                    console.log("search index created");
                    cb(null, result);
                } else {
                    cb(error);
                }
            });

            /*configSearchIndex(schKey, params, function (error, result) {
                if (!error) {
                    cb(null, result);
                } else {
                    cb(error);
                }
            });*/
        }
    ], function (err, results) {
        if (!err) {
            callback(null, results, schKey);
        } else {
            callback(err);
        }
    });

}

function getSearchSeviceKey(token, paramsSearch, callback) {
    var params = {
        uri: util.format("https://management.azure.com/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Search/searchServices/%s/listAdminKeys?api-version=2015-08-19",
            paramsSearch.subscription, paramsSearch.resourceGroupName, paramsSearch.searchServiceName),
        method: 'POST',
        json: true,
        headers: {
            'Authorization': 'Bearer ' + token,
            'Content-Type': 'application/json;charset=utf-8'
        }
    };

    console.log("Get searchservice key: ", paramsSearch.searchServiceName);
    request(params, function (error, result, response) {
        if (!error) {
            //console.log(result);
            var schkey = result.body.primaryKey; // result.body.secondaryKey

            callback(null, result, schkey);
        } else {
            callback(error);
        }

    });
}

var retryConfigSearchIndex = (function () {
    var count = 0;

    return function (schkey, params, max, timeout, next) {

        var body = {
            "name": params.searchIndex,
            "fields": [
                { "name": "id", "type": "Edm.String", "key": true, "searchable": false, "filterable": false, "sortable": false, "facetable": false },
                { "name": "uri", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
                { "name": "uri2", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
                { "name": "thumbnail", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
                { "name": "thumbnail2", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
                { "name": "tags", "type": "Collection(Edm.String)", "searchable": true, "filterable": true, "sortable": false, "facetable": true },
                { "name": "caption", "type": "Edm.String", "searchable": true, "filterable": false, "sortable": false, "facetable": false }
            ]
        };

        var _params = {
            uri: "https://" + params.searchServiceName + ".search.windows.net/indexes?api-version=2016-09-01",
            method: 'POST',
            json: true,
            headers: {
                "Content-Type": "application/json",
                "api-key": schkey
            },
            body: body
        };

        request(_params, function (error, response) {

            if (error || response.statusCode != 201) {
                if (error) {
                    console.log('count, err code:', count, (error.code) ? error.code : error);
                }
                if (response) {
                    console.log('count, statuscode:', count, (response.statusCode) ? response.statusCode : response);
                }

                if (count++ < max) {
                    return setTimeout(function () {
                        retryConfigSearchIndex(schkey, params, max, timeout, next);
                    }, timeout);
                } else {
                    return next('max retries reached');
                }
            }
            console.log('statuscode:', (response.statusCode) ? response.statusCode : response);
            next(null, response);
        });
    };
})();

function configSearchIndex(schkey, paramsSearch, callback) {

    var body = {
        "name": paramsSearch.searchIndex,
        "fields": [
            { "name": "id", "type": "Edm.String", "key": true, "searchable": false, "filterable": false, "sortable": false, "facetable": false },
            { "name": "uri", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
            { "name": "uri2", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
            { "name": "thumbnail", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
            { "name": "thumbnail2", "type": "Edm.String", "searchable": false, "filterable": false, "sortable": false, "facetable": false },
            { "name": "tags", "type": "Collection(Edm.String)", "searchable": true, "filterable": true, "sortable": false, "facetable": true },
            { "name": "caption", "type": "Edm.String", "searchable": true, "filterable": false, "sortable": false, "facetable": false }
        ]
    };

    var params = {
        uri: "https://" + paramsSearch.searchServiceName + ".search.windows.net/indexes?api-version=2016-09-01",
        method: 'POST',
        json: true,
        headers: {
            "Content-Type": "application/json",
            "api-key": schkey
        },
        body: body
    };

    console.log("Config search index: ", body.name);
    request(params, function (error, response) {
        // TODO: status 503, DNS not found issue
        if (!error) {
            callback(null, response);
        } else {
            callback(error);
        }
    });

}

function configSearchDS(schkey, paramsSearch, callback) {

    var params = {
        uri: "https://" + paramsSearch.searchServiceName + ".search.windows.net/datasources?api-version=2016-09-01",
        method: 'POST',
        json: true,
        headers: {
            "Content-Type": "application/json",
            "api-key": schkey
        },
        body: {
            "name": paramsSearch.searchDataSource,
            "type": "azureblob",
            "credentials": { "connectionString": paramsSearch.storageConnString },
            "container": { "name": paramsSearch.containerName, "query": "log" }
        }
    };

    console.log("Config search datasource: ", params.body.name);
    request(params, function (error, result) {
        if (!error) {
            //console.log(result);
            callback(null, result);
        }
    });
}

// this is for DR index
function configSearchIndexer(schkey, paramsSearch, callback) {

    var params = {
        uri: "https://" + paramsSearch.searchServiceName + ".search.windows.net/indexers?api-version=2016-09-01",
        method: 'POST',
        json: true,
        headers: {
            "Content-Type": "application/json",
            "api-key": schkey
        },
        body: {
            "name": paramsSearch.searchIndexer,
            "dataSourceName": paramsSearch.searchDataSource,
            "targetIndexName": paramsSearch.searchIndex,
            "parameters": { "configuration": { "parsingMode": "json" } },
            "schedule": { "interval": "PT30M" } // 30 min
        }
    };

    console.log("Config search indexer: ", params.body.name);

    request(params, function (error, result) {
        if (!error) {
            //console.log(result);
            callback(null, result);
        }
    });
}
<|endoftext|>


<commit_before>/*global $t */

"use strict";

function diceInitialize(container, w, h) {
    function onSetChange(/*ev*/) {
        set.style.width = set.value.length + 3 + 'ex';
    }

    $t.remove($t.id('loading_text'));

    var canvas = $t.id('canvas');
    canvas.style.width = w + 'px';
    canvas.style.height = h + 'px';
    var label = $t.id('label');
    var set = $t.id('set');
    var selectorDiv = $t.id('selector_div');
    var infoDiv = $t.id('info_div');
    onSetChange();

    $t.bind(set, 'keyup', onSetChange);
    $t.bind(set, 'mousedown', function(ev) { ev.stopPropagation(); });
    $t.bind(set, 'mouseup', function(ev) { ev.stopPropagation(); });
    $t.bind(set, 'focus', function() { $t.set(container, { class: '' }); });
    $t.bind(set, 'blur', function() { $t.set(container, { class: 'svg' }); });

    $t.bind($t.id('clear'), ['mouseup', 'touchend', 'touchcancel'], function(ev) {
        ev.stopPropagation();
        set.value = '0';
        onSetChange();
    });

    var box = new $t.dice.dieBox(canvas);

    function showSelector() {
        infoDiv.style.display = 'none';
        selectorDiv.style.display = 'inline-block';
        box.drawSelector();
    }

    function beforeRoll(/*vectors*/) {
        infoDiv.style.display = 'none';
        selectorDiv.style.display = 'none';
    }

    function notationGetter() {
        return JSON.parse(set.dataset.fullDieProps);
    }

    function afterRoll(notation, result) {
        var res = result.join(' ');
        if (notation.constant) {
            res += ' +' + notation.constant;
        }
        if (result.length > 1) {
            res += ' = ' +
                (result.reduce(function(s, a) { return s + a; }) + notation.constant);
        }
        label.innerHTML = res;
        infoDiv.style.display = 'inline-block';
    }

    $t.bind(container, ['mousedown', 'touchstart'], function(ev) {
        box.mouseTime = (new Date()).getTime();
        box.mouseStart = { x: ev.clientX, y: ev.clientY };
    });
    $t.bind(container, ['mouseup', 'touchend', 'touchcancel'], function(ev) {
        if (box.rolling) {
            return;
        }
        var coords = {x: ev.clientX - box.mouseStart.x,
                      y: -(ev.clientY - box.mouseStart.y)};
        var dist = Math.sqrt(coords.x * coords.x + coords.y * coords.y);
        if (dist < Math.sqrt(box.w * box.h * 0.01)) {
            return;
        }

        var dieSpec = set.dataset.fullDieProps || '{"set":[], "constant":0}';
        var dieSet = JSON.parse(dieSpec);
        if (dieSet.set.length === 0) {
            return;
        }

        var timeInt = Math.min((new Date()).getTime() - box.mouseTime,
                               2000);
        var boost = Math.sqrt((2500 - timeInt) / 2500) * dist * 2;
        coords.x /= dist; coords.y /= dist;

        box.rollDice(dieSet, coords, boost, beforeRoll, afterRoll);
    });

    $t.bind($t.id('throw'), ['mouseup', 'touchend', 'touchcancel'], function(ev) {
        if (box.rolling) {
            return;
        }
        ev.stopPropagation();
        var coords = {x: (box.rnd() * 2 - 1) * box.w,
                      y: -(box.rnd() * 2 - 1) * box.h};
        var dist = Math.sqrt(coords.x * coords.x + coords.y * coords.y);
        var notation = notationGetter.call(box);
        if (notation.set.length === 0) {
            return;
        }
        var boost = (box.rnd() + 3) * dist;
        coords.x /= dist; coords.y /= dist;

        box.rollDice(notation, coords, boost, beforeRoll, afterRoll);
    });

    $t.bind(container, ['mouseup', 'touchend', 'touchcancel'], function(ev) {
        if (selectorDiv.style.display === 'none') {
            if (!box.rolling) {
                showSelector();
            }
            box.rolling = false;
            return;
        }
        var dieProps = box.searchDieByMouse(ev);
        if (dieProps !== undefined) {
            var notation = set.dataset.fullDieProps ?
                    JSON.parse(set.dataset.fullDieProps) :
                    {set: [], constant: 0};
            notation.set.push(dieProps);
            set.dataset.fullDieProps = JSON.stringify(notation);
            set.value = $t.dice.stringifyNotation(notation);
            onSetChange();
        }
    });

    var params = $t.getUrlParams();
    if (params.notation) {
        set.value = params.notation;
    }
    if (params.roll) {
        $t.raiseEvent($t.id('throw'), 'mouseup');
    }
    else {
        showSelector();
    }
}
<commit_msg>Drop notationGetter now that event binding is in main.js<commit_after>/*global $t */

"use strict";

function diceInitialize(container, w, h) {
    function onSetChange(/*ev*/) {
        set.style.width = set.value.length + 3 + 'ex';
    }

    $t.remove($t.id('loading_text'));

    var canvas = $t.id('canvas');
    canvas.style.width = w + 'px';
    canvas.style.height = h + 'px';
    var label = $t.id('label');
    var set = $t.id('set');
    var selectorDiv = $t.id('selector_div');
    var infoDiv = $t.id('info_div');
    onSetChange();

    $t.bind(set, 'keyup', onSetChange);
    $t.bind(set, 'mousedown', function(ev) { ev.stopPropagation(); });
    $t.bind(set, 'mouseup', function(ev) { ev.stopPropagation(); });
    $t.bind(set, 'focus', function() { $t.set(container, { class: '' }); });
    $t.bind(set, 'blur', function() { $t.set(container, { class: 'svg' }); });

    $t.bind($t.id('clear'), ['mouseup', 'touchend', 'touchcancel'], function(ev) {
        ev.stopPropagation();
        set.value = '0';
        onSetChange();
    });

    var box = new $t.dice.dieBox(canvas);

    function showSelector() {
        infoDiv.style.display = 'none';
        selectorDiv.style.display = 'inline-block';
        box.drawSelector();
    }

    function beforeRoll(/*vectors*/) {
        infoDiv.style.display = 'none';
        selectorDiv.style.display = 'none';
    }

    function afterRoll(notation, result) {
        var res = result.join(' ');
        if (notation.constant) {
            res += ' +' + notation.constant;
        }
        if (result.length > 1) {
            res += ' = ' +
                (result.reduce(function(s, a) { return s + a; }) + notation.constant);
        }
        label.innerHTML = res;
        infoDiv.style.display = 'inline-block';
    }

    $t.bind(container, ['mousedown', 'touchstart'], function(ev) {
        box.mouseTime = (new Date()).getTime();
        box.mouseStart = { x: ev.clientX, y: ev.clientY };
    });
    $t.bind(container, ['mouseup', 'touchend', 'touchcancel'], function(ev) {
        if (box.rolling) {
            return;
        }
        var coords = {x: ev.clientX - box.mouseStart.x,
                      y: -(ev.clientY - box.mouseStart.y)};
        var dist = Math.sqrt(coords.x * coords.x + coords.y * coords.y);
        if (dist < Math.sqrt(box.w * box.h * 0.01)) {
            return;
        }

        var dieSpec = set.dataset.fullDieProps || '{"set":[], "constant":0}';
        var dieSet = JSON.parse(dieSpec);
        if (dieSet.set.length === 0) {
            return;
        }

        var timeInt = Math.min((new Date()).getTime() - box.mouseTime,
                               2000);
        var boost = Math.sqrt((2500 - timeInt) / 2500) * dist * 2;
        coords.x /= dist; coords.y /= dist;

        box.rollDice(dieSet, coords, boost, beforeRoll, afterRoll);
    });

    $t.bind($t.id('throw'), ['mouseup', 'touchend', 'touchcancel'], function(ev) {
        if (box.rolling) {
            return;
        }
        ev.stopPropagation();
        var coords = {x: (box.rnd() * 2 - 1) * box.w,
                      y: -(box.rnd() * 2 - 1) * box.h};
        var dist = Math.sqrt(coords.x * coords.x + coords.y * coords.y);
        var dieSpec = set.dataset.fullDieProps || '{"set":[], "constant":0}';
        var dieSet = JSON.parse(dieSpec);
        if (dieSet.set.length === 0) {
            return;
        }
        var boost = (box.rnd() + 3) * dist;
        coords.x /= dist; coords.y /= dist;

        box.rollDice(dieSet, coords, boost, beforeRoll, afterRoll);
    });

    $t.bind(container, ['mouseup', 'touchend', 'touchcancel'], function(ev) {
        if (selectorDiv.style.display === 'none') {
            if (!box.rolling) {
                showSelector();
            }
            box.rolling = false;
            return;
        }
        var dieProps = box.searchDieByMouse(ev);
        if (dieProps !== undefined) {
            var notation = set.dataset.fullDieProps ?
                    JSON.parse(set.dataset.fullDieProps) :
                    {set: [], constant: 0};
            notation.set.push(dieProps);
            set.dataset.fullDieProps = JSON.stringify(notation);
            set.value = $t.dice.stringifyNotation(notation);
            onSetChange();
        }
    });

    var params = $t.getUrlParams();
    if (params.notation) {
        set.value = params.notation;
    }
    if (params.roll) {
        $t.raiseEvent($t.id('throw'), 'mouseup');
    }
    else {
        showSelector();
    }
}
<|endoftext|>


<commit_before>// Application Context is available to all actions and containers,
// so this is the place for shared variables in your app

import { Meteor } from 'meteor/meteor';
import * as Collections from '/lib/collections';
import { FlowRouter } from 'meteor/kadira:flow-router';
import { ReactiveDict } from 'meteor/reactive-dict';
import { Tracker } from 'meteor/tracker';
import { Accounts } from 'meteor/accounts-base';

export default function () {
  return {
    Meteor,
    FlowRouter,
    Collections,
    LocalState: new ReactiveDict(),
    Tracker,
    Accounts,
  };
}
<commit_msg>Add roles to application context<commit_after>// Application Context is available to all actions and containers,
// so this is the place for shared variables in your app

import { Meteor } from 'meteor/meteor';
import * as Collections from '/lib/collections';
import { FlowRouter } from 'meteor/kadira:flow-router';
import { ReactiveDict } from 'meteor/reactive-dict';
import { Tracker } from 'meteor/tracker';
import { Accounts } from 'meteor/accounts-base';
import { Roles } from 'meteor/alanning:roles';

export default function () {
  return {
    Meteor,
    FlowRouter,
    Collections,
    LocalState: new ReactiveDict(),
    Tracker,
    Accounts,
    Roles,
  };
}
<|endoftext|>