<commit_before>/* global describe */

var utils = require('./lib/utils')
var RRule = require('../')

var RRuleSet = RRule.RRuleSet

var parse = utils.parse
var datetime = utils.datetime
var testRecurring = utils.testRecurring

describe('RRuleSet', function () {
  // Enable additional toString() / fromString() tests
  // for each testRecurring().
  // this.ctx.ALSO_TEST_STRING_FUNCTIONS = false

  // Thorough after()/before()/between() tests.
  // NOTE: can take a longer time.
  this.ctx.ALSO_TEST_BEFORE_AFTER_BETWEEN = true

  testRecurring('testSet',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.YEARLY,
        count: 2,
        byweekday: RRule.TU,
        dtstart: parse('19970902T090000')
      }))
      set.rrule(new RRule({
        freq: RRule.YEARLY,
        count: 1,
        byweekday: RRule.TH,
        dtstart: parse('19970902T090000')
      }))
      return set
    },
    [
      datetime(1997, 9, 2, 9, 0),
      datetime(1997, 9, 4, 9, 0),
      datetime(1997, 9, 9, 9, 0)
    ]
  )

  testRecurring('testSetDate',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.YEARLY,
        count: 1,
        byweekday: RRule.TU,
        dtstart: parse('19970902T090000')
      }))
      set.rdate(datetime(1997, 9, 4, 9))
      set.rdate(datetime(1997, 9, 9, 9))
      return set
    },
    [
      datetime(1997, 9, 2, 9, 0),
      datetime(1997, 9, 4, 9, 0),
      datetime(1997, 9, 9, 9, 0)
    ]
  )

  testRecurring('testSetExRule',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.YEARLY,
        count: 6,
        byweekday: [RRule.TU, RRule.TH],
        dtstart: parse('19970902T090000')
      }))
      set.exrule(new RRule({
        freq: RRule.YEARLY,
        count: 3,
        byweekday: RRule.TH,
        dtstart: parse('19970902T090000')
      }))
      return set
    },
    [
      datetime(1997, 9, 2, 9, 0),
      datetime(1997, 9, 9, 9, 0),
      datetime(1997, 9, 16, 9, 0)
    ]
  )

  testRecurring('testSetExDate',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.YEARLY,
        count: 6,
        byweekday: [RRule.TU, RRule.TH],
        dtstart: parse('19970902T090000')
      }))
      set.exdate(datetime(1997, 9, 4, 9))
      set.exdate(datetime(1997, 9, 11, 9))
      set.exdate(datetime(1997, 9, 18, 9))
      return set
    },
    [
      datetime(1997, 9, 2, 9, 0),
      datetime(1997, 9, 9, 9, 0),
      datetime(1997, 9, 16, 9, 0)
    ]
  )

  testRecurring('testSetExDateRevOrder',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.MONTHLY,
        count: 5,
        bymonthday: 10,
        dtstart: parse('20040101T090000')
      }))
      set.exdate(datetime(2004, 4, 10, 9, 0))
      set.exdate(datetime(2004, 2, 10, 9, 0))
      return set
    },
    [
      datetime(2004, 1, 10, 9, 0),
      datetime(2004, 3, 10, 9, 0),
      datetime(2004, 5, 10, 9, 0)
    ]
  )

  testRecurring('testSetDateAndExDate',
    function () {
      var set = new RRuleSet()

      set.rdate(datetime(1997, 9, 2, 9))
      set.rdate(datetime(1997, 9, 4, 9))
      set.rdate(datetime(1997, 9, 9, 9))
      set.rdate(datetime(1997, 9, 11, 9))
      set.rdate(datetime(1997, 9, 16, 9))
      set.rdate(datetime(1997, 9, 18, 9))
      set.exdate(datetime(1997, 9, 4, 9))
      set.exdate(datetime(1997, 9, 11, 9))
      set.exdate(datetime(1997, 9, 18, 9))
      return set
    },
    [
      datetime(1997, 9, 2, 9, 0),
      datetime(1997, 9, 9, 9, 0),
      datetime(1997, 9, 16, 9, 0)
    ]
  )

  testRecurring('testSetDateAndExRule',
    function () {
      var set = new RRuleSet()

      set.rdate(datetime(1997, 9, 2, 9))
      set.rdate(datetime(1997, 9, 4, 9))
      set.rdate(datetime(1997, 9, 9, 9))
      set.rdate(datetime(1997, 9, 11, 9))
      set.rdate(datetime(1997, 9, 16, 9))
      set.rdate(datetime(1997, 9, 18, 9))
      set.exrule(new RRule({
        freq: RRule.YEARLY,
        count: 3,
        byweekday: RRule.TH,
        dtstart: parse('19970902T090000')
      }))
      return set
    },
    [
      datetime(1997, 9, 2, 9, 0),
      datetime(1997, 9, 9, 9, 0),
      datetime(1997, 9, 16, 9, 0)
    ]
  )

  testRecurring('testSetCachePre',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.YEARLY,
        count: 2,
        byweekday: RRule.TU,
        dtstart: parse('19970902T090000')
      }))
      set.rrule(new RRule({
        freq: RRule.YEARLY,
        count: 1,
        byweekday: RRule.TH,
        dtstart: parse('19970902T090000')
      }))
      return set
    },
    [
      datetime(1997, 9, 2, 9, 0),
      datetime(1997, 9, 4, 9, 0),
      datetime(1997, 9, 9, 9, 0)
    ]
  )

  testRecurring('testSetCachePost',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.YEARLY,
        count: 2,
        byweekday: RRule.TU,
        dtstart: parse('19970902T090000')
      }))
      set.rrule(new RRule({
        freq: RRule.YEARLY,
        count: 1,
        byweekday: RRule.TH,
        dtstart: parse('19970902T090000')
      }))
      set.all()
      return set
    },
    [
      datetime(1997, 9, 2, 9, 0),
      datetime(1997, 9, 4, 9, 0),
      datetime(1997, 9, 9, 9, 0)
    ]
  )

  testRecurring('testSetInfiniteAll',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.YEARLY,
        dtstart: parse('19970902T090000')
      }))
      set.exrule(new RRule({
        freq: RRule.YEARLY,
        count: 10,
        dtstart: parse('19970902T090000')
      }))

      return {
        rrule: set,
        method: 'all',
        args: [
          function (date, count) {
            return count < 3
          }
        ]
      }
    },
    [
      datetime(2007, 9, 2, 9, 0),
      datetime(2008, 9, 2, 9, 0),
      datetime(2009, 9, 2, 9, 0)
    ]
  )

  testRecurring('testSetInfiniteBetween',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.YEARLY,
        dtstart: parse('19970902T090000')
      }))
      set.exrule(new RRule({
        freq: RRule.YEARLY,
        count: 10,
        dtstart: parse('19970902T090000')
      }))
      return {
        rrule: set,
        method: 'between',
        args: [
          datetime(2000, 9, 2, 9, 0),
          datetime(2010, 9, 2, 9, 0)
        ]
      }
    },
    [
      datetime(2007, 9, 2, 9, 0),
      datetime(2008, 9, 2, 9, 0),
      datetime(2009, 9, 2, 9, 0)
    ]
  )

  testRecurring('testSetInfiniteBefore',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.YEARLY,
        dtstart: parse('19970902T090000')
      }))
      set.exrule(new RRule({
        freq: RRule.YEARLY,
        count: 10,
        dtstart: parse('19970902T090000')
      }))
      return {
        rrule: set,
        method: 'before',
        args: [
          datetime(2015, 9, 2, 9, 0),
          false
        ]
      }
    },
    [
      datetime(2014, 9, 2, 9, 0)
    ]
  )

  testRecurring('testSetInfiniteAfter',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.YEARLY,
        dtstart: parse('19970902T090000')
      }))
      set.exrule(new RRule({
        freq: RRule.YEARLY,
        count: 10,
        dtstart: parse('19970902T090000')
      }))
      return {
        rrule: set,
        method: 'after',
        args: [
          datetime(2000, 9, 2, 9, 0),
          false
        ]
      }
    },
    [
      datetime(2007, 9, 2, 9, 0)
    ]
  )
})
<commit_msg>add a test for dates before 1970<commit_after>/* global describe */

var utils = require('./lib/utils')
var RRule = require('../')

var RRuleSet = RRule.RRuleSet

var parse = utils.parse
var datetime = utils.datetime
var testRecurring = utils.testRecurring

