<commit_before>const moment = require('moment')
const { client } = require('nightwatch-cucumber')
const { defineSupportCode } = require('cucumber')
const { get, set } = require('lodash')

defineSupportCode(({ Given, Then, When }) => {
  const CompanyList = client.page.CompanyList()

  When(/^I click on the first company collection link$/, async function () {
    await CompanyList
      .section.firstCompanyInList
      .waitForElementVisible('@header')
      .click('@header')
  })

  When(/^I filter the companies list by company/, async function () {
    await CompanyList.section.filters
      .waitForElementPresent('@company')
      .setValue('@company', this.state.company.uniqueSearchTerm)
      .sendKeys('@company', [ client.Keys.ENTER ])
      .wait() // wait for xhr
  })

  When(/^I filter the companies list by sector$/, async function () {
    await CompanyList.section.filters
      .waitForElementPresent('@sector')
      .clickMultipleChoiceOption('sector', this.state.company.sector)
      .wait() // wait for xhr
  })

  When(/^I filter the companies list by country$/, async function () {
    await CompanyList.section.filters
      .waitForElementPresent('@country')
      .clickMultipleChoiceOption('country', this.state.company.country)
      .wait() // wait for xhr
  })

  When(/^I filter the companies list by UK region/, async function () {
    await CompanyList.section.filters
      .waitForElementPresent('@ukRegion')
      .clickMultipleChoiceOption('uk_region', this.state.company.ukRegion)
      .wait() // wait for xhr
  })

  When(/^the companies are sorted by (Company name: A-Z|Recently updated)$/, async function (sortOption) {
    await CompanyList
      .section.collectionHeader
      .waitForElementVisible('@sortBy')
      .clickListOption('sortby', sortOption)
      .wait() // wait for xhr

    await CompanyList
      .section.firstCompanyInList
      .waitForElementPresent('@header')
      .getText('@header', (result) => {
        set(this.state, 'collection.firstItem.field', result.value)
      })
  })

  When(/^the companies are sorted by (Company name: Z-A|Least recently updated)$/, async function (sortOption) {
    await CompanyList
      .section.collectionHeader
      .waitForElementVisible('@sortBy')
      .clickListOption('sortby', sortOption)
      .wait() // wait for xhr

    await CompanyList
      .section.firstCompanyInList
      .waitForElementPresent('@header')
      .getText('@header', (result) => {
        set(this.state, 'collection.lastItem.field', result.value)
      })
  })

  Then(/^the companies should be filtered by company name/, async function () {
    const expected = get(this.state, `company.heading`)

    await CompanyList
      .section.firstCompanyInList
      .waitForElementVisible('@header')
      .assert.containsText('@header', expected)
  })

  Then(/^the companies should be filtered by company sector$/, async function () {
    const expected = get(this.state, `company.sector`)

    await CompanyList
      .section.firstCompanyInList
      .waitForElementVisible('@companySector')
      .assert.containsText('@companySector', expected)
  })

  Then(/^the companies should be filtered to show badge company country$/, async function () {
    const expectedBadgeText = get(this.state, 'company.country')

    await CompanyList
      .section.firstCompanyInList
      .waitForElementVisible('@countryBadge')
      .assert.containsText('@countryBadge', expectedBadgeText)
  })

  Then(/^the companies should be filtered to show badge company UK region/, async function () {
    const expectedBadgeText = get(this.state, 'company.ukRegion')

    await CompanyList
      .section.firstCompanyInList
      .waitForElementVisible('@ukRegionBadge')
      .assert.containsText('@ukRegionBadge', expectedBadgeText)
  })

  // TODO potentially abstract this out to collections
  Then(/^the companies should be sorted by (Least recently|Recently) updated$/, async function (sortType) {
    const updateValues = {
      firstItem: null,
      secondItem: null,
    }
    const formatDateString = (string) => {
      return moment(string, 'DD MMM YYYY, h:mma')
    }

    await CompanyList
      .section.firstCompanyInList
      .waitForElementPresent('@header')
      .getText('@updated', (text) => {
        set(updateValues, 'firstItem', formatDateString(text.value))
      })

    await CompanyList
      .section.secondCompanyInList
      .waitForElementPresent('@header')
      .getText('@updated', (text) => {
        set(updateValues, 'secondItem', formatDateString(text.value))
      })

    if (sortType === 'Recently') {
      client.expect(updateValues.firstItem.isAfter(updateValues.secondItem)).to.be.true
    }

    if (sortType === 'Least recently') {
      client.expect(updateValues.firstItem.isBefore(updateValues.secondItem)).to.be.true
    }
  })

  Then(/^the companies should have been correctly sorted for text fields$/, async function () {
    const firstItemField = get(this.state, 'collection.firstItem.field')
    const lastItemField = get(this.state, 'collection.lastItem.field')

    return client.expect(firstItemField < lastItemField).to.be.true
  })
})
<commit_msg>fix error where sometimes the results are equal<commit_after>const moment = require('moment')
const { client } = require('nightwatch-cucumber')
const { defineSupportCode } = require('cucumber')
const { get, set } = require('lodash')

defineSupportCode(({ Given, Then, When }) => {
  const CompanyList = client.page.CompanyList()

  When(/^I click on the first company collection link$/, async function () {
    await CompanyList
      .section.firstCompanyInList
      .waitForElementVisible('@header')
      .click('@header')
  })

  When(/^I filter the companies list by company/, async function () {
    await CompanyList.section.filters
      .waitForElementPresent('@company')
      .setValue('@company', this.state.company.uniqueSearchTerm)
      .sendKeys('@company', [ client.Keys.ENTER ])
      .wait() // wait for xhr
  })

  When(/^I filter the companies list by sector$/, async function () {
    await CompanyList.section.filters
      .waitForElementPresent('@sector')
      .clickMultipleChoiceOption('sector', this.state.company.sector)
      .wait() // wait for xhr
  })

  When(/^I filter the companies list by country$/, async function () {
    await CompanyList.section.filters
      .waitForElementPresent('@country')
      .clickMultipleChoiceOption('country', this.state.company.country)
      .wait() // wait for xhr
  })

  When(/^I filter the companies list by UK region/, async function () {
    await CompanyList.section.filters
      .waitForElementPresent('@ukRegion')
      .clickMultipleChoiceOption('uk_region', this.state.company.ukRegion)
      .wait() // wait for xhr
  })

  When(/^the companies are sorted by (Company name: A-Z|Recently updated)$/, async function (sortOption) {
    await CompanyList
      .section.collectionHeader
      .waitForElementVisible('@sortBy')
      .clickListOption('sortby', sortOption)
      .wait() // wait for xhr

    await CompanyList
      .section.firstCompanyInList
      .waitForElementPresent('@header')
      .getText('@header', (result) => {
        set(this.state, 'collection.firstItem.field', result.value)
      })
  })

  When(/^the companies are sorted by (Company name: Z-A|Least recently updated)$/, async function (sortOption) {
    await CompanyList
      .section.collectionHeader
      .waitForElementVisible('@sortBy')
      .clickListOption('sortby', sortOption)
      .wait() // wait for xhr

    await CompanyList
      .section.firstCompanyInList
      .waitForElementPresent('@header')
      .getText('@header', (result) => {
        set(this.state, 'collection.lastItem.field', result.value)
      })
  })

  Then(/^the companies should be filtered by company name/, async function () {
    const expected = get(this.state, `company.heading`)

    await CompanyList
      .section.firstCompanyInList
      .waitForElementVisible('@header')
      .assert.containsText('@header', expected)
  })

  Then(/^the companies should be filtered by company sector$/, async function () {
    const expected = get(this.state, `company.sector`)

    await CompanyList
      .section.firstCompanyInList
      .waitForElementVisible('@companySector')
      .assert.containsText('@companySector', expected)
  })

  Then(/^the companies should be filtered to show badge company country$/, async function () {
    const expectedBadgeText = get(this.state, 'company.country')

    await CompanyList
      .section.firstCompanyInList
      .waitForElementVisible('@countryBadge')
      .assert.containsText('@countryBadge', expectedBadgeText)
  })

  Then(/^the companies should be filtered to show badge company UK region/, async function () {
    const expectedBadgeText = get(this.state, 'company.ukRegion')

    await CompanyList
      .section.firstCompanyInList
      .waitForElementVisible('@ukRegionBadge')
      .assert.containsText('@ukRegionBadge', expectedBadgeText)
  })

  // TODO potentially abstract this out to collections
  Then(/^the companies should be sorted by (Least recently|Recently) updated$/, async function (sortType) {
    const updateValues = {
      firstItem: null,
      secondItem: null,
    }
    const formatDateString = (string) => {
      return moment(string, 'DD MMM YYYY, h:mma')
    }

    await CompanyList
      .section.firstCompanyInList
      .waitForElementPresent('@header')
      .getText('@updated', (text) => {
        set(updateValues, 'firstItem', formatDateString(text.value))
      })

    await CompanyList
      .section.secondCompanyInList
      .waitForElementPresent('@header')
      .getText('@updated', (text) => {
        set(updateValues, 'secondItem', formatDateString(text.value))
      })

    if (sortType === 'Recently') {
      client.expect(updateValues.firstItem.isSameOrAfter(updateValues.secondItem)).to.be.true
    }

    if (sortType === 'Least recently') {
      client.expect(updateValues.firstItem.isSameOrBefore(updateValues.secondItem)).to.be.true
    }
  })

  Then(/^the companies should have been correctly sorted for text fields$/, async function () {
    const firstItemField = get(this.state, 'collection.firstItem.field')
    const lastItemField = get(this.state, 'collection.lastItem.field')

    return client.expect(firstItemField < lastItemField).to.be.true
  })
})
<|endoftext|>


<commit_before>// Unique place to configure the browsers which are used in the different CI jobs in Sauce Labs (SL) and BrowserStack (BS).
// If the target is set to null, then the browser is not run anywhere during CI.
// If a category becomes empty (e.g. BS and required), then the corresponding job must be commented out in Travis configuration.
var CIconfiguration = {
  'Chrome':       { unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
  'Firefox':      { unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
  // FirefoxBeta should be required:true
  // https://github.com/angular/angular/issues/7560
  'FirefoxBeta':  { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: false}},
  'ChromeDev':    { unitTest: {target: null, required: true}, e2e: {target: null, required: true}},
  'FirefoxDev':   { unitTest: {target: null, required: true}, e2e: {target: null, required: true}},
  'IE9':          { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  'IE10':         { unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
  'IE11':         { unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
  'Edge':         { unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
  'Android4.1':   { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  'Android4.2':   { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  'Android4.3':   { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  'Android4.4':   { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  'Android5':     { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  'Safari7':      { unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
  'Safari8':      { unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
  'Safari9':      { unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
  'iOS7':         { unitTest: {target: 'BS', required: true}, e2e: {target: null, required: true}},
  'iOS8':         { unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
  // TODO(mlaval): iOS9 deactivated as not reliable, reactivate after https://github.com/angular/angular/issues/5408
  'iOS9':         { unitTest: {target: null, required: false}, e2e: {target: null, required: true}},
  'WindowsPhone': { unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}}
};

var customLaunchers = {
  'DartiumWithWebPlatform': {
    base: 'Dartium',
    flags: ['--enable-experimental-web-platform-features'] },
  'ChromeNoSandbox': {
    base: 'Chrome',
    flags: ['--no-sandbox'] },
  'SL_CHROME': {
    base: 'SauceLabs',
    browserName: 'chrome',
    version: '50'
  },
  'SL_CHROMEBETA': {
    base: 'SauceLabs',
    browserName: 'chrome',
    version: 'beta'
  },
  'SL_CHROMEDEV': {
    base: 'SauceLabs',
    browserName: 'chrome',
    version: 'dev'
  },
  'SL_FIREFOX': {
    base: 'SauceLabs',
    browserName: 'firefox',
    version: '45'
  },
  'SL_FIREFOXBETA': {
    base: 'SauceLabs',
    browserName: 'firefox',
    version: 'beta'
  },
  'SL_FIREFOXDEV': {
    base: 'SauceLabs',
    browserName: 'firefox',
    version: 'dev'
  },
  'SL_SAFARI7': {
    base: 'SauceLabs',
    browserName: 'safari',
    platform: 'OS X 10.9',
    version: '7'
  },
  'SL_SAFARI8': {
    base: 'SauceLabs',
    browserName: 'safari',
    platform: 'OS X 10.10',
    version: '8'
  },
  'SL_SAFARI9': {
    base: 'SauceLabs',
    browserName: 'safari',
    platform: 'OS X 10.11',
    version: '9.0'
  },
  'SL_IOS7': {
    base: 'SauceLabs',
    browserName: 'iphone',
    platform: 'OS X 10.10',
    version: '7.1'
  },
  'SL_IOS8': {
    base: 'SauceLabs',
    browserName: 'iphone',
    platform: 'OS X 10.10',
    version: '8.4'
  },
  'SL_IOS9': {
    base: 'SauceLabs',
    browserName: 'iphone',
    platform: 'OS X 10.10',
    version: '9.1'
  },
  'SL_IE9': {
    base: 'SauceLabs',
    browserName: 'internet explorer',
    platform: 'Windows 2008',
    version: '9'
  },
  'SL_IE10': {
    base: 'SauceLabs',
    browserName: 'internet explorer',
    platform: 'Windows 2012',
    version: '10'
  },
  'SL_IE11': {
    base: 'SauceLabs',
    browserName: 'internet explorer',
    platform: 'Windows 8.1',
    version: '11'
  },
  'SL_EDGE': {
    base: 'SauceLabs',
    browserName: 'microsoftedge',
    platform: 'Windows 10',
    version: '20.10240'
  },
  'SL_ANDROID4.1': {
    base: 'SauceLabs',
    browserName: 'android',
    platform: 'Linux',
    version: '4.1'
  },
  'SL_ANDROID4.2': {
    base: 'SauceLabs',
    browserName: 'android',
    platform: 'Linux',
    version: '4.2'
  },
  'SL_ANDROID4.3': {
    base: 'SauceLabs',
    browserName: 'android',
    platform: 'Linux',
    version: '4.3'
  },
  'SL_ANDROID4.4': {
    base: 'SauceLabs',
    browserName: 'android',
    platform: 'Linux',
    version: '4.4'
  },
  'SL_ANDROID5': {
    base: 'SauceLabs',
    browserName: 'android',
    platform: 'Linux',
    version: '5.1'
  },

  'BS_CHROME': {
    base: 'BrowserStack',
    browser: 'chrome',
    os: 'OS X',
    os_version: 'Yosemite'
  },
  'BS_FIREFOX': {
    base: 'BrowserStack',
    browser: 'firefox',
    os: 'Windows',
    os_version: '10'
  },
  'BS_SAFARI7': {
    base: 'BrowserStack',
    browser: 'safari',
    os: 'OS X',
    os_version: 'Mavericks'
  },
  'BS_SAFARI8': {
    base: 'BrowserStack',
    browser: 'safari',
    os: 'OS X',
    os_version: 'Yosemite'
  },
  'BS_SAFARI9': {
    base: 'BrowserStack',
    browser: 'safari',
    os: 'OS X',
    os_version: 'El Capitan'
  },
  'BS_IOS7': {
    base: 'BrowserStack',
    device: 'iPhone 5S',
    os: 'ios',
    os_version: '7.0'
  },
  'BS_IOS8': {
    base: 'BrowserStack',
    device: 'iPhone 6',
    os: 'ios',
    os_version: '8.3'
  },
  'BS_IOS9': {
    base: 'BrowserStack',
    device: 'iPhone 6S',
    os: 'ios',
    os_version: '9.0'
  },
  'BS_IE9': {
    base: 'BrowserStack',
    browser: 'ie',
    browser_version: '9.0',
    os: 'Windows',
    os_version: '7'
  },
  'BS_IE10': {
    base: 'BrowserStack',
    browser: 'ie',
    browser_version: '10.0',
    os: 'Windows',
    os_version: '8'
  },
  'BS_IE11': {
    base: 'BrowserStack',
    browser: 'ie',
    browser_version: '11.0',
    os: 'Windows',
    os_version: '10'
  },
  'BS_EDGE': {
    base: 'BrowserStack',
    browser: 'edge',
    os: 'Windows',
    os_version: '10'
  },
  'BS_WINDOWSPHONE' : {
    base: 'BrowserStack',
    device: 'Nokia Lumia 930',
    os: 'winphone',
    os_version: '8.1'
  },
  'BS_ANDROID5': {
    base: 'BrowserStack',
    device: 'Google Nexus 5',
    os: 'android',
    os_version: '5.0'
  },
  'BS_ANDROID4.4': {
    base: 'BrowserStack',
    device: 'HTC One M8',
    os: 'android',
    os_version: '4.4'
  },
  'BS_ANDROID4.3': {
    base: 'BrowserStack',
    device: 'Samsung Galaxy S4',
    os: 'android',
    os_version: '4.3'
  },
  'BS_ANDROID4.2': {
    base: 'BrowserStack',
    device: 'Google Nexus 4',
    os: 'android',
    os_version: '4.2'
  },
  'BS_ANDROID4.1': {
    base: 'BrowserStack',
    device: 'Google Nexus 7',
    os: 'android',
    os_version: '4.1'
  }
};

var sauceAliases = {
  'ALL': Object.keys(customLaunchers).filter(function(item) {return customLaunchers[item].base == 'SauceLabs';}),
  'DESKTOP': ['SL_CHROME', 'SL_FIREFOX', 'SL_IE9', 'SL_IE10', 'SL_IE11', 'SL_EDGE', 'SL_SAFARI7', 'SL_SAFARI8', 'SL_SAFARI9'],
  'MOBILE': ['SL_ANDROID4.1', 'SL_ANDROID4.2', 'SL_ANDROID4.3', 'SL_ANDROID4.4', 'SL_ANDROID5', 'SL_IOS7', 'SL_IOS8', 'SL_IOS9'],
  'ANDROID': ['SL_ANDROID4.1', 'SL_ANDROID4.2', 'SL_ANDROID4.3', 'SL_ANDROID4.4', 'SL_ANDROID5'],
  'IE': ['SL_IE9', 'SL_IE10', 'SL_IE11'],
  'IOS': ['SL_IOS7', 'SL_IOS8', 'SL_IOS9'],
  'SAFARI': ['SL_SAFARI7', 'SL_SAFARI8', 'SL_SAFARI9'],
  'BETA': ['SL_CHROMEBETA', 'SL_FIREFOXBETA'],
  'DEV': ['SL_CHROMEDEV', 'SL_FIREFOXDEV'],
  'CI_REQUIRED': buildConfiguration('unitTest', 'SL', true),
  'CI_OPTIONAL': buildConfiguration('unitTest', 'SL', false)
};

var browserstackAliases = {
  'ALL': Object.keys(customLaunchers).filter(function(item) {return customLaunchers[item].base == 'BrowserStack';}),
  'DESKTOP': ['BS_CHROME', 'BS_FIREFOX', 'BS_IE9', 'BS_IE10', 'BS_IE11', 'BS_EDGE', 'BS_SAFARI7', 'BS_SAFARI8', 'BS_SAFARI9'],
  'MOBILE': ['BS_ANDROID4.3', 'BS_ANDROID4.4', 'BS_IOS7', 'BS_IOS8', 'BS_IOS9', 'BS_WINDOWSPHONE'],
  'ANDROID': ['BS_ANDROID4.3', 'BS_ANDROID4.4'],
  'IE': ['BS_IE9', 'BS_IE10', 'BS_IE11'],
  'IOS': ['BS_IOS7', 'BS_IOS8', 'BS_IOS9'],
  'SAFARI': ['BS_SAFARI7', 'BS_SAFARI8', 'BS_SAFARI9'],
  'CI_REQUIRED': buildConfiguration('unitTest', 'BS', true),
  'CI_OPTIONAL': buildConfiguration('unitTest', 'BS', false)
};

module.exports = {
  customLaunchers: customLaunchers,
  sauceAliases: sauceAliases,
  browserstackAliases: browserstackAliases
};

function buildConfiguration(type, target, required) {
  return Object.keys(CIconfiguration)
    .filter((item) => {
      var conf = CIconfiguration[item][type];
      return conf.required === required && conf.target === target;
    })
    .map((item) => {
      return target + '_' + item.toUpperCase();
    });
}
<commit_msg>ci: temporarily disable Edge because of SauceLabs issues<commit_after>// Unique place to configure the browsers which are used in the different CI jobs in Sauce Labs (SL) and BrowserStack (BS).
// If the target is set to null, then the browser is not run anywhere during CI.
// If a category becomes empty (e.g. BS and required), then the corresponding job must be commented out in Travis configuration.
var CIconfiguration = {
  'Chrome':       { unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
  'Firefox':      { unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
  // FirefoxBeta should be required:true
  // https://github.com/angular/angular/issues/7560
  'FirefoxBeta':  { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: false}},
  'ChromeDev':    { unitTest: {target: null, required: true}, e2e: {target: null, required: true}},
  'FirefoxDev':   { unitTest: {target: null, required: true}, e2e: {target: null, required: true}},
  'IE9':          { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  'IE10':         { unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
  'IE11':         { unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
  'Edge':         { unitTest: {target: null, required: true}, e2e: {target: null, required: false}},
  'Android4.1':   { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  'Android4.2':   { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  'Android4.3':   { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  'Android4.4':   { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  'Android5':     { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},
  'Safari7':      { unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
  'Safari8':      { unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
  'Safari9':      { unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
  'iOS7':         { unitTest: {target: 'BS', required: true}, e2e: {target: null, required: true}},
  'iOS8':         { unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}},
  // TODO(mlaval): iOS9 deactivated as not reliable, reactivate after https://github.com/angular/angular/issues/5408
  'iOS9':         { unitTest: {target: null, required: false}, e2e: {target: null, required: true}},
  'WindowsPhone': { unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}}
};

var customLaunchers = {
  'DartiumWithWebPlatform': {
    base: 'Dartium',
    flags: ['--enable-experimental-web-platform-features'] },
  'ChromeNoSandbox': {
    base: 'Chrome',
    flags: ['--no-sandbox'] },
  'SL_CHROME': {
    base: 'SauceLabs',
    browserName: 'chrome',
    version: '50'
  },
  'SL_CHROMEBETA': {
    base: 'SauceLabs',
    browserName: 'chrome',
    version: 'beta'
  },
  'SL_CHROMEDEV': {
    base: 'SauceLabs',
    browserName: 'chrome',
    version: 'dev'
  },
  'SL_FIREFOX': {
    base: 'SauceLabs',
    browserName: 'firefox',
    version: '45'
  },
  'SL_FIREFOXBETA': {
    base: 'SauceLabs',
    browserName: 'firefox',
    version: 'beta'
  },
  'SL_FIREFOXDEV': {
    base: 'SauceLabs',
    browserName: 'firefox',
    version: 'dev'
  },
  'SL_SAFARI7': {
    base: 'SauceLabs',
    browserName: 'safari',
    platform: 'OS X 10.9',
    version: '7'
  },
  'SL_SAFARI8': {
    base: 'SauceLabs',
    browserName: 'safari',
    platform: 'OS X 10.10',
    version: '8'
  },
  'SL_SAFARI9': {
    base: 'SauceLabs',
    browserName: 'safari',
    platform: 'OS X 10.11',
    version: '9.0'
  },
  'SL_IOS7': {
    base: 'SauceLabs',
    browserName: 'iphone',
    platform: 'OS X 10.10',
    version: '7.1'
  },
  'SL_IOS8': {
    base: 'SauceLabs',
    browserName: 'iphone',
    platform: 'OS X 10.10',
    version: '8.4'
  },
  'SL_IOS9': {
    base: 'SauceLabs',
    browserName: 'iphone',
    platform: 'OS X 10.10',
    version: '9.1'
  },
  'SL_IE9': {
    base: 'SauceLabs',
    browserName: 'internet explorer',
    platform: 'Windows 2008',
    version: '9'
  },
  'SL_IE10': {
    base: 'SauceLabs',
    browserName: 'internet explorer',
    platform: 'Windows 2012',
    version: '10'
  },
  'SL_IE11': {
    base: 'SauceLabs',
    browserName: 'internet explorer',
    platform: 'Windows 8.1',
    version: '11'
  },
  'SL_EDGE': {
    base: 'SauceLabs',
    browserName: 'microsoftedge',
    platform: 'Windows 10',
    version: '20.10240'
  },
  'SL_ANDROID4.1': {
    base: 'SauceLabs',
    browserName: 'android',
    platform: 'Linux',
    version: '4.1'
  },
  'SL_ANDROID4.2': {
    base: 'SauceLabs',
    browserName: 'android',
    platform: 'Linux',
    version: '4.2'
  },
  'SL_ANDROID4.3': {
    base: 'SauceLabs',
    browserName: 'android',
    platform: 'Linux',
    version: '4.3'
  },
  'SL_ANDROID4.4': {
    base: 'SauceLabs',
    browserName: 'android',
    platform: 'Linux',
    version: '4.4'
  },
  'SL_ANDROID5': {
    base: 'SauceLabs',
    browserName: 'android',
    platform: 'Linux',
    version: '5.1'
  },

  'BS_CHROME': {
    base: 'BrowserStack',
    browser: 'chrome',
    os: 'OS X',
    os_version: 'Yosemite'
  },
  'BS_FIREFOX': {
    base: 'BrowserStack',
    browser: 'firefox',
    os: 'Windows',
    os_version: '10'
  },
  'BS_SAFARI7': {
    base: 'BrowserStack',
    browser: 'safari',
    os: 'OS X',
    os_version: 'Mavericks'
  },
  'BS_SAFARI8': {
    base: 'BrowserStack',
    browser: 'safari',
    os: 'OS X',
    os_version: 'Yosemite'
  },
  'BS_SAFARI9': {
    base: 'BrowserStack',
    browser: 'safari',
    os: 'OS X',
    os_version: 'El Capitan'
  },
  'BS_IOS7': {
    base: 'BrowserStack',
    device: 'iPhone 5S',
    os: 'ios',
    os_version: '7.0'
  },
  'BS_IOS8': {
    base: 'BrowserStack',
    device: 'iPhone 6',
    os: 'ios',
    os_version: '8.3'
  },
  'BS_IOS9': {
    base: 'BrowserStack',
    device: 'iPhone 6S',
    os: 'ios',
    os_version: '9.0'
  },
  'BS_IE9': {
    base: 'BrowserStack',
    browser: 'ie',
    browser_version: '9.0',
    os: 'Windows',
    os_version: '7'
  },
  'BS_IE10': {
    base: 'BrowserStack',
    browser: 'ie',
    browser_version: '10.0',
    os: 'Windows',
    os_version: '8'
  },
  'BS_IE11': {
    base: 'BrowserStack',
    browser: 'ie',
    browser_version: '11.0',
    os: 'Windows',
    os_version: '10'
  },
  'BS_EDGE': {
    base: 'BrowserStack',
    browser: 'edge',
    os: 'Windows',
    os_version: '10'
  },
  'BS_WINDOWSPHONE' : {
    base: 'BrowserStack',
    device: 'Nokia Lumia 930',
    os: 'winphone',
    os_version: '8.1'
  },
  'BS_ANDROID5': {
    base: 'BrowserStack',
    device: 'Google Nexus 5',
    os: 'android',
    os_version: '5.0'
  },
  'BS_ANDROID4.4': {
    base: 'BrowserStack',
    device: 'HTC One M8',
    os: 'android',
    os_version: '4.4'
  },
  'BS_ANDROID4.3': {
    base: 'BrowserStack',
    device: 'Samsung Galaxy S4',
    os: 'android',
    os_version: '4.3'
  },
  'BS_ANDROID4.2': {
    base: 'BrowserStack',
    device: 'Google Nexus 4',
    os: 'android',
    os_version: '4.2'
  },
  'BS_ANDROID4.1': {
    base: 'BrowserStack',
    device: 'Google Nexus 7',
    os: 'android',
    os_version: '4.1'
  }
};

var sauceAliases = {
  'ALL': Object.keys(customLaunchers).filter(function(item) {return customLaunchers[item].base == 'SauceLabs';}),
  'DESKTOP': ['SL_CHROME', 'SL_FIREFOX', 'SL_IE9', 'SL_IE10', 'SL_IE11', 'SL_EDGE', 'SL_SAFARI7', 'SL_SAFARI8', 'SL_SAFARI9'],
  'MOBILE': ['SL_ANDROID4.1', 'SL_ANDROID4.2', 'SL_ANDROID4.3', 'SL_ANDROID4.4', 'SL_ANDROID5', 'SL_IOS7', 'SL_IOS8', 'SL_IOS9'],
  'ANDROID': ['SL_ANDROID4.1', 'SL_ANDROID4.2', 'SL_ANDROID4.3', 'SL_ANDROID4.4', 'SL_ANDROID5'],
  'IE': ['SL_IE9', 'SL_IE10', 'SL_IE11'],
  'IOS': ['SL_IOS7', 'SL_IOS8', 'SL_IOS9'],
  'SAFARI': ['SL_SAFARI7', 'SL_SAFARI8', 'SL_SAFARI9'],
  'BETA': ['SL_CHROMEBETA', 'SL_FIREFOXBETA'],
  'DEV': ['SL_CHROMEDEV', 'SL_FIREFOXDEV'],
  'CI_REQUIRED': buildConfiguration('unitTest', 'SL', true),
  'CI_OPTIONAL': buildConfiguration('unitTest', 'SL', false)
};

var browserstackAliases = {
  'ALL': Object.keys(customLaunchers).filter(function(item) {return customLaunchers[item].base == 'BrowserStack';}),
  'DESKTOP': ['BS_CHROME', 'BS_FIREFOX', 'BS_IE9', 'BS_IE10', 'BS_IE11', 'BS_EDGE', 'BS_SAFARI7', 'BS_SAFARI8', 'BS_SAFARI9'],
  'MOBILE': ['BS_ANDROID4.3', 'BS_ANDROID4.4', 'BS_IOS7', 'BS_IOS8', 'BS_IOS9', 'BS_WINDOWSPHONE'],
  'ANDROID': ['BS_ANDROID4.3', 'BS_ANDROID4.4'],
  'IE': ['BS_IE9', 'BS_IE10', 'BS_IE11'],
  'IOS': ['BS_IOS7', 'BS_IOS8', 'BS_IOS9'],
  'SAFARI': ['BS_SAFARI7', 'BS_SAFARI8', 'BS_SAFARI9'],
  'CI_REQUIRED': buildConfiguration('unitTest', 'BS', true),
  'CI_OPTIONAL': buildConfiguration('unitTest', 'BS', false)
};

module.exports = {
  customLaunchers: customLaunchers,
  sauceAliases: sauceAliases,
  browserstackAliases: browserstackAliases
};

function buildConfiguration(type, target, required) {
  return Object.keys(CIconfiguration)
    .filter((item) => {
      var conf = CIconfiguration[item][type];
      return conf.required === required && conf.target === target;
    })
    .map((item) => {
      return target + '_' + item.toUpperCase();
    });
}
<|endoftext|>


<commit_before>import invariant from 'invariant';
import React, { Component, PropTypes } from 'react';
import { connect, Provider } from 'react-redux';

export function isolateDispatch(isolateState: Function, isolateAction: Function) {
	invariant(typeof(isolateState) !== 'function',
		'The first argument of isolateDispatch must be a function that selects an isolated subtree'
	);
	invariant(typeof(isolateAction) !== 'function',
		'The second argument of isolateDispatch must be a function that creates a wrapping action for the isolation reducer'
	);

	return (dispatch: Function, ownProps: ?Object) => {
		invariant(typeof(dispatch) !== 'function',
			'dispatch must be a function. Are you trying to execute a thunk without redux-thunk?'
		);
		const isolatedDispatch = action => {
			if(typeof(action) === 'function') {
				return dispatch((realDispatch, realGetState, ...extra) => {
					return action(isolatedDispatch, () => isolateState(realGetState(), ownProps), ...extra);
				});
			} else {
				return dispatch(isolateAction(action, ownProps));
			}
		};
		return isolatedDispatch;
	};
}

export function isolate(isolateState: Function, isolateAction: Function) {
	invariant(typeof(isolateState) !== 'function',
		'The first argument of isolate must be a function that selects an isolated subtree'
	);
	invariant(typeof(isolateAction) !== 'function',
		'The second argument of isolate must be a function that creates a wrapping action for the isolation reducer'
	);

	const createDispatch = isolateDispatch(isolateState, isolateAction);
	return ComponentToIsolate => {
		class IsolatedComponent extends Component {
			static propTypes = {
				state: PropTypes.object.isRequired,
				dispatch: PropTypes.func.isRequired
			};

			constructor(props) {
				super(props);

				const { state, dispatch, ...ownProps } = props;

				this.listeners = [];
				this.lastState = state;
				this.currentIsolatedState = isolateState(state, ownProps);
				this.currentisolatedDispatch = createDispatch(dispatch, ownProps);

				const getIsolatedState = () => this.currentIsolatedState;
				const isolatedDispatch = (...args) => this.currentisolatedDispatch(...args);

				const localSubscribe = (listener: Function): Function => {
					let isSubscribed = true;
					const listeners = this.listeners;
					listeners.push(listener);
					return function unsubscribe() {
						if (!isSubscribed) {
							return;
						}
						isSubscribed = false;
						const index = listeners.indexOf(listener);
						listeners.splice(index, 1);
					};
				};

				// Our store proxy - matches a redux store minus
				// replaceReducers, which we will not need anyway
				this.proxyStore = {
					getState: getIsolatedState,
					dispatch: isolatedDispatch,
					subscribe: localSubscribe
				};
			}

			componentWillReceiveProps(props) {
				if(props.state !== this.lastState) {
					const { state, dispatch, ...ownProps } = props;
					this.lastState = props.state;
					this.currentIsolatedState = isolateState(state, ownProps);
					this.currentisolatedDispatch = createDispatch(dispatch, ownProps);
					this.updateListeners = true;
				}
			}

			componentDidUpdate() {
				if(this.updateListeners) {
					this.listeners.map(l => l());
					this.updateListeners = false;
				}
			}

			render() {
				const { state: _state, dispatch: _dispatch, ...ownProps } = this.props;
				return (
					<Provider store={this.proxyStore}>
						<ComponentToIsolate {...ownProps} />
					</Provider>
				);
			}
		}

		const displayName = ComponentToIsolate.displayName || ComponentToIsolate.name || 'Component';
		IsolatedComponent.displayName = `IsolatedComponent(${displayName})`;
		return connect(state => ({ state }))(IsolatedComponent);
	};
}
<commit_msg>Fix inverted invariant logic and some invariant messages<commit_after>import invariant from 'invariant';
import React, { Component, PropTypes } from 'react';
import { connect, Provider } from 'react-redux';

export function isolateDispatch(isolateState: Function, isolateAction: Function) {
	invariant(typeof(isolateState) === 'function',
		'The first argument of isolateDispatch must be a function that selects an isolated subtree'
	);
	invariant(typeof(isolateAction) === 'function',
		'The second argument of isolateDispatch must be a function that creates a wrapping action for the isolation reducer'
	);

	return (dispatch: Function, ownProps: ?Object) => {
		invariant(typeof(dispatch) === 'function',
			'the isolated dispatch creator must be called with the dispatch function to create an isolated dispatch function'
		);
		const isolatedDispatch = action => {
			if(typeof(action) === 'function') {
				return dispatch((realDispatch, realGetState, ...extra) => {
					invariant(typeof(realDispatch) === 'function' && typeof(realGetState) === 'function',
						'dispatch and getState must be functions. Are you trying to execute a thunk without redux-thunk?'
					);
					return action(isolatedDispatch, () => isolateState(realGetState(), ownProps), ...extra);
				});
			} else {
				return dispatch(isolateAction(action, ownProps));
			}
		};
		return isolatedDispatch;
	};
}

export function isolate(isolateState: Function, isolateAction: Function) {
	invariant(typeof(isolateState) === 'function',
		'The first argument of isolate must be a function that selects an isolated subtree'
	);
	invariant(typeof(isolateAction) === 'function',
		'The second argument of isolate must be a function that creates a wrapping action for the isolation reducer'
	);

	const createDispatch = isolateDispatch(isolateState, isolateAction);
	return ComponentToIsolate => {
		class IsolatedComponent extends Component {
			static propTypes = {
				state: PropTypes.object.isRequired,
				dispatch: PropTypes.func.isRequired
			};

			constructor(props) {
				super(props);

				const { state, dispatch, ...ownProps } = props;

				this.listeners = [];
				this.lastState = state;
				this.currentIsolatedState = isolateState(state, ownProps);
				this.currentisolatedDispatch = createDispatch(dispatch, ownProps);

				const getIsolatedState = () => this.currentIsolatedState;
				const isolatedDispatch = (...args) => this.currentisolatedDispatch(...args);

				const localSubscribe = (listener: Function): Function => {
					let isSubscribed = true;
					const listeners = this.listeners;
					listeners.push(listener);
					return function unsubscribe() {
						if (!isSubscribed) {
							return;
						}
						isSubscribed = false;
						const index = listeners.indexOf(listener);
						listeners.splice(index, 1);
					};
				};

				// Our store proxy - matches a redux store minus
				// replaceReducers, which we will not need anyway
				this.proxyStore = {
					getState: getIsolatedState,
					dispatch: isolatedDispatch,
					subscribe: localSubscribe
				};
			}

			componentWillReceiveProps(props) {
				if(props.state !== this.lastState) {
					const { state, dispatch, ...ownProps } = props;
					this.lastState = props.state;
					this.currentIsolatedState = isolateState(state, ownProps);
					this.currentisolatedDispatch = createDispatch(dispatch, ownProps);
					this.updateListeners = true;
				}
			}

			componentDidUpdate() {
				if(this.updateListeners) {
					this.listeners.map(l => l());
					this.updateListeners = false;
				}
			}

			render() {
				const { state: _state, dispatch: _dispatch, ...ownProps } = this.props;
				return (
					<Provider store={this.proxyStore}>
						<ComponentToIsolate {...ownProps} />
					</Provider>
				);
			}
		}

		const displayName = ComponentToIsolate.displayName || ComponentToIsolate.name || 'Component';
		IsolatedComponent.displayName = `IsolatedComponent(${displayName})`;
		return connect(state => ({ state }))(IsolatedComponent);
	};
}
<|endoftext|>


<commit_before>import {DOM} from 'aurelia-pal';

let hasSetImmediate = typeof setImmediate === 'function';

function makeRequestFlushFromMutationObserver(flush) {
  let toggle = 1;
  let observer = DOM.createMutationObserver(flush);
  let node = DOM.createTextNode('');
  observer.observe(node, {characterData: true});
  return function requestFlush() {
    toggle = -toggle;
    node.data = toggle;
  };
}

function makeRequestFlushFromTimer(flush) {
  return function requestFlush() {
    // We dispatch a timeout with a specified delay of 0 for engines that
    // can reliably accommodate that request. This will usually be snapped
    // to a 4 milisecond delay, but once we're flushing, there's no delay
    // between events.
    let timeoutHandle = setTimeout(handleFlushTimer, 0);
    // However, since this timer gets frequently dropped in Firefox
    // workers, we enlist an interval handle that will try to fire
    // an event 20 times per second until it succeeds.
    let intervalHandle = setInterval(handleFlushTimer, 50);
    function handleFlushTimer() {
      // Whichever timer succeeds will cancel both timers and request the
      // flush.
      clearTimeout(timeoutHandle);
      clearInterval(intervalHandle);
      flush();
    }
  };
}

function onError(error, task) {
  if ('onError' in task) {
    task.onError(error);
  } else if (hasSetImmediate) {
    setImmediate(() => { throw error; });
  } else {
    setTimeout(() => { throw error; }, 0);
  }
}

/**
* Something that is callable. Either a Function or a class with a call method.
*/
interface Callable {
  /**
  * Call it.
  */
  call(): void;
}

/**
* Implements an asynchronous task queue.
*/
export class TaskQueue {
  /**
  * Creates an instance of TaskQueue.
  */
  constructor() {
    this.microTaskQueue = [];
    this.microTaskQueueCapacity = 1024;
    this.taskQueue = [];

    this.requestFlushMicroTaskQueue = makeRequestFlushFromMutationObserver(() => this.flushMicroTaskQueue());
    this.requestFlushTaskQueue = makeRequestFlushFromTimer(() => this.flushTaskQueue());
  }

  /**
  * Queues a task on the micro task queue for ASAP execution.
  * @param task The task to queue up for ASAP execution.
  */
  queueMicroTask(task: Callable | Function): void {
    if (this.microTaskQueue.length < 1) {
      this.requestFlushMicroTaskQueue();
    }

    this.microTaskQueue.push(task);
  }

  /**
  * Queues a task on the macro task queue for turn-based execution.
  * @param task The task to queue up for turn-based execution.
  */
  queueTask(task: Callable | Function): void {
    if (this.taskQueue.length < 1) {
      this.requestFlushTaskQueue();
    }

    this.taskQueue.push(task);
  }

  /**
  * Immediately flushes the task queue.
  */
  flushTaskQueue(): void {
    let queue = this.taskQueue;
    let index = 0;
    let task;

    this.taskQueue = []; //recursive calls to queueTask should be scheduled after the next cycle

    try {
      while (index < queue.length) {
        task = queue[index];
        task.call();
        index++;
      }
    } catch (error) {
      onError(error, task);
    }
  }

  /**
  * Immediately flushes the micro task queue.
  */
  flushMicroTaskQueue(): void {
    let queue = this.microTaskQueue;
    let capacity = this.microTaskQueueCapacity;
    let index = 0;
    let task;

    try {
      while (index < queue.length) {
        task = queue[index];
        task.call();
        index++;

        // Prevent leaking memory for long chains of recursive calls to `queueMicroTask`.
        // If we call `queueMicroTask` within a MicroTask scheduled by `queueMicroTask`, the queue will
        // grow, but to avoid an O(n) walk for every MicroTask we execute, we don't
        // shift MicroTasks off the queue after they have been executed.
        // Instead, we periodically shift 1024 MicroTasks off the queue.
        if (index > capacity) {
          // Manually shift all values starting at the index back to the
          // beginning of the queue.
          for (let scan = 0, newLength = queue.length - index; scan < newLength; scan++) {
            queue[scan] = queue[scan + index];
          }

          queue.length -= index;
          index = 0;
        }
      }
    } catch (error) {
      onError(error, task);
    }

    queue.length = 0;
  }
}
<commit_msg>fix(index): enable running without mutation observers<commit_after>import {DOM, FEATURE} from 'aurelia-pal';

let hasSetImmediate = typeof setImmediate === 'function';

function makeRequestFlushFromMutationObserver(flush) {
  let toggle = 1;
  let observer = DOM.createMutationObserver(flush);
  let node = DOM.createTextNode('');
  observer.observe(node, {characterData: true});
  return function requestFlush() {
    toggle = -toggle;
    node.data = toggle;
  };
}

function makeRequestFlushFromTimer(flush) {
  return function requestFlush() {
    // We dispatch a timeout with a specified delay of 0 for engines that
    // can reliably accommodate that request. This will usually be snapped
    // to a 4 milisecond delay, but once we're flushing, there's no delay
    // between events.
    let timeoutHandle = setTimeout(handleFlushTimer, 0);
    // However, since this timer gets frequently dropped in Firefox
    // workers, we enlist an interval handle that will try to fire
    // an event 20 times per second until it succeeds.
    let intervalHandle = setInterval(handleFlushTimer, 50);
    function handleFlushTimer() {
      // Whichever timer succeeds will cancel both timers and request the
      // flush.
      clearTimeout(timeoutHandle);
      clearInterval(intervalHandle);
      flush();
    }
  };
}

function onError(error, task) {
  if ('onError' in task) {
    task.onError(error);
  } else if (hasSetImmediate) {
    setImmediate(() => { throw error; });
  } else {
    setTimeout(() => { throw error; }, 0);
  }
}

/**
* Something that is callable. Either a Function or a class with a call method.
*/
interface Callable {
  /**
  * Call it.
  */
  call(): void;
}

/**
* Implements an asynchronous task queue.
*/
export class TaskQueue {
  /**
  * Creates an instance of TaskQueue.
  */
  constructor() {
    this.microTaskQueue = [];
    this.microTaskQueueCapacity = 1024;
    this.taskQueue = [];

    if (FEATURE.mutationObserver) {
      this.requestFlushMicroTaskQueue = makeRequestFlushFromMutationObserver(() => this.flushMicroTaskQueue());
    } else {
      this.requestFlushMicroTaskQueue = makeRequestFlushFromTimer(() => this.flushMicroTaskQueue());
    }

    this.requestFlushTaskQueue = makeRequestFlushFromTimer(() => this.flushTaskQueue());
  }

  /**
  * Queues a task on the micro task queue for ASAP execution.
  * @param task The task to queue up for ASAP execution.
  */
  queueMicroTask(task: Callable | Function): void {
    if (this.microTaskQueue.length < 1) {
      this.requestFlushMicroTaskQueue();
    }

    this.microTaskQueue.push(task);
  }

  /**
  * Queues a task on the macro task queue for turn-based execution.
  * @param task The task to queue up for turn-based execution.
  */
  queueTask(task: Callable | Function): void {
    if (this.taskQueue.length < 1) {
      this.requestFlushTaskQueue();
    }

    this.taskQueue.push(task);
  }

  /**
  * Immediately flushes the task queue.
  */
  flushTaskQueue(): void {
    let queue = this.taskQueue;
    let index = 0;
    let task;

    this.taskQueue = []; //recursive calls to queueTask should be scheduled after the next cycle

    try {
      while (index < queue.length) {
        task = queue[index];
        task.call();
        index++;
      }
    } catch (error) {
      onError(error, task);
    }
  }

  /**
  * Immediately flushes the micro task queue.
  */
  flushMicroTaskQueue(): void {
    let queue = this.microTaskQueue;
    let capacity = this.microTaskQueueCapacity;
    let index = 0;
    let task;

    try {
      while (index < queue.length) {
        task = queue[index];
        task.call();
        index++;

        // Prevent leaking memory for long chains of recursive calls to `queueMicroTask`.
        // If we call `queueMicroTask` within a MicroTask scheduled by `queueMicroTask`, the queue will
        // grow, but to avoid an O(n) walk for every MicroTask we execute, we don't
        // shift MicroTasks off the queue after they have been executed.
        // Instead, we periodically shift 1024 MicroTasks off the queue.
        if (index > capacity) {
          // Manually shift all values starting at the index back to the
          // beginning of the queue.
          for (let scan = 0, newLength = queue.length - index; scan < newLength; scan++) {
            queue[scan] = queue[scan + index];
          }

          queue.length -= index;
          index = 0;
        }
      }
    } catch (error) {
      onError(error, task);
    }

    queue.length = 0;
  }
}
<|endoftext|>


<commit_before>let path = require('path');
let Mix = require('./Mix');

/**
 * We'll fetch some Webpack config plugins here for cleanliness.
 */
module.exports.plugins = {
    WebpackNotifierPlugin: require('webpack-notifier'),
    WebpackOnBuildPlugin: require('on-build-webpack'),
    ExtractTextPlugin: require('extract-text-webpack-plugin'),
    CopyWebpackPlugin: require('copy-webpack-plugin'),
    FriendlyErrorsWebpackPlugin: require('friendly-errors-webpack-plugin'),
    StatsWriterPlugin: require('webpack-stats-plugin').StatsWriterPlugin,
    WebpackMd5HashPlugin: require('webpack-md5-hash')
};

/**
 * Register the Webpack entry/output paths.
 *
 * @param {mixed}  entry
 * @param {string} output
 */
module.exports.js = (entry, output) => {
    entry = (Array.isArray(entry) ? entry : [entry]).map(file => {
        return new Mix.File(path.resolve(file)).parsePath();
    });

    output = new Mix.File(output).parsePath();

    if (output.isDir) {
        output = new Mix.File(
            path.posix.join(output.path, entry[0].file)
        ).parsePath();
    }

    Mix.js = (Mix.js || []).concat({ entry, output, vendor: false });

    return this;
};

/**
 * Register vendor libs that should be extracted.
 * This helps drastically with long-term caching.
 *
 * @param {array} libs
 */
module.exports.extract = (libs) => {
    Mix.js.vendor = libs;

    return this;
};

/**
 * Register libraries to automatically "autoload" when
 * the appropriate variable is references in js
 *
 * @param {object} libs
 */
module.exports.autoload = (libs) => {
    let aliases = {};

    Object.keys(libs).forEach(library => {
        libs[library].forEach(alias => {
            aliases[alias] = library;
        });
    });

    Mix.js.autoload = aliases;

    return this;
};

/**
 * Register Sass compilation.
 *
 * @param {string} src
 * @param {string} output
 */
module.exports.sass = (src, output) => {
    return module.exports.preprocess('sass', src, output);
};

/**
 * Register Less compilation.
 *
 * @param {string} src
 * @param {string} output
 */
module.exports.less = (src, output) => {
    return module.exports.preprocess('less', src, output);
};

/**
 * Register a generic CSS preprocessor.
 *
 * @param {string} type
 * @param {string} src
 * @param {string} output
 */
module.exports.preprocess = (type, src, output) => {
    src = new Mix.File(path.resolve(src)).parsePath();
    output = new Mix.File(output).parsePath();

    if (output.isDir) {
        output = new Mix.File(
            path.posix.join(output.path, src.name + '.css')
        ).parsePath();
    }

    Mix[type] = (Mix[type] || []).concat({ src, output });

    Mix.cssPreprocessor = type;

    return this;
};

/**
 * Combine a collection of files.
 *
 * @param {string|array} src
 * @param {string}       output
 */
module.exports.combine = (src, output) => {
    Mix.combine = (Mix.combine || []).concat({ src, output });

    return this;
};

/**
 * Copy one or more files to a new location.
 *
 * @param {string} from
 * @param {string} to
 */
module.exports.copy = (from, to) => {
    Mix.copy = (Mix.copy || []).concat({
        from,
        to: Mix.Paths.root(to),
        flatten: true
    });

    return this;
};

/**
 * Minify the provided file.
 *
 * @param {string|array} src
 */
module.exports.minify = (src) => {
    Mix.minify = (Mix.minify || []).concat(src);

    return this;
};

/**
 * Enable sourcemap support.
 */
module.exports.sourceMaps = () => {
    Mix.sourcemaps = (Mix.inProduction ? '#source-map' : '#inline-source-map');

    return this;
};

/**
 * Enable compiled file versioning.
 */
module.exports.version = () => {
    Mix.versioning = true;

    return this;
};

/**
 * Disable all OS notifications.
 */
module.exports.disableNotifications = () => {
    Mix.notifications = false;

    return this;
};

/**
 * Set the path to your public folder.
 *
 * @param {string} path
 */
module.exports.setPublicPath = (path) => {
    Mix.publicPath = path;

    return this;
};

/**
 * Set the temporary cache directory.
 *
 * @param {string} path
 */
module.exports.setCachePath = (path) => {
    Mix.cachePath = path;

    return this;
};

/**
 * Merge custom config with the provided webpack.config file.
 *
 * @param {object} config
 */
module.exports.webpackConfig = (config) => {
    Mix.webpackConfig = config;

    return this;
}

/**
 * Reset all configuration to their defaults.
 */
module.exports.reset = () => {
    [
        'js', 'cssPreprocessor', 'sass',
        'less', 'sourceMaps'
    ].forEach(prop => Mix[prop] = null);

    return this;
};

module.exports.config = Mix;
<commit_msg>Return mix export temporarily<commit_after>let path = require('path');
let Mix = require('./Mix');

/**
 * We'll fetch some Webpack config plugins here for cleanliness.
 */
module.exports.plugins = {
    WebpackNotifierPlugin: require('webpack-notifier'),
    WebpackOnBuildPlugin: require('on-build-webpack'),
    ExtractTextPlugin: require('extract-text-webpack-plugin'),
    CopyWebpackPlugin: require('copy-webpack-plugin'),
    FriendlyErrorsWebpackPlugin: require('friendly-errors-webpack-plugin'),
    StatsWriterPlugin: require('webpack-stats-plugin').StatsWriterPlugin,
    WebpackMd5HashPlugin: require('webpack-md5-hash')
};

/**
 * Register the Webpack entry/output paths.
 *
 * @param {mixed}  entry
 * @param {string} output
 */
module.exports.js = (entry, output) => {
    entry = (Array.isArray(entry) ? entry : [entry]).map(file => {
        return new Mix.File(path.resolve(file)).parsePath();
    });

    output = new Mix.File(output).parsePath();

    if (output.isDir) {
        output = new Mix.File(
            path.posix.join(output.path, entry[0].file)
        ).parsePath();
    }

    Mix.js = (Mix.js || []).concat({ entry, output, vendor: false });

    return this;
};

/**
 * Register vendor libs that should be extracted.
 * This helps drastically with long-term caching.
 *
 * @param {array} libs
 */
module.exports.extract = (libs) => {
    Mix.js.vendor = libs;

    return this;
};

/**
 * Register libraries to automatically "autoload" when
 * the appropriate variable is references in js
 *
 * @param {object} libs
 */
module.exports.autoload = (libs) => {
    let aliases = {};

    Object.keys(libs).forEach(library => {
        libs[library].forEach(alias => {
            aliases[alias] = library;
        });
    });

    Mix.js.autoload = aliases;

    return this;
};

/**
 * Register Sass compilation.
 *
 * @param {string} src
 * @param {string} output
 */
module.exports.sass = (src, output) => {
    return module.exports.preprocess('sass', src, output);
};

/**
 * Register Less compilation.
 *
 * @param {string} src
 * @param {string} output
 */
module.exports.less = (src, output) => {
    return module.exports.preprocess('less', src, output);
};

/**
 * Register a generic CSS preprocessor.
 *
 * @param {string} type
 * @param {string} src
 * @param {string} output
 */
module.exports.preprocess = (type, src, output) => {
    src = new Mix.File(path.resolve(src)).parsePath();
    output = new Mix.File(output).parsePath();

    if (output.isDir) {
        output = new Mix.File(
            path.posix.join(output.path, src.name + '.css')
        ).parsePath();
    }

    Mix[type] = (Mix[type] || []).concat({ src, output });

    Mix.cssPreprocessor = type;

    return this;
};

/**
 * Combine a collection of files.
 *
 * @param {string|array} src
 * @param {string}       output
 */
module.exports.combine = (src, output) => {
    Mix.combine = (Mix.combine || []).concat({ src, output });

    return this;
};

/**
 * Copy one or more files to a new location.
 *
 * @param {string} from
 * @param {string} to
 */
module.exports.copy = (from, to) => {
    Mix.copy = (Mix.copy || []).concat({
        from,
        to: Mix.Paths.root(to),
        flatten: true
    });

    return this;
};

/**
 * Minify the provided file.
 *
 * @param {string|array} src
 */
module.exports.minify = (src) => {
    Mix.minify = (Mix.minify || []).concat(src);

    return this;
};

/**
 * Enable sourcemap support.
 */
module.exports.sourceMaps = () => {
    Mix.sourcemaps = (Mix.inProduction ? '#source-map' : '#inline-source-map');

    return this;
};

/**
 * Enable compiled file versioning.
 */
module.exports.version = () => {
    Mix.versioning = true;

    return this;
};

/**
 * Disable all OS notifications.
 */
module.exports.disableNotifications = () => {
    Mix.notifications = false;

    return this;
};

/**
 * Set the path to your public folder.
 *
 * @param {string} path
 */
module.exports.setPublicPath = (path) => {
    Mix.publicPath = path;

    return this;
};

/**
 * Set the temporary cache directory.
 *
 * @param {string} path
 */
module.exports.setCachePath = (path) => {
    Mix.cachePath = path;

    return this;
};

/**
 * Merge custom config with the provided webpack.config file.
 *
 * @param {object} config
 */
module.exports.webpackConfig = (config) => {
    Mix.webpackConfig = config;

    return this;
}

/**
 * Reset all configuration to their defaults.
 */
module.exports.reset = () => {
    [
        'js', 'cssPreprocessor', 'sass',
        'less', 'sourceMaps'
    ].forEach(prop => Mix[prop] = null);

    return this;
};

module.exports.config = Mix;
module.exports.mix = module.exports;
<|endoftext|>


<commit_before>/* global kuromoji */
import d3 from "d3"
import "kuromoji"

var i,j,k,l;

var width = 960,
    height = 500;

var color = d3.scale.category20c();

var force = d3.layout.force()
    .charge(-120)
    .linkDistance(30)
    .size([width, height]);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

kuromoji.builder({dicPath: 'dict/'}).build((err, tokenizer) => {
  const path = tokenizer.tokenize("I have a pen."); //1集計単位ごとにこの関数を用いよう
  console.log(path);

  var keitaisokaiseki = new Array; //ゆくゆくはArrayの大きさを段落数に指定
  keitaisokaiseki[0] = new Array(path.length);

  for(i=0;i<path.length;i++){
    keitaisokaiseki[0][i] = path[i].basic_form;
  }

//以下、想定していた形態素解析後の結果から、共起ネットワークのノード・エッジ作成へ

    var danraku0 = ["A","B","C"];
    var danraku1 = ["B","D"];
    /*
    var keitaisokaiseki = [["あ","い","う","え"],
                            ["い","あ","え"],
                            ["あ","お"],
                          ["い","か"]];
                          */

console.log(keitaisokaiseki[0][0]);

var tangoset = new Set();

console.log(keitaisokaiseki.length);
for(i=0;i<keitaisokaiseki.length;++i){
  console.log(keitaisokaiseki[i].length);
  for(j=0;j<keitaisokaiseki[i].length;++j){
    tangoset.add(keitaisokaiseki[i][j]);
  }
}
var miserables={"nodes":new Array,"links":new Array};

console.log(tangoset);

miserables.nodes = Array.from(tangoset).map(function(t) {
  return {name:t};
  // body...
});

console.log(miserables.nodes[0]);

for(k=0;k<miserables.nodes.length;++k){

  miserables.nodes[k].group =1;//ゆくゆくは媒介中心性に
}
//node作成終了。miserables.nodes.lengthがtangosetになってるはず
  console.log(miserables.nodes);
  console.log(miserables.nodes.length);

var danrakusuu = keitaisokaiseki.length;

console.log(danrakusuu);
//あとはlinksの作成だけ
//まずはlistをつくる
var list = new Array(keitaisokaiseki.length);
//list作成
//keitaisokaisekiとnodesを照らしあわせる
for(i=0;i<keitaisokaiseki.length;++i){//danrakusuuはkeitaisokaisekiとlistで共
  list[i] = new Array(miserables.nodes.length);
  for(j=0;j<keitaisokaiseki[i].length;++j){
    for(k=0;k<miserables.nodes.length;++k){
      if(keitaisokaiseki[i][j]==miserables.nodes[k].name){
        list[i][k]=1;
        console.log(i,k,list[i][k]);
      }
    }
  }
}
console.log(keitaisokaiseki[0][0]);
console.log(miserables.nodes[0].name);
console.log(list);
console.log(list[0][0]);
//listはi*k

//listからmiserables.linksとlist3をつくる

var x,y,z;

var edge=-1;

    for(k=0;k<miserables.nodes.length;++k){

      for(l=k+1;l<miserables.nodes.length;++l){//別の単語を見る
        //現在単語2個の組み合わせを選択中

        //ここから段落を指定して縦になめる

        for(i=0;i<keitaisokaiseki.length;++i){
          x=list[i][k];
          y=list[i][l];

          if(x==1 && y==1){
            console.log("hello");
            console.log(i);
            console.log(k);
            console.log(l);
            miserables.links.push({"source":l,"target":k,"value":0});
            edge++;//最初のedgeが0
            break;
          }
        }
        //とりあえずエッジつくってbreak
        //こっからvalueを与える
        for(i=0;i<keitaisokaiseki.length;++i){
          x=list[i][k];
          y=list[i][l];
          if(x==1 && y==1){
            z = miserables.links[edge].value;
            z++;
            miserables.links[edge].value = z;
          }
        }
      }
    }
console.log(miserables.links[0]);

//以上計算中

var graph = miserables;

    force
        .nodes(graph.nodes)
        .links(graph.links)
        .start();

    var link = svg.selectAll(".link")
        .data(graph.links)
      .enter().append("line")
        .attr("class", "link")
        .style("stroke-width", function(d) { return Math.sqrt(d.value); });

  var node = svg.selectAll(".node")
      .data(graph.nodes)
    .enter().append("text")
      .attr("class", "node")
      .style("fill", function(d) { return color(d.group); })
      .call(force.drag)
      .text(function(d) { return d.name; });

    force.on("tick", function() {
      link.attr("x1", function(d) { return d.source.x; })
          .attr("y1", function(d) { return d.source.y; })
          .attr("x2", function(d) { return d.target.x; })
          .attr("y2", function(d) { return d.target.y; });

      node.attr("x", function(d) { return d.x; })
          .attr("y", function(d) { return d.y; });
    });
    });
<commit_msg>俺は強い。俺は弱い。<commit_after>/* global kuromoji */
import d3 from "d3"
import "kuromoji"

var i,j,k,l;

var width = 960,
    height = 500;

var color = d3.scale.category20c();

var force = d3.layout.force()
    .charge(-120)
    .linkDistance(30)
    .size([width, height]);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

kuromoji.builder({dicPath: 'dict/'}).build((err, tokenizer) => {
  const path = tokenizer.tokenize("俺は強い。俺は弱い。"); //1集計単位ごとにこの関数を用いよう
  console.log(path);

  var keitaisokaiseki = new Array; //このlengthは段落数

  i=0; //iは全データ内で何文字目か
  j=0; //集計単位の何個目か。
  while(i<path.length){
    keitaisokaiseki[j] = new Array;
    k=0; //集計単位内で何文字目か
    while(i<path.length){
      if(path[i].basic_form=="。"){
        i++
        break;
      }
      keitaisokaiseki[j][k] = path[i].basic_form;
      i++;
      k++;
    }
    j++;
  }

//以下、想定していた形態素解析後の結果から、共起ネットワークのノード・エッジ作成へ

    var danraku0 = ["A","B","C"];
    var danraku1 = ["B","D"];
    /*
    var keitaisokaiseki = [["あ","い","う","え"],
                            ["い","あ","え"],
                            ["あ","お"],
                          ["い","か"]];
                          */

console.log(keitaisokaiseki);

var tangoset = new Set();

console.log(keitaisokaiseki.length);
for(i=0;i<keitaisokaiseki.length;++i){
  console.log(keitaisokaiseki[i]);
  for(j=0;j<keitaisokaiseki[i].length;++j){
    tangoset.add(keitaisokaiseki[i][j]);
  }
}
var miserables={"nodes":new Array,"links":new Array};

console.log(tangoset);

miserables.nodes = Array.from(tangoset).map(function(t) {
  return {name:t};
  // body...
});

console.log(miserables.nodes[0]);

for(k=0;k<miserables.nodes.length;++k){

  miserables.nodes[k].group =1;//ゆくゆくは媒介中心性に
}
//node作成終了。miserables.nodes.lengthがtangosetになってるはず
  console.log(miserables.nodes);
  console.log(miserables.nodes.length);

var danrakusuu = keitaisokaiseki.length;

console.log(danrakusuu);
//あとはlinksの作成だけ
//まずはlistをつくる
var list = new Array(keitaisokaiseki.length);
//list作成
//keitaisokaisekiとnodesを照らしあわせる
for(i=0;i<keitaisokaiseki.length;++i){//danrakusuuはkeitaisokaisekiとlistで共
  list[i] = new Array(miserables.nodes.length);
  for(j=0;j<keitaisokaiseki[i].length;++j){
    for(k=0;k<miserables.nodes.length;++k){
      if(keitaisokaiseki[i][j]==miserables.nodes[k].name){
        list[i][k]=1;
        console.log(i,k,list[i][k]);
      }
    }
  }
}
console.log(keitaisokaiseki[0][0]);
console.log(miserables.nodes[0].name);
console.log(list);
console.log(list[0][0]);
//listはi*k

//listからmiserables.linksとlist3をつくる

var x,y,z;

var edge=-1;

    for(k=0;k<miserables.nodes.length;++k){

      for(l=k+1;l<miserables.nodes.length;++l){//別の単語を見る
        //現在単語2個の組み合わせを選択中

        //ここから段落を指定して縦になめる

        for(i=0;i<keitaisokaiseki.length;++i){
          x=list[i][k];
          y=list[i][l];

          if(x==1 && y==1){
            console.log("hello");
            console.log(i);
            console.log(k);
            console.log(l);
            miserables.links.push({"source":l,"target":k,"value":0});
            edge++;//最初のedgeが0
            break;
          }
        }
        //とりあえずエッジつくってbreak
        //こっからvalueを与える
        for(i=0;i<keitaisokaiseki.length;++i){
          x=list[i][k];
          y=list[i][l];
          if(x==1 && y==1){
            z = miserables.links[edge].value;
            z++;
            miserables.links[edge].value = z;
          }
        }
      }
    }
console.log(miserables.links[0]);

//以上計算中

var graph = miserables;

    force
        .nodes(graph.nodes)
        .links(graph.links)
        .start();

    var link = svg.selectAll(".link")
        .data(graph.links)
      .enter().append("line")
        .attr("class", "link")
        .style("stroke-width", function(d) { return Math.sqrt(d.value); });

  var node = svg.selectAll(".node")
      .data(graph.nodes)
    .enter().append("text")
      .attr("class", "node")
      .style("fill", function(d) { return color(d.group); })
      .call(force.drag)
      .text(function(d) { return d.name; });

    force.on("tick", function() {
      link.attr("x1", function(d) { return d.source.x; })
          .attr("y1", function(d) { return d.source.y; })
          .attr("x2", function(d) { return d.target.x; })
          .attr("y2", function(d) { return d.target.y; });

      node.attr("x", function(d) { return d.x; })
          .attr("y", function(d) { return d.y; });
    });
    });
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

var data = [
	{
		title: 'Tab1',
		content: 'This is a paragraph 1',
		id: 1
	},
	{
		title: 'Tab2',
		content: 'This is a paragraph 2',
		id: 2
	},
	{
		title: 'Tab3',
		content: 'This is a paragraph 3',
		id: 3
	}
];

class TabContent extends Component {
	render() {
		return (

{this.props.data_tabcontent.content}

		);
	}
}

class Tab extends Component {
	onClick = () => {
		this.props.onClick(this.props.ele_id);
	};

	render() {
		const style_selected = { backgroundColor: 'red', padding: 20 };
		const style_not_selected = { backgroundColor: 'blue', padding: 20 };
		if (this.props.idNumber === this.props.ele_id) {
			return (

					{this.props.title}

			);
		} else {
			return (

					{this.props.title}

			);
		}
	}
}

class UlContainer extends Component {
	constructor(props) {
		super(props);
		this.state = {
			id: 1
		};
	}

	onClick = id => {
		this.setState({ id: id });
	};

	render() {
		const tabs = [];
		for (let i = 0; i < data.length; i++) {
			tabs.push(
				<Tab
					title={data[i].title}
					key={i}
					onClick={this.onClick}
					ele_id={i}
					idNumber={this.state.id}
				/>
			);
		}

		return (

					{tabs}

				<TabContent
					id={this.state.id}
					data_tabcontent={this.props.data[this.state.id]}
				/>

		);
	}
}

class App extends Component {
	render() {
		return (

Welcome to React

					To get started, edit src/App.js and save to reload.

				<UlContainer data={data} />

		);
	}
}

export default App;
<commit_msg>DropDown working<commit_after>import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

//------------------------ UlContainer ----------------------------

var data = [
	{
		title: 'Tab1',
		content: 'This is a paragraph 1',
		id: 1
	},
	{
		title: 'Tab2',
		content: 'This is a paragraph 2',
		id: 2
	},
	{
		title: 'Tab3',
		content: 'This is a paragraph 3',
		id: 3
	}
];

class TabContent extends Component {
	render() {
		return (

{this.props.data_tabcontent.content}

		);
	}
}

class Tab extends Component {
	onClick = () => {
		this.props.onClick(this.props.ele_id);
	};

	render() {
		const style_selected = { backgroundColor: 'red', padding: 20 };
		const style_not_selected = { backgroundColor: 'blue', padding: 20 };
		if (this.props.idNumber === this.props.ele_id) {
			return (

					{this.props.title}

			);
		} else {
			return (

					{this.props.title}

			);
		}
	}
}

class UlContainer extends Component {
	constructor(props) {
		super(props);
		this.state = {
			id: 1
		};
	}

	onClick = id => {
		this.setState({ id: id });
	};

	render() {
		const tabs = [];
		for (let i = 0; i < data.length; i++) {
			tabs.push(
				<Tab
					title={data[i].title}
					key={i}
					onClick={this.onClick}
					ele_id={i}
					idNumber={this.state.id}
				/>
			);
		}

		return (

					{tabs}

				<TabContent
					id={this.state.id}
					data_tabcontent={this.props.data[this.state.id]}
				/>

		);
	}
}

//------------------------ UlContainer ----------------------------

//------------------------ Dropdown ----------------------------

var DropdownElementNames = [
	{
		name: 'Dropdown',
		link_: '#1'
	},
	{
		name: 'Dropdown1',
		link_: '#2'
	},
	{
		name: 'Dropdown2',
		link_: '#3'
	},
	{
		name: 'Dropdown3',
		link_: '#4'
	}
];

class DropdownElement extends Component {
	render() {
		return (

				{this.props.name}

		);
	}
}

class Dropdown extends Component {
	constructor(props) {
		super(props);

		this.state = {
			isClicked: false
		};
	}

	onClick = () => {
		this.setState({
			isClicked: !this.state.isClicked
		});
	};

	render() {
		var Elements = [];
		for (var i = 0; i < this.props.DropdownElementNames.length; i++) {
			Elements.push(
				<DropdownElement
					name={this.props.DropdownElementNames[i].name}
					link={this.props.DropdownElementNames[i].link_}
					key={i.toString()}
				/>
			);
		}

		if (this.state.isClicked) {
			var style_not_visible = { visibility: 'hidden' };
			var style_visible = { visibility: 'visible' };
			return (

Dropdown List

						{Elements}

			);
		} else {
			return (

Dropdown List

						{Elements}

			);
		}
	}
}

//------------------------ Dropdown ----------------------------

class App extends Component {
	render() {
		return (

Welcome to React

					To get started, edit src/App.js and save to reload.

				<Dropdown DropdownElementNames={DropdownElementNames} />

		);
	}
}
// <UlContainer data={data} />

export default App;
<|endoftext|>


<commit_before>// @flow

export const test =
  (ele : any, types : Array<string> | string, ...addTypes : Array<string>) : boolean => {
    if (isString(types) && isEmpty(addTypes)) {
      return Object.prototype.toString(ele) === types || typeof ele === types
    }

    return addTypes
      .concat(types)
      .some(
        (t : string) : boolean =>
          test(ele, t)
      )
  }

export const is =
  (ele : any, ...types : Array<string>) : boolean =>
    test(ele, types)

export const not =
  (ele : any, ...types: Array<string>) : boolean =>
    !test(ele, types)

export const isArray =
  (ele : any) : boolean =>
    isTruthy(ele) &&
    isFunction(ele.forEach)

export const isBoolean =
  (ele : any) : boolean =>
    typeof ele === 'boolean'

export const isDefined =
  (ele : any) : boolean =>
    typeof ele !== 'undefined'

export const isFunction =
  (ele : any) : boolean =>
    typeof ele === 'function'

export const isNumber =
  (ele : any) : boolean =>
    ele === +ele

export const isInteger =
  (ele : any) : boolean =>
    ele === +ele &&
    ele === (ele | 0)

export const isFloat =
  (ele : any) : boolean =>
    ele === +ele

export const isObject =
  (ele : any) : boolean =>
    typeof ele === 'object'

export const isString =
  (ele : any) : boolean =>
    typeof ele === 'string'

export const isRGBAObject =
  (e : any) : boolean =>
    isObject(e) &&
    isNumber(e.r) &&
    isNumber(e.g) &&
    isNumber(e.b) &&
    isNumber(e.a)

export const isRGBObject =
  (e : any) : boolean =>
    isObject(e) &&
    isNumber(e.r) &&
    isNumber(e.g) &&
    isNumber(e.b)

export const isHexColor =
  (c : any) : boolean =>
    /\#\b([a-f0-9]{3}|[a-f0-9]{6}|[a-f0-9]{4}|[a-f0-9]{8})\b/i.test(c)

export const isHexAlphaColor =
  (c : any) : boolean =>
    /\#\b([a-f0-9]{4}|[a-f0-9]{8})\b/i.test(c)

export const isColor =
  (e : any) : boolean =>
    isRGBAObject(e) ||
    isRGBObject(e) ||
    isHexColor(e) ||
    isHexAlphaColor(e)

export const isDate =
  (ele : any) : boolean =>
    ele.constructor === Date

export const isRegExp =
  (ele : any) : boolean =>
    ele.constructor === RegExp

export const isTruthy =
  (ele : any) : boolean =>
    !!ele

export const isFalsy =
  (ele : any) : boolean =>
    !ele ||
    isEmpty(ele)

export const isEmpty =
  (ele : any) : boolean =>
    !ele ||
    isObject(ele) && Object.keys(ele).length === 0 ||
    false

export const isError =
  (ele : any) : boolean =>
    Object.getPrototypeOf(ele).name === 'Error'

export const isIterable =
  (ele : any) : boolean =>
    typeof ele === 'object'

export const isEmail =
  (ele : any) : boolean =>
    typeof ele === 'string' &&
    ele.indexOf('@') > 0
<commit_msg>use Array.isArray if it exists<commit_after>// @flow

export const test =
  (ele : any, types : Array<string> | string, ...addTypes : Array<string>) : boolean => {
    if (isString(types) && isEmpty(addTypes)) {
      return Object.prototype.toString(ele) === types || typeof ele === types
    }

    return addTypes
      .concat(types)
      .some(
        (t : string) : boolean =>
          test(ele, t)
      )
  }

export const is =
  (ele : any, ...types : Array<string>) : boolean =>
    test(ele, types)

export const not =
  (ele : any, ...types: Array<string>) : boolean =>
    !test(ele, types)

export const isArray =
  (ele : any) : boolean =>
    isFunction(Array.isArray)
      ? Array.isArray(ele)
      : isTruthy(ele) && isFunction(ele.forEach)

export const isBoolean =
  (ele : any) : boolean =>
    typeof ele === 'boolean'

export const isDefined =
  (ele : any) : boolean =>
    typeof ele !== 'undefined'

export const isFunction =
  (ele : any) : boolean =>
    typeof ele === 'function'

export const isNumber =
  (ele : any) : boolean =>
    ele === +ele

export const isInteger =
  (ele : any) : boolean =>
    ele === +ele &&
    ele === (ele | 0)

export const isFloat =
  (ele : any) : boolean =>
    ele === +ele

export const isObject =
  (ele : any) : boolean =>
    typeof ele === 'object'

export const isString =
  (ele : any) : boolean =>
    typeof ele === 'string'

export const isRGBAObject =
  (e : any) : boolean =>
    isObject(e) &&
    isNumber(e.r) &&
    isNumber(e.g) &&
    isNumber(e.b) &&
    isNumber(e.a)

export const isRGBObject =
  (e : any) : boolean =>
    isObject(e) &&
    isNumber(e.r) &&
    isNumber(e.g) &&
    isNumber(e.b)

export const isHexColor =
  (c : any) : boolean =>
    /\#\b([a-f0-9]{3}|[a-f0-9]{6}|[a-f0-9]{4}|[a-f0-9]{8})\b/i.test(c)

export const isHexAlphaColor =
  (c : any) : boolean =>
    /\#\b([a-f0-9]{4}|[a-f0-9]{8})\b/i.test(c)

export const isColor =
  (e : any) : boolean =>
    isRGBAObject(e) ||
    isRGBObject(e) ||
    isHexColor(e) ||
    isHexAlphaColor(e)

export const isDate =
  (ele : any) : boolean =>
    ele.constructor === Date

export const isRegExp =
  (ele : any) : boolean =>
    ele.constructor === RegExp

export const isTruthy =
  (ele : any) : boolean =>
    !!ele

export const isFalsy =
  (ele : any) : boolean =>
    !ele ||
    isEmpty(ele)

export const isEmpty =
  (ele : any) : boolean =>
    !ele ||
    isObject(ele) && Object.keys(ele).length === 0 ||
    false

export const isError =
  (ele : any) : boolean =>
    Object.getPrototypeOf(ele).name === 'Error'

export const isIterable =
  (ele : any) : boolean =>
    typeof ele === 'object'

export const isEmail =
  (ele : any) : boolean =>
    typeof ele === 'string' &&
    ele.indexOf('@') > 0
<|endoftext|>


<commit_before>function ARIAListBox(element) {
    element.aria = this;
    this.element = element;
    this.createList();
}

ARIAListBox.prototype.createList = function() {
    Array.prototype.forEach.call(
        this.element.querySelectorAll('[role=option]'),
        function(element, i) {
            Array.prototype.push.call(this, ARIAOption.getOption(element));
        }, this);
}

ARIAListBox.prototype.unselect = function() {
    Array.prototype.forEach.call(this, function(option) {
        option.selected = 'false';
    });
}

ARIAListBox.getListBox = function(element) {
    return element.aria || new ARIAListBox(element);
}

////////////////////////////////////////////////////////////////

function ARIAOption(element) {
    element.aria = this;
    this.element = element;
}

Object.defineProperty(ARIAOption.prototype, 'selected', {
    enumerable : true,
    get : function() {
        return this.element.getAttribute('aria-selected') || '';
    },
    set : function(value) {
        value = String(value);
        this.element.setAttribute('aria-selected', value);
    }
});

ARIAOption.prototype.getListBox = function() {
    return ARIAListBox.getListBox(this.element.closest('[role=listbox]'));
}

ARIAOption.prototype.onMouseDown = function(e) {
    this.getListBox().unselect();
    this.selected = 'true';
    this.element.dispatchEvent(new Event('change'));
}

ARIAOption.isOption = function(element) {
    return Boolean(element.aria) ||
        (typeof element.getAttribute === 'function' &&
            element.getAttribute('role') === 'option');
}

ARIAOption.getOption = function(element) {
    return element.aria || new ARIAOption(element);
}

ARIAOption.attachToDocument = function() {
    var _this = this;

    document.addEventListener('mousedown', function(e) {
        if(_this.isOption(e.target)) _this.getOption(e.target).onMouseDown(e);
    }, true);
}

ARIAOption.attachToDocument();
<commit_msg>ARIAListBox arrow keys<commit_after>function ARIAListBox(element) {
    element.aria = this;
    this.element = element;
    this.createList();
    element.addEventListener('keydown', this.onKeyDown.bind(this));
}

ARIAListBox.prototype = new Array();

Object.defineProperty(ARIAListBox.prototype, 'selected', {
    enumerable : true,
    get : function() {
        return this.filter(function(option) {
            return option.selected === 'true';
        });
    }
});

ARIAListBox.prototype.createList = function() {
    this.forEach.call(
        this.element.querySelectorAll('[role=option]'),
        function(element, i) {
            this.push(ARIAOption.getOption(element));
        }, this);
}

ARIAListBox.prototype.unselect = function() {
    this.forEach(function(option) {
        option.selected = 'false';
    });
}

ARIAListBox.prototype.onKeyDown = function(e) {
    var keyCode = e.keyCode;

    if(keyCode >= 37 && keyCode <= 40) {
        e.preventDefault(); // prevent page scrolling
        var direction = keyCode < 39? -1 : 1,
            selected = this.selected[0],
            next = this.indexOf(selected) + direction;
        if(next === this.length) next = 0;
        if(next < 0) next = this.length - 1;
        this.unselect();
        this[next].selected = true;
    }
}

ARIAListBox.isListBox = function(element) {
    return Boolean(element.aria) ||
        (typeof element.getAttribute === 'function' &&
            element.getAttribute('role') === 'listbox');
}

ARIAListBox.getListBox = function(element) {
    return element.aria || new ARIAListBox(element);
}

ARIAListBox.attachToDocument = function() {
    var _this = this;
    document.addEventListener('focus', function(e) {
        if(_this.isListBox(e.target)) _this.getListBox(e.target);
    }, true);
}

ARIAListBox.attachToDocument();

////////////////////////////////////////////////////////////////

function ARIAOption(element) {
    element.aria = this;
    this.element = element;
}

Object.defineProperty(ARIAOption.prototype, 'selected', {
    enumerable : true,
    get : function() {
        return this.element.getAttribute('aria-selected') || '';
    },
    set : function(value) {
        value = String(value);
        this.element.setAttribute('aria-selected', value);
    }
});

ARIAOption.prototype.getListBox = function() {
    return ARIAListBox.getListBox(this.element.closest('[role=listbox]'));
}

ARIAOption.prototype.onMouseDown = function(e) {
    this.getListBox().unselect();
    this.selected = 'true';
    this.element.dispatchEvent(new Event('change'));
}

ARIAOption.isOption = function(element) {
    return Boolean(element.aria) ||
        (typeof element.getAttribute === 'function' &&
            element.getAttribute('role') === 'option');
}

ARIAOption.getOption = function(element) {
    return element.aria || new ARIAOption(element);
}

ARIAOption.attachToDocument = function() {
    var _this = this;
    document.addEventListener('mousedown', function(e) {
        if(_this.isOption(e.target)) _this.getOption(e.target).onMouseDown(e);
    }, true);
}

ARIAOption.attachToDocument();
<|endoftext|>


<commit_before>const {resolve} = require('path')

const tasksEngine = require('@projectlint/tasks-engine')

const {parsedTypeParse} = require('levn')
// const pkgDir = require('pkg-dir')
const {parseType} = require('type-check')

const entry = '(String | Number, Undefined | {...})'
const ruleTypeDesc = `${entry} | [${entry}] | {...}`

const ruleType = parseType(ruleTypeDesc)
const configEntryType = parseType(`(String, Undefined | ${ruleTypeDesc})`)

const levels =
{
  warn    : 1,  // output the failure
  warning : 1,  // alias of `warn`
  error   : 2,  // same as `warn`. but process will exit with an error code
  critical: 3,  // same as `error`, but prevent its dependendents to execute

  // Control levels, don't affect directly to errors counting
  ignore  : -1,  // ignore the result, just pass it to its dependents
  skipIf  : -2,  // execute rule, and if it fails, skip its dependents
  skip    : -3,  // skip the rule and its dependents
  disabled: -4   // explicitly disable a rule, failing its dependents
}

class Failure extends Error
{
  name = 'Failure'

  constructor(result, message)
  {
    super(message || result?.message || result)

    this.result = result
  }
}

function filterDuplicated(value)
{
  if(!this.includes(value)) return this.push(value)
}

function mapConfigs(config)
{
  if(typeof config !== 'string') return config

  return parsedTypeParse(configEntryType, config)
}

function mapProjectRootResults({reason: error, value})
{
  // This could only happen by a severe crash of the `tasksEngine` instance
  if(error) return {error}

  return value
}

function normalizeRules([ruleName, rule])
{
  const {evaluate, fetch, fix: fixFunc} = rule

  if(!evaluate)
    throw new SyntaxError(`'evaluate' function not defined for rule '${ruleName}'`)

  const {errorLevel, fix} = this

  rule.func = async function(context, dependenciesResults, {config, rules})
  {
    let fixConfig, needFix, result

    if(fetch) result = await fetch({config, context, dependenciesResults})

    for(const [level, ruleConfig] of rules)
      try
      {
        const evaluation = evaluate({
          config: ruleConfig,
          context,
          dependenciesResults,
          fetch: {config, result}
        })

        if(evaluation instanceof Promise)
          await evaluation
        else if(evaluation)
          throw evaluation instanceof Error
            ? evaluation
            : new Failure(evaluation)
      }
      catch(error)
      {
        needFix = true
        fixConfig = ruleConfig

        // Level where a failure is considered an error
        if(!(error instanceof errorLevel)) throw error

        rule.failure = error
        rule.level = level
      }

    // We wait to last errors to fix the more critical ones first
    if(needFix && fixFunc && fix)
      await fix({
        config: fixConfig,
        context,
        dependenciesResults,
        fetch: {config, result}
      })

    return result
  }
}

function parseRuleConfig(rules)
{
  if(!rules) throw new SyntaxError('`rules` argument must be set')

  let config
  if(rules.rules != null)
  {
    config = {...rules}
    delete config.rules

    rules = rules.rules
  }

  // Unify as array of entries
  if(typeof rules === 'number') rules = [[number]]

  else
  {
    if(typeof rules === 'string') rules = parsedTypeParse(ruleType, rules)

    if(rules.constructor.name === 'Object') rules = Object.entries(rules)
    else if(Array.isArray(rules) && !Array.isArray(rules[0])) rules = [rules]
  }

  if(!rules.length) throw new SyntaxError('`rules` argument must not be empty')

  // Unify all levels as numbers
  rules.forEach(unifyRuleLevel)

  // Sort rules from less to more critical
  rules.sort(sortRulesConfig)

  return {config, rules}
}

function projectRootResults(results)
{
  return results.map(mapProjectRootResults)
}

function sortRulesConfig([a], [b])
{
  return a - b
}

function unifyRuleLevel(entry)
{
  const key = entry[0]

  if(typeof key === 'number') return

  const level = levels[key]
  if(level == null) throw new SyntaxError(`Unknown level '${key}'`)

  entry[0] = level
}

module.exports = exports = function(rules, configs, options = {})
{
  // Normalize rules
  if(!rules) throw new SyntaxError('`rules` argument must be set')

  if(Array.isArray(rules)) rules = Object.fromEntries(rules)

  // Normalize config
  if(!configs) throw new SyntaxError('`configs` argument must be set')

  if(Array.isArray(configs))
    configs = Object.fromEntries(configs.map(mapConfigs))

  for(const [ruleName, config] of Object.entries(configs))
    configs[ruleName] = parseRuleConfig(config)

  // Normalize error level and project root
  let {errorLevel = 'failure', projectRoot} = options

  switch(errorLevel)
  {
    case 'failure': options.errorLevel = Failure; break
    case 'error'  : options.errorLevel = Error  ; break

    default: throw new Error(`Unknown errorLevel '${errorLevel}'`)
  }

  if(!projectRoot?.length) projectRoot = [resolve()]
  else if(typeof projectRoot === 'string') projectRoot = [projectRoot]

  // Filter duplicated project roots
  if(projectRoot.length > 1) projectRoot = projectRoot.filter(filterDuplicated, [])

  // TODO: apply filtering and expansion of rules here

  // Normalize rules
  Object.entries(rules).forEach(normalizeRules, options)

  // Run tasks
  return Promise.allSettled(projectRoot.map(function(projectRoot)
  {
    const visited = tasksEngine(rules, configs, {context: {projectRoot}})

    const names    = Object.keys(visited)
    const promises = Object.values(visited)

    return Promise.allSettled(promises)
    .then(function(results)
    {
      return results.map(function({reason: error, value: result}, index)
      {
        const name = names[index]
        const {dependsOn, failure, level} = rules[name]

        return {dependsOn, error, failure, level, name, projectRoot, result}
      })
    })
  }))
  .then(projectRootResults)
}

exports.Failure = Failure
<commit_msg>Pass error to rules `fix` function<commit_after>const {resolve} = require('path')

const tasksEngine = require('@projectlint/tasks-engine')

const {parsedTypeParse} = require('levn')
// const pkgDir = require('pkg-dir')
const {parseType} = require('type-check')

const entry = '(String | Number, Undefined | {...})'
const ruleTypeDesc = `${entry} | [${entry}] | {...}`

const ruleType = parseType(ruleTypeDesc)
const configEntryType = parseType(`(String, Undefined | ${ruleTypeDesc})`)

const levels =
{
  warn    : 1,  // output the failure
  warning : 1,  // alias of `warn`
  error   : 2,  // same as `warn`. but process will exit with an error code
  critical: 3,  // same as `error`, but prevent its dependendents to execute

  // Control levels, don't affect directly to errors counting
  ignore  : -1,  // ignore the result, just pass it to its dependents
  skipIf  : -2,  // execute rule, and if it fails, skip its dependents
  skip    : -3,  // skip the rule and its dependents
  disabled: -4   // explicitly disable a rule, failing its dependents
}

class Failure extends Error
{
  name = 'Failure'

  constructor(result, message)
  {
    super(message || result?.message || result)

    this.result = result
  }
}

function filterDuplicated(value)
{
  if(!this.includes(value)) return this.push(value)
}

function mapConfigs(config)
{
  if(typeof config !== 'string') return config

  return parsedTypeParse(configEntryType, config)
}

function mapProjectRootResults({reason: error, value})
{
  // This could only happen by a severe crash of the `tasksEngine` instance
  if(error) return {error}

  return value
}

function normalizeRules([ruleName, rule])
{
  const {evaluate, fetch, fix: fixFunc} = rule

  if(!evaluate)
    throw new SyntaxError(`'evaluate' function not defined for rule '${ruleName}'`)

  const {errorLevel, fix} = this

  rule.func = async function(context, dependenciesResults, {config, rules})
  {
    let fixConfig, needFix, result

    if(fetch) result = await fetch({config, context, dependenciesResults})

    for(const [level, ruleConfig] of rules)
      try
      {
        const evaluation = evaluate({
          config: ruleConfig,
          context,
          dependenciesResults,
          fetch: {config, result}
        })

        if(evaluation instanceof Promise)
          await evaluation
        else if(evaluation)
          throw evaluation instanceof Error
            ? evaluation
            : new Failure(evaluation)
      }
      catch(error)
      {
        needFix = error
        fixConfig = ruleConfig

        // Level where a failure is considered an error
        if(!(error instanceof errorLevel)) throw error

        rule.failure = error
        rule.level = level
      }

    // We wait to last errors to fix the more critical ones first
    if(needFix && fixFunc && fix)
      await fix({
        config: fixConfig,
        context,
        dependenciesResults,
        error: needFix,
        fetch: {config, result}
      })

    return result
  }
}

function parseRuleConfig(rules)
{
  if(!rules) throw new SyntaxError('`rules` argument must be set')

  let config
  if(rules.rules != null)
  {
    config = {...rules}
    delete config.rules

    rules = rules.rules
  }

  // Unify as array of entries
  if(typeof rules === 'number') rules = [[number]]

  else
  {
    if(typeof rules === 'string') rules = parsedTypeParse(ruleType, rules)

    if(rules.constructor.name === 'Object') rules = Object.entries(rules)
    else if(Array.isArray(rules) && !Array.isArray(rules[0])) rules = [rules]
  }

  if(!rules.length) throw new SyntaxError('`rules` argument must not be empty')

  // Unify all levels as numbers
  rules.forEach(unifyRuleLevel)

  // Sort rules from less to more critical
  rules.sort(sortRulesConfig)

  return {config, rules}
}

function projectRootResults(results)
{
  return results.map(mapProjectRootResults)
}

function sortRulesConfig([a], [b])
{
  return a - b
}

function unifyRuleLevel(entry)
{
  const key = entry[0]

  if(typeof key === 'number') return

  const level = levels[key]
  if(level == null) throw new SyntaxError(`Unknown level '${key}'`)

  entry[0] = level
}

module.exports = exports = function(rules, configs, options = {})
{
  // Normalize rules
  if(!rules) throw new SyntaxError('`rules` argument must be set')

  if(Array.isArray(rules)) rules = Object.fromEntries(rules)

  // Normalize config
  if(!configs) throw new SyntaxError('`configs` argument must be set')

  if(Array.isArray(configs))
    configs = Object.fromEntries(configs.map(mapConfigs))

  for(const [ruleName, config] of Object.entries(configs))
    configs[ruleName] = parseRuleConfig(config)

  // Normalize error level and project root
  let {errorLevel = 'failure', projectRoot} = options

  switch(errorLevel)
  {
    case 'failure': options.errorLevel = Failure; break
    case 'error'  : options.errorLevel = Error  ; break

    default: throw new Error(`Unknown errorLevel '${errorLevel}'`)
  }

  if(!projectRoot?.length) projectRoot = [resolve()]
  else if(typeof projectRoot === 'string') projectRoot = [projectRoot]

  // Filter duplicated project roots
  if(projectRoot.length > 1) projectRoot = projectRoot.filter(filterDuplicated, [])

  // TODO: apply filtering and expansion of rules here

  // Normalize rules
  Object.entries(rules).forEach(normalizeRules, options)

  // Run tasks
  return Promise.allSettled(projectRoot.map(function(projectRoot)
  {
    const visited = tasksEngine(rules, configs, {context: {projectRoot}})

    const names    = Object.keys(visited)
    const promises = Object.values(visited)

    return Promise.allSettled(promises)
    .then(function(results)
    {
      return results.map(function({reason: error, value: result}, index)
      {
        const name = names[index]
        const {dependsOn, failure, level} = rules[name]

        return {dependsOn, error, failure, level, name, projectRoot, result}
      })
    })
  }))
  .then(projectRootResults)
}

exports.Failure = Failure
<|endoftext|>


<commit_before>var locastyle = locastyle || {};

locastyle.topbarCurtain = (function() {
  'use strict';

  function init() {
    unbind();
    positionTarget();
    bindCloseCurtains();
    bindPreventClosing();
  }

  function unbind() {
    $("[data-ls-module='topbarCurtain']").off("click.ls");
    $(".ls-notification-list").off("click.ls");
    $("body").off("click.lsTopCurtain");
  }

  function positionTarget() {
    $("[data-ls-module='topbarCurtain']").each(function (index, item){
      var leftDistance = $(item).position().left;
      var iconWidth = (22/ 2);
      var curtainWidth = $($(item).data("target")).width() / 2;

      var ua = window.navigator.userAgent;
      var msie = ua.indexOf('MSIE ');
      var trident = ua.indexOf('Trident/');

      if (msie > 0 || trident > 0) {
        $($(item).data("target")).css({left: (leftDistance + iconWidth) - curtainWidth  + "px", top: "60px"});
      } else {
        $($(item).data("target")).css({left: (leftDistance + iconWidth) + curtainWidth  + "px"});
      }

      bindTopCurtainTrigger(item);
    });
  }

  function bindPreventClosing() {
    $(".ls-notification-list").on("click.ls", function(evt) {
      evt.stopPropagation();
    })
  }

  function bindCloseCurtains() {
    $("body").on("click.lsTopCurtain", function () {
      hideCurtains();
    });
  }

  function bindTopCurtainTrigger(trigger) {
    $(trigger).on("click.ls", function(evt){
      evt.stopPropagation();
      var targetState = $($(trigger).data("target")).hasClass("ls-active");
      hideCurtains();
      if(!targetState) {
        $(trigger).addClass("ls-active");
        showCurtain($(trigger).data("target"));
      }
    });
  }

  function showCurtain(curtain) {
    $(curtain).addClass("ls-active");
    locastyle.dropdown.closeDropdown();
  }

  function hideCurtains() {
    $("[data-ls-module='topbarCurtain']").removeClass("ls-active");
    $(".ls-notification-list").removeClass("ls-active");
  }

  return {
    init: init,
    hideCurtains: hideCurtains,
    unbind: unbind
  }

}());
<commit_msg>Creating a function to reposition topbar-curtain when resize window.<commit_after>var locastyle = locastyle || {};

locastyle.topbarCurtain = (function() {
  'use strict';

  function init() {
    unbind();
    positionTarget();
    bindCloseCurtains();
    bindPreventClosing();
    repositionOnResize();
  }

  function unbind() {
    $("[data-ls-module='topbarCurtain']").off("click.ls");
    $(".ls-notification-list").off("click.ls");
    $("body").off("click.lsTopCurtain");
  }

  function positionTarget() {
    $("[data-ls-module='topbarCurtain']").each(function (index, item){
      var leftDistance = $(item).position().left;
      var iconWidth = (22/ 2);
      var curtainWidth = $($(item).data("target")).width() / 2;

      var ua = window.navigator.userAgent;
      var msie = ua.indexOf('MSIE ');
      var trident = ua.indexOf('Trident/');

      if (msie > 0 || trident > 0) {
        $($(item).data("target")).css({left: (leftDistance + iconWidth) - curtainWidth  + "px", top: "60px"});
      } else {
        $($(item).data("target")).css({left: (leftDistance + iconWidth) + curtainWidth  + "px"});
      }

      bindTopCurtainTrigger(item);
    });
  }

  function bindPreventClosing() {
    $(".ls-notification-list").on("click.ls", function(evt) {
      evt.stopPropagation();
    })
  }

  function bindCloseCurtains() {
    $("body").on("click.lsTopCurtain", function () {
      hideCurtains();
    });
  }

  function bindTopCurtainTrigger(trigger) {
    $(trigger).on("click.ls", function(evt){
      evt.stopPropagation();
      var targetState = $($(trigger).data("target")).hasClass("ls-active");
      hideCurtains();
      if(!targetState) {
        $(trigger).addClass("ls-active");
        showCurtain($(trigger).data("target"));
      }
    });
  }

  function showCurtain(curtain) {
    $(curtain).addClass("ls-active");
    locastyle.dropdown.closeDropdown();
  }

  function hideCurtains() {
    $("[data-ls-module='topbarCurtain']").removeClass("ls-active");
    $(".ls-notification-list").removeClass("ls-active");
  }

  function repositionOnResize (argument) {
    window.onresize = function() {
      clearTimeout(repositionTarget);
      var repositionTarget = setTimeout(function() {
      unbind();
      positionTarget();
      bindCloseCurtains();
      bindPreventClosing();
      }, 300);
    };
  }

  return {
    init: init,
    hideCurtains: hideCurtains,
    unbind: unbind
  }

}());
<|endoftext|>