<commit_before>/**
 * Copyright IBM Corp. 2016, 2018
 *
 * This source code is licensed under the Apache-2.0 license found in the
 * LICENSE file in the root directory of this source tree.
 */

import cx from 'classnames';
import Downshift from 'downshift';
import PropTypes from 'prop-types';
import React from 'react';
import { settings } from 'carbon-components';
import WarningFilled16 from '@carbon/icons-react/lib/warning--filled/16';
import ListBox, { PropTypes as ListBoxPropTypes } from '../ListBox';

const { prefix } = settings;

const defaultItemToString = item => {
  if (typeof item === 'string') {
    return item;
  }

  return item ? item.label : '';
};

export default class Dropdown extends React.Component {
  static propTypes = {
    /**
     * Disable the control
     */
    disabled: PropTypes.bool,

    /**
     * We try to stay as generic as possible here to allow individuals to pass
     * in a collection of whatever kind of data structure they prefer
     */
    items: PropTypes.array.isRequired,

    /**
     * Allow users to pass in an arbitrary item or a string (in case their items are an array of strings)
     * from their collection that are pre-selected
     */
    initialSelectedItem: PropTypes.oneOfType([
      PropTypes.object,
      PropTypes.string,
    ]),

    /**
     * Specify a custom `id`
     */
    id: PropTypes.string.isRequired,

    /**
     * Specify whether you want the inline version of this control
     */
    inline: PropTypes.bool,

    /**
     * Specify if the currently selected value is invalid.
     */
    invalid: PropTypes.bool,

    /**
     * Message which is displayed if the value is invalid.
     */
    invalidText: PropTypes.string,

    /**
     * Helper function passed to downshift that allows the library to render a
     * given item to a string label. By default, it extracts the `label` field
     * from a given item to serve as the item label in the list.
     */
    itemToString: PropTypes.func,

    /**
     * Function to render items as custom components instead of strings.
     * Defaults to null and is overriden by a getter
     */
    itemToElement: PropTypes.func,

    /**
     * `onChange` is a utility for this controlled component to communicate to a
     * consuming component what kind of internal state changes are occuring.
     */
    onChange: PropTypes.func,

    /**
     * Generic `label` that will be used as the textual representation of what
     * this field is for
     */
    label: PropTypes.node.isRequired,

    /**
     * 'aria-label' of the ListBox component.
     */
    ariaLabel: PropTypes.string,

    /**
     * The dropdown type, `default` or `inline`
     */
    type: ListBoxPropTypes.ListBoxType,

    /**
     * In the case you want to control the dropdown selection entirely.
     */
    selectedItem: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),

    /**
     * `true` to use the light version.
     */
    light: PropTypes.bool,

    /**
     * Provide the title text that will be read by a screen reader when
     * visiting this control
     */
    titleText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),

    /**
     * Provide helper text that is used alongside the control label for
     * additional help
     */
    helperText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
  };

  static defaultProps = {
    disabled: false,
    type: 'default',
    itemToString: defaultItemToString,
    itemToElement: null,
    light: false,
    titleText: '',
    helperText: '',
  };

  handleOnChange = selectedItem => {
    if (this.props.onChange) {
      this.props.onChange({ selectedItem });
    }
  };

  render() {
    const {
      className: containerClassName,
      disabled,
      items,
      label,
      ariaLabel,
      itemToString,
      itemToElement,
      type,
      initialSelectedItem,
      selectedItem,
      id,
      titleText,
      helperText,
      light,
      invalid,
      invalidText,
    } = this.props;
    const inline = type === 'inline';
    const className = ({ isOpen }) =>
      cx(`${prefix}--dropdown`, containerClassName, {
        [`${prefix}--dropdown--invalid`]: invalid,
        [`${prefix}--dropdown--open`]: isOpen,
        [`${prefix}--dropdown--inline`]: inline,
        [`${prefix}--dropdown--disabled`]: disabled,
        [`${prefix}--dropdown--light`]: light,
      });
    const titleClasses = cx(`${prefix}--label`, {
      [`${prefix}--label--disabled`]: disabled,
    });
    const title = titleText ? (

        {titleText}

    ) : null;
    const helperClasses = cx(`${prefix}--form__helper-text`, {
      [`${prefix}--form__helper-text--disabled`]: disabled,
    });
    const helper = helperText ? (

{helperText}

    ) : null;
    const wrapperClasses = cx(
      `${prefix}--dropdown__wrapper`,
      `${prefix}--list-box__wrapper`,
      {
        [`${prefix}--dropdown__wrapper--inline`]: inline,
        [`${prefix}--list-box__wrapper--inline`]: inline,
        [`${prefix}--dropdown__wrapper--inline--invalid`]: inline && invalid,
        [`${prefix}--list-box__wrapper--inline--invalid`]: inline && invalid,
      }
    );

    // needs to be Capitalized for react to render it correctly
    const ItemToElement = itemToElement;
    return (

        {title}
        {!inline && helper}
        <Downshift
          onChange={this.handleOnChange}
          itemToString={itemToString}
          defaultSelectedItem={initialSelectedItem}
          selectedItem={selectedItem}>
          {({
            isOpen,
            itemToString,
            selectedItem,
            highlightedIndex,
            getRootProps,
            getButtonProps,
            getItemProps,
            getLabelProps,
          }) => (
            <ListBox
              id={id}
              type={type}
              className={className({ isOpen })}
              disabled={disabled}
              isOpen={isOpen}
              invalid={invalid}
              invalidText={invalidText}
              {...getRootProps({ refKey: 'innerRef' })}>
              {invalid && (
                <WarningFilled16
                  className={`${prefix}--list-box__invalid-icon`}
                />
              )}
              <ListBox.Field
                id={id}
                tabIndex="0"
                {...getButtonProps({ disabled })}>
                <span
                  className={`${prefix}--list-box__label`}
                  {...getLabelProps()}>
                  {selectedItem ? itemToString(selectedItem) : label}

                <ListBox.MenuIcon isOpen={isOpen} />
              </ListBox.Field>
              {isOpen && (
                <ListBox.Menu aria-label={ariaLabel} id={id}>
                  {items.map((item, index) => (
                    <ListBox.MenuItem
                      key={itemToString(item)}
                      isActive={selectedItem === item}
                      isHighlighted={
                        highlightedIndex === index || selectedItem === item
                      }
                      {...getItemProps({ item, index })}>
                      {itemToElement ? (
                        <ItemToElement key={itemToString(item)} {...item} />
                      ) : (
                        itemToString(item)
                      )}
                    </ListBox.MenuItem>
                  ))}
                </ListBox.Menu>
              )}
            </ListBox>
          )}
        </Downshift>

    );
  }
}
<commit_msg>fix(Dropdown): pass translationWithId through (#2298)<commit_after>/**
 * Copyright IBM Corp. 2016, 2018
 *
 * This source code is licensed under the Apache-2.0 license found in the
 * LICENSE file in the root directory of this source tree.
 */

import cx from 'classnames';
import Downshift from 'downshift';
import PropTypes from 'prop-types';
import React from 'react';
import { settings } from 'carbon-components';
import WarningFilled16 from '@carbon/icons-react/lib/warning--filled/16';
import ListBox, { PropTypes as ListBoxPropTypes } from '../ListBox';

const { prefix } = settings;

const defaultItemToString = item => {
  if (typeof item === 'string') {
    return item;
  }

  return item ? item.label : '';
};

export default class Dropdown extends React.Component {
  static propTypes = {
    /**
     * Disable the control
     */
    disabled: PropTypes.bool,

    /**
     * We try to stay as generic as possible here to allow individuals to pass
     * in a collection of whatever kind of data structure they prefer
     */
    items: PropTypes.array.isRequired,

    /**
     * Allow users to pass in an arbitrary item or a string (in case their items are an array of strings)
     * from their collection that are pre-selected
     */
    initialSelectedItem: PropTypes.oneOfType([
      PropTypes.object,
      PropTypes.string,
    ]),

    /**
     * Specify a custom `id`
     */
    id: PropTypes.string.isRequired,

    /**
     * Specify whether you want the inline version of this control
     */
    inline: PropTypes.bool,

    /**
     * Specify if the currently selected value is invalid.
     */
    invalid: PropTypes.bool,

    /**
     * Message which is displayed if the value is invalid.
     */
    invalidText: PropTypes.string,

    /**
     * Helper function passed to downshift that allows the library to render a
     * given item to a string label. By default, it extracts the `label` field
     * from a given item to serve as the item label in the list.
     */
    itemToString: PropTypes.func,

    /**
     * Function to render items as custom components instead of strings.
     * Defaults to null and is overriden by a getter
     */
    itemToElement: PropTypes.func,

    /**
     * `onChange` is a utility for this controlled component to communicate to a
     * consuming component what kind of internal state changes are occuring.
     */
    onChange: PropTypes.func,

    /**
     * Generic `label` that will be used as the textual representation of what
     * this field is for
     */
    label: PropTypes.node.isRequired,

    /**
     * Callback function for translating ListBoxMenuIcon SVG title
     */
    translateWithId: PropTypes.func,

    /**
     * 'aria-label' of the ListBox component.
     */
    ariaLabel: PropTypes.string,

    /**
     * The dropdown type, `default` or `inline`
     */
    type: ListBoxPropTypes.ListBoxType,

    /**
     * In the case you want to control the dropdown selection entirely.
     */
    selectedItem: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),

    /**
     * `true` to use the light version.
     */
    light: PropTypes.bool,

    /**
     * Provide the title text that will be read by a screen reader when
     * visiting this control
     */
    titleText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),

    /**
     * Provide helper text that is used alongside the control label for
     * additional help
     */
    helperText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
  };

  static defaultProps = {
    disabled: false,
    type: 'default',
    itemToString: defaultItemToString,
    itemToElement: null,
    light: false,
    titleText: '',
    helperText: '',
  };

  handleOnChange = selectedItem => {
    if (this.props.onChange) {
      this.props.onChange({ selectedItem });
    }
  };

  render() {
    const {
      className: containerClassName,
      disabled,
      items,
      label,
      ariaLabel,
      itemToString,
      itemToElement,
      type,
      initialSelectedItem,
      selectedItem,
      id,
      titleText,
      helperText,
      translateWithId,
      light,
      invalid,
      invalidText,
    } = this.props;
    const inline = type === 'inline';
    const className = ({ isOpen }) =>
      cx(`${prefix}--dropdown`, containerClassName, {
        [`${prefix}--dropdown--invalid`]: invalid,
        [`${prefix}--dropdown--open`]: isOpen,
        [`${prefix}--dropdown--inline`]: inline,
        [`${prefix}--dropdown--disabled`]: disabled,
        [`${prefix}--dropdown--light`]: light,
      });
    const titleClasses = cx(`${prefix}--label`, {
      [`${prefix}--label--disabled`]: disabled,
    });
    const title = titleText ? (

        {titleText}

    ) : null;
    const helperClasses = cx(`${prefix}--form__helper-text`, {
      [`${prefix}--form__helper-text--disabled`]: disabled,
    });
    const helper = helperText ? (

{helperText}

    ) : null;
    const wrapperClasses = cx(
      `${prefix}--dropdown__wrapper`,
      `${prefix}--list-box__wrapper`,
      {
        [`${prefix}--dropdown__wrapper--inline`]: inline,
        [`${prefix}--list-box__wrapper--inline`]: inline,
        [`${prefix}--dropdown__wrapper--inline--invalid`]: inline && invalid,
        [`${prefix}--list-box__wrapper--inline--invalid`]: inline && invalid,
      }
    );

    // needs to be Capitalized for react to render it correctly
    const ItemToElement = itemToElement;
    return (

        {title}
        {!inline && helper}
        <Downshift
          onChange={this.handleOnChange}
          itemToString={itemToString}
          defaultSelectedItem={initialSelectedItem}
          selectedItem={selectedItem}>
          {({
            isOpen,
            itemToString,
            selectedItem,
            highlightedIndex,
            getRootProps,
            getButtonProps,
            getItemProps,
            getLabelProps,
          }) => (
            <ListBox
              id={id}
              type={type}
              className={className({ isOpen })}
              disabled={disabled}
              isOpen={isOpen}
              invalid={invalid}
              invalidText={invalidText}
              {...getRootProps({ refKey: 'innerRef' })}>
              {invalid && (
                <WarningFilled16
                  className={`${prefix}--list-box__invalid-icon`}
                />
              )}
              <ListBox.Field
                id={id}
                tabIndex="0"
                {...getButtonProps({ disabled })}>
                <span
                  className={`${prefix}--list-box__label`}
                  {...getLabelProps()}>
                  {selectedItem ? itemToString(selectedItem) : label}

                <ListBox.MenuIcon
                  isOpen={isOpen}
                  translateWithId={translateWithId}
                />
              </ListBox.Field>
              {isOpen && (
                <ListBox.Menu aria-label={ariaLabel} id={id}>
                  {items.map((item, index) => (
                    <ListBox.MenuItem
                      key={itemToString(item)}
                      isActive={selectedItem === item}
                      isHighlighted={
                        highlightedIndex === index || selectedItem === item
                      }
                      {...getItemProps({ item, index })}>
                      {itemToElement ? (
                        <ItemToElement key={itemToString(item)} {...item} />
                      ) : (
                        itemToString(item)
                      )}
                    </ListBox.MenuItem>
                  ))}
                </ListBox.Menu>
              )}
            </ListBox>
          )}
        </Downshift>

    );
  }
}
<|endoftext|>


<commit_before>/**
 * @typedef {Object} Language
 * @property {string} name
 * @property {string} type
 * @property {string} scope
 * @property {string} iso6393
 * @property {string} [iso6392B]
 * @property {string} [iso6392T]
 * @property {string} [iso6391]
 */

import assert from 'node:assert'
import fs from 'node:fs'
import path from 'node:path'
import https from 'node:https'
import concatStream from 'concat-stream'
import yauzl from 'yauzl'
import {tsvParse} from 'd3-dsv'
import {bail} from 'bail'

/** @type {string[]} */
const other = []
let found = false

/** @type {Record<string, string>} */
const scopes = {
  I: 'individual',
  M: 'macrolanguage',
  S: 'special'
}

/** @type {Record<string, string>} */
const types = {
  A: 'ancient',
  C: 'constructed',
  E: 'extinct',
  H: 'historical',
  L: 'living',
  S: 'special'
}

// Note:
// You can find download links here:
// <https://iso639-3.sil.org/code_tables/download_tables>
// Just get the complete code tables in UTF-8.
const url =
  'https://iso639-3.sil.org/sites/iso639-3/files/downloads/iso-639-3_Code_Tables_20200515.zip'
const expectedName = 'iso-639-3_20200515.tab'

https.request(url, onrequest).end()

/**
 * @param {import('http').IncomingMessage} request
 */
function onrequest(request) {
  request
    .pipe(fs.createWriteStream('archive.zip'))
    .on('close', onclose)
    .on('error', bail)
}

function onclose() {
  yauzl.open('archive.zip', {lazyEntries: true}, (error, archive) => {
    bail(error)
    assert(archive, 'expecter `archive` if w/o error')

    read()

    archive.on(
      'entry',
      /**
       * @param {import('yauzl').Entry} entry
       */ (entry) => {
        const name = path.basename(entry.fileName)

        if (name !== expectedName) {
          other.push(name)
          return read()
        }

        found = true
        archive.openReadStream(entry, (error, rs) => {
          bail(error)
          assert(rs, 'expecter readable stream if w/o error')
          rs.pipe(concatStream(onconcat)).on('error', bail)
          rs.on('end', read)
        })
      }
    )

    archive.on('end', () => {
      if (!found) {
        throw new Error('File not found, pick one of: `' + other + '`')
      }
    })

    function read() {
      assert(archive, 'expecter `archive` if w/o error')
      archive.readEntry()
    }
  })
}

/**
 * @param {Buffer} body
 */
function onconcat(body) {
  const data = tsvParse(String(body)).map((d) => {
    const name = d.Ref_Name
    const id = d.Id
    const languageType = d.Language_Type
    const languageScope = d.Scope
    assert(typeof name === 'string', 'expected language w/ names')
    assert(typeof languageType === 'string', 'expected language w/ types')
    assert(typeof languageScope === 'string', 'expected language w/ scopes')
    assert(typeof id === 'string', 'expected language w/ ids')
    assert(languageType in types, 'expected language w/ types')
    assert(languageScope in scopes, 'expected language w/ scopes')

    /** @type {Language} */
    const result = {
      name,
      type: types[languageType],
      scope: scopes[languageScope],
      iso6393: id,
      iso6392B: d.Part2B || undefined,
      iso6392T: d.Part2T || undefined,
      iso6391: d.Part1 || undefined
    }

    return result
  })

  /** @type {Record<string, string>} */
  const toB = {}
  /** @type {Record<string, string>} */
  const toT = {}
  /** @type {Record<string, string>} */
  const to1 = {}
  let index = -1

  while (++index < data.length) {
    const d = data[index]
    if (d.iso6392B) toB[d.iso6393] = d.iso6392B
    if (d.iso6392T) toT[d.iso6393] = d.iso6392T
    if (d.iso6391) to1[d.iso6393] = d.iso6391
  }

  fs.writeFile(
    'iso6393.js',
    [
      '/**',
      " * @typedef {'living'|'historical'|'extinct'|'ancient'|'constructed'|'special'} Type",
      ' *   Category of a language:',
      ' *',
      " *   *   `'living'`",
      ' *       — currently spoken language',
      ' *       (example: `nhi` for `Zacatlán-Ahuacatlán-Tepetzintla Nahuatl`)',
      " *   *   `'historical'`",
      ' *       — extinct language distinct from modern languages that descended from it',
      ' *       (example: `ofs` for `Old Frisian`)',
      " *   *   `'extinct'`",
      ' *       — language that went extinct recently',
      ' *       (example: `rbp` for `Barababaraba`)',
      " *   *   `'ancient'`",
      ' *       — language that went extinct long ago',
      ' *       (example: `got` for `Gothic`)',
      " *   *   `'constructed'`",
      ' *       — artificial languages, excluding programming languages',
      ' *       (example: `epo` for `Esperanto`)',
      " *   *   `'special'`",
      ' *       — non-language codes',
      ' *       (example: `und` for `Undetermined`)',
      ' *',
      " * @typedef {'individual'|'macrolanguage'|'special'} Scope",
      ' *   Scope of a language:',
      ' *',
      " *   *   `'individual'`",
      ' *       — normal, single language',
      ' *       (example: `eng` for `English`)',
      " *   *   `'macrolanguage'`",
      ' *       — one-to-many grouping of languages, because older ISO 639s included them',
      ' *       (example: `ara` for `Arabic`)',
      " *   *   `'special'`",
      ' *       — non-language codes',
      ' *       (example: `und` for `Undetermined`)',
      ' *',
      ' * @typedef Language',
      ' *   Object representing a language.',
      ' * @property {string} name',
      " *   Name (example: `'English'`).",
      ' * @property {Type} type',
      " *   Type (example: `'living'`).",
      ' * @property {Scope} scope',
      " *   Scope (example: `'individual'`)",
      ' * @property {string} iso6393',
      ' *   ISO 639-3 code.',
      ' * @property {string} [iso6392B]',
      " *   ISO 639-2 (bibliographic) code (example: `'eng'`).",
      ' * @property {string} [iso6392T]',
      " *   ISO 639-2 (terminologic) code (example: `'eng'`).",
      ' * @property {string} [iso6391]',
      " *   ISO 639-1 code (example: `'en'`).",
      ' */',
      '',
      '/**',
      ' * List of ISO 639-3 languages.',
      ' *',
      ' * @type {Array<Language>}',
      ' */',
      '// @ts-expect-error',
      'export const iso6393 = ' + JSON.stringify(data, null, 2),
      ''
    ].join('\n'),
    bail
  )
  fs.writeFile(
    'iso6393-to-1.js',
    [
      '/**',
      ' * Map of ISO 639-3 codes to ISO 639-1 codes.',
      ' *',
      ' * @type {Record<string, string>}',
      ' */',
      'export const iso6393To1 = ' + JSON.stringify(to1, null, 2),
      ''
    ].join('\n'),
    bail
  )
  fs.writeFile(
    'iso6393-to-2b.js',
    [
      '/**',
      ' * Map of ISO 639-3 codes to bibliographic ISO 639-2 codes.',
      ' *',
      ' * @type {Record<string, string>}',
      ' */',
      'export const iso6393To2B = ' + JSON.stringify(toB, null, 2),
      ''
    ].join('\n'),
    bail
  )
  fs.writeFile(
    'iso6393-to-2t.js',
    [
      '/**',
      ' * Map of ISO 639-3 codes to terminologic ISO 639-2 codes.',
      ' *',
      ' * @type {Record<string, string>}',
      ' */',
      'export const iso6393To2T = ' + JSON.stringify(toT, null, 2),
      ''
    ].join('\n'),
    bail
  )
}
<commit_msg>Refactor build script<commit_after>/**
 * @typedef {Object} Language
 * @property {string} name
 * @property {string} type
 * @property {string} scope
 * @property {string} iso6393
 * @property {string} [iso6392B]
 * @property {string} [iso6392T]
 * @property {string} [iso6391]
 */

import assert from 'node:assert/strict'
import fs from 'node:fs'
import path from 'node:path'
import https from 'node:https'
import concatStream from 'concat-stream'
import yauzl from 'yauzl'
import {tsvParse} from 'd3-dsv'
import {bail} from 'bail'

/** @type {string[]} */
const other = []
let found = false

/** @type {Record<string, string>} */
const scopes = {
  I: 'individual',
  M: 'macrolanguage',
  S: 'special'
}

/** @type {Record<string, string>} */
const types = {
  A: 'ancient',
  C: 'constructed',
  E: 'extinct',
  H: 'historical',
  L: 'living',
  S: 'special'
}

// Note:
// You can find download links here:
// <https://iso639-3.sil.org/code_tables/download_tables>
// Just get the complete code tables in UTF-8.
const url =
  'https://iso639-3.sil.org/sites/iso639-3/files/downloads/iso-639-3_Code_Tables_20200515.zip'
const expectedName = 'iso-639-3_20200515.tab'

https.request(url, onrequest).end()

/**
 * @param {import('http').IncomingMessage} request
 */
function onrequest(request) {
  request
    .pipe(fs.createWriteStream('archive.zip'))
    .on('close', onclose)
    .on('error', bail)
}

function onclose() {
  yauzl.open('archive.zip', {lazyEntries: true}, (error, archive) => {
    bail(error)
    assert(archive, 'expecter `archive` if w/o error')

    read()

    archive.on(
      'entry',
      /**
       * @param {import('yauzl').Entry} entry
       */ (entry) => {
        const name = path.basename(entry.fileName)

        if (name !== expectedName) {
          other.push(name)
          return read()
        }

        found = true
        archive.openReadStream(entry, (error, rs) => {
          bail(error)
          assert(rs, 'expecter readable stream if w/o error')
          rs.pipe(concatStream(onconcat)).on('error', bail)
          rs.on('end', read)
        })
      }
    )

    archive.on('end', () => {
      if (!found) {
        throw new Error('File not found, pick one of: `' + other + '`')
      }
    })

    function read() {
      assert(archive, 'expecter `archive` if w/o error')
      archive.readEntry()
    }
  })
}

/**
 * @param {Buffer} body
 */
async function onconcat(body) {
  const data = tsvParse(String(body)).map((d) => {
    const name = d.Ref_Name
    const id = d.Id
    const languageType = d.Language_Type
    const languageScope = d.Scope
    assert(typeof name === 'string', 'expected language w/ names')
    assert(typeof languageType === 'string', 'expected language w/ types')
    assert(typeof languageScope === 'string', 'expected language w/ scopes')
    assert(typeof id === 'string', 'expected language w/ ids')
    assert(languageType in types, 'expected language w/ types')
    assert(languageScope in scopes, 'expected language w/ scopes')

    /** @type {Language} */
    const result = {
      name,
      type: types[languageType],
      scope: scopes[languageScope],
      iso6393: id,
      iso6392B: d.Part2B || undefined,
      iso6392T: d.Part2T || undefined,
      iso6391: d.Part1 || undefined
    }

    return result
  })

  /** @type {Record<string, string>} */
  const toB = {}
  /** @type {Record<string, string>} */
  const toT = {}
  /** @type {Record<string, string>} */
  const to1 = {}
  let index = -1

  while (++index < data.length) {
    const d = data[index]
    if (d.iso6392B) toB[d.iso6393] = d.iso6392B
    if (d.iso6392T) toT[d.iso6393] = d.iso6392T
    if (d.iso6391) to1[d.iso6393] = d.iso6391
  }

  await fs.promises.writeFile(
    'iso6393.js',
    [
      '/**',
      " * @typedef {'living'|'historical'|'extinct'|'ancient'|'constructed'|'special'} Type",
      ' *   Category of a language:',
      ' *',
      " *   *   `'living'`",
      ' *       — currently spoken language',
      ' *       (example: `nhi` for `Zacatlán-Ahuacatlán-Tepetzintla Nahuatl`)',
      " *   *   `'historical'`",
      ' *       — extinct language distinct from modern languages that descended from it',
      ' *       (example: `ofs` for `Old Frisian`)',
      " *   *   `'extinct'`",
      ' *       — language that went extinct recently',
      ' *       (example: `rbp` for `Barababaraba`)',
      " *   *   `'ancient'`",
      ' *       — language that went extinct long ago',
      ' *       (example: `got` for `Gothic`)',
      " *   *   `'constructed'`",
      ' *       — artificial languages, excluding programming languages',
      ' *       (example: `epo` for `Esperanto`)',
      " *   *   `'special'`",
      ' *       — non-language codes',
      ' *       (example: `und` for `Undetermined`)',
      ' *',
      " * @typedef {'individual'|'macrolanguage'|'special'} Scope",
      ' *   Scope of a language:',
      ' *',
      " *   *   `'individual'`",
      ' *       — normal, single language',
      ' *       (example: `eng` for `English`)',
      " *   *   `'macrolanguage'`",
      ' *       — one-to-many grouping of languages, because older ISO 639s included them',
      ' *       (example: `ara` for `Arabic`)',
      " *   *   `'special'`",
      ' *       — non-language codes',
      ' *       (example: `und` for `Undetermined`)',
      ' *',
      ' * @typedef Language',
      ' *   Object representing a language.',
      ' * @property {string} name',
      " *   Name (example: `'English'`).",
      ' * @property {Type} type',
      " *   Type (example: `'living'`).",
      ' * @property {Scope} scope',
      " *   Scope (example: `'individual'`)",
      ' * @property {string} iso6393',
      ' *   ISO 639-3 code.',
      ' * @property {string} [iso6392B]',
      " *   ISO 639-2 (bibliographic) code (example: `'eng'`).",
      ' * @property {string} [iso6392T]',
      " *   ISO 639-2 (terminologic) code (example: `'eng'`).",
      ' * @property {string} [iso6391]',
      " *   ISO 639-1 code (example: `'en'`).",
      ' */',
      '',
      '/**',
      ' * List of ISO 639-3 languages.',
      ' *',
      ' * @type {Array<Language>}',
      ' */',
      '// @ts-expect-error',
      'export const iso6393 = ' + JSON.stringify(data, null, 2),
      ''
    ].join('\n')
  )

  await fs.promises.writeFile(
    'iso6393-to-1.js',
    [
      '/**',
      ' * Map of ISO 639-3 codes to ISO 639-1 codes.',
      ' *',
      ' * @type {Record<string, string>}',
      ' */',
      'export const iso6393To1 = ' + JSON.stringify(to1, null, 2),
      ''
    ].join('\n')
  )

  await fs.promises.writeFile(
    'iso6393-to-2b.js',
    [
      '/**',
      ' * Map of ISO 639-3 codes to bibliographic ISO 639-2 codes.',
      ' *',
      ' * @type {Record<string, string>}',
      ' */',
      'export const iso6393To2B = ' + JSON.stringify(toB, null, 2),
      ''
    ].join('\n')
  )

  await fs.promises.writeFile(
    'iso6393-to-2t.js',
    [
      '/**',
      ' * Map of ISO 639-3 codes to terminologic ISO 639-2 codes.',
      ' *',
      ' * @type {Record<string, string>}',
      ' */',
      'export const iso6393To2T = ' + JSON.stringify(toT, null, 2),
      ''
    ].join('\n')
  )
}
<|endoftext|>


<commit_before>'use strict';

var mongoose = require('mongoose');
var mockgoose = require('mockgoose');
var Promise = require('bluebird');
var recent = require('../index');
var chai = require('chai');
chai.should();
var expect = chai.expect;

mockgoose(mongoose);

describe('mongoose-recent', function() {
  var Schema;

  beforeEach(function() {
    Schema = new mongoose.Schema({}, { strict: false });
  });

  it('should use default options', function() {
    Schema.plugin(recent);
    var Test = mongoose.model('TestSmoke', Schema);
    var testDoc = new Test();

    expect(testDoc.recentViews).to.exist;
    expect(testDoc.addRecentView).to.exist;
    return testDoc.addRecentView(mongoose.Types.ObjectId()).spread(function(me) {
      expect(me.recentViews[0].view).to.exist;
      expect(me.recentViews[0].date).to.exist;
    });
  });

  it('should allow changing the name and date field name', function() {
    Schema.plugin(recent, {name: 'play', dateFieldName: 'time'});
    var Test = mongoose.model('TestChanging', Schema);
    var testDoc = new Test();

    expect(testDoc.recentPlays).to.exist;
    expect(testDoc.addRecentPlay).to.exist;
    return testDoc.addRecentPlay(mongoose.Types.ObjectId()).spread(function(me) {
      expect(me.recentPlays[0].play).to.exist;
      expect(me.recentPlays[0].time).to.exist;
    });
  });

  it('should allow fully specifying the schema names', function() {
    Schema.plugin(recent, {name: 'foo', collectionPath: 'myAwesomeCollection', addFunctionName: 'soYouWantToAdd'});
    var Test = mongoose.model('TestFullSpec', Schema);
    var testDoc = new Test();

    expect(testDoc.myAwesomeCollection).to.exist;
    expect(testDoc.soYouWantToAdd).to.exist;
    return testDoc.soYouWantToAdd(mongoose.Types.ObjectId()).spread(function(me) {
      expect(me.myAwesomeCollection[0].foo).to.exist;
    });
  });

  it('should not overwrite a field that already exists', function() {
    var OverwriteSchema = new mongoose.Schema({
      recentViews: String
    }, { strict: false });

    OverwriteSchema.plugin(recent);
    expect(OverwriteSchema.paths.recentViews.instance).to.eql('String');
  });

  it('should not allow duplicates by default', function() {
    Schema.plugin(recent);
    var Test = mongoose.model('TestNoDupe', Schema);
    var testDoc = new Test();

    var id1 = mongoose.Types.ObjectId();
    return testDoc.addRecentView(id1).then(function() {
      return testDoc.addRecentView(mongoose.Types.ObjectId());
    }).then(function() {
      return testDoc.addRecentView(id1);
    }).spread(function(me) {
      me.recentViews.should.have.length(2);
      me.recentViews[0].view.should.eql(id1);
    });
  });

  it('should allow duplicates if specified', function() {
    Schema.plugin(recent, { allowDuplicates: true });
    var Test = mongoose.model('TestDupes', Schema);
    var testDoc = new Test();

    var id1 = mongoose.Types.ObjectId();
    return testDoc.addRecentView(id1).then(function() {
      return testDoc.addRecentView(mongoose.Types.ObjectId());
    }).delay(10).then(function() {
      return testDoc.addRecentView(id1);
    }).spread(function(me) {
      me.recentViews.should.have.length(3);
      me.recentViews[0].view.should.eql(id1);
      me.recentViews[2].view.should.eql(id1);
    });
  });

  it('should allow a different type of id', function() {
    Schema.plugin(recent, { schemaType: String });
    var Test = mongoose.model('TestDifferentIds', Schema);
    var testDoc = new Test();

    return testDoc.addRecentView('id1').then(function() {
      return testDoc.addRecentView('id2');
    }).delay(10).then(function() {
      return testDoc.addRecentView('id1');
    }).spread(function(me) {
      me.recentViews.should.have.length(2);
      me.recentViews[0].view.should.eql('id1');
      me.recentViews[1].view.should.eql('id2');
    });
  });

  it('should allow an object instead of an id', function() {
    Schema.plugin(recent, { schemaType: { foo: String, bar: {type: String, 'default': 'whee'} } });
    var Test = mongoose.model('TestObjects', Schema);
    var testDoc = new Test();

    return testDoc.addRecentView({foo: 'ha'}).spread(function(me) {
      me.recentViews.should.have.length(1);
      me.recentViews[0].view.toObject().should.eql({foo: 'ha', bar: 'whee'});
    });
  });

  it('should use the passed compare function', function() {
    var compareFunc = function(o1, o2) {
      return o1.foo === o2.foo;
    };

    Schema.plugin(recent, { schemaType: { foo: String }, compareFunc: compareFunc } );
    var Test = mongoose.model('TestCompare', Schema);
    var testDoc = new Test();

    return testDoc.addRecentView({foo: 'ha'}).then(function() {
      return testDoc.addRecentView({foo: 'ya'});
    }).delay(10).then(function() {
      return testDoc.addRecentView({foo: 'ha'});
    }).spread(function(me) {
      me.recentViews.should.have.length(2);
      me.recentViews[0].view.toObject().should.eql({foo: 'ha'});
    });
  });

  it('should allow using a callback', function(done) {
    Schema.plugin(recent);
    var Test = mongoose.model('TestCallback', Schema);
    var testDoc = new Test();

    testDoc.addRecentView(mongoose.Types.ObjectId(), function(err, me) {
      expect(err).to.not.exist;
      expect(me.recentViews).to.exist;
      done();
    });
  });

  it('should use the passed number of records to keep', function() {
    Schema.plugin(recent, { numToKeep: 3 });
    var Test = mongoose.model('TestNumToKeep', Schema);
    var testDoc = new Test();

    var views = [];
    for (var i = 0; i < 4; i++) {
      views.push(testDoc.addRecentView(mongoose.Types.ObjectId()));
    }

    Promise.all(views).then(function() {
      testDoc.recentViews.should.have.length(3);
    });
  });

  it('should allow using a static function', function() {
    Schema.plugin(recent);
    var Test = mongoose.model('TestStatic', Schema);
    var testDoc = new Test();

    testDoc.saveAsync().spread(function(me) {
      return Test.addRecentView({_id: me._id}, mongoose.Types.ObjectId());
    }).spread(function(me) {
      me._id.should.eql(testDoc._id);
      me.recentViews.should.have.length(1);
    });
  });

  it('should allow using a static function with a callback', function(done) {
    Schema.plugin(recent);
    var Test = mongoose.model('TestStaticCallback', Schema);
    var testDoc = new Test();

    testDoc.saveAsync().spread(function(me) {
      Test.addRecentView({_id: me._id}, mongoose.Types.ObjectId(), function(err, me) {
        expect(err).to.not.exist;

        me._id.should.eql(testDoc._id);
        me.recentViews.should.have.length(1);
        done();
      });
    });
  });
});
<commit_msg>Actually return the promise in test.<commit_after>'use strict';

var mongoose = require('mongoose');
var mockgoose = require('mockgoose');
var Promise = require('bluebird');
var recent = require('../index');
var chai = require('chai');
chai.should();
var expect = chai.expect;

mockgoose(mongoose);

describe('mongoose-recent', function() {
  var Schema;

  beforeEach(function() {
    Schema = new mongoose.Schema({}, { strict: false });
  });

  it('should use default options', function() {
    Schema.plugin(recent);
    var Test = mongoose.model('TestSmoke', Schema);
    var testDoc = new Test();

    expect(testDoc.recentViews).to.exist;
    expect(testDoc.addRecentView).to.exist;
    return testDoc.addRecentView(mongoose.Types.ObjectId()).spread(function(me) {
      expect(me.recentViews[0].view).to.exist;
      expect(me.recentViews[0].date).to.exist;
    });
  });

  it('should allow changing the name and date field name', function() {
    Schema.plugin(recent, {name: 'play', dateFieldName: 'time'});
    var Test = mongoose.model('TestChanging', Schema);
    var testDoc = new Test();

    expect(testDoc.recentPlays).to.exist;
    expect(testDoc.addRecentPlay).to.exist;
    return testDoc.addRecentPlay(mongoose.Types.ObjectId()).spread(function(me) {
      expect(me.recentPlays[0].play).to.exist;
      expect(me.recentPlays[0].time).to.exist;
    });
  });

  it('should allow fully specifying the schema names', function() {
    Schema.plugin(recent, {name: 'foo', collectionPath: 'myAwesomeCollection', addFunctionName: 'soYouWantToAdd'});
    var Test = mongoose.model('TestFullSpec', Schema);
    var testDoc = new Test();

    expect(testDoc.myAwesomeCollection).to.exist;
    expect(testDoc.soYouWantToAdd).to.exist;
    return testDoc.soYouWantToAdd(mongoose.Types.ObjectId()).spread(function(me) {
      expect(me.myAwesomeCollection[0].foo).to.exist;
    });
  });

  it('should not overwrite a field that already exists', function() {
    var OverwriteSchema = new mongoose.Schema({
      recentViews: String
    }, { strict: false });

    OverwriteSchema.plugin(recent);
    expect(OverwriteSchema.paths.recentViews.instance).to.eql('String');
  });

  it('should not allow duplicates by default', function() {
    Schema.plugin(recent);
    var Test = mongoose.model('TestNoDupe', Schema);
    var testDoc = new Test();

    var id1 = mongoose.Types.ObjectId();
    return testDoc.addRecentView(id1).then(function() {
      return testDoc.addRecentView(mongoose.Types.ObjectId());
    }).then(function() {
      return testDoc.addRecentView(id1);
    }).spread(function(me) {
      me.recentViews.should.have.length(2);
      me.recentViews[0].view.should.eql(id1);
    });
  });

  it('should allow duplicates if specified', function() {
    Schema.plugin(recent, { allowDuplicates: true });
    var Test = mongoose.model('TestDupes', Schema);
    var testDoc = new Test();

    var id1 = mongoose.Types.ObjectId();
    return testDoc.addRecentView(id1).then(function() {
      return testDoc.addRecentView(mongoose.Types.ObjectId());
    }).delay(10).then(function() {
      return testDoc.addRecentView(id1);
    }).spread(function(me) {
      me.recentViews.should.have.length(3);
      me.recentViews[0].view.should.eql(id1);
      me.recentViews[2].view.should.eql(id1);
    });
  });

  it('should allow a different type of id', function() {
    Schema.plugin(recent, { schemaType: String });
    var Test = mongoose.model('TestDifferentIds', Schema);
    var testDoc = new Test();

    return testDoc.addRecentView('id1').then(function() {
      return testDoc.addRecentView('id2');
    }).delay(10).then(function() {
      return testDoc.addRecentView('id1');
    }).spread(function(me) {
      me.recentViews.should.have.length(2);
      me.recentViews[0].view.should.eql('id1');
      me.recentViews[1].view.should.eql('id2');
    });
  });

  it('should allow an object instead of an id', function() {
    Schema.plugin(recent, { schemaType: { foo: String, bar: {type: String, 'default': 'whee'} } });
    var Test = mongoose.model('TestObjects', Schema);
    var testDoc = new Test();

    return testDoc.addRecentView({foo: 'ha'}).spread(function(me) {
      me.recentViews.should.have.length(1);
      me.recentViews[0].view.toObject().should.eql({foo: 'ha', bar: 'whee'});
    });
  });

  it('should use the passed compare function', function() {
    var compareFunc = function(o1, o2) {
      return o1.foo === o2.foo;
    };

    Schema.plugin(recent, { schemaType: { foo: String }, compareFunc: compareFunc } );
    var Test = mongoose.model('TestCompare', Schema);
    var testDoc = new Test();

    return testDoc.addRecentView({foo: 'ha'}).then(function() {
      return testDoc.addRecentView({foo: 'ya'});
    }).delay(10).then(function() {
      return testDoc.addRecentView({foo: 'ha'});
    }).spread(function(me) {
      me.recentViews.should.have.length(2);
      me.recentViews[0].view.toObject().should.eql({foo: 'ha'});
    });
  });

  it('should allow using a callback', function(done) {
    Schema.plugin(recent);
    var Test = mongoose.model('TestCallback', Schema);
    var testDoc = new Test();

    testDoc.addRecentView(mongoose.Types.ObjectId(), function(err, me) {
      expect(err).to.not.exist;
      expect(me.recentViews).to.exist;
      done();
    });
  });

  it('should use the passed number of records to keep', function() {
    Schema.plugin(recent, { numToKeep: 3 });
    var Test = mongoose.model('TestNumToKeep', Schema);
    var testDoc = new Test();

    var views = [];
    for (var i = 0; i < 4; i++) {
      views.push(testDoc.addRecentView(mongoose.Types.ObjectId()));
    }

    Promise.all(views).then(function() {
      testDoc.recentViews.should.have.length(3);
    });
  });

  it('should allow using a static function', function() {
    Schema.plugin(recent);
    var Test = mongoose.model('TestStatic', Schema);
    var testDoc = new Test();

    return testDoc.saveAsync().spread(function(me) {
      return Test.addRecentView({_id: me._id}, mongoose.Types.ObjectId());
    }).spread(function(me) {
      me._id.should.eql(testDoc._id);
      me.recentViews.should.have.length(1);
    });
  });

  it('should allow using a static function with a callback', function(done) {
    Schema.plugin(recent);
    var Test = mongoose.model('TestStaticCallback', Schema);
    var testDoc = new Test();

    testDoc.saveAsync().spread(function(me) {
      Test.addRecentView({_id: me._id}, mongoose.Types.ObjectId(), function(err, me) {
        expect(err).to.not.exist;

        me._id.should.eql(testDoc._id);
        me.recentViews.should.have.length(1);
        done();
      });
    });
  });
});
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react';
import Styles from './main.scss';
import Grids from 'theme/Grid.scss';
import PixelPerfect from 'components/PixelPerfect/component';
import BreakPoints from 'components/PixelPerfect/breakpoints';

export default function Breadcrumbs(props) {
    const templates = [
        BreakPoints.tabletPortrait.name,
        BreakPoints.tabletLandscape.name
    ];

    const { mediaType } =  props;

    return (
        <PixelPerfect templates={ templates } component="breadcrumbs">

Главная

                            { [
                                BreakPoints.tabletLandscape.name
                            ].indexOf(mediaType) !== -1 ? (
                                Список программ
                            ) : null }
                            { [
                                BreakPoints.tabletPortrait.name
                            ].indexOf(mediaType) !== -1 ? (
                                Где нас смотреть?
                            ) : null }

        </PixelPerfect>
    );
}

Breadcrumbs.propTypes = {
    mediaType: PropTypes.string.isRequired
};
<commit_msg>fixed visibility<commit_after>import React, { PropTypes } from 'react';
import Styles from './main.scss';
import Grids from 'theme/Grid.scss';
import PixelPerfect from 'components/PixelPerfect/component';
import BreakPoints from 'components/PixelPerfect/breakpoints';

export default function Breadcrumbs(props) {
    const templates = [
        BreakPoints.tabletPortrait.name,
        BreakPoints.tabletLandscape.name
    ];

    const { mediaType } =  props;

    if ([
        BreakPoints.phonePortrait.name,
        BreakPoints.phoneLandscape.name].indexOf(mediaType) !== -1) {
        return null;
    }

    return (
        <PixelPerfect templates={ templates } component="breadcrumbs">

Главная

                            { [
                                BreakPoints.tabletLandscape.name
                            ].indexOf(mediaType) !== -1 ? (

Список программ

                            ) : null }
                            { [
                                BreakPoints.tabletPortrait.name
                            ].indexOf(mediaType) !== -1 ? (

Где нас смотреть?

                            ) : null }

        </PixelPerfect>
    );
}

Breadcrumbs.propTypes = {
    mediaType: PropTypes.string.isRequired
};
<|endoftext|>


<commit_before>// The portion of the React app to represent a message one may send to the user.
var Message = React.createClass({
    render: function () {
        return (

{this.props.message}

        );
    }
});

// The portion of the React app that is the input form.
var Form = React.createClass({
    render: function () {
        return (
            <form method="post" action="/" enctype="multipart/form-data">

            </form>
        );
    }
});

// The primary host application for the React app.
var App = React.createClass({
    getInitialState: function () {
        return {
            message: 'No message yet!'
        };
    },

    setMessage: function (message) {
        this.setState({ message: message });
    },

    render: function () {
        return (

{this.state.message}

                <Form setMessage={this.setMessage} />

        );
    }
});

// Rendering the app once the page has loaded.
$(document).ready(function () {
    React.render((
        <App />
    ), $('#reactWrapper')[0]);
});
<commit_msg>Starting to implement the actual form and reaction and stuff.<commit_after>// The portion of the React app to represent a message one may send to the user.
var Message = React.createClass({
    render: function () {
        return (

{this.props.message}

        );
    }
});

// The portion of the React app that is the input form.
var Form = React.createClass({
    onSubmit: function (e) {
        e.preventDefault();
    },

    render: function () {
        return (
            <form onSubmit={this.onSubmit}>

                    Upload something:
                    <input ref="fileInput" type="file" required />

                <button className="btn btn-default" type="submit">Upload</button>
            </form>
        );
    }
});

// The primary host application for the React app.
var App = React.createClass({
    getInitialState: function () {
        return {
            message: 'No message yet!'
        };
    },

    setMessage: function (message) {
        this.setState({ message: message });
    },

    render: function () {
        return (

{this.state.message}

                <Form setMessage={this.setMessage} />

        );
    }
});

// Rendering the app once the page has loaded.
$(document).ready(function () {
    React.render((
        <App />
    ), $('#reactWrapper')[0]);
});
<|endoftext|>


<commit_before>/**
 * Created by tamas on 1/9/15.
 */
//these tests intended to ensure that every used feature of mongodb and its used client is work as expected

describe('MONGO',function(){
  var MONGO = require('mongodb'),
    db,collection,collName = 'mongotest___test',
    fsyncDatabase = function(callback) {

      var error = null;
      var synced = 0;

      /*function fsyncConnection (conn) {
        db.lastError({
          fsync: true
        }, {
          connection: conn
        }, function (err, res) {
          // ignoring the last error, just forcing all commands through
          error = error || err;

          if (++synced === conns.length) {
            callback(error);
          }
        });
      }*/
      function fsyncConnection (conn) {
        db.command({ getLastError: 1 },{connection:conn},
          function(err,result){
            //TODO we ignore the result right now
            error = error || err;
            if (++synced === conns.length) {
              callback(error);
            }
          });
      }

      var conns = db.serverConfig.allRawConnections();
      if (conns instanceof Array && conns.length >= 1) {
        for ( var i = 0; i < conns.length; ++i) {
          fsyncConnection(conns[i]);
        }
      } else {
        callback(new Error("not connected"));
      }
    };
  before(function(done){
    MONGO.MongoClient.connect("mongodb://127.0.0.1/mongotest",{
      'w':1,
      'native-parser':true,
      'auto_reconnect': true,
      'poolSize': 20,
      socketOptions: {keepAlive: 1}
    },function(err,d){
      if(!err && d){
        db = d;

        for(var i in db){
          console.warn('DB - ',i);
        }
        db.collection(collName, function (err, result) {
          if (err) {
            done(err);
          } else {
            collection = result;
            done();
          }
        });
      } else {
        db = null;
        done(err);
      }
    });
  });
  after(function(done){
    db.dropCollection(collName, function (err) {
      db.close(done);
    });
  });
  it('insert some objects and in a parallel insertion uses fsync and checks if really everything is in place',function(done){
    var i,filler="",normalItemCount = 100,error=null,
      addObject = function(index){
        console.warn('object insertion started ',index);
        collection.insert({data:filler},function(err){
          console.warn('object insertion returned ',index);
          error = error ||err;
          if(--normalItemCount === 0){
            finishedAll();
          }
        });
      },
      finishedAll = function(){
        done(error);
      };
    for(i=0;i<1000;i++){
      filler+=String.fromCharCode(Math.floor(Math.random()*255));
    }

    for(i=0;i<99;i++){
      addObject(i);
    }
    fsyncDatabase(function(err){
      error = error || err;
      collection.insert({data:filler,extra:'should be the last element'},function(err){
        error = error || err;
        if(--normalItemCount !== 0){
          error = new Error('fsync not functioning!!! '+normalItemCount);
        } else {
          finishedAll();
        }
      });
    });
  });
  it('insert some object paralelly then checks if the order really gets mixed',function(done){
    var i,filler="",normalItemCount = 101,error=null,
      addObject = function(index){
        console.warn('object insertion started ',index);
        collection.insert({data:filler},function(err){
          console.warn('object insertion returned ',index);
          error = error ||err;
          if(--normalItemCount === 0){
            finishedAll();
          }
        });
      },
      finishedAll = function(){
        done(error);
      };
    for(i=0;i<1000;i++){
      filler+=String.fromCharCode(Math.floor(Math.random()*255));
    }

    for(i=0;i<100;i++){
      addObject(i);
    }
    console.warn('special start');
    collection.insert({data:filler,extra:'should get a mixed order'},function(err){
      console.warn('special finished');
      error = error || err;
      if(--normalItemCount === 0){
        error = new Error('insertions do not get mixed'+normalItemCount);
        finishedAll();
      }
    });
  });
});<commit_msg>#129 remove unused mongo test<commit_after>/**
 * Created by tamas on 1/9/15.
 */
//these tests intended to ensure that every used feature of mongodb and its used client is work as expected

describe('MONGO',function(){
  var MONGO = require('mongodb'),
    db,collection,collName = 'mongotest___test',
    fsyncDatabase = function(callback) {

      var error = null;
      var synced = 0;

      /*function fsyncConnection (conn) {
        db.lastError({
          fsync: true
        }, {
          connection: conn
        }, function (err, res) {
          // ignoring the last error, just forcing all commands through
          error = error || err;

          if (++synced === conns.length) {
            callback(error);
          }
        });
      }*/
      function fsyncConnection (conn) {
        db.command({ getLastError: 1 },{connection:conn},
          function(err,result){
            //TODO we ignore the result right now
            error = error || err;
            if (++synced === conns.length) {
              callback(error);
            }
          });
      }

      var conns = db.serverConfig.allRawConnections();
      if (conns instanceof Array && conns.length >= 1) {
        for ( var i = 0; i < conns.length; ++i) {
          fsyncConnection(conns[i]);
        }
      } else {
        callback(new Error("not connected"));
      }
    };
  before(function(done){
    MONGO.MongoClient.connect("mongodb://127.0.0.1/mongotest",{
      'w':1,
      'native-parser':true,
      'auto_reconnect': true,
      'poolSize': 20,
      socketOptions: {keepAlive: 1}
    },function(err,d){
      if(!err && d){
        db = d;

        for(var i in db){
          console.warn('DB - ',i);
        }
        db.collection(collName, function (err, result) {
          if (err) {
            done(err);
          } else {
            collection = result;
            done();
          }
        });
      } else {
        db = null;
        done(err);
      }
    });
  });
  after(function(done){
    db.dropCollection(collName, function (err) {
      db.close(done);
    });
  });
  it('insert some objects and in a parallel insertion uses fsync and checks if really everything is in place',function(done){
    var i,filler="",normalItemCount = 100,error=null,
      addObject = function(index){
        console.warn('object insertion started ',index);
        collection.insert({data:filler},function(err){
          console.warn('object insertion returned ',index);
          error = error ||err;
          if(--normalItemCount === 0){
            finishedAll();
          }
        });
      },
      finishedAll = function(){
        done(error);
      };
    for(i=0;i<1000;i++){
      filler+=String.fromCharCode(Math.floor(Math.random()*255));
    }

    for(i=0;i<99;i++){
      addObject(i);
    }
    fsyncDatabase(function(err){
      error = error || err;
      collection.insert({data:filler,extra:'should be the last element'},function(err){
        error = error || err;
        if(--normalItemCount !== 0){
          error = new Error('fsync not functioning!!! '+normalItemCount);
        } else {
          finishedAll();
        }
      });
    });
  });
});<|endoftext|>


<commit_before>var map = L.map('map', {
  zoom: 8,
  fullscreenControl: true,
% if dataset:
  timeDimension: true,
  timeDimensionOptions:{
        times: "${times}",
  },
  timeDimensionControl: true,
% endif
  center: [20.0, 0.0],
});

var osmLayer = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
  attribution: '© OpenStreetMap contributors'
});
osmLayer.addTo(map);

% if dataset:
var dsWMS = "/ows/proxy/wms?DATASET=${dataset}"
var dsLayer = L.tileLayer.wms(dsWMS, {
  layers: '${layers}',
  format: 'image/png',
  transparent: true,
  styles: '${styles}',
  attribution: 'Birdhouse'
});
var dsTimeLayer = L.timeDimension.layer.wms(dsLayer, {
  updateTimeDimension: false,
});
dsTimeLayer.addTo(map);
% endif

var baseMaps = {
  "OpenStreetMap": osmLayer,
};

var overlayMaps = {
  "${layers}": dsTimeLayer
};

L.control.layers(baseMaps, overlayMaps).addTo(map);

% if dataset:
var dsLegend = L.control({
    position: 'topright'
});
dsLegend.onAdd = function(map) {
    var src = dsWMS + "&SERVICE=WMS&VERSION=1.3.0&REQUEST=GetLegendGraphic&LAYERS=${layers}&STYLES=${styles}&PALETTE=default&HEIGHT=300";
    var div = L.DomUtil.create('div', 'info legend');
    div.innerHTML +=
        '';
    return div;
};
dsLegend.addTo(map);
% endif

L.control.coordinates({
    position: "bottomright",
    decimals: 3,
    labelTemplateLat: "Latitude: {y}",
    labelTemplateLng: "Longitude: {x}",
    useDMS: true,
    enableUserInput: false
}).addTo(map);

<commit_msg>using wms.timeseries for ncwms layer<commit_after>var map = L.map('map', {
  zoom: 8,
  fullscreenControl: true,
% if dataset:
  timeDimensionControl: true,
  timeDimensionControlOptions: {
     position: 'bottomleft',
     playerOptions: {
        transitionTime: 1000,
     }
  },
  timeDimension: true,
% endif
  center: [20.0, 0.0],
});

var osmLayer = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
  attribution: '© OpenStreetMap contributors'
});
osmLayer.addTo(map);

% if dataset:
var dsWMS = "/ows/proxy/wms?DATASET=${dataset}"
var dsLayer = L.tileLayer.wms(dsWMS, {
  layers: '${layers}',
  format: 'image/png',
  transparent: true,
  styles: '${styles}',
  attribution: 'Birdhouse'
});
var dsTimeLayer = L.timeDimension.layer.wms.timeseries(dsLayer, {
  updateTimeDimension: false,
});
dsTimeLayer.addTo(map);
% endif

var baseMaps = {
  "OpenStreetMap": osmLayer,
};

var overlayMaps = {
  "${layers}": dsTimeLayer
};

L.control.layers(baseMaps, overlayMaps).addTo(map);

% if dataset:
var dsLegend = L.control({
    position: 'topright'
});
dsLegend.onAdd = function(map) {
    var src = dsWMS + "&SERVICE=WMS&VERSION=1.3.0&REQUEST=GetLegendGraphic&LAYERS=${layers}&STYLES=${styles}&PALETTE=default&HEIGHT=300";
    var div = L.DomUtil.create('div', 'info legend');
    div.innerHTML +=
        '';
    return div;
};
dsLegend.addTo(map);
% endif

L.control.coordinates({
    position: "bottomright",
    decimals: 3,
    labelTemplateLat: "Latitude: {y}",
    labelTemplateLng: "Longitude: {x}",
    useDMS: true,
    enableUserInput: false
}).addTo(map);

<|endoftext|>


<commit_before>var Flume = require('flumedb')
var FlumelogOffset = require('flumelog-offset')

//var file = '/tmp/test_flumeview-reduce/initial_'+Date.now()+'/log.offset'

require('./')(
function create (file) {
  return Flume(FlumelogOffset(file, 1024, require('flumecodec/json')))
})

<commit_msg>fix test/persistent<commit_after>var Flume = require('flumedb')
var FlumelogOffset = require('flumelog-offset')

var file = '/tmp/test_flumeview-reduce/initial_'+Date.now()+'/log.offset'

require('./')(
function create () {
  return Flume(FlumelogOffset(file, {block: 1024, codec: require('flumecodec/json')}))
})

<|endoftext|>


<commit_before>/**
 * @author alteredq / http://alteredqualia.com/
 *
 * parameters = {
 *  fragmentShader: <string>,
 *  vertexShader: <string>,
 *
 *  uniforms: { "parameter1": { type: "f", value: 1.0 }, "parameter2": { type: "i" value2: 2 } },
 *
 *  defines: { "label" : "value" },
 *
 *  shading: THREE.SmoothShading,
 *  blending: THREE.NormalBlending,
 *  depthTest: <bool>,
 *  depthWrite: <bool>,
 *
 *  wireframe: <boolean>,
 *  wireframeLinewidth: <float>,
 *
 *  lights: <bool>,
 *
 *  vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors,
 *
 *  skinning: <bool>,
 *  morphTargets: <bool>,
 *  morphNormals: <bool>,
 *
 *	fog: <bool>
 * }
 */

THREE.ShaderMaterial = function ( parameters ) {

	THREE.Material.call( this );

	this.fragmentShader = 'void main() {}';
	this.vertexShader = 'void main() {}';
	this.uniforms = {};
	this.defines = {};
	this.attributes = null;

	this.shading = THREE.SmoothShading;

	this.linewidth = 1;

	this.wireframe = false;
	this.wireframeLinewidth = 1;

	this.fog = false; // set to use scene fog

	this.lights = false; // set to use scene lights

	this.vertexColors = THREE.NoColors; // set to use "color" attribute stream

	this.skinning = false; // set to use skinning attribute streams

	this.morphTargets = false; // set to use morph targets
	this.morphNormals = false; // set to use morph normals

	// When rendered geometry doesn't include these attributes but the material does,
	// use these default values in WebGL. This avoids errors when buffer data is missing.
	this.defaultAttributeValues = {
		'color': [ 1, 1, 1 ],
		'uv': [ 0, 0 ],
		'uv2': [ 0, 0 ]
	};

	this.index0AttributeName = undefined;

	this.setValues( parameters );

};

THREE.ShaderMaterial.prototype = Object.create( THREE.Material.prototype );

THREE.ShaderMaterial.prototype.clone = function () {

	var material = new THREE.ShaderMaterial();

	THREE.Material.prototype.clone.call( this, material );

	material.fragmentShader = this.fragmentShader;
	material.vertexShader = this.vertexShader;

	material.uniforms = THREE.UniformsUtils.clone( this.uniforms );

	material.attributes = this.attributes;
	material.defines = this.defines;

	material.shading = this.shading;

	material.wireframe = this.wireframe;
	material.wireframeLinewidth = this.wireframeLinewidth;

	material.fog = this.fog;

	material.lights = this.lights;

	material.vertexColors = this.vertexColors;

	material.skinning = this.skinning;

	material.morphTargets = this.morphTargets;
	material.morphNormals = this.morphNormals;

	return material;

};
<commit_msg>Default shader code for ShaderMaterial.<commit_after>/**
 * @author alteredq / http://alteredqualia.com/
 *
 * parameters = {
 *  fragmentShader: <string>,
 *  vertexShader: <string>,
 *
 *  uniforms: { "parameter1": { type: "f", value: 1.0 }, "parameter2": { type: "i" value2: 2 } },
 *
 *  defines: { "label" : "value" },
 *
 *  shading: THREE.SmoothShading,
 *  blending: THREE.NormalBlending,
 *  depthTest: <bool>,
 *  depthWrite: <bool>,
 *
 *  wireframe: <boolean>,
 *  wireframeLinewidth: <float>,
 *
 *  lights: <bool>,
 *
 *  vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors,
 *
 *  skinning: <bool>,
 *  morphTargets: <bool>,
 *  morphNormals: <bool>,
 *
 *	fog: <bool>
 * }
 */

THREE.ShaderMaterial = function ( parameters ) {

	THREE.Material.call( this );

	this.fragmentShader = 'void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}';
	this.vertexShader = 'void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}';
	this.uniforms = {};
	this.defines = {};
	this.attributes = null;

	this.shading = THREE.SmoothShading;

	this.linewidth = 1;

	this.wireframe = false;
	this.wireframeLinewidth = 1;

	this.fog = false; // set to use scene fog

	this.lights = false; // set to use scene lights

	this.vertexColors = THREE.NoColors; // set to use "color" attribute stream

	this.skinning = false; // set to use skinning attribute streams

	this.morphTargets = false; // set to use morph targets
	this.morphNormals = false; // set to use morph normals

	// When rendered geometry doesn't include these attributes but the material does,
	// use these default values in WebGL. This avoids errors when buffer data is missing.
	this.defaultAttributeValues = {
		'color': [ 1, 1, 1 ],
		'uv': [ 0, 0 ],
		'uv2': [ 0, 0 ]
	};

	this.index0AttributeName = undefined;

	this.setValues( parameters );

};

THREE.ShaderMaterial.prototype = Object.create( THREE.Material.prototype );

THREE.ShaderMaterial.prototype.clone = function () {

	var material = new THREE.ShaderMaterial();

	THREE.Material.prototype.clone.call( this, material );

	material.fragmentShader = this.fragmentShader;
	material.vertexShader = this.vertexShader;

	material.uniforms = THREE.UniformsUtils.clone( this.uniforms );

	material.attributes = this.attributes;
	material.defines = this.defines;

	material.shading = this.shading;

	material.wireframe = this.wireframe;
	material.wireframeLinewidth = this.wireframeLinewidth;

	material.fog = this.fog;

	material.lights = this.lights;

	material.vertexColors = this.vertexColors;

	material.skinning = this.skinning;

	material.morphTargets = this.morphTargets;
	material.morphNormals = this.morphNormals;

	return material;

};
<|endoftext|>


<commit_before>/**
 * @fileoverview Hash Map을 구현한 모듈이 정의 되어있다.
 * @author FE개발팀
 * @dependency type, collection.js
 */

(function(ne) {
    'use strict';
    /* istanbul ignore if */
    if (!ne) {
        ne = window.ne = {};
    }

    /**
     * 해쉬맵에서 사용하는 데이터는 _MAPDATAPREFIX로 시작한다.
     * @type {string}
     * @private
     */
    var _MAPDATAPREFIX = 'å';

    /**
     * HashMap
     * 키/밸류로 데이터를 관리할수있다(자바의 hashMap과 유사)
     * 주의) length프로퍼티를 가지고있어 유사 배열을 length의 유무로 체크하는 로직에서 의도되지 않은 동작을 할수있다.
     * @param {Object} [obj] 인스턴스가 만들어질때 셋팅할 초기 데이터
     * @constructor
     * @example
     * var hm = new HashMap({
     *     'mydata': {
     *          'hello': 'imfine'
     *      },
     *     'what': 'time'
     * });
     */
    function HashMap(obj) {
        /**
         * 사이즈
         * @type {number}
         */
        this.length = 0;

        if (obj) {
            this.setObject(obj);
        }
    }

    /**
     * 키/밸류 혹은 Object를 전달하여 데이터를 셋팅한다.
     * @param {String|Object} key 키에 해당하는 스트링이나 객체
     * @param {*} [value] 데이터
     * @example
     * var hm = new HashMap();
     *
     * hm.set('key', 'value');
     * hm.set({
     *     'key1': 'data1',
     *     'key2': 'data2'
     * });
     */
    HashMap.prototype.set = function(key, value) {
        arguments.length === 2 ? this.setKeyValue(key, value) : this.setObject(key);
    };

    /**
     * 키/밸류로 데이터를 셋팅한다.
     * @param {String} key 키스트링
     * @param {*} value 데이터
     * @example
     * var hm = new HashMap();
     * hm.setKeyValue('key', 'value');
     */
    HashMap.prototype.setKeyValue = function(key, value) {
        if (!this.has(key)) {
            this.length += 1;
        }
        this[this.encodeKey(key)] = value;
    };

    /**
     * 객체로 데이터를 셋팅한다.
     * @param {Object} obj
     * @example
     * var hm = new HashMap();
     *
     * hm.setObject({
     *     'key1': 'data1',
     *     'key2': 'data2'
     * });
     */
    HashMap.prototype.setObject = function(obj) {
        var self = this;

        ne.forEachOwnProperties(obj, function(value, key) {
            self.setKeyValue(key, value);
        });
    };

    /**
     * 해쉬맵에서 사용할 키를 생성한다.
     * @param {String} key
     * @returns {string}
     * @private
     */
    HashMap.prototype.encodeKey = function(key) {
        return _MAPDATAPREFIX + key;
    };

    /**
     * 해쉬맵키에서 실제 키를 가져온다.
     * @param {String} key
     * @returns {String}
     * @private
     */
    HashMap.prototype.decodeKey = function(key) {
        var decodedKey = key.split(_MAPDATAPREFIX);
        return decodedKey[decodedKey.length-1];
    };

    /**
     * 키값을 전달하여 데이터를 반환한다.
     * @param {String} key
     * @returns {*}
     * @example
     * var hm = new HashMap();
     * hm.set('key', 'value');
     *
     * hm.get('key') // value
     */
    HashMap.prototype.get = function(key) {
        return this[this.encodeKey(key)];
    };

    /**
     * 키를 전달하여 데이터가 존재하는지 체크한다.
     * @param {String} key
     * @returns {boolean}
     * @example
     * var hm = new HashMap();
     * hm.set('key', 'value');
     *
     * hm.has('key') // true
     */
    HashMap.prototype.has = function(key) {
        return this.hasOwnProperty(this.encodeKey(key));
    };

    /**
     * 키나 키의 목록을 전달하여 데이터를 삭제한다.
     * @param {String...|String[]} key
     * @returns {String|String[]}
     * @example
     * var hm = new HashMap();
     * hm.set('key', 'value');
     * hm.set('key2', 'value');
     *
     * //ex1
     * hm.remove('key');
     *
     * //ex2
     * hm.remove('key', 'key2');
     *
     * //ex3
     * hm.remove(['key', 'key2']);
     */
    HashMap.prototype.remove = function(key) {
        if (arguments.length > 1) {
            key = ne.toArray(arguments);
        }

        return ne.isArray(key) ? this.removeByKeyArray(key) : this.removeByKey(key);
    };

    /**
     * 키를 전달하여 데이터를 삭제한다.
     * @param {String} key
     * @returns {*|null} 삭제된 데이터
     * @example
     * var hm = new HashMap();
     * hm.set('key', 'value');
     *
     * hm.removeByKey('key')
     */
    HashMap.prototype.removeByKey = function(key) {
        var data = this.has(key) ? this.get(key) : null;

        if (data !== null) {
            delete this[this.encodeKey(key)];
            this.length -= 1;
        }

        return data;
    };

    /**
     * 키의 목록을 전달하여 데이터를 삭제한다.
     * @param {String[]} keyArray
     * @returns {String[]} 삭제된 데이터
     * @example
     * var hm = new HashMap();
     * hm.set('key', 'value');
     * hm.set('key2', 'value');
     *
     * hm.removeByKeyArray(['key', 'key2']);
     */
    HashMap.prototype.removeByKeyArray = function(keyArray) {
        var data = [],
            self = this;

        ne.forEach(keyArray, function(key) {
            data.push(self.removeByKey(key));
        });

        return data;
    };

    /**
     * 모든데이터를 지운다.
     */
    HashMap.prototype.removeAll = function() {
        var self = this;

        this.each(function(value, key) {
            self.remove(key);
        });
    };

    /**
     * 데이터를 순회하며 콜백에 전달해준다.
     * @param {Function} iteratee
     * @example
     * var hm = new HashMap();
     * hm.set('key', 'value');
     * hm.set('key2', 'value');
     *
     * hm.each(function(value, key) {
     *     //do something...
     * });
     */
    HashMap.prototype.each = function(iteratee) {
        var self = this;

        ne.forEachOwnProperties(this, function(value, key){
            if (key.charAt(0) === _MAPDATAPREFIX) {
                iteratee(value, self.decodeKey(key));
            }
        });
    };

    /**
     * 저장된 키의 목록을 배열로 리턴해준다.
     * @returns {Array}
     * @example
     * var hm = new HashMap();
     * hm.set('key', 'value');
     * hm.set('key2', 'value');
     *
     * hm.keys();  //['key', 'key2');
     */
    HashMap.prototype.keys = function() {
        var keys = [],
            self = this;

        this.each(function(value, key) {
            keys.push(self.decodeKey(key));
        });

        return keys;
    };

    /**
     * 조건을 체크하는 콜백을 전달받아 데이터를 전달해주고 콜백의 결과가 true인경우의 데이터를 모와 배열로 만들어 리턴해준다.
     * @param {Function} condition
     * @returns {Array}
     * @example
     *
     * //ex1
     * var hm = new HashMap();
     * hm.set('key', 'value');
     * hm.set('key2', 'value');
     *
     * hm.find(function(value, key) {
     *     return key === 'key2';
     * }); // ['value']
     *
     * //ex2
     * var hm = new HashMap({
     *     'myobj1': {
     *          visible: true
     *      },
     *     'mybobj2': {
     *          visible: false
     *      }
     * });
     *
     * hm.find(function(obj, key) {
     *     return obj.visible === true;
     * }); // [{visible: true}];
     */
    HashMap.prototype.find = function(condition) {
        var founds = [];

        this.each(function(value, key) {
            if (condition(value, key)) {
                founds.push(value);
            }
        });

        return founds;
    };

    ne.HashMap = HashMap;

})(window.ne);
<commit_msg>hashMap.each 폴백에서 false리턴시 순회멈추도록 수정<commit_after>/**
 * @fileoverview Hash Map을 구현한 모듈이 정의 되어있다.
 * @author FE개발팀
 * @dependency type, collection.js
 */

(function(ne) {
    'use strict';
    /* istanbul ignore if */
    if (!ne) {
        ne = window.ne = {};
    }

    /**
     * 해쉬맵에서 사용하는 데이터는 _MAPDATAPREFIX로 시작한다.
     * @type {string}
     * @private
     */
    var _MAPDATAPREFIX = 'å';

    /**
     * HashMap
     * 키/밸류로 데이터를 관리할수있다(자바의 hashMap과 유사)
     * 주의) length프로퍼티를 가지고있어 유사 배열을 length의 유무로 체크하는 로직에서 의도되지 않은 동작을 할수있다.
     * @param {Object} [obj] 인스턴스가 만들어질때 셋팅할 초기 데이터
     * @constructor
     * @example
     * var hm = new HashMap({
     *     'mydata': {
     *          'hello': 'imfine'
     *      },
     *     'what': 'time'
     * });
     */
    function HashMap(obj) {
        /**
         * 사이즈
         * @type {number}
         */
        this.length = 0;

        if (obj) {
            this.setObject(obj);
        }
    }

    /**
     * 키/밸류 혹은 Object를 전달하여 데이터를 셋팅한다.
     * @param {String|Object} key 키에 해당하는 스트링이나 객체
     * @param {*} [value] 데이터
     * @example
     * var hm = new HashMap();
     *
     * hm.set('key', 'value');
     * hm.set({
     *     'key1': 'data1',
     *     'key2': 'data2'
     * });
     */
    HashMap.prototype.set = function(key, value) {
        arguments.length === 2 ? this.setKeyValue(key, value) : this.setObject(key);
    };

    /**
     * 키/밸류로 데이터를 셋팅한다.
     * @param {String} key 키스트링
     * @param {*} value 데이터
     * @example
     * var hm = new HashMap();
     * hm.setKeyValue('key', 'value');
     */
    HashMap.prototype.setKeyValue = function(key, value) {
        if (!this.has(key)) {
            this.length += 1;
        }
        this[this.encodeKey(key)] = value;
    };

    /**
     * 객체로 데이터를 셋팅한다.
     * @param {Object} obj
     * @example
     * var hm = new HashMap();
     *
     * hm.setObject({
     *     'key1': 'data1',
     *     'key2': 'data2'
     * });
     */
    HashMap.prototype.setObject = function(obj) {
        var self = this;

        ne.forEachOwnProperties(obj, function(value, key) {
            self.setKeyValue(key, value);
        });
    };

    /**
     * 해쉬맵에서 사용할 키를 생성한다.
     * @param {String} key
     * @returns {string}
     * @private
     */
    HashMap.prototype.encodeKey = function(key) {
        return _MAPDATAPREFIX + key;
    };

    /**
     * 해쉬맵키에서 실제 키를 가져온다.
     * @param {String} key
     * @returns {String}
     * @private
     */
    HashMap.prototype.decodeKey = function(key) {
        var decodedKey = key.split(_MAPDATAPREFIX);
        return decodedKey[decodedKey.length-1];
    };

    /**
     * 키값을 전달하여 데이터를 반환한다.
     * @param {String} key
     * @returns {*}
     * @example
     * var hm = new HashMap();
     * hm.set('key', 'value');
     *
     * hm.get('key') // value
     */
    HashMap.prototype.get = function(key) {
        return this[this.encodeKey(key)];
    };

    /**
     * 키를 전달하여 데이터가 존재하는지 체크한다.
     * @param {String} key
     * @returns {boolean}
     * @example
     * var hm = new HashMap();
     * hm.set('key', 'value');
     *
     * hm.has('key') // true
     */
    HashMap.prototype.has = function(key) {
        return this.hasOwnProperty(this.encodeKey(key));
    };

    /**
     * 키나 키의 목록을 전달하여 데이터를 삭제한다.
     * @param {String...|String[]} key
     * @returns {String|String[]}
     * @example
     * var hm = new HashMap();
     * hm.set('key', 'value');
     * hm.set('key2', 'value');
     *
     * //ex1
     * hm.remove('key');
     *
     * //ex2
     * hm.remove('key', 'key2');
     *
     * //ex3
     * hm.remove(['key', 'key2']);
     */
    HashMap.prototype.remove = function(key) {
        if (arguments.length > 1) {
            key = ne.toArray(arguments);
        }

        return ne.isArray(key) ? this.removeByKeyArray(key) : this.removeByKey(key);
    };

    /**
     * 키를 전달하여 데이터를 삭제한다.
     * @param {String} key
     * @returns {*|null} 삭제된 데이터
     * @example
     * var hm = new HashMap();
     * hm.set('key', 'value');
     *
     * hm.removeByKey('key')
     */
    HashMap.prototype.removeByKey = function(key) {
        var data = this.has(key) ? this.get(key) : null;

        if (data !== null) {
            delete this[this.encodeKey(key)];
            this.length -= 1;
        }

        return data;
    };

    /**
     * 키의 목록을 전달하여 데이터를 삭제한다.
     * @param {String[]} keyArray
     * @returns {String[]} 삭제된 데이터
     * @example
     * var hm = new HashMap();
     * hm.set('key', 'value');
     * hm.set('key2', 'value');
     *
     * hm.removeByKeyArray(['key', 'key2']);
     */
    HashMap.prototype.removeByKeyArray = function(keyArray) {
        var data = [],
            self = this;

        ne.forEach(keyArray, function(key) {
            data.push(self.removeByKey(key));
        });

        return data;
    };

    /**
     * 모든데이터를 지운다.
     */
    HashMap.prototype.removeAll = function() {
        var self = this;

        this.each(function(value, key) {
            self.remove(key);
        });
    };

    /**
     * 데이터를 순회하며 콜백에 전달해준다.
     * @param {Function} iteratee
     * @example
     * var hm = new HashMap();
     * hm.set('key', 'value');
     * hm.set('key2', 'value');
     *
     * hm.each(function(value, key) {
     *     //do something...
     * });
     */
    HashMap.prototype.each = function(iteratee) {
        var self = this,
            flag;

        ne.forEachOwnProperties(this, function(value, key) {
            if (key.charAt(0) === _MAPDATAPREFIX) {
                flag = iteratee(value, self.decodeKey(key));
            }

            if (flag === false) {
                return flag;
            }
        });
    };

    /**
     * 저장된 키의 목록을 배열로 리턴해준다.
     * @returns {Array}
     * @example
     * var hm = new HashMap();
     * hm.set('key', 'value');
     * hm.set('key2', 'value');
     *
     * hm.keys();  //['key', 'key2');
     */
    HashMap.prototype.keys = function() {
        var keys = [],
            self = this;

        this.each(function(value, key) {
            keys.push(self.decodeKey(key));
        });

        return keys;
    };

    /**
     * 조건을 체크하는 콜백을 전달받아 데이터를 전달해주고 콜백의 결과가 true인경우의 데이터를 모와 배열로 만들어 리턴해준다.
     * @param {Function} condition
     * @returns {Array}
     * @example
     *
     * //ex1
     * var hm = new HashMap();
     * hm.set('key', 'value');
     * hm.set('key2', 'value');
     *
     * hm.find(function(value, key) {
     *     return key === 'key2';
     * }); // ['value']
     *
     * //ex2
     * var hm = new HashMap({
     *     'myobj1': {
     *          visible: true
     *      },
     *     'mybobj2': {
     *          visible: false
     *      }
     * });
     *
     * hm.find(function(obj, key) {
     *     return obj.visible === true;
     * }); // [{visible: true}];
     */
    HashMap.prototype.find = function(condition) {
        var founds = [];

        this.each(function(value, key) {
            if (condition(value, key)) {
                founds.push(value);
            }
        });

        return founds;
    };

    ne.HashMap = HashMap;

})(window.ne);
<|endoftext|>


<commit_before>import { ContentNodeResource, ContentNodeProgressResource } from 'kolibri.resources';
import samePageCheckGenerator from 'kolibri.utils.samePageCheckGenerator';
import ConditionalPromise from 'kolibri.lib.conditionalPromise';
import router from 'kolibri.coreVue.router';
import { PageNames } from '../../constants';
import { _collectionState, normalizeContentNode, contentState } from '../coreLearn/utils';

export function showTopicsChannel(store, id) {
  return store.dispatch('loading').then(() => {
    store.commit('SET_PAGE_NAME', PageNames.TOPICS_CHANNEL);
    return showTopicsTopic(store, { id, isRoot: true });
  });
}

export function showTopicsContent(store, id) {
  store.commit('SET_EMPTY_LOGGING_STATE');
  store.commit('CORE_SET_PAGE_LOADING', true);
  store.commit('SET_PAGE_NAME', PageNames.TOPICS_CONTENT);

  const promises = [
    ContentNodeResource.fetchModel({ id }),
    ContentNodeResource.fetchNextContent(id),
    store.dispatch('setChannelInfo'),
  ];
  ConditionalPromise.all(promises).only(
    samePageCheckGenerator(store),
    ([content, nextContent]) => {
      const currentChannel = store.getters.getChannelObject(content.channel_id);
      if (!currentChannel) {
        router.replace({ name: PageNames.CONTENT_UNAVAILABLE });
        return;
      }
      store.commit('topicsTree/SET_STATE', {
        content: contentState(content, nextContent),
        channel: currentChannel,
      });
      store.commit('CORE_SET_PAGE_LOADING', false);
      store.commit('CORE_SET_ERROR', null);
    },
    error => {
      store.dispatch('handleApiError', error);
    }
  );
}

export function showTopicsTopic(store, { id, isRoot = false }) {
  return store.dispatch('loading').then(() => {
    store.commit('SET_PAGE_NAME', isRoot ? PageNames.TOPICS_CHANNEL : PageNames.TOPICS_TOPIC);
    const promises = [
      ContentNodeResource.fetchModel({ id, force: true }), // the topic
      ContentNodeResource.fetchCollection({
        getParams: {
          parent: id,
          include_coach_content:
            store.getters.isAdmin || store.getters.isCoach || store.getters.isSuperuser,
        },
      }), // the topic's children
      store.dispatch('setChannelInfo'),
    ];

    return ConditionalPromise.all(promises).only(
      samePageCheckGenerator(store),
      ([topic, children]) => {
        const currentChannel = store.getters.getChannelObject(topic.channel_id);
        if (!currentChannel) {
          router.replace({ name: PageNames.CONTENT_UNAVAILABLE });
          return;
        }
        if (isRoot) {
          topic.description = currentChannel.description;
          topic.tagline = currentChannel.tagline;
          topic.thumbnail = currentChannel.thumbnail;
        }
        store.commit('topicsTree/SET_STATE', {
          isRoot,
          channel: currentChannel,
          topic: normalizeContentNode(topic),
          contents: _collectionState(children),
        });

        // Only load contentnode progress if the user is logged in
        if (store.getters.isUserLoggedIn) {
          if (children.length > 0) {
            ContentNodeProgressResource.fetchCollection({
              getParams: { parent: id },
            }).then(progresses => {
              store.commit('topicsTree/SET_NODE_PROGRESS', progresses);
            });
          }
        }

        store.dispatch('notLoading');
        store.commit('CORE_SET_ERROR', null);
      },
      error => {
        store.dispatch('handleApiError', error);
      }
    );
  });
}
<commit_msg>Fetch recommended resources for completion modal<commit_after>import { ContentNodeResource, ContentNodeProgressResource } from 'kolibri.resources';
import samePageCheckGenerator from 'kolibri.utils.samePageCheckGenerator';
import ConditionalPromise from 'kolibri.lib.conditionalPromise';
import router from 'kolibri.coreVue.router';
import { PageNames } from '../../constants';
import { _collectionState, normalizeContentNode, contentState } from '../coreLearn/utils';

export function showTopicsChannel(store, id) {
  return store.dispatch('loading').then(() => {
    store.commit('SET_PAGE_NAME', PageNames.TOPICS_CHANNEL);
    return showTopicsTopic(store, { id, isRoot: true });
  });
}

export function showTopicsContent(store, id) {
  store.commit('SET_EMPTY_LOGGING_STATE');
  store.commit('CORE_SET_PAGE_LOADING', true);
  store.commit('SET_PAGE_NAME', PageNames.TOPICS_CONTENT);

  const promises = [
    ContentNodeResource.fetchModel({ id }),
    ContentNodeResource.fetchNextContent(id),
    ContentNodeResource.fetchRecommendationsFor(id),
    store.dispatch('setChannelInfo'),
  ];
  ConditionalPromise.all(promises).only(
    samePageCheckGenerator(store),
    ([content, nextContent, recommended]) => {
      const currentChannel = store.getters.getChannelObject(content.channel_id);
      if (!currentChannel) {
        router.replace({ name: PageNames.CONTENT_UNAVAILABLE });
        return;
      }
      store.commit('topicsTree/SET_STATE', {
        content: contentState(content, nextContent),
        channel: currentChannel,
        recommended: recommended,
      });
      store.commit('CORE_SET_PAGE_LOADING', false);
      store.commit('CORE_SET_ERROR', null);
    },
    error => {
      store.dispatch('handleApiError', error);
    }
  );
}

export function showTopicsTopic(store, { id, isRoot = false }) {
  return store.dispatch('loading').then(() => {
    store.commit('SET_PAGE_NAME', isRoot ? PageNames.TOPICS_CHANNEL : PageNames.TOPICS_TOPIC);
    const promises = [
      ContentNodeResource.fetchModel({ id, force: true }), // the topic
      ContentNodeResource.fetchCollection({
        getParams: {
          parent: id,
          include_coach_content:
            store.getters.isAdmin || store.getters.isCoach || store.getters.isSuperuser,
        },
      }), // the topic's children
      store.dispatch('setChannelInfo'),
    ];

    return ConditionalPromise.all(promises).only(
      samePageCheckGenerator(store),
      ([topic, children]) => {
        const currentChannel = store.getters.getChannelObject(topic.channel_id);
        if (!currentChannel) {
          router.replace({ name: PageNames.CONTENT_UNAVAILABLE });
          return;
        }
        if (isRoot) {
          topic.description = currentChannel.description;
          topic.tagline = currentChannel.tagline;
          topic.thumbnail = currentChannel.thumbnail;
        }
        store.commit('topicsTree/SET_STATE', {
          isRoot,
          channel: currentChannel,
          topic: normalizeContentNode(topic),
          contents: _collectionState(children),
        });

        // Only load contentnode progress if the user is logged in
        if (store.getters.isUserLoggedIn) {
          if (children.length > 0) {
            ContentNodeProgressResource.fetchCollection({
              getParams: { parent: id },
            }).then(progresses => {
              store.commit('topicsTree/SET_NODE_PROGRESS', progresses);
            });
          }
        }

        store.dispatch('notLoading');
        store.commit('CORE_SET_ERROR', null);
      },
      error => {
        store.dispatch('handleApiError', error);
      }
    );
  });
}
<|endoftext|>