describe('RRuleSet', function () {
  // Enable additional toString() / fromString() tests
  // for each testRecurring().
  // this.ctx.ALSO_TEST_STRING_FUNCTIONS = false

  // Thorough after()/before()/between() tests.
  // NOTE: can take a longer time.
  this.ctx.ALSO_TEST_BEFORE_AFTER_BETWEEN = true

  testRecurring('testSet',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.YEARLY,
        count: 2,
        byweekday: RRule.TU,
        dtstart: parse('19970902T090000')
      }))
      set.rrule(new RRule({
        freq: RRule.YEARLY,
        count: 1,
        byweekday: RRule.TH,
        dtstart: parse('19970902T090000')
      }))
      return set
    },
    [
      datetime(1997, 9, 2, 9, 0),
      datetime(1997, 9, 4, 9, 0),
      datetime(1997, 9, 9, 9, 0)
    ]
  )

  testRecurring('testSetDate',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.YEARLY,
        count: 1,
        byweekday: RRule.TU,
        dtstart: parse('19970902T090000')
      }))
      set.rdate(datetime(1997, 9, 4, 9))
      set.rdate(datetime(1997, 9, 9, 9))
      return set
    },
    [
      datetime(1997, 9, 2, 9, 0),
      datetime(1997, 9, 4, 9, 0),
      datetime(1997, 9, 9, 9, 0)
    ]
  )

  testRecurring('testSetExRule',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.YEARLY,
        count: 6,
        byweekday: [RRule.TU, RRule.TH],
        dtstart: parse('19970902T090000')
      }))
      set.exrule(new RRule({
        freq: RRule.YEARLY,
        count: 3,
        byweekday: RRule.TH,
        dtstart: parse('19970902T090000')
      }))
      return set
    },
    [
      datetime(1997, 9, 2, 9, 0),
      datetime(1997, 9, 9, 9, 0),
      datetime(1997, 9, 16, 9, 0)
    ]
  )

  testRecurring('testSetExDate',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.YEARLY,
        count: 6,
        byweekday: [RRule.TU, RRule.TH],
        dtstart: parse('19970902T090000')
      }))
      set.exdate(datetime(1997, 9, 4, 9))
      set.exdate(datetime(1997, 9, 11, 9))
      set.exdate(datetime(1997, 9, 18, 9))
      return set
    },
    [
      datetime(1997, 9, 2, 9, 0),
      datetime(1997, 9, 9, 9, 0),
      datetime(1997, 9, 16, 9, 0)
    ]
  )

  testRecurring('testSetExDateRevOrder',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.MONTHLY,
        count: 5,
        bymonthday: 10,
        dtstart: parse('20040101T090000')
      }))
      set.exdate(datetime(2004, 4, 10, 9, 0))
      set.exdate(datetime(2004, 2, 10, 9, 0))
      return set
    },
    [
      datetime(2004, 1, 10, 9, 0),
      datetime(2004, 3, 10, 9, 0),
      datetime(2004, 5, 10, 9, 0)
    ]
  )

  testRecurring('testSetDateAndExDate',
    function () {
      var set = new RRuleSet()

      set.rdate(datetime(1997, 9, 2, 9))
      set.rdate(datetime(1997, 9, 4, 9))
      set.rdate(datetime(1997, 9, 9, 9))
      set.rdate(datetime(1997, 9, 11, 9))
      set.rdate(datetime(1997, 9, 16, 9))
      set.rdate(datetime(1997, 9, 18, 9))
      set.exdate(datetime(1997, 9, 4, 9))
      set.exdate(datetime(1997, 9, 11, 9))
      set.exdate(datetime(1997, 9, 18, 9))
      return set
    },
    [
      datetime(1997, 9, 2, 9, 0),
      datetime(1997, 9, 9, 9, 0),
      datetime(1997, 9, 16, 9, 0)
    ]
  )

  testRecurring('testSetDateAndExRule',
    function () {
      var set = new RRuleSet()

      set.rdate(datetime(1997, 9, 2, 9))
      set.rdate(datetime(1997, 9, 4, 9))
      set.rdate(datetime(1997, 9, 9, 9))
      set.rdate(datetime(1997, 9, 11, 9))
      set.rdate(datetime(1997, 9, 16, 9))
      set.rdate(datetime(1997, 9, 18, 9))
      set.exrule(new RRule({
        freq: RRule.YEARLY,
        count: 3,
        byweekday: RRule.TH,
        dtstart: parse('19970902T090000')
      }))
      return set
    },
    [
      datetime(1997, 9, 2, 9, 0),
      datetime(1997, 9, 9, 9, 0),
      datetime(1997, 9, 16, 9, 0)
    ]
  )

  testRecurring('testSetCachePre',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.YEARLY,
        count: 2,
        byweekday: RRule.TU,
        dtstart: parse('19970902T090000')
      }))
      set.rrule(new RRule({
        freq: RRule.YEARLY,
        count: 1,
        byweekday: RRule.TH,
        dtstart: parse('19970902T090000')
      }))
      return set
    },
    [
      datetime(1997, 9, 2, 9, 0),
      datetime(1997, 9, 4, 9, 0),
      datetime(1997, 9, 9, 9, 0)
    ]
  )

  testRecurring('testSetCachePost',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.YEARLY,
        count: 2,
        byweekday: RRule.TU,
        dtstart: parse('19970902T090000')
      }))
      set.rrule(new RRule({
        freq: RRule.YEARLY,
        count: 1,
        byweekday: RRule.TH,
        dtstart: parse('19970902T090000')
      }))
      set.all()
      return set
    },
    [
      datetime(1997, 9, 2, 9, 0),
      datetime(1997, 9, 4, 9, 0),
      datetime(1997, 9, 9, 9, 0)
    ]
  )

  testRecurring('testSetInfiniteAll',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.YEARLY,
        dtstart: parse('19970902T090000')
      }))
      set.exrule(new RRule({
        freq: RRule.YEARLY,
        count: 10,
        dtstart: parse('19970902T090000')
      }))

      return {
        rrule: set,
        method: 'all',
        args: [
          function (date, count) {
            return count < 3
          }
        ]
      }
    },
    [
      datetime(2007, 9, 2, 9, 0),
      datetime(2008, 9, 2, 9, 0),
      datetime(2009, 9, 2, 9, 0)
    ]
  )

  testRecurring('testSetInfiniteBetween',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.YEARLY,
        dtstart: parse('19970902T090000')
      }))
      set.exrule(new RRule({
        freq: RRule.YEARLY,
        count: 10,
        dtstart: parse('19970902T090000')
      }))
      return {
        rrule: set,
        method: 'between',
        args: [
          datetime(2000, 9, 2, 9, 0),
          datetime(2010, 9, 2, 9, 0)
        ]
      }
    },
    [
      datetime(2007, 9, 2, 9, 0),
      datetime(2008, 9, 2, 9, 0),
      datetime(2009, 9, 2, 9, 0)
    ]
  )

  testRecurring('testSetInfiniteBefore',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.YEARLY,
        dtstart: parse('19970902T090000')
      }))
      set.exrule(new RRule({
        freq: RRule.YEARLY,
        count: 10,
        dtstart: parse('19970902T090000')
      }))
      return {
        rrule: set,
        method: 'before',
        args: [
          datetime(2015, 9, 2, 9, 0),
          false
        ]
      }
    },
    [
      datetime(2014, 9, 2, 9, 0)
    ]
  )

  testRecurring('testSetInfiniteAfter',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.YEARLY,
        dtstart: parse('19970902T090000')
      }))
      set.exrule(new RRule({
        freq: RRule.YEARLY,
        count: 10,
        dtstart: parse('19970902T090000')
      }))
      return {
        rrule: set,
        method: 'after',
        args: [
          datetime(2000, 9, 2, 9, 0),
          false
        ]
      }
    },
    [
      datetime(2007, 9, 2, 9, 0)
    ]
  )

  testRecurring('testBefore70',
    function () {
      var set = new RRuleSet()

      set.rrule(new RRule({
        freq: RRule.YEARLY,
        count: 2,
        dtstart: parse('19600101T090000')
      }))
      return {
        rrule: set,
        method: 'all'
      }
    },
    [
      datetime(1960, 1, 1, 9, 0),
      datetime(1961, 1, 1, 9, 0)
    ]
  )
})
<|endoftext|>


<commit_before>#!/usr/bin/env node
const fs = require('fs')
const path = require('path')
const tableToXSV = require('../src/tableToXSV')
const argv = require('minimist')(process.argv.slice(2))

const {
  _: [input],
  output,
  separator = '\t',
  help
} = argv

if (help || !input) {
  console.log()
  console.log('TABLE TO XSV')
  console.log('  Converts a HTML <table> to a X-separated value string.')
  console.log()
  console.log('USAGE')
  console.log(`  node ${path.relative(process.cwd(), __filename)} [options] <path to html>`)
  console.log()
  console.log('OPTIONS')
  console.log('  --separator <string>  : The separator to use. (default: \\t)')
  console.log('  --output <path>       : Output file. (default: stdout)')
  console.log()
  process.exit(help ? 0 : 1)
}

const html = fs.readFileSync(path.resolve(input))

const result = tableToXSV({ separator })(html)

if (output) {
  const resolvedOutput = path.resolve(argv.output)
  console.log(`Writing to ${resolvedOutput}`)
  fs.writeFileSync(resolvedOutput, result)
} else {
  console.log(result)
}
<commit_msg>chore: chmod +x bin files<commit_after>#!/usr/bin/env node
const fs = require('fs')
const path = require('path')
const tableToXSV = require('../src/tableToXSV')
const argv = require('minimist')(process.argv.slice(2))

const {
  _: [input],
  output,
  separator = '\t',
  help
} = argv

if (help || !input) {
  console.log()
  console.log('TABLE TO XSV')
  console.log('  Converts a HTML <table> to a X-separated value string.')
  console.log()
  console.log('USAGE')
  console.log(`  node ${path.relative(process.cwd(), __filename)} [options] <path to html>`)
  console.log()
  console.log('OPTIONS')
  console.log('  --separator <string>  : The separator to use. (default: \\t)')
  console.log('  --output <path>       : Output file. (default: stdout)')
  console.log()
  process.exit(help ? 0 : 1)
}

const html = fs.readFileSync(path.resolve(input))

const result = tableToXSV({ separator })(html)

if (output) {
  const resolvedOutput = path.resolve(argv.output)
  console.log(`Writing to ${resolvedOutput}`)
  fs.writeFileSync(resolvedOutput, result)
} else {
  console.log(result)
}
<|endoftext|>


<commit_before>const configureMockStore = require('redux-mock-store').default;
const thunk = require('redux-thunk').default;
const nock = require('nock');
const expect = require('expect');

const actions = require('../../../../app/actions/admin/newTerm');
const types = require('../../../../app/actions/_constants');
const reducer = require('../../../../app/reducers').default;
const initialState = require('../../../../app/reducers/_initial').default;
const languages = require('../../../../app/helpers/lang').default;

let middlewares = [thunk];
let mockStore = configureMockStore(middlewares);

describe('admin/newTerm actions', () => {
  beforeEach(() => {
    nock.disableNetConnect();
    nock.enableNetConnect('127.0.0.1');
    console.log = jest.fn();
  });

  afterEach(() => {
    nock.cleanAll();
    nock.enableNetConnect();
  });

  it('should return the initial state', () => {
    expect(reducer(undefined, {})).toEqual(initialState);
  });

  it('should change wylie', () => {
    const newWylieString = 'wylie';
    const expectedAction = {
      type: types.CHANGE_NEW_TERM_WYLIE,
      newWylieString
    };
    let expectedState = JSON.parse(JSON.stringify(initialState));
    expectedState.admin.newTerm.wylie = newWylieString;

    // test reducers
    expect(reducer(initialState, expectedAction)).toEqual(expectedState);
    // test actions
    expect(actions.changeWylie(newWylieString)).toEqual(expectedAction);
  });

  it('should change sanskrit', () => {
    languages.list.forEach(elem => {
      const key = 'sanskrit_' + elem;
      const value = 'new_sanskrit on language ' + elem;
      const expectedAction = {
        type: types.CHANGE_NEW_TERM_SANSKRIT,
        key,
        value
      };
      let expectedState = JSON.parse(JSON.stringify(initialState));
      expectedState.admin.newTerm.sanskrit[key] = value;

      // test reducers
      expect(reducer(initialState, expectedAction)).toEqual(expectedState);
      // test actions
      expect(actions.changeSanskrit(key, value)).toEqual(expectedAction);
    });
  });

  it('should save term async', () => {
    const expectedSuccessResponse = {
      success: true,
      term:	{
        wylie: 'New Term',
        translations: [],
        id: 'New_Term'
      }
    };
    languages.list.forEach(elem => {
      expectedSuccessResponse.term['sanskrit_' + elem] = 'Sanskrit on ' + elem;
      expectedSuccessResponse.term['sanskrit_' + elem + '_lower'] = ('Sanskrit on ' + elem).toLowerCase();
    });
    const expectedSuccessActions = [
      { type: types.ADD_TERM_START },
      {
        type: types.ADD_TERM_END,
        error: null,
        termId: expectedSuccessResponse.term.id
      },
      {
        idLast: 1,
        notification: {
          id: 1,
          text: 'NewTerm.alert_success',
          ttl: 3000,
          // timer: 16,  // it will be removed further
          type: 'success',
          values: {termId: expectedSuccessResponse.term.id}
        },
        type: types.CREATE_NOTIFICATION
      }
    ];

    // test reducers
    let expectedState = JSON.parse(JSON.stringify(initialState));
    expectedState.admin.newTerm.termId = expectedSuccessActions[1].termId;
    expect(reducer(initialState, expectedSuccessActions[1])).toEqual(expectedState);
    let nextState = JSON.parse(JSON.stringify(expectedState));
    expectedState.notifications.list.push(expectedSuccessActions[2].notification);
    expectedState.notifications.idLast = expectedSuccessActions[2].idLast;
    expect(reducer(nextState, expectedSuccessActions[2])).toEqual(expectedState);

    // test async actions
    let store = mockStore(initialState);
    nock('http://localhost')
      .post('/api/terms')
      .reply(200, expectedSuccessResponse);
    return store.dispatch(actions.saveTermAsync()).then(() => {
      let storeActions = store.getActions();
      delete storeActions[2].notification.timer;  // remove function-property
      expect(store.getActions()).toEqual(expectedSuccessActions)
    });
  });

  it('should not save term async', () => {
    const expectedErrorResponse = {
      error: true,
      code: 500,
      message: 'Can\'t create new term. Unauthorized access. Database error'
    };
    const expectedErrorActions = [
      { type: types.ADD_TERM_START },
      {
        type: types.ADD_TERM_END,
        termId: null,
        error: expectedErrorResponse
      },
      {
        idLast: 1,
        notification: {
          id: 1,
          text: expectedErrorResponse.message,
          ttl: -1,
          type: 'danger',
          values: {}
        },
        type: types.CREATE_NOTIFICATION
      }
    ];

    // test reducers
    let expectedState = JSON.parse(JSON.stringify(initialState));
    expectedState.admin.newTerm.error = expectedErrorActions[1].error;
    expect(reducer(initialState, expectedErrorActions[1])).toEqual(expectedState);

    // test async actions
    let store = mockStore(initialState);
    nock('http://localhost')
      .post('/api/terms')
      .reply(200, expectedErrorResponse);
    return store.dispatch(actions.saveTermAsync()).then(() => {
      expect(store.getActions()).toEqual(expectedErrorActions)
    });
  });
})
<commit_msg>Refactore newTerm.spec<commit_after>const configureMockStore = require('redux-mock-store').default;
const thunk = require('redux-thunk').default;
const nock = require('nock');
const expect = require('expect');

const actions = require('../../../../app/actions/admin/newTerm');
const types = require('../../../../app/actions/_constants');
const reducer = require('../../../../app/reducers').default;
const initialState = require('../../../../app/reducers/_initial').default;
const languages = require('../../../../app/helpers/lang').default;

let middlewares = [thunk];
let mockStore = configureMockStore(middlewares);

describe('admin/newTerm actions', () => {
  beforeEach(() => {
    nock.disableNetConnect();
    nock.enableNetConnect('127.0.0.1');
    console.log = jest.fn();
  });

  afterEach(() => {
    nock.cleanAll();
    nock.enableNetConnect();
  });

  it('should return the initial state', () => {
    expect(reducer(undefined, {})).toEqual(initialState);
  });

  it('should change wylie', () => {
    const newWylieString = 'wylie';
    const expectedAction = {
      type: types.CHANGE_NEW_TERM_WYLIE,
      newWylieString
    };
    let expectedState = JSON.parse(JSON.stringify(initialState));
    expectedState.admin.newTerm.wylie = newWylieString;

    // test reducers
    expect(reducer(initialState, expectedAction)).toEqual(expectedState);
    // test actions
    expect(actions.changeWylie(newWylieString)).toEqual(expectedAction);
  });

  it('should change sanskrit', () => {
    languages.list.forEach(elem => {
      const key = 'sanskrit_' + elem;
      const value = 'new_sanskrit on language ' + elem;
      const expectedAction = {
        type: types.CHANGE_NEW_TERM_SANSKRIT,
        key,
        value
      };
      let expectedState = JSON.parse(JSON.stringify(initialState));
      expectedState.admin.newTerm.sanskrit[key] = value;

      // test reducers
      expect(reducer(initialState, expectedAction)).toEqual(expectedState);
      // test actions
      expect(actions.changeSanskrit(key, value)).toEqual(expectedAction);
    });
  });

  it('should save term async', () => {
    const wylie = 'New Term';
    const expectedSuccessResponse = {
      success: true,
      term:	{
        wylie,
        translations: [],
        id: 'New_Term'
      }
    };
    languages.list.forEach(elem => {
      expectedSuccessResponse.term['sanskrit_' + elem] = 'Sanskrit on ' + elem;
      expectedSuccessResponse.term['sanskrit_' + elem + '_lower'] = ('Sanskrit on ' + elem).toLowerCase();
    });
    const expectedSuccessActions = [
      { type: types.ADD_TERM_START },
      {
        type: types.ADD_TERM_END,
        error: null,
        termId: expectedSuccessResponse.term.id
      },
      {
        type: types.CREATE_NOTIFICATION,
        idLast: 1,
        notification: {
          id: 1,
          text: 'NewTerm.alert_success',
          ttl: 3000,
          // timer: 16,  // it will be removed further
          type: 'success',
          values: {termId: expectedSuccessResponse.term.id}
        },
      }
    ];

    // test reducers
    let expectedState = JSON.parse(JSON.stringify(initialState));
    expectedState.admin.newTerm.termId = expectedSuccessActions[1].termId;
    expect(reducer(initialState, expectedSuccessActions[1])).toEqual(expectedState);
    let nextState = JSON.parse(JSON.stringify(expectedState));
    expectedState.notifications.list.push(expectedSuccessActions[2].notification);
    expectedState.notifications.idLast = expectedSuccessActions[2].idLast;
    expect(reducer(nextState, expectedSuccessActions[2])).toEqual(expectedState);

    // test async actions
    let store = mockStore(initialState);
    store.dispatch(actions.changeWylie(wylie));
    languages.list.forEach(elem =>
      store.dispatch(actions.changeSanskrit('sanskrit_' + elem, 'value on language' + elem))
    );

    nock('http://localhost')
      .post('/api/terms', {
        term: store.getState().admin.newTerm.wylie,
        sanskrit: store.getState().admin.newTerm.sanskrit
      })
      .reply(200, expectedSuccessResponse);

    return store.dispatch(actions.saveTermAsync()).then(() => {
      const successAction = store.getActions().find(elem => elem.type === types.ADD_TERM_END);
      let successNotification = store.getActions().find(elem => elem.type === types.CREATE_NOTIFICATION);
      delete successNotification.notification.timer;  // remove function-property
      expect(successAction).toEqual(expectedSuccessActions[1]);
      expect(successNotification).toEqual(expectedSuccessActions[2]);
    });
  });

  it('should not save term async', () => {
    const wylie = 'New Term';
    const expectedErrorResponse = {
      error: true,
      code: 500,
      message: 'Can\'t create new term. Unauthorized access. Database error'
    };
    const expectedErrorActions = [
      { type: types.ADD_TERM_START },
      {
        type: types.ADD_TERM_END,
        termId: null,
        error: expectedErrorResponse
      },
      {
        idLast: 1,
        notification: {
          id: 1,
          text: expectedErrorResponse.message,
          ttl: -1,
          type: 'danger',
          values: {}
        },
        type: types.CREATE_NOTIFICATION
      }
    ];

    // test reducers
    let expectedState = JSON.parse(JSON.stringify(initialState));
    expectedState.admin.newTerm.error = expectedErrorActions[1].error;
    expect(reducer(initialState, expectedErrorActions[1])).toEqual(expectedState);

    // test async actions
    let store = mockStore(initialState);
    store.dispatch(actions.changeWylie(wylie));
    languages.list.forEach(elem =>
      store.dispatch(actions.changeSanskrit('sanskrit_' + elem, 'value on language' + elem))
    );

    nock('http://localhost')
      .post('/api/terms', {
        term: store.getState().admin.newTerm.wylie,
        sanskrit: store.getState().admin.newTerm.sanskrit
      })
      .reply(200, expectedErrorResponse);

    return store.dispatch(actions.saveTermAsync()).then(() => {
      const errorAction = store.getActions().find(elem => elem.type === types.ADD_TERM_END);
      let errorNotification = store.getActions().find(elem => elem.type === types.CREATE_NOTIFICATION);
      expect(errorAction).toEqual(expectedErrorActions[1]);
      expect(errorNotification).toEqual(expectedErrorActions[2]);
    });
  });
})
<|endoftext|>


<commit_before>/*!
 * jQuery Fork stuff
 */

/**
 * Share-button
 * This plugin will convert a single item into a list with share-options.
 *
 * What information will be used.
 * - Url that will be shared: if there is a href-attribute this value will be used as url, if not the url of the current page will be used
 * - The title of the item:
 *         1. if the OpenGraph-title-tag is provided, the value of the tag is used.
 *         2. if the title-attribute is used this value will be used in favor of the OpenGraph-title-tag.
 *         3. if the data-title-attribute is set this value will be used, OpenGraph and title-attribute will be ignored.
 *         4. as a fallback the value of the title-tag is used.
 * - The description (used by: Delicious, LinkedIn, Twitter)
 *         1. if the OpenGraph-description-tag is provided, that value will be used.
 *         2. if the data-description-attribute is set this value will be used, even if the OpenGraph-image-tag is provided.
 *         3. no description will be used.
 * - The image
 *         1. if the OpenGraph-image tag is available the value of this tag will be used.
 *         2. if the data-image-attribute is set this value will be used, even if the OpenGraph-image-tag is provided.
 *         3. the default image if there is one provided.
 *         4. no image will be used .
 *
 * Possible options:
 * - debug            if debug is enabled a warning will be logged to the console if og-parameters aren't available, possible values are: true, false.
 * - default_image    the image that will be used by default.
 * - sequence         an array containing the names of the share-items in the wanted sequence.
 * - isDropdown       will the plugin be used as a drop-down-menu? If so we will hide it by default an show on click/hover.
 */
(function($)
{
    $.fn.shareMenu = function(options)
    {
        var twitterLoaded = false;
        var linkedInLoaded = false;
        var googlePlusLoaded = false;
        var pinterestLoaded = false;

        // define defaults
        var defaults =
        {
            debug: false,
            default_image: document.location.protocol + '//' + document.location.host + '/apple-touch-icon.png',
            sequence: ['facebook', 'twitter', 'linkedin', 'digg', 'delicious', 'googleplus', 'pinterest'],
            isDropdown: true
        };
        var settings =
        {
            delicious: { name: 'delicious', show: true, label: 'Delicious'},
            digg: { name: 'digg', show: true, label: 'Digg' },
            facebook: { name: 'facebook', show: true, width: 90, verb: 'like', colorScheme: 'light', font : 'arial' },
            linkedin: { name: 'linkedin', show: true, label: 'LinkedIn' },
            twitter: { name: 'twitter', show: true, label: 'tweet' },
            googleplus: { name: 'googleplus', show: true, label: 'Google +1' },
            pinterest: { name: 'pinterest', show: true, label: 'Pin it', countLayout: 'horizontal' } // possible values for countLayout: horizontal/vertical/none
        };

        // extend options
        options = $.extend(defaults, options);
        options = $.extend(true, settings, options);

        return this.each(function()
        {
            // grab current element
            var $this = $(this);

            // init vars
            var link = document.location.href;
            var title = $('title').html();
            var description = '';
            var image = '';

            // get the link
            if($this.attr('href') !== undefined) link = $this.attr('href');
            if(link.substr(0, 1) == '#') link = document.location.href;
            if(link.substr(0, 4) != 'http') link = document.location.protocol + '//' + document.location.host + link;

            // get the title
            if($('meta[property="og:title"]').attr('content') !== undefined) title = $('meta[property="og:title"]').attr('content');
            if($this.attr('title') !== undefined) title = $this.attr('title');
            if($this.data('title') !== undefined) title = $this.data('title');

            // get the description
            if($('meta[property="og:description"]').attr('content') !== undefined) description = $('meta[property="og:description"]').attr('content');
            if($this.data('description') !== undefined) description = $this.data('description');

            // get the image
            if($('meta[property="og:image"]').attr('content') !== undefined) image = $('meta[property="og:image"]').attr('content');
            if($this.data('image') !== undefined) image = $this.data('image');
            if(image === '' && options.default_image !== '') image = options.default_image;

            // start HTML
            var html;
            if(options.isDropdown) html = '
' + "\n";
            else html = '
' + "\n";

            // loop items
            for(var i in options.sequence)
            {
                // is the option enabled?
                if(options[options.sequence[i]].show)
                {
                    // based on the type we should generate the correct markup
                    switch(options[options.sequence[i]].name)
                    {
                        // Delicious
                        case 'delicious':
                            // build url
                            var url = 'https://delicious.com/save?url=' + encodeURIComponent(link);
                            if(title !== '') url += '&title=' + title;
                            if(description !== '') url += '&notes=' + description;

                            // add html
                            html += '
' +
                                    '    ' +
                                    '        ' +
                                    '        ' + options.delicious.label + '' +
                                    '    ' +
                                    '
' + "\n";
                        break;

                        // Digg
                        case 'digg':
                            // build url
                            var url = 'https://digg.com/submit?url=' + encodeURIComponent(link);
                            if(title !== '') url += '&title=' + title;

                            // add html
                            html += '
' +
                                    '    ' +
                                    '        ' +
                                    '        ' + options.digg.label + '' +
                                    '    ' +
                                    '
' + "\n";
                        break;

                        // Facebook?
                        case 'facebook':
                            // check for OG-data.
                            if(options.debug && $('meta[property^="og"]').length === 0) console.log('You should provide OpenGraph data.');

                            // add html
                            html += '
';

                            // check if the FB-object is available
                            if(typeof FB != 'object')
                            {
                                html += '';
                            }
                            else
                            {
                                html += '<fb:like href="' + link + '" send="false" layout="button_count" width="' + options.facebook.width + '" show_face="false" action="' + options.facebook.verb + '" colorscheme="' + options.facebook.colorScheme + '" font="' + options.facebook.font  + '"></fb:like>' + "\n";
                            }

                            // end html
                            html += '
';
                        break;

                        // LinkedIn
                        case 'linkedin':
                            if(!linkedInLoaded)
                            {
                                // loop all script to check if the Linkedin widget is already loaded
                                $('script').each(function()
                                {
                                    if($(this).attr('src') == 'https://platform.linkedin.com/in.js') linkedInLoaded = true;
                                });

                                // not loaded?
                                if(!linkedInLoaded)
                                {
                                    // create the script tag
                                    var script = document.createElement('script');
                                    script.src = 'https://platform.linkedin.com/in.js';

                                    // add into head
                                    $('head').after(script);

                                    // reset var
                                    linkedInLoaded = true;
                                }
                            }

                            // add html
                            html += '
' +
                                    '    ' +
                                    '
' + "\n";
                        break;

                        // Twitter
                        case 'twitter':
                            if(!twitterLoaded)
                            {
                                // loop all script to check if the twitter-widget is already loaded
                                $('script').each(function()
                                {
                                    if($(this).attr('src') == 'https://platform.twitter.com/widgets.js') twitterLoaded = true;
                                });

                                // not loaded?
                                if(!twitterLoaded)
                                {
                                    // create the script tag
                                    var script = document.createElement('script');
                                    script.src = 'https://platform.twitter.com/widgets.js';

                                    // add into head
                                    $('head').after(script);

                                    // reset var
                                    twitterLoaded = true;
                                }
                            }

                            // build & add html
                            html += '
' +
                                    '    ' + options.twitter.label  + '' +
                                    '
';
                        break;

                        // google plus
                        case 'googleplus':
                            if(!googlePlusLoaded)
                            {
                                // loop all script to check if the twitter-widget is already loaded
                                $('script').each(function()
                                {
                                    if($(this).attr('src') == 'https://apis.google.com/js/plusone.js') googlePlusLoaded = true;
                                });

                                // not loaded?
                                if(!googlePlusLoaded)
                                {
                                    // create the script tag
                                    var script = document.createElement('script');
                                    script.src = 'https://apis.google.com/js/plusone.js';

                                    // add into head
                                    $('head').after(script);

                                    // reset var
                                    googlePlusLoaded = true;
                                }
                            }

                            // build & add html
                            html += '
' +
                                    '

' +
                                    '
';
                        break;

                        // pinterest
                        case 'pinterest':
                            if(image !== '')
                            {
                                if(!pinterestLoaded)
                                {
                                    // loop all script to check if the google plus widget is already loaded
                                    $('script').each(function()
                                    {
                                        if($(this).attr('src') == '//assets.pinterest.com/js/pinit.js') pinterestLoaded = true;
                                    });

                                    // not loaded?
                                    if(!pinterestLoaded)
                                    {
                                        // create the script tag
                                        var script = document.createElement('script');
                                        script.src = '//assets.pinterest.com/js/pinit.js';

                                        // add into head
                                        $('head').after(script);

                                        // ugly hack, for some stupid reason Pinterests adds an iframe at the bottom of the page
                                        // therefor we set it to display none.
                                        $('head').append('');

                                        // reset var
                                        pinterestLoaded = true;
                                    }

                                    if(typeof options[options.sequence[i]].countLayout != 'undefined') countLayout = options[options.sequence[i]].countLayout;
                                    else countLayout = 'none';
                                    if(countLayout != 'horizontal' || countLayout != 'vertical' || countLayout != 'none') countLayout = 'none';

                                    // build & add html
                                    html += '
' +
                                            '    ' +
                                                '' +
                                            '
';
                                }
                            }
                        break;
                    }
                }
            }

            // end html
            html += '
';

            // append to current element
            $this.append(html);

            if(options.isDropdown)
            {
                // bind click
                $this.on('click', function(e)
                {
                    // toggle menu
                    $this.find('ul.shareMenu').toggle();
                });

                $this.hover(
                    function()
                    {
                        $this.find('ul.shareMenu').show();
                    },
                    function()
                    {
                        $this.find('ul.shareMenu').hide();
                    }
                );
            }
        });
    };
})(jQuery);

/**
 * HTML5 validation
 */
(function($)
{
	$.fn.html5validation = function(options)
	{
		// define defaults
		var $input = $(this),
			errorMessage = '',
			type = '',
			defaults =
			{
				required: jsFrontend.locale.err('FieldIsRequired'),
				email: 	  jsFrontend.locale.err('EmailIsInvalid'),
				date: 	  jsFrontend.locale.err('DateIsInvalid'),
				number:   jsFrontend.locale.err('NumberIsInvalid'),
				value:    jsFrontend.locale.err('InvalidValue')
			};

		options = $.extend(defaults, options);

		$input.on('invalid', function(e) {

			if ($input.context.validity.valueMissing) {
				errorMessage = options.required;
			} else if (!$input.context.validity.valid) {
				type = $input.context.type;
				errorMessage = options.value;

				if (options[type]) {
					errorMessage = options[type];
				}
			}

			e.target.setCustomValidity(errorMessage);

			$input.on('input', function(e) {
				e.target.setCustomValidity('');
			});
		});
	};
})(jQuery);
<commit_msg>Tabs to spaces<commit_after>/*!
 * jQuery Fork stuff
 */

/**
 * Share-button
 * This plugin will convert a single item into a list with share-options.
 *
 * What information will be used.
 * - Url that will be shared: if there is a href-attribute this value will be used as url, if not the url of the current page will be used
 * - The title of the item:
 *         1. if the OpenGraph-title-tag is provided, the value of the tag is used.
 *         2. if the title-attribute is used this value will be used in favor of the OpenGraph-title-tag.
 *         3. if the data-title-attribute is set this value will be used, OpenGraph and title-attribute will be ignored.
 *         4. as a fallback the value of the title-tag is used.
 * - The description (used by: Delicious, LinkedIn, Twitter)
 *         1. if the OpenGraph-description-tag is provided, that value will be used.
 *         2. if the data-description-attribute is set this value will be used, even if the OpenGraph-image-tag is provided.
 *         3. no description will be used.
 * - The image
 *         1. if the OpenGraph-image tag is available the value of this tag will be used.
 *         2. if the data-image-attribute is set this value will be used, even if the OpenGraph-image-tag is provided.
 *         3. the default image if there is one provided.
 *         4. no image will be used .
 *
 * Possible options:
 * - debug            if debug is enabled a warning will be logged to the console if og-parameters aren't available, possible values are: true, false.
 * - default_image    the image that will be used by default.
 * - sequence         an array containing the names of the share-items in the wanted sequence.
 * - isDropdown       will the plugin be used as a drop-down-menu? If so we will hide it by default an show on click/hover.
 */
(function($)
{
    $.fn.shareMenu = function(options)
    {
        var twitterLoaded = false;
        var linkedInLoaded = false;
        var googlePlusLoaded = false;
        var pinterestLoaded = false;

        // define defaults
        var defaults =
        {
            debug: false,
            default_image: document.location.protocol + '//' + document.location.host + '/apple-touch-icon.png',
            sequence: ['facebook', 'twitter', 'linkedin', 'digg', 'delicious', 'googleplus', 'pinterest'],
            isDropdown: true
        };
        var settings =
        {
            delicious: { name: 'delicious', show: true, label: 'Delicious'},
            digg: { name: 'digg', show: true, label: 'Digg' },
            facebook: { name: 'facebook', show: true, width: 90, verb: 'like', colorScheme: 'light', font : 'arial' },
            linkedin: { name: 'linkedin', show: true, label: 'LinkedIn' },
            twitter: { name: 'twitter', show: true, label: 'tweet' },
            googleplus: { name: 'googleplus', show: true, label: 'Google +1' },
            pinterest: { name: 'pinterest', show: true, label: 'Pin it', countLayout: 'horizontal' } // possible values for countLayout: horizontal/vertical/none
        };

        // extend options
        options = $.extend(defaults, options);
        options = $.extend(true, settings, options);

        return this.each(function()
        {
            // grab current element
            var $this = $(this);

            // init vars
            var link = document.location.href;
            var title = $('title').html();
            var description = '';
            var image = '';

            // get the link
            if($this.attr('href') !== undefined) link = $this.attr('href');
            if(link.substr(0, 1) == '#') link = document.location.href;
            if(link.substr(0, 4) != 'http') link = document.location.protocol + '//' + document.location.host + link;

            // get the title
            if($('meta[property="og:title"]').attr('content') !== undefined) title = $('meta[property="og:title"]').attr('content');
            if($this.attr('title') !== undefined) title = $this.attr('title');
            if($this.data('title') !== undefined) title = $this.data('title');

            // get the description
            if($('meta[property="og:description"]').attr('content') !== undefined) description = $('meta[property="og:description"]').attr('content');
            if($this.data('description') !== undefined) description = $this.data('description');

            // get the image
            if($('meta[property="og:image"]').attr('content') !== undefined) image = $('meta[property="og:image"]').attr('content');
            if($this.data('image') !== undefined) image = $this.data('image');
            if(image === '' && options.default_image !== '') image = options.default_image;

            // start HTML
            var html;
            if(options.isDropdown) html = '
' + "\n";
            else html = '
' + "\n";

            // loop items
            for(var i in options.sequence)
            {
                // is the option enabled?
                if(options[options.sequence[i]].show)
                {
                    // based on the type we should generate the correct markup
                    switch(options[options.sequence[i]].name)
                    {
                        // Delicious
                        case 'delicious':
                            // build url
                            var url = 'https://delicious.com/save?url=' + encodeURIComponent(link);
                            if(title !== '') url += '&title=' + title;
                            if(description !== '') url += '&notes=' + description;

                            // add html
                            html += '
' +
                                    '    ' +
                                    '        ' +
                                    '        ' + options.delicious.label + '' +
                                    '    ' +
                                    '
' + "\n";
                        break;

                        // Digg
                        case 'digg':
                            // build url
                            var url = 'https://digg.com/submit?url=' + encodeURIComponent(link);
                            if(title !== '') url += '&title=' + title;

                            // add html
                            html += '
' +
                                    '    ' +
                                    '        ' +
                                    '        ' + options.digg.label + '' +
                                    '    ' +
                                    '
' + "\n";
                        break;

                        // Facebook?
                        case 'facebook':
                            // check for OG-data.
                            if(options.debug && $('meta[property^="og"]').length === 0) console.log('You should provide OpenGraph data.');

                            // add html
                            html += '
';

                            // check if the FB-object is available
                            if(typeof FB != 'object')
                            {
                                html += '';
                            }
                            else
                            {
                                html += '<fb:like href="' + link + '" send="false" layout="button_count" width="' + options.facebook.width + '" show_face="false" action="' + options.facebook.verb + '" colorscheme="' + options.facebook.colorScheme + '" font="' + options.facebook.font  + '"></fb:like>' + "\n";
                            }

                            // end html
                            html += '
';
                        break;

                        // LinkedIn
                        case 'linkedin':
                            if(!linkedInLoaded)
                            {
                                // loop all script to check if the Linkedin widget is already loaded
                                $('script').each(function()
                                {
                                    if($(this).attr('src') == 'https://platform.linkedin.com/in.js') linkedInLoaded = true;
                                });

                                // not loaded?
                                if(!linkedInLoaded)
                                {
                                    // create the script tag
                                    var script = document.createElement('script');
                                    script.src = 'https://platform.linkedin.com/in.js';

                                    // add into head
                                    $('head').after(script);

                                    // reset var
                                    linkedInLoaded = true;
                                }
                            }

                            // add html
                            html += '
' +
                                    '    ' +
                                    '
' + "\n";
                        break;

                        // Twitter
                        case 'twitter':
                            if(!twitterLoaded)
                            {
                                // loop all script to check if the twitter-widget is already loaded
                                $('script').each(function()
                                {
                                    if($(this).attr('src') == 'https://platform.twitter.com/widgets.js') twitterLoaded = true;
                                });

                                // not loaded?
                                if(!twitterLoaded)
                                {
                                    // create the script tag
                                    var script = document.createElement('script');
                                    script.src = 'https://platform.twitter.com/widgets.js';

                                    // add into head
                                    $('head').after(script);

                                    // reset var
                                    twitterLoaded = true;
                                }
                            }

                            // build & add html
                            html += '
' +
                                    '    ' + options.twitter.label  + '' +
                                    '
';
                        break;

                        // google plus
                        case 'googleplus':
                            if(!googlePlusLoaded)
                            {
                                // loop all script to check if the twitter-widget is already loaded
                                $('script').each(function()
                                {
                                    if($(this).attr('src') == 'https://apis.google.com/js/plusone.js') googlePlusLoaded = true;
                                });

                                // not loaded?
                                if(!googlePlusLoaded)
                                {
                                    // create the script tag
                                    var script = document.createElement('script');
                                    script.src = 'https://apis.google.com/js/plusone.js';

                                    // add into head
                                    $('head').after(script);

                                    // reset var
                                    googlePlusLoaded = true;
                                }
                            }

                            // build & add html
                            html += '
' +
                                    '

' +
                                    '
';
                        break;

                        // pinterest
                        case 'pinterest':
                            if(image !== '')
                            {
                                if(!pinterestLoaded)
                                {
                                    // loop all script to check if the google plus widget is already loaded
                                    $('script').each(function()
                                    {
                                        if($(this).attr('src') == '//assets.pinterest.com/js/pinit.js') pinterestLoaded = true;
                                    });

                                    // not loaded?
                                    if(!pinterestLoaded)
                                    {
                                        // create the script tag
                                        var script = document.createElement('script');
                                        script.src = '//assets.pinterest.com/js/pinit.js';

                                        // add into head
                                        $('head').after(script);

                                        // ugly hack, for some stupid reason Pinterests adds an iframe at the bottom of the page
                                        // therefor we set it to display none.
                                        $('head').append('');

                                        // reset var
                                        pinterestLoaded = true;
                                    }

                                    if(typeof options[options.sequence[i]].countLayout != 'undefined') countLayout = options[options.sequence[i]].countLayout;
                                    else countLayout = 'none';
                                    if(countLayout != 'horizontal' || countLayout != 'vertical' || countLayout != 'none') countLayout = 'none';

                                    // build & add html
                                    html += '
' +
                                            '    ' +
                                                '' +
                                            '
';
                                }
                            }
                        break;
                    }
                }
            }

            // end html
            html += '
';

            // append to current element
            $this.append(html);

            if(options.isDropdown)
            {
                // bind click
                $this.on('click', function(e)
                {
                    // toggle menu
                    $this.find('ul.shareMenu').toggle();
                });

                $this.hover(
                    function()
                    {
                        $this.find('ul.shareMenu').show();
                    },
                    function()
                    {
                        $this.find('ul.shareMenu').hide();
                    }
                );
            }
        });
    };
})(jQuery);

/**
 * HTML5 validation
 */
(function($)
{
    $.fn.html5validation = function(options)
    {
        // define defaults
        var $input = $(this),
            errorMessage = '',
            type = '',
            defaults =
            {
                required: jsFrontend.locale.err('FieldIsRequired'),
                email: 	  jsFrontend.locale.err('EmailIsInvalid'),
                date: 	  jsFrontend.locale.err('DateIsInvalid'),
                number:   jsFrontend.locale.err('NumberIsInvalid'),
                value:    jsFrontend.locale.err('InvalidValue')
            };

        options = $.extend(defaults, options);

        $input.on('invalid', function(e) {

            if ($input.context.validity.valueMissing) {
                errorMessage = options.required;
            } else if (!$input.context.validity.valid) {
                type = $input.context.type;
                errorMessage = options.value;

                if (options[type]) {
                    errorMessage = options[type];
                }
            }

            e.target.setCustomValidity(errorMessage);

            $input.on('input', function(e) {
                e.target.setCustomValidity('');
            });
        });
    };
})(jQuery);
<|endoftext|>


<commit_before>/*!
 * jQuery Fork stuff
 */

/**
 * Share-button
 * This plugin will convert a single item into a list with share-options.
 *
 * What information will be used.
 * - Url that will be shared: if there is a href-attribute this value will be used as url, if not the url of the current page will be used
 * - The title of the item:
 * 		1. if the OpenGraph-title-tag is provided, the value of the tag is used.
 * 		2. if the title-attribute is used this value will be used in favor of the OpenGraph-title-tag.
 * 		3. if the data-title-attribute is set this value will be used, OpenGraph and title-attribute will be ignored.
 * 		4. as a fallback the value of the title-tag is used.
 * - The description (used by: Delicious, LinkedIn, Netlog, Twitter)
 * 		1. if the OpenGraph-description-tag is provided, that value will be used.
 * 		2. if the data-description-attribute is set this value will be used, even if the OpenGraph-image-tag is provided.
 * 		3. no description will be used.
 * - The image (used by: Netlog)
 * 		1. if the OpenGraph-image tag is available the value of this tag will be used.
 * 		2. if the data-image-attribute is set this value will be used, even if the OpenGraph-image-tag is provided.
 * 		3. the default image if there is one provided.
 * 		4. no image will be used .
 *
 * Possible options:
 * - debug			if debug is enabled a warning will be logged to the console if og-parameters aren't available, possible values are: true, false.
 * - default_image	the image that will be used by default.
 * - sequence		an array containing the names of the share-items in the wanted sequence.
 * - isDropdown		will the plugin be used as a drop-down-menu? If so we will hide it by default an show on click/hover.
 *
 * @author	Tijs Verkoyen <tijs@sumocoders.be>
 */
(function($)
{
	$.fn.shareMenu = function(options)
	{
		var twitterLoaded = false;
		var linkedInLoaded = false;
		var googlePlusLoaded = false;
		var pinterestLoaded = false;

		// define defaults
		var defaults =
		{
			debug: false,
			default_image: document.location.protocol + '//' + document.location.host + '/apple-touch-icon.png',
			sequence: ['facebook', 'twitter', 'netlog', 'linkedin', 'digg', 'delicious', 'googleplus', 'pinterest'],
			isDropdown: true
		};
		var settings =
		{
			delicious: { name: 'delicious', show: true, label: 'Delicious'},
			digg: { name: 'digg', show: true, label: 'Digg' },
			facebook: { name: 'facebook', show: true, width: 90, verb: 'like', colorScheme: 'light', font : 'arial' },
			linkedin: { name: 'linkedin', show: true, label: 'LinkedIn' },
			netlog: { name: 'netlog', show: true, label: 'Netlog' },
			twitter: { name: 'twitter', show: true, label: 'tweet' },
			googleplus: { name: 'googleplus', show: true, label: 'Google +1' },
			pinterest: { name: 'pinterest', show: true, label: 'Pin it', countLayout: 'horizontal' } // possible values for countLayout: horizontal/vertical/none
		};

		// extend options
		var options = $.extend(defaults, options);
		options = $.extend(true, settings, options);

		return this.each(function()
		{
			// grab current element
			var $this = $(this);

			// init vars
			var link = document.location.href;
			var title = $('title').html();
			var description = '';
			var image = '';

			// get the link
			if($this.attr('href') != undefined) link = $this.attr('href');
			if(link.substr(0, 1) == '#') link = document.location.href;
			if(link.substr(0, 4) != 'http') link = document.location.protocol + '//' + document.location.host + link;

			// get the title
			if($('meta[property="og:title"]').attr('content') != undefined) title = $('meta[property="og:title"]').attr('content');
			if($this.attr('title') != undefined) title = $this.attr('title');
			if($this.data('title') != undefined) title = $this.data('title');

			// get the description
			if($('meta[property="og:description"]').attr('content') != undefined) description = $('meta[property="og:description"]').attr('content');
			if($this.data('description') != undefined) description = $this.data('description');

			// get the image
			if($('meta[property="og:image"]').attr('content') != undefined) image = $('meta[property="og:image"]').attr('content');
			if($this.data('image') != undefined) image = $this.data('image');
			if(image == '' && options.default_image != '') image = options.default_image;

			// start HTML
			if(options.isDropdown) var html = '
' + "\n";
			else var html = '
' + "\n";

			// loop items
			for(var i in options.sequence)
			{
				// is the option enabled?
				if(options[options.sequence[i]].show)
				{
					// based on the type we should generate the correct markup
					switch(options[options.sequence[i]].name)
					{
						// Delicious
						case 'delicious':
							// build url
							var url = 'http://delicious.com/save?url=' + encodeURIComponent(link);
							if(title != '') url += '&title=' + title;
							if(description != '') url += '&notes=' + description;

							// add html
							html += '
' +
									'	' +
									'		' +
									'		' + options.delicious.label + '' +
									'	' +
									'
' + "\n";
						break;

						// Digg
						case 'digg':
							// build url
							var url = 'http://digg.com/submit?url=' + encodeURIComponent(link);
							if(title != '') url += '&title=' + title;

							// add html
							html += '
' +
									'	' +
									'		' +
									'		' + options.digg.label + '' +
									'	' +
									'
' + "\n";
						break;

						// Facebook?
						case 'facebook':
							// check for OG-data.
							if(options.debug && $('meta[property^="og"]').length == 0) console.log('You should provide OpenGraph data.');

							// add html
							html += '
';

							// check if the FB-object is available
							if(typeof FB != 'object')
							{
								html += '';
							}
							else
							{
								html += '<fb:like href="' + link + '" send="false" layout="button_count" width="' + options.facebook.width + '" show_face="false" action="' + options.facebook.verb + '" colorscheme="' + options.facebook.colorScheme + '" font="' + options.facebook.font  + '"></fb:like>' + "\n";
							}

							// end html
							html += '
';
						break;

						// LinkedIn
						case 'linkedin':
							if(!linkedInLoaded)
							{
								// loop all script to check if the Linkedin widget is already loaded
								$('script').each(function()
								{
									if($(this).attr('src') == 'http://platform.linkedin.com/in.js') linkedInLoaded = true;
								});

								// not loaded?
								if(!linkedInLoaded)
								{
									// create the script tag
									var script = document.createElement('script')
									script.src = 'http://platform.linkedin.com/in.js';

									// add into head
									$('head').after(script);

									// reset var
									linkedInLoaded = true;
								}
							}

							// add html
							html += '
' +
									'	' +
									'
' + "\n";
						break;

						// Netlog?
						case 'netlog':
							// build url
							var url = 'http://www.netlog.com/go/manage/links/view=save&origin=external&url=' + encodeURIComponent(link);
							if(title != '') url += '&title=' + title;
							if(description != '') url += '&description=' + description;
							if(image != '') url += '&thumb=' + encodeURIComponent(image);
							url += '&referer=' + encodeURIComponent(document.location);

							// add html
							html += '
' +
									'	' +
									'		' +
									'		' + options.netlog.label + '' +
									'	' +
									'
' + "\n";
						break;

						// Twitter
						case 'twitter':
							if(!twitterLoaded)
							{
								// loop all script to check if the twitter-widget is already loaded
								$('script').each(function()
								{
									if($(this).attr('src') == 'http://platform.twitter.com/widgets.js') twitterLoaded = true;
								});

								// not loaded?
								if(!twitterLoaded)
								{
									// create the script tag
									var script = document.createElement('script')
									script.src = 'http://platform.twitter.com/widgets.js';

									// add into head
									$('head').after(script);

									// reset var
									twitterLoaded = true;
								}
							}

							// build & add html
							html += '
' +
									'	' + options.twitter.label  + '' +
									'
';
						break;

						// google plus
						case 'googleplus':
							if(!googlePlusLoaded)
							{
								// loop all script to check if the twitter-widget is already loaded
								$('script').each(function()
								{
									if($(this).attr('src') == 'https://apis.google.com/js/plusone.js') googlePlusLoaded = true;
								});

								// not loaded?
								if(!googlePlusLoaded)
								{
									// create the script tag
									var script = document.createElement('script')
									script.src = 'https://apis.google.com/js/plusone.js';

									// add into head
									$('head').after(script);

									// reset var
									googlePlusLoaded = true;
								}
							}

							// build & add html
							html += '
' +
									'

' +
									'
';
						break;

						// pinterest
						case 'pinterest':
							if(image != '')
							{
								if(!pinterestLoaded)
								{
									// loop all script to check if the google plus widget is already loaded
									$('script').each(function()
									{
										if($(this).attr('src') == '//assets.pinterest.com/js/pinit.js') pinterestLoaded = true;
									});

									// not loaded?
									if(!pinterestLoaded)
									{
										// create the script tag
										var script = document.createElement('script')
										script.src = '//assets.pinterest.com/js/pinit.js';

										// add into head
										$('head').after(script);

										// ugly hack, for some stupid reason Pinterests adds an iframe at the bottom of the page
										// therefor we set it to display none.
										$('head').append('');

										// reset var
										pinterestLoaded = true;
									}

									if(typeof options[options.sequence[i]].countLayout != 'undefined') countLayout = options[options.sequence[i]].countLayout;
									else countLayout = 'none';
									if(countLayout != 'horizontal' || countLayout != 'vertical' || countLayout != 'none') countLayout = 'none';

									// build & add html
									html += '
' +
											'	' +
												'' +
											'
';
								}
							}
						break;
					}
				}
			}

			// end html
			html += '
';

			// append to current element
			$this.append(html);

			if(options.isDropdown)
			{
				// bind click
				$this.on('click', function(e)
				{
					// toggle menu
					$this.find('ul.shareMenu').toggle();
				});

				$this.hover(
					function()
					{
						$this.find('ul.shareMenu').show();
					},
					function()
					{
						$this.find('ul.shareMenu').hide();
					}
				);
			}
		});
	};
})(jQuery);
<commit_msg>Remove netlog from the default share menu<commit_after>/*!
 * jQuery Fork stuff
 */

/**
 * Share-button
 * This plugin will convert a single item into a list with share-options.
 *
 * What information will be used.
 * - Url that will be shared: if there is a href-attribute this value will be used as url, if not the url of the current page will be used
 * - The title of the item:
 * 		1. if the OpenGraph-title-tag is provided, the value of the tag is used.
 * 		2. if the title-attribute is used this value will be used in favor of the OpenGraph-title-tag.
 * 		3. if the data-title-attribute is set this value will be used, OpenGraph and title-attribute will be ignored.
 * 		4. as a fallback the value of the title-tag is used.
 * - The description (used by: Delicious, LinkedIn, Twitter)
 * 		1. if the OpenGraph-description-tag is provided, that value will be used.
 * 		2. if the data-description-attribute is set this value will be used, even if the OpenGraph-image-tag is provided.
 * 		3. no description will be used.
 * - The image
 * 		1. if the OpenGraph-image tag is available the value of this tag will be used.
 * 		2. if the data-image-attribute is set this value will be used, even if the OpenGraph-image-tag is provided.
 * 		3. the default image if there is one provided.
 * 		4. no image will be used .
 *
 * Possible options:
 * - debug			if debug is enabled a warning will be logged to the console if og-parameters aren't available, possible values are: true, false.
 * - default_image	the image that will be used by default.
 * - sequence		an array containing the names of the share-items in the wanted sequence.
 * - isDropdown		will the plugin be used as a drop-down-menu? If so we will hide it by default an show on click/hover.
 *
 * @author	Tijs Verkoyen <tijs@sumocoders.be>
 */
(function($)
{
	$.fn.shareMenu = function(options)
	{
		var twitterLoaded = false;
		var linkedInLoaded = false;
		var googlePlusLoaded = false;
		var pinterestLoaded = false;

		// define defaults
		var defaults =
		{
			debug: false,
			default_image: document.location.protocol + '//' + document.location.host + '/apple-touch-icon.png',
			sequence: ['facebook', 'twitter', 'linkedin', 'digg', 'delicious', 'googleplus', 'pinterest'],
			isDropdown: true
		};
		var settings =
		{
			delicious: { name: 'delicious', show: true, label: 'Delicious'},
			digg: { name: 'digg', show: true, label: 'Digg' },
			facebook: { name: 'facebook', show: true, width: 90, verb: 'like', colorScheme: 'light', font : 'arial' },
			linkedin: { name: 'linkedin', show: true, label: 'LinkedIn' },
			twitter: { name: 'twitter', show: true, label: 'tweet' },
			googleplus: { name: 'googleplus', show: true, label: 'Google +1' },
			pinterest: { name: 'pinterest', show: true, label: 'Pin it', countLayout: 'horizontal' } // possible values for countLayout: horizontal/vertical/none
		};

		// extend options
		var options = $.extend(defaults, options);
		options = $.extend(true, settings, options);

		return this.each(function()
		{
			// grab current element
			var $this = $(this);

			// init vars
			var link = document.location.href;
			var title = $('title').html();
			var description = '';
			var image = '';

			// get the link
			if($this.attr('href') != undefined) link = $this.attr('href');
			if(link.substr(0, 1) == '#') link = document.location.href;
			if(link.substr(0, 4) != 'http') link = document.location.protocol + '//' + document.location.host + link;

			// get the title
			if($('meta[property="og:title"]').attr('content') != undefined) title = $('meta[property="og:title"]').attr('content');
			if($this.attr('title') != undefined) title = $this.attr('title');
			if($this.data('title') != undefined) title = $this.data('title');

			// get the description
			if($('meta[property="og:description"]').attr('content') != undefined) description = $('meta[property="og:description"]').attr('content');
			if($this.data('description') != undefined) description = $this.data('description');

			// get the image
			if($('meta[property="og:image"]').attr('content') != undefined) image = $('meta[property="og:image"]').attr('content');
			if($this.data('image') != undefined) image = $this.data('image');
			if(image == '' && options.default_image != '') image = options.default_image;

			// start HTML
			if(options.isDropdown) var html = '
' + "\n";
			else var html = '
' + "\n";

			// loop items
			for(var i in options.sequence)
			{
				// is the option enabled?
				if(options[options.sequence[i]].show)
				{
					// based on the type we should generate the correct markup
					switch(options[options.sequence[i]].name)
					{
						// Delicious
						case 'delicious':
							// build url
							var url = 'http://delicious.com/save?url=' + encodeURIComponent(link);
							if(title != '') url += '&title=' + title;
							if(description != '') url += '&notes=' + description;

							// add html
							html += '
' +
									'	' +
									'		' +
									'		' + options.delicious.label + '' +
									'	' +
									'
' + "\n";
						break;

						// Digg
						case 'digg':
							// build url
							var url = 'http://digg.com/submit?url=' + encodeURIComponent(link);
							if(title != '') url += '&title=' + title;

							// add html
							html += '
' +
									'	' +
									'		' +
									'		' + options.digg.label + '' +
									'	' +
									'
' + "\n";
						break;

						// Facebook?
						case 'facebook':
							// check for OG-data.
							if(options.debug && $('meta[property^="og"]').length == 0) console.log('You should provide OpenGraph data.');

							// add html
							html += '
';

							// check if the FB-object is available
							if(typeof FB != 'object')
							{
								html += '';
							}
							else
							{
								html += '<fb:like href="' + link + '" send="false" layout="button_count" width="' + options.facebook.width + '" show_face="false" action="' + options.facebook.verb + '" colorscheme="' + options.facebook.colorScheme + '" font="' + options.facebook.font  + '"></fb:like>' + "\n";
							}

							// end html
							html += '
';
						break;

						// LinkedIn
						case 'linkedin':
							if(!linkedInLoaded)
							{
								// loop all script to check if the Linkedin widget is already loaded
								$('script').each(function()
								{
									if($(this).attr('src') == 'http://platform.linkedin.com/in.js') linkedInLoaded = true;
								});

								// not loaded?
								if(!linkedInLoaded)
								{
									// create the script tag
									var script = document.createElement('script')
									script.src = 'http://platform.linkedin.com/in.js';

									// add into head
									$('head').after(script);

									// reset var
									linkedInLoaded = true;
								}
							}

							// add html
							html += '
' +
									'	' +
									'
' + "\n";
						break;

						// Twitter
						case 'twitter':
							if(!twitterLoaded)
							{
								// loop all script to check if the twitter-widget is already loaded
								$('script').each(function()
								{
									if($(this).attr('src') == 'http://platform.twitter.com/widgets.js') twitterLoaded = true;
								});

								// not loaded?
								if(!twitterLoaded)
								{
									// create the script tag
									var script = document.createElement('script')
									script.src = 'http://platform.twitter.com/widgets.js';

									// add into head
									$('head').after(script);

									// reset var
									twitterLoaded = true;
								}
							}

							// build & add html
							html += '
' +
									'	' + options.twitter.label  + '' +
									'
';
						break;

						// google plus
						case 'googleplus':
							if(!googlePlusLoaded)
							{
								// loop all script to check if the twitter-widget is already loaded
								$('script').each(function()
								{
									if($(this).attr('src') == 'https://apis.google.com/js/plusone.js') googlePlusLoaded = true;
								});

								// not loaded?
								if(!googlePlusLoaded)
								{
									// create the script tag
									var script = document.createElement('script')
									script.src = 'https://apis.google.com/js/plusone.js';

									// add into head
									$('head').after(script);

									// reset var
									googlePlusLoaded = true;
								}
							}

							// build & add html
							html += '
' +
									'

' +
									'
';
						break;

						// pinterest
						case 'pinterest':
							if(image != '')
							{
								if(!pinterestLoaded)
								{
									// loop all script to check if the google plus widget is already loaded
									$('script').each(function()
									{
										if($(this).attr('src') == '//assets.pinterest.com/js/pinit.js') pinterestLoaded = true;
									});

									// not loaded?
									if(!pinterestLoaded)
									{
										// create the script tag
										var script = document.createElement('script')
										script.src = '//assets.pinterest.com/js/pinit.js';

										// add into head
										$('head').after(script);

										// ugly hack, for some stupid reason Pinterests adds an iframe at the bottom of the page
										// therefor we set it to display none.
										$('head').append('');

										// reset var
										pinterestLoaded = true;
									}

									if(typeof options[options.sequence[i]].countLayout != 'undefined') countLayout = options[options.sequence[i]].countLayout;
									else countLayout = 'none';
									if(countLayout != 'horizontal' || countLayout != 'vertical' || countLayout != 'none') countLayout = 'none';

									// build & add html
									html += '
' +
											'	' +
												'' +
											'
';
								}
							}
						break;
					}
				}
			}

			// end html
			html += '
';

			// append to current element
			$this.append(html);

			if(options.isDropdown)
			{
				// bind click
				$this.on('click', function(e)
				{
					// toggle menu
					$this.find('ul.shareMenu').toggle();
				});

				$this.hover(
					function()
					{
						$this.find('ul.shareMenu').show();
					},
					function()
					{
						$this.find('ul.shareMenu').hide();
					}
				);
			}
		});
	};
})(jQuery);
<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';

import {
	ReactiveBase,
	TagCloud,
	ResultList,
	SelectedFilters,
	ReactiveList,
} from '@appbaseio/reactivesearch';

import './index.css';

const Main = () => (
	<ReactiveBase app="meetup_app" credentials="lW70IgSjr:87c5ae16-73fb-4559-a29e-0a02760d2181">

				<TagCloud
					title="TagCloud"
					componentId="CitySensor"
					dataField="group.group_city.raw"
					multiSelect
					size={50}
				/>

				<SelectedFilters />
				<ReactiveList
					componentId="SearchResult"
					dataField="group.group_topics.topic_name_raw"
					title="Results"
					sortBy="asc"
					className="result-list-container"
					from={0}
					size={5}
					innerClass={{
						image: 'meetup-list-image',
					}}
					pagination
					react={{
						and: ['CitySensor'],
					}}
					render={({ data }) => (
						<ReactiveList.ResultListWrapper>
							{data.map(item => (
								<ResultList href={data.event.event_url} key={item._id}>
									<ResultList.Image src={item.member.photo} small />
									<ResultList.Content>
										<ResultList.Title>

												{data.member ? data.member.member_name : ''} is
												going to ${data.event ? data.event.event_name : ''}

										</ResultList.Title>
										<ResultList.Description>

													{data.group ? data.group.group_city : ''}

													{data.group.group_topics
														.slice(0, 4)
														.map(tag => (

																{tag.topic_name}

														))}

										</ResultList.Description>
									</ResultList.Content>
								</ResultList>
							))}
						</ReactiveList.ResultListWrapper>
					)}
				/>

	</ReactiveBase>
);

ReactDOM.render(, document.getElementById('root'));
<commit_msg>fix(web): tag cloud example (#1341)<commit_after>import React from 'react';
import ReactDOM from 'react-dom';

import {
	ReactiveBase,
	TagCloud,
	ResultList,
	SelectedFilters,
	ReactiveList,
} from '@appbaseio/reactivesearch';

import './index.css';

const Main = () => (
	<ReactiveBase app="meetup_app" credentials="lW70IgSjr:87c5ae16-73fb-4559-a29e-0a02760d2181">

				<TagCloud
					title="TagCloud"
					componentId="CitySensor"
					dataField="group.group_city.raw"
					multiSelect
					size={50}
				/>

				<SelectedFilters />
				<ReactiveList
					componentId="SearchResult"
					dataField="group.group_topics.topic_name_raw"
					title="Results"
					sortBy="asc"
					className="result-list-container"
					from={0}
					size={5}
					innerClass={{
						image: 'meetup-list-image',
					}}
					pagination
					react={{
						and: ['CitySensor'],
					}}
					render={({ data }) => (
						<ReactiveList.ResultListWrapper>
							{data.map(item => (
								<ResultList
									href={data.event && data.event.event_url}
									key={item._id}
								>
									<ResultList.Image src={item.member.photo} small />
									<ResultList.Content>
										<ResultList.Title>

												{data.member ? data.member.member_name : ''} is
												going to ${data.event ? data.event.event_name : ''}

										</ResultList.Title>
										<ResultList.Description>

													{data.group ? data.group.group_city : ''}

													{data.group
														&& (data.group.group_topics || [])
															.slice(0, 4)
															.map(tag => (

																	{tag.topic_name}

															))}

										</ResultList.Description>
									</ResultList.Content>
								</ResultList>
							))}
						</ReactiveList.ResultListWrapper>
					)}
				/>

	</ReactiveBase>
);

ReactDOM.render(, document.getElementById('root'));
<|endoftext|>