<commit_before>import { BodyComponent } from 'mjml-core'
import range from 'lodash/range'
import repeat from 'lodash/repeat'
import min from 'lodash/min'
import map from 'lodash/map'
import crypto from 'crypto'

import { msoConditionalTag } from 'mjml-core/lib/helpers/conditionalTag'

export default class MjCarousel extends BodyComponent {
  static allowedAttributes = {
    align: 'enum(left,center,right)',
    'border-radius': 'unit(px,%)',
    'icon-width': 'unit(px,%)',
    'left-icon': 'string',
    padding: 'unit(px,%){1,4}',
    'padding-top': 'unit(px,%)',
    'padding-bottom': 'unit(px,%)',
    'padding-left': 'unit(px,%)',
    'padding-right': 'unit(px,%)',
    'right-icon': 'string',
    thumbnails: 'enum(visible,hidden)',
    'tb-border': 'string',
    'tb-border-radius': 'unit(px,%)',
    'tb-hover-border-color': 'color',
    'tb-selected-border-color': 'color',
    'tb-width': 'unit(px,%)',
  }

  static defaultAttributes = {
    align: 'center',
    'border-radius': '6px',
    'icon-width': '44px',
    'left-icon': 'http://i.imgur.com/xTh3hln.png',
    'right-icon': 'http://i.imgur.com/os7o9kz.png',
    thumbnails: 'visible',
    'tb-border': '2px solid transparent',
    'tb-border-radius': '6px',
    'tb-hover-border-color': '#fead0d',
    'tb-selected-border-color': '#ccc',
  }

  constructor(initialDatas = {}) {
    super(initialDatas)
    this.carouselId = crypto.randomBytes(6).toString('hex')
  }

  componentHeadStyle = () => {
    const length = this.props.children.length
    const { carouselId } = this

    if (!length) return ''

    const carouselCss = `
    .mj-carousel {
      -webkit-user-select: none;
      -moz-user-select: none;
      user-select: none;
    }

    .mj-carousel-${this.carouselId}-icons-cell {
      display: table-cell !important;
      width: ${this.getAttribute('icon-width')} !important;
    }

    .mj-carousel-radio,
    .mj-carousel-next,
    .mj-carousel-previous {
      display: none !important;
    }

    .mj-carousel-thumbnail,
    .mj-carousel-next,
    .mj-carousel-previous {
      touch-action: manipulation;
    }

    ${range(0, length)
      .map(
        i =>
          `.mj-carousel-${carouselId}-radio:checked ${repeat(
            '+ * ',
            i,
          )}+ .mj-carousel-content .mj-carousel-image`,
      )
      .join(',')} {
      display: none !important;
    }

    ${range(0, length)
      .map(
        i =>
          `.mj-carousel-${carouselId}-radio-${i + 1}:checked ${repeat(
            '+ * ',
            length - i - 1,
          )}+ .mj-carousel-content .mj-carousel-image-${i + 1}`,
      )
      .join(',')} {
      display: block !important;
    }

    .mj-carousel-previous-icons,
    .mj-carousel-next-icons,
    ${range(0, length).map(
      i =>
        `.mj-carousel-${carouselId}-radio-${i + 1}:checked ${repeat(
          '+ * ',
          length - i - 1,
        )}+ .mj-carousel-content .mj-carousel-next-${(i + 1 % length + length) %
          length +
          1}`,
    )},
    ${range(0, length).map(
      i =>
        `.mj-carousel-${carouselId}-radio-${i + 1}:checked ${repeat(
          '+ * ',
          length - i - 1,
        )}+ .mj-carousel-content .mj-carousel-previous-${(i -
          1 % length +
          length) %
          length +
          1}`,
    )} {
      display: block !important;
    }

    ${range(0, length)
      .map(
        i =>
          `.mj-carousel-${carouselId}-radio-${i + 1}:checked ${repeat(
            '+ * ',
            length - i - 1,
          )}+ .mj-carousel-content .mj-carousel-${carouselId}-thumbnail-${i +
            1}`,
      )
      .join(',')} {
      border-color: ${this.getAttribute('tb-selected-border-color')} !important;
    }

    .mj-carousel-image img + div,
    .mj-carousel-thumbnail img + div {
      display: none !important;
    }

    ${range(0, length)
      .map(
        i =>
          `.mj-carousel-${carouselId}-thumbnail:hover ${repeat(
            '+ * ',
            length - i - 1,
          )}+ .mj-carousel-main .mj-carousel-image`,
      )
      .join(',')} {
      display: none !important;
    }

    .mj-carousel-thumbnail:hover {
      border-color: ${this.getAttribute('tb-hover-border-color')} !important;
    }

    ${range(0, length)
      .map(
        i =>
          `.mj-carousel-${carouselId}-thumbnail-${i + 1}:hover ${repeat(
            '+ * ',
            length - i - 1,
          )}+ .mj-carousel-main .mj-carousel-image-${i + 1}`,
      )
      .join(',')} {
      display: block !important;
    }
    `

    const fallback = `
      .mj-carousel noinput { display:block !important; }
      .mj-carousel noinput .mj-carousel-image-1 { display: block !important;  }
      .mj-carousel noinput .mj-carousel-arrows,
      .mj-carousel noinput .mj-carousel-thumbnails { display: none !important; }

      [owa] .mj-carousel-thumbnail { display: none !important; }

      @media screen yahoo {
          .mj-carousel-${this.carouselId}-icons-cell,
          .mj-carousel-previous-icons,
          .mj-carousel-next-icons {
              display: none !important;
          }

          .mj-carousel-${carouselId}-radio-1:checked ${repeat(
      '+ *',
      length - 1,
    )}+ .mj-carousel-content .mj-carousel-${carouselId}-thumbnail-1 {
              border-color: transparent;
          }
      }
    `

    return `${carouselCss}\n${fallback}`
  }

  getStyles() { // eslint-disable-line class-methods-use-this
    return {
      carousel: {
        div: {
          display: 'table',
          width: '100%',
          'table-layout': 'fixed',
          'text-align': 'center',
          'font-size': '0px',
        },
        table: {
          'caption-side': 'top',
          display: 'table-caption',
          'table-layout': 'fixed',
          width: '100%',
        },
      },
      images: {
        td: {
          padding: '0px',
        },
      },
      controls: {
        div: {
          display: 'none',
          'mso-hide': 'all',
        },
        img: {
          display: 'block',
          width: this.getAttribute('icon-width'),
          height: 'auto',
        },
        td: {
          'font-size': '0px',
          display: 'none',
          'mso-hide': 'all',
          padding: '0px',
        },
      },
    }
  }

  thumbnailsWidth() {
    if (!this.props.children.length) return 0
    return (
      this.getAttribute('tb-width') ||
      `${min([this.context.parentWidth / this.props.children.length, 110])}px`
    )
  }

  imagesAttributes() {
    return map(this.children, 'attributes')
  }

  generateRadios() {
    return this.renderChildren(this.props.children, {
      renderer: component => component.renderRadio(),
      attributes: {
        carouselId: this.carouselId,
      },
    })
  }

  generateThumbnails() {
    if (this.getAttribute('thumbnails') !== 'visible') return ''

    return this.renderChildren(this.props.children, {
      attributes: {
        'tb-border': this.getAttribute('tb-border'),
        'tb-border-radius': this.getAttribute('tb-border-radius'),
        'tb-width': this.thumbnailsWidth(),
        carouselId: this.carouselId,
      },
      renderer: component => component.renderThumbnail(),
    })
  }

  generateControls(direction, icon) {
    const iconWidth = parseInt(this.getAttribute('icon-width'), 10)

    return `
      <td
        ${this.htmlAttributes({
          class: `mj-carousel-${this.carouselId}-icons-cell`,
          style: 'controls.td',
        })}
      >
        <div
          ${this.htmlAttributes({
            class: `mj-carousel-${direction}-icons`,
            style: 'controls.div',
          })}
        >
          ${range(1, this.props.children.length + 1).map(
            i => `
              <label
                ${this.htmlAttributes({
                  for: `mj-carousel-${this.carouselId}-radio-${i}`,
                  class: `mj-carousel-${direction} mj-carousel-${direction}-${i}`,
                })}
              >

            `,
          )}

    `
  }

  generateImages() {
    return `

          ${this.renderChildren(this.props.children, {
            attributes: {
              'border-radius': this.getAttribute('border-radius'),
            },
          })}

    `
  }

  generateCarousel() {
    return `

            ${this.generateControls('previous', this.getAttribute('left-icon'))}
            ${this.generateImages()}
            ${this.generateControls('next', this.getAttribute('right-icon'))}

    `
  }

  renderFallback() {
    const { children } = this.props
    if (children.length === 0) return ''

    return msoConditionalTag(
      this.renderChildren([children[0]], {
        attributes: {
          'border-radius': this.getAttribute('border-radius'),
        },
      }),
    )
  }

  render() {
    return `
      ${msoConditionalTag(
        `

          ${this.generateRadios()}

            ${this.generateThumbnails()}
            ${this.generateCarousel()}

      `,
        true,
      )}
      ${this.renderFallback()}
    `
  }
}
<commit_msg>remove commas appearing near carousel radios<commit_after>import { BodyComponent } from 'mjml-core'
import range from 'lodash/range'
import repeat from 'lodash/repeat'
import min from 'lodash/min'
import map from 'lodash/map'
import crypto from 'crypto'

import { msoConditionalTag } from 'mjml-core/lib/helpers/conditionalTag'

export default class MjCarousel extends BodyComponent {
  static allowedAttributes = {
    align: 'enum(left,center,right)',
    'border-radius': 'unit(px,%)',
    'icon-width': 'unit(px,%)',
    'left-icon': 'string',
    padding: 'unit(px,%){1,4}',
    'padding-top': 'unit(px,%)',
    'padding-bottom': 'unit(px,%)',
    'padding-left': 'unit(px,%)',
    'padding-right': 'unit(px,%)',
    'right-icon': 'string',
    thumbnails: 'enum(visible,hidden)',
    'tb-border': 'string',
    'tb-border-radius': 'unit(px,%)',
    'tb-hover-border-color': 'color',
    'tb-selected-border-color': 'color',
    'tb-width': 'unit(px,%)',
  }

  static defaultAttributes = {
    align: 'center',
    'border-radius': '6px',
    'icon-width': '44px',
    'left-icon': 'http://i.imgur.com/xTh3hln.png',
    'right-icon': 'http://i.imgur.com/os7o9kz.png',
    thumbnails: 'visible',
    'tb-border': '2px solid transparent',
    'tb-border-radius': '6px',
    'tb-hover-border-color': '#fead0d',
    'tb-selected-border-color': '#ccc',
  }

  constructor(initialDatas = {}) {
    super(initialDatas)
    this.carouselId = crypto.randomBytes(6).toString('hex')
  }

  componentHeadStyle = () => {
    const length = this.props.children.length
    const { carouselId } = this

    if (!length) return ''

    const carouselCss = `
    .mj-carousel {
      -webkit-user-select: none;
      -moz-user-select: none;
      user-select: none;
    }

    .mj-carousel-${this.carouselId}-icons-cell {
      display: table-cell !important;
      width: ${this.getAttribute('icon-width')} !important;
    }

    .mj-carousel-radio,
    .mj-carousel-next,
    .mj-carousel-previous {
      display: none !important;
    }

    .mj-carousel-thumbnail,
    .mj-carousel-next,
    .mj-carousel-previous {
      touch-action: manipulation;
    }

    ${range(0, length)
      .map(
        i =>
          `.mj-carousel-${carouselId}-radio:checked ${repeat(
            '+ * ',
            i,
          )}+ .mj-carousel-content .mj-carousel-image`,
      )
      .join(',')} {
      display: none !important;
    }

    ${range(0, length)
      .map(
        i =>
          `.mj-carousel-${carouselId}-radio-${i + 1}:checked ${repeat(
            '+ * ',
            length - i - 1,
          )}+ .mj-carousel-content .mj-carousel-image-${i + 1}`,
      )
      .join(',')} {
      display: block !important;
    }

    .mj-carousel-previous-icons,
    .mj-carousel-next-icons,
    ${range(0, length).map(
      i =>
        `.mj-carousel-${carouselId}-radio-${i + 1}:checked ${repeat(
          '+ * ',
          length - i - 1,
        )}+ .mj-carousel-content .mj-carousel-next-${(i + 1 % length + length) %
          length +
          1}`,
    )},
    ${range(0, length).map(
      i =>
        `.mj-carousel-${carouselId}-radio-${i + 1}:checked ${repeat(
          '+ * ',
          length - i - 1,
        )}+ .mj-carousel-content .mj-carousel-previous-${(i -
          1 % length +
          length) %
          length +
          1}`,
    )} {
      display: block !important;
    }

    ${range(0, length)
      .map(
        i =>
          `.mj-carousel-${carouselId}-radio-${i + 1}:checked ${repeat(
            '+ * ',
            length - i - 1,
          )}+ .mj-carousel-content .mj-carousel-${carouselId}-thumbnail-${i +
            1}`,
      )
      .join(',')} {
      border-color: ${this.getAttribute('tb-selected-border-color')} !important;
    }

    .mj-carousel-image img + div,
    .mj-carousel-thumbnail img + div {
      display: none !important;
    }

    ${range(0, length)
      .map(
        i =>
          `.mj-carousel-${carouselId}-thumbnail:hover ${repeat(
            '+ * ',
            length - i - 1,
          )}+ .mj-carousel-main .mj-carousel-image`,
      )
      .join(',')} {
      display: none !important;
    }

    .mj-carousel-thumbnail:hover {
      border-color: ${this.getAttribute('tb-hover-border-color')} !important;
    }

    ${range(0, length)
      .map(
        i =>
          `.mj-carousel-${carouselId}-thumbnail-${i + 1}:hover ${repeat(
            '+ * ',
            length - i - 1,
          )}+ .mj-carousel-main .mj-carousel-image-${i + 1}`,
      )
      .join(',')} {
      display: block !important;
    }
    `

    const fallback = `
      .mj-carousel noinput { display:block !important; }
      .mj-carousel noinput .mj-carousel-image-1 { display: block !important;  }
      .mj-carousel noinput .mj-carousel-arrows,
      .mj-carousel noinput .mj-carousel-thumbnails { display: none !important; }

      [owa] .mj-carousel-thumbnail { display: none !important; }

      @media screen yahoo {
          .mj-carousel-${this.carouselId}-icons-cell,
          .mj-carousel-previous-icons,
          .mj-carousel-next-icons {
              display: none !important;
          }

          .mj-carousel-${carouselId}-radio-1:checked ${repeat(
      '+ *',
      length - 1,
    )}+ .mj-carousel-content .mj-carousel-${carouselId}-thumbnail-1 {
              border-color: transparent;
          }
      }
    `

    return `${carouselCss}\n${fallback}`
  }

  getStyles() { // eslint-disable-line class-methods-use-this
    return {
      carousel: {
        div: {
          display: 'table',
          width: '100%',
          'table-layout': 'fixed',
          'text-align': 'center',
          'font-size': '0px',
        },
        table: {
          'caption-side': 'top',
          display: 'table-caption',
          'table-layout': 'fixed',
          width: '100%',
        },
      },
      images: {
        td: {
          padding: '0px',
        },
      },
      controls: {
        div: {
          display: 'none',
          'mso-hide': 'all',
        },
        img: {
          display: 'block',
          width: this.getAttribute('icon-width'),
          height: 'auto',
        },
        td: {
          'font-size': '0px',
          display: 'none',
          'mso-hide': 'all',
          padding: '0px',
        },
      },
    }
  }

  thumbnailsWidth() {
    if (!this.props.children.length) return 0
    return (
      this.getAttribute('tb-width') ||
      `${min([this.context.parentWidth / this.props.children.length, 110])}px`
    )
  }

  imagesAttributes() {
    return map(this.children, 'attributes')
  }

  generateRadios() {
    return this.renderChildren(this.props.children, {
      renderer: component => component.renderRadio(),
      attributes: {
        carouselId: this.carouselId,
      },
    })
  }

  generateThumbnails() {
    if (this.getAttribute('thumbnails') !== 'visible') return ''

    return this.renderChildren(this.props.children, {
      attributes: {
        'tb-border': this.getAttribute('tb-border'),
        'tb-border-radius': this.getAttribute('tb-border-radius'),
        'tb-width': this.thumbnailsWidth(),
        carouselId: this.carouselId,
      },
      renderer: component => component.renderThumbnail(),
    })
  }

  generateControls(direction, icon) {
    const iconWidth = parseInt(this.getAttribute('icon-width'), 10)

    return `
      <td
        ${this.htmlAttributes({
          class: `mj-carousel-${this.carouselId}-icons-cell`,
          style: 'controls.td',
        })}
      >
        <div
          ${this.htmlAttributes({
            class: `mj-carousel-${direction}-icons`,
            style: 'controls.div',
          })}
        >
          ${range(1, this.props.children.length + 1).map(
            i => `
              <label
                ${this.htmlAttributes({
                  for: `mj-carousel-${this.carouselId}-radio-${i}`,
                  class: `mj-carousel-${direction} mj-carousel-${direction}-${i}`,
                })}
              >

            `,
          ).join('')}

    `
  }

  generateImages() {
    return `

          ${this.renderChildren(this.props.children, {
            attributes: {
              'border-radius': this.getAttribute('border-radius'),
            },
          })}

    `
  }

  generateCarousel() {
    return `

            ${this.generateControls('previous', this.getAttribute('left-icon'))}
            ${this.generateImages()}
            ${this.generateControls('next', this.getAttribute('right-icon'))}

    `
  }

  renderFallback() {
    const { children } = this.props
    if (children.length === 0) return ''

    return msoConditionalTag(
      this.renderChildren([children[0]], {
        attributes: {
          'border-radius': this.getAttribute('border-radius'),
        },
      }),
    )
  }

  render() {
    return `
      ${msoConditionalTag(
        `

          ${this.generateRadios()}

            ${this.generateThumbnails()}
            ${this.generateCarousel()}

      `,
        true,
      )}
      ${this.renderFallback()}
    `
  }
}
<|endoftext|>


<commit_before>import {
    WS_INSERT_OTU,
    WS_UPDATE_OTU,
    WS_REMOVE_OTU,
    FIND_OTUS,
    GET_OTU,
    GET_OTU_HISTORY,
    CREATE_OTU,
    EDIT_OTU,
    REMOVE_OTU,
    ADD_ISOLATE,
    EDIT_ISOLATE,
    SET_ISOLATE_AS_DEFAULT,
    REMOVE_ISOLATE,
    ADD_SEQUENCE,
    EDIT_SEQUENCE,
    REMOVE_SEQUENCE,
    REVERT,
    SELECT_ISOLATE,
    SHOW_EDIT_OTU,
    SHOW_REMOVE_OTU,
    SHOW_ADD_ISOLATE,
    SHOW_EDIT_ISOLATE,
    SHOW_REMOVE_ISOLATE,
    SHOW_ADD_SEQUENCE,
    SHOW_EDIT_SEQUENCE,
    SHOW_REMOVE_SEQUENCE,
    HIDE_OTU_MODAL
} from "../../app/actionTypes";
import {
    wsInsertOTU,
    wsUpdateOTU,
    wsRemoveOTU,
    findOTUs,
    getOTU,
    getOTUHistory,
    createOTU,
    editOTU,
    removeOTU,
    addIsolate,
    setIsolateAsDefault,
    editIsolate,
    removeIsolate,
    addSequence,
    editSequence,
    removeSequence,
    revert,
    selectIsolate,
    showEditOTU,
    showRemoveOTU,
    showAddIsolate,
    showEditIsolate,
    showRemoveIsolate,
    showAddSequence,
    showEditSequence,
    showRemoveSequence,
    hideOTUModal
} from "../actions";

describe("OTUs Action Creators", () => {
    const otuId = "test-otu";
    const isolateId = "test-isolate";
    const sequenceId = "test-sequence";
    const sourceType = "test-source-type";
    const sourceName = "test-source-name";
    const definition = "test-definition";
    const host = "test-host";
    const sequence = "test-sequence";
    const segment = "test-segment";

    it("wsInsertOTU: returns action to insert OTU entry via websocket", () => {
        const data = { id: "test" };
        const result = wsInsertOTU(data);
        expect(result).toEqual({ type: WS_INSERT_OTU, data });
    });

    it("wsUpdateOTU: returns action to update OTU entry via websocket", () => {
        const data = { id: "test", foo: "bar" };
        const result = wsUpdateOTU(data);
        expect(result).toEqual({ type: WS_UPDATE_OTU, data });
    });

    it("wsRemoveOTU: returns action to remove OTU entry via websocket", () => {
        const data = ["test"];
        const result = wsRemoveOTU(data);
        expect(result).toEqual({ type: WS_REMOVE_OTU, data });
    });

    it("findOTUs: returns action to list specific page of otu documents", () => {
        const refId = "123abc";
        const term = "foo";
        const verified = true;
        const page = 2;
        const result = findOTUs(refId, term, verified, page);
        expect(result).toEqual({ type: FIND_OTUS.REQUESTED, refId, term, verified, page });
    });

    it("getOTU: returns action to retrieve a specific otu", () => {
        const result = getOTU(otuId);
        expect(result).toEqual({ type: GET_OTU.REQUESTED, otuId });
    });

    it("getOTUHistory: returns action to retrieve change history of specific otu", () => {
        const result = getOTUHistory(otuId);
        expect(result).toEqual({ type: GET_OTU_HISTORY.REQUESTED, otuId });
    });

    it("createOTU: returns action to create a new otu", () => {
        const refId = "123abc";
        const name = "new otu";
        const abbreviation = "NEW";
        const result = createOTU(refId, name, abbreviation);
        expect(result).toEqual({ type: CREATE_OTU.REQUESTED, refId, name, abbreviation });
    });

    it("editOTU: return action to edit a specific otu", () => {
        const name = "target-otu";
        const abbreviation = "OLD";
        const schema = [];
        const result = editOTU(otuId, name, abbreviation, schema);
        expect(result).toEqual({ type: EDIT_OTU.REQUESTED, otuId, name, abbreviation, schema });
    });

    it("removeOTU: returns action to delete specific otu", () => {
        const refId = "123abc";
        const history = {};
        const result = removeOTU(refId, otuId, history);
        expect(result).toEqual({ type: REMOVE_OTU.REQUESTED, refId, otuId, history });
    });

    it("addIsolate: returns action to add an isolate to an otu", () => {
        const result = addIsolate(otuId, sourceType, sourceName);
        expect(result).toEqual({ type: ADD_ISOLATE.REQUESTED, otuId, sourceType, sourceName });
    });

    it("setIsolateAsDefault: returns action to set specific isolate as default", () => {
        const result = setIsolateAsDefault(otuId, isolateId);
        expect(result).toEqual({ type: SET_ISOLATE_AS_DEFAULT.REQUESTED, otuId, isolateId });
    });

    it("editIsolate: returns action to edit a specific isolate", () => {
        const result = editIsolate(otuId, isolateId, sourceType, sourceName);
        expect(result).toEqual({
            type: EDIT_ISOLATE.REQUESTED,
            otuId,
            isolateId,
            sourceType,
            sourceName
        });
    });

    it("removeIsolate: returns action to delete a specific isolate", () => {
        const nextIsolateId = "test-other-isolate";
        const result = removeIsolate(otuId, isolateId, nextIsolateId);
        expect(result).toEqual({
            type: REMOVE_ISOLATE.REQUESTED,
            otuId,
            isolateId,
            nextIsolateId
        });
    });

    it("addSequence: returns action to add a new sequence to an isolate", () => {
        const result = addSequence(otuId, isolateId, sequenceId, definition, host, sequence, segment);
        expect(result).toEqual({
            type: ADD_SEQUENCE.REQUESTED,
            otuId,
            isolateId,
            sequenceId,
            definition,
            host,
            sequence,
            segment
        });
    });

    it("editSequence: returns action to edit a specific sequence", () => {
        const result = editSequence(otuId, isolateId, sequenceId, definition, host, sequence, segment);
        expect(result).toEqual({
            type: EDIT_SEQUENCE.REQUESTED,
            otuId,
            isolateId,
            sequenceId,
            definition,
            host,
            sequence,
            segment
        });
    });

    it("removeSequence: returns action to remove a specific sequence", () => {
        const result = removeSequence(otuId, isolateId, sequenceId);
        expect(result).toEqual({
            type: REMOVE_SEQUENCE.REQUESTED,
            otuId,
            isolateId,
            sequenceId
        });
    });

    it("revert: returns action to undo the latest change of a particular otu", () => {
        const changeId = "123abc";
        const result = revert(otuId, changeId);
        expect(result).toEqual({ type: REVERT.REQUESTED, otuId, change_id: changeId });
    });

    it("selectIsolate: returns action to select isolate to expand", () => {
        const result = selectIsolate(isolateId);
        expect(result).toEqual({ type: SELECT_ISOLATE, isolateId });
    });

    it("showEditOTU: returns action to display edit otu modal", () => {
        expect(showEditOTU()).toEqual({ type: SHOW_EDIT_OTU });
    });

    it("showRemoveOTU: returns action to display remove otu modal", () => {
        expect(showRemoveOTU()).toEqual({ type: SHOW_REMOVE_OTU });
    });

    it("showAddIsolate: returns action to display add isolate modal", () => {
        expect(showAddIsolate()).toEqual({ type: SHOW_ADD_ISOLATE });
    });

    it("showEditIsolate: returns action to display edit isolate modal", () => {
        const result = showEditIsolate(otuId, isolateId, sourceType, sourceName);
        expect(result).toEqual({
            type: SHOW_EDIT_ISOLATE,
            otuId,
            isolateId,
            sourceType,
            sourceName
        });
    });

    it("showRemoveIsolate: returns action to display remove isolate modal", () => {
        expect(showRemoveIsolate()).toEqual({ type: SHOW_REMOVE_ISOLATE });
    });

    it("showAddSequence: returns action to display add sequence modal", () => {
        expect(showAddSequence()).toEqual({ type: SHOW_ADD_SEQUENCE });
    });

    it("showEditSequence: returns action to display edit sequence modal", () => {
        const result = showEditSequence(sequenceId);
        expect(result).toEqual({ type: SHOW_EDIT_SEQUENCE, sequenceId });
    });

    it("showRemoveSequence: returns action to display remove sequence modal", () => {
        const result = showRemoveSequence(sequenceId);
        expect(result).toEqual({ type: SHOW_REMOVE_SEQUENCE, sequenceId });
    });

    it("hideOTUModal: returns action to hide otu modal", () => {
        expect(hideOTUModal()).toEqual({ type: HIDE_OTU_MODAL });
    });
});
<commit_msg>Update tests<commit_after>import {
    WS_INSERT_OTU,
    WS_UPDATE_OTU,
    WS_REMOVE_OTU,
    FIND_OTUS,
    GET_OTU,
    GET_OTU_HISTORY,
    CREATE_OTU,
    EDIT_OTU,
    REMOVE_OTU,
    ADD_ISOLATE,
    EDIT_ISOLATE,
    SET_ISOLATE_AS_DEFAULT,
    REMOVE_ISOLATE,
    ADD_SEQUENCE,
    EDIT_SEQUENCE,
    REMOVE_SEQUENCE,
    REVERT,
    SELECT_ISOLATE,
    SHOW_EDIT_OTU,
    SHOW_REMOVE_OTU,
    SHOW_ADD_ISOLATE,
    SHOW_EDIT_ISOLATE,
    SHOW_REMOVE_ISOLATE,
    SHOW_ADD_SEQUENCE,
    SHOW_EDIT_SEQUENCE,
    SHOW_REMOVE_SEQUENCE,
    HIDE_OTU_MODAL
} from "../../app/actionTypes";
import {
    wsInsertOTU,
    wsUpdateOTU,
    wsRemoveOTU,
    findOTUs,
    getOTU,
    getOTUHistory,
    createOTU,
    editOTU,
    removeOTU,
    addIsolate,
    setIsolateAsDefault,
    editIsolate,
    removeIsolate,
    addSequence,
    editSequence,
    removeSequence,
    revert,
    selectIsolate,
    showEditOTU,
    showRemoveOTU,
    showAddIsolate,
    showEditIsolate,
    showRemoveIsolate,
    showAddSequence,
    showEditSequence,
    showRemoveSequence,
    hideOTUModal
} from "../actions";

describe("OTUs Action Creators", () => {
    const otuId = "test-otu";
    const isolateId = "test-isolate";
    const sequenceId = "test-sequence";
    const sourceType = "test-source-type";
    const sourceName = "test-source-name";
    const definition = "test-definition";
    const host = "test-host";
    const sequence = "test-sequence";
    const segment = "test-segment";

    it("wsInsertOTU: returns action to insert OTU entry via websocket", () => {
        const data = { id: "test" };
        const result = wsInsertOTU(data);
        expect(result).toEqual({ type: WS_INSERT_OTU, data });
    });

    it("wsUpdateOTU: returns action to update OTU entry via websocket", () => {
        const data = { id: "test", foo: "bar" };
        const result = wsUpdateOTU(data);
        expect(result).toEqual({ type: WS_UPDATE_OTU, data });
    });

    it("wsRemoveOTU: returns action to remove OTU entry via websocket", () => {
        const data = ["test"];
        const result = wsRemoveOTU(data);
        expect(result).toEqual({ type: WS_REMOVE_OTU, data });
    });

    it("findOTUs: returns action to list specific page of otu documents", () => {
        const refId = "123abc";
        const term = "foo";
        const verified = true;
        const page = 2;
        const result = findOTUs(refId, term, verified, page);
        expect(result).toEqual({ type: FIND_OTUS.REQUESTED, refId, term, verified, page });
    });

    it("getOTU: returns action to retrieve a specific otu", () => {
        const result = getOTU(otuId);
        expect(result).toEqual({ type: GET_OTU.REQUESTED, otuId });
    });

    it("getOTUHistory: returns action to retrieve change history of specific otu", () => {
        const result = getOTUHistory(otuId);
        expect(result).toEqual({ type: GET_OTU_HISTORY.REQUESTED, otuId });
    });

    it("createOTU: returns action to create a new otu", () => {
        const refId = "123abc";
        const name = "new otu";
        const abbreviation = "NEW";
        const result = createOTU(refId, name, abbreviation);
        expect(result).toEqual({ type: CREATE_OTU.REQUESTED, refId, name, abbreviation });
    });

    it("editOTU: return action to edit a specific otu", () => {
        const name = "target-otu";
        const abbreviation = "OLD";
        const schema = [];
        const result = editOTU(otuId, name, abbreviation, schema);
        expect(result).toEqual({ type: EDIT_OTU.REQUESTED, otuId, name, abbreviation, schema });
    });

    it("removeOTU: returns action to delete specific otu", () => {
        const refId = "123abc";
        const history = {};
        const result = removeOTU(refId, otuId, history);
        expect(result).toEqual({ type: REMOVE_OTU.REQUESTED, refId, otuId, history });
    });

    it("addIsolate: returns action to add an isolate to an otu", () => {
        const result = addIsolate(otuId, sourceType, sourceName);
        expect(result).toEqual({ type: ADD_ISOLATE.REQUESTED, otuId, sourceType, sourceName });
    });

    it("setIsolateAsDefault: returns action to set specific isolate as default", () => {
        const result = setIsolateAsDefault(otuId, isolateId);
        expect(result).toEqual({ type: SET_ISOLATE_AS_DEFAULT.REQUESTED, otuId, isolateId });
    });

    it("editIsolate: returns action to edit a specific isolate", () => {
        const result = editIsolate(otuId, isolateId, sourceType, sourceName);
        expect(result).toEqual({
            type: EDIT_ISOLATE.REQUESTED,
            otuId,
            isolateId,
            sourceType,
            sourceName
        });
    });

    it("removeIsolate: returns action to delete a specific isolate", () => {
        const nextIsolateId = "test-other-isolate";
        const result = removeIsolate(otuId, isolateId, nextIsolateId);
        expect(result).toEqual({
            type: REMOVE_ISOLATE.REQUESTED,
            otuId,
            isolateId,
            nextIsolateId
        });
    });

    it("addSequence: returns action to add a new sequence to an isolate", () => {
        const result = addSequence(otuId, isolateId, sequenceId, definition, host, sequence, segment);
        expect(result).toEqual({
            type: ADD_SEQUENCE.REQUESTED,
            otuId,
            isolateId,
            sequenceId,
            definition,
            host,
            sequence,
            segment
        });
    });

    it("editSequence: returns action to edit a specific sequence", () => {
        const result = editSequence(otuId, isolateId, sequenceId, definition, host, sequence, segment);
        expect(result).toEqual({
            type: EDIT_SEQUENCE.REQUESTED,
            otuId,
            isolateId,
            sequenceId,
            definition,
            host,
            sequence,
            segment
        });
    });

    it("removeSequence: returns action to remove a specific sequence", () => {
        const result = removeSequence(otuId, isolateId, sequenceId);
        expect(result).toEqual({
            type: REMOVE_SEQUENCE.REQUESTED,
            otuId,
            isolateId,
            sequenceId
        });
    });

    it("revert: returns action to undo the latest change of a particular otu", () => {
        const changeId = "123abc";
        const otuVersion = 3;
        const result = revert(otuId, otuVersion, changeId);
        expect(result).toEqual({ type: REVERT.REQUESTED, otuId, otuVersion, change_id: changeId });
    });

    it("selectIsolate: returns action to select isolate to expand", () => {
        const result = selectIsolate(isolateId);
        expect(result).toEqual({ type: SELECT_ISOLATE, isolateId });
    });

    it("showEditOTU: returns action to display edit otu modal", () => {
        expect(showEditOTU()).toEqual({ type: SHOW_EDIT_OTU });
    });

    it("showRemoveOTU: returns action to display remove otu modal", () => {
        expect(showRemoveOTU()).toEqual({ type: SHOW_REMOVE_OTU });
    });

    it("showAddIsolate: returns action to display add isolate modal", () => {
        expect(showAddIsolate()).toEqual({ type: SHOW_ADD_ISOLATE });
    });

    it("showEditIsolate: returns action to display edit isolate modal", () => {
        const result = showEditIsolate(otuId, isolateId, sourceType, sourceName);
        expect(result).toEqual({
            type: SHOW_EDIT_ISOLATE,
            otuId,
            isolateId,
            sourceType,
            sourceName
        });
    });

    it("showRemoveIsolate: returns action to display remove isolate modal", () => {
        expect(showRemoveIsolate()).toEqual({ type: SHOW_REMOVE_ISOLATE });
    });

    it("showAddSequence: returns action to display add sequence modal", () => {
        expect(showAddSequence()).toEqual({ type: SHOW_ADD_SEQUENCE });
    });

    it("showEditSequence: returns action to display edit sequence modal", () => {
        const result = showEditSequence(sequenceId);
        expect(result).toEqual({ type: SHOW_EDIT_SEQUENCE, sequenceId });
    });

    it("showRemoveSequence: returns action to display remove sequence modal", () => {
        const result = showRemoveSequence(sequenceId);
        expect(result).toEqual({ type: SHOW_REMOVE_SEQUENCE, sequenceId });
    });

    it("hideOTUModal: returns action to hide otu modal", () => {
        expect(hideOTUModal()).toEqual({ type: HIDE_OTU_MODAL });
    });
});
<|endoftext|>


<commit_before>import { translate } from '../../../../common/i18n';
import config from '../../../common/const';
import { oppositesToDropdown } from '../utils';
import { symbolApi } from '../../shared';
import { get as getStorage, set as setStorage } from '../../../../common/utils/storageManager';
import { generateLiveApiInstance } from '../../../../common/appId';

let purchaseChoices = [[translate('Click to select'), '']];

export const getPurchaseChoices = () => purchaseChoices;

const filterPurchaseChoices = (contractType, oppositesName) => {
    const { [oppositesName]: tradeTypes } = config.opposites;

    let tmpPurchaseChoices = tradeTypes.filter(k =>
        contractType === 'both' ? true : contractType === Object.keys(k)[0]
    );

    if (!tmpPurchaseChoices.length) {
        tmpPurchaseChoices = tradeTypes;
    }
    return oppositesToDropdown(tmpPurchaseChoices);
};

export const updatePurchaseChoices = (contractType, oppositesName) => {
    purchaseChoices = filterPurchaseChoices(contractType, oppositesName);
    const purchases = Blockly.mainWorkspace
        .getAllBlocks()
        .filter(r => ['purchase', 'payout', 'ask_price'].indexOf(r.type) >= 0);
    Blockly.Events.recordUndo = false;
    purchases.forEach(purchase => {
        const value = purchase.getField('PURCHASE_LIST').getValue();
        Blockly.WidgetDiv.hideIfOwner(purchase.getField('PURCHASE_LIST'));
        if (value === purchaseChoices[0][1]) {
            purchase.getField('PURCHASE_LIST').setText(purchaseChoices[0][0]);
        } else if (purchaseChoices.length === 2 && value === purchaseChoices[1][1]) {
            purchase.getField('PURCHASE_LIST').setText(purchaseChoices[1][0]);
        } else {
            purchase.getField('PURCHASE_LIST').setValue(purchaseChoices[0][1]);
            purchase.getField('PURCHASE_LIST').setText(purchaseChoices[0][0]);
        }
    });
    Blockly.Events.recordUndo = true;
};

export const expectValue = (block, field) => {
    const value = Blockly.JavaScript.valueToCode(block, field, Blockly.JavaScript.ORDER_ATOMIC);
    if (!value) {
        throw Error(translate(`${field} cannot be empty`));
    }
    return value;
};

export const fieldGeneratorMapping = {};

const getActiveSymbols = symbols =>
    Object.keys(symbols).reduce(
        (acc, symbol) =>
            symbolApi.getAllowedCategories(symbol).length ? { ...acc, [symbol]: symbols[symbol] } : { ...acc },
        {}
    );

const getActiveSubMarket = submarkets =>
    Object.keys(submarkets).reduce(
        (acc, submarket) =>
            Object.keys(getActiveSymbols(submarkets[submarket].symbols)).length
                ? { ...acc, [submarket]: submarkets[submarket] }
                : { ...acc },
        {}
    );

const getActiveMarket = markets =>
    Object.keys(markets).reduce(
        (acc, market) =>
            Object.keys(getActiveSubMarket(markets[market].submarkets)).length
                ? { ...acc, [market]: markets[market] }
                : { ...acc },
        {}
    );

fieldGeneratorMapping.MARKET_LIST = () => {
    const markets = getActiveMarket(symbolApi.activeSymbols.getMarkets());
    return Object.keys(markets).map(e => [markets[e].name, e]);
};

fieldGeneratorMapping.SUBMARKET_LIST = block => () => {
    const markets = getActiveMarket(symbolApi.activeSymbols.getMarkets());
    const marketName = block.getFieldValue('MARKET_LIST');
    if (!marketName || marketName === 'Invalid') {
        return [['', 'Invalid']];
    }
    const submarkets = getActiveSubMarket(markets[marketName].submarkets);
    return Object.keys(submarkets).map(e => [submarkets[e].name, e]);
};

fieldGeneratorMapping.SYMBOL_LIST = block => () => {
    const markets = getActiveMarket(symbolApi.activeSymbols.getMarkets());
    const submarketName = block.getFieldValue('SUBMARKET_LIST');
    if (!submarketName || submarketName === 'Invalid') {
        return [['', '']];
    }
    const marketName = block.getFieldValue('MARKET_LIST');
    const submarkets = getActiveSubMarket(markets[marketName].submarkets);
    const symbols = getActiveSymbols(submarkets[submarketName].symbols);
    return Object.keys(symbols).map(e => [symbols[e].display, symbols[e].symbol]);
};

fieldGeneratorMapping.TRADETYPECAT_LIST = block => () => {
    const symbol = block.getFieldValue('SYMBOL_LIST');
    if (!symbol) {
        return [['', '']];
    }
    const allowedCategories = symbolApi.getAllowedCategories(symbol.toLowerCase());
    return Object.keys(config.conditionsCategoryName)
        .filter(e => allowedCategories.indexOf(e) >= 0)
        .map(e => [config.conditionsCategoryName[e], e]);
};

fieldGeneratorMapping.TRADETYPE_LIST = block => () => {
    const tradeTypeCat = block.getFieldValue('TRADETYPECAT_LIST');
    if (!tradeTypeCat) {
        return [['', '']];
    }
    return config.conditionsCategory[tradeTypeCat].map(e => [
        config.opposites[e.toUpperCase()].map(c => c[Object.keys(c)[0]]).join('/'),
        e,
    ]);
};

export const dependentFieldMapping = {
    MARKET_LIST      : 'SUBMARKET_LIST',
    SUBMARKET_LIST   : 'SYMBOL_LIST',
    SYMBOL_LIST      : 'TRADETYPECAT_LIST',
    TRADETYPECAT_LIST: 'TRADETYPE_LIST',
};

export const getAvailableDurations = (symbol, selectedContractType) => {
    const contractsForStore = JSON.parse(getStorage('contractsForStore') || '[]');
    const defaultDurations = [
        [translate('Ticks'), 't'],
        [translate('Seconds'), 's'],
        [translate('Minutes'), 'm'],
        [translate('Hours'), 'h'],
        [translate('Days'), 'd'],
    ];
    const getContractsForSymbolFromApi = async underlyingSymbol => {
        // Refactor this when reducing WS connections
        let api = generateLiveApiInstance();
        const response = await api.getContractsForSymbol(underlyingSymbol);
        const contractsForSymbol = {};
        if (response.contracts_for) {
            Object.assign(contractsForSymbol, {
                symbol   : underlyingSymbol,
                available: response.contracts_for.available,
                timestamp: Date.now(),
            });
            contractsForStore.push(contractsForSymbol);
            setStorage('contractsForStore', JSON.stringify(contractsForStore));
        }
        api.disconnect();
        api = null;
        return contractsForSymbol;
    };
    const getDurationsForContract = contractsForSymbol => {
        if (!contractsForSymbol) return defaultDurations;

        // Resolve contract_category (e.g. risefall = callput)
        const contractCategory = Object.keys(config.conditionsCategory).find(
            c => c === selectedContractType || config.conditionsCategory[c].includes(selectedContractType)
        );

        // Get contracts based on `contract_category` and `barrier_category`
        const contractsForContractCategory = contractsForSymbol.filter(c => {
            const meetsBarrierConditions = () => {
                const conditions = [];
                Object.keys(config.barrierCategories).some(barrierCategory => {
                    if (config.barrierCategories[barrierCategory].includes(selectedContractType)) {
                        conditions.push(c.barrier_category === barrierCategory);
                    }
                    return conditions.length;
                });
                // If `barrierCategory` for `selectedContractType` not found fallback to all contracts for durations
                return !conditions.includes(false);
            };
            return c.contract_category === contractCategory && meetsBarrierConditions();
        });

        const getDurationIndex = input => defaultDurations.findIndex(d => d[1] === input.replace(/\d+/g, ''));

        // Generate list of available durations from filtered contracts
        const offeredDurations = [];
        contractsForContractCategory.forEach(c => {
            const startIndex = getDurationIndex(c.min_contract_duration);
            const endIndex = getDurationIndex(c.max_contract_duration);
            defaultDurations.slice(startIndex, endIndex + 1).forEach(duration => {
                if (!offeredDurations.includes(duration)) {
                    offeredDurations.push(duration);
                }
            });
        });
        const isIntraday = contractsForContractCategory.every(c => c.expiry_type === 'intraday');
        if (isIntraday) {
            const dayDurationIndex = offeredDurations.findIndex(d => d[1] === 'd');
            if (dayDurationIndex) {
                offeredDurations.splice(dayDurationIndex, 1);
            }
        }
        if (offeredDurations.length) {
            offeredDurations.sort((a, b) => getDurationIndex(a[1]) - getDurationIndex(b[1]));
            return offeredDurations;
        }
        return config.durationTypes[selectedContractType.toUpperCase()];
    };
    // Check if we have local data to get durations from
    const contractsForSymbol = contractsForStore.find(c => c.symbol === symbol);
    if (contractsForSymbol) {
        // If `contracts_for` data is expired, request new data in background but return current cached data
        if (Math.floor((Date.now() - contractsForSymbol.timestamp) / 1000) > 600) {
            getContractsForSymbolFromApi(symbol);
        }
        return Promise.resolve(getDurationsForContract(contractsForSymbol.available));
    }
    return new Promise(resolve => {
        getContractsForSymbolFromApi(symbol).then(contractsForSymbolFromApi => {
            resolve(getDurationsForContract(contractsForSymbolFromApi.available));
        });
    });
};
<commit_msg>Re-order imports for blocks/shared.js<commit_after>import { oppositesToDropdown } from '../utils';
import { symbolApi } from '../../shared';
import config from '../../../common/const';
import { generateLiveApiInstance } from '../../../../common/appId';
import { translate } from '../../../../common/i18n';
import { get as getStorage, set as setStorage } from '../../../../common/utils/storageManager';

let purchaseChoices = [[translate('Click to select'), '']];

export const getPurchaseChoices = () => purchaseChoices;

const filterPurchaseChoices = (contractType, oppositesName) => {
    const { [oppositesName]: tradeTypes } = config.opposites;

    let tmpPurchaseChoices = tradeTypes.filter(k =>
        contractType === 'both' ? true : contractType === Object.keys(k)[0]
    );

    if (!tmpPurchaseChoices.length) {
        tmpPurchaseChoices = tradeTypes;
    }
    return oppositesToDropdown(tmpPurchaseChoices);
};

export const updatePurchaseChoices = (contractType, oppositesName) => {
    purchaseChoices = filterPurchaseChoices(contractType, oppositesName);
    const purchases = Blockly.mainWorkspace
        .getAllBlocks()
        .filter(r => ['purchase', 'payout', 'ask_price'].indexOf(r.type) >= 0);
    Blockly.Events.recordUndo = false;
    purchases.forEach(purchase => {
        const value = purchase.getField('PURCHASE_LIST').getValue();
        Blockly.WidgetDiv.hideIfOwner(purchase.getField('PURCHASE_LIST'));
        if (value === purchaseChoices[0][1]) {
            purchase.getField('PURCHASE_LIST').setText(purchaseChoices[0][0]);
        } else if (purchaseChoices.length === 2 && value === purchaseChoices[1][1]) {
            purchase.getField('PURCHASE_LIST').setText(purchaseChoices[1][0]);
        } else {
            purchase.getField('PURCHASE_LIST').setValue(purchaseChoices[0][1]);
            purchase.getField('PURCHASE_LIST').setText(purchaseChoices[0][0]);
        }
    });
    Blockly.Events.recordUndo = true;
};

export const expectValue = (block, field) => {
    const value = Blockly.JavaScript.valueToCode(block, field, Blockly.JavaScript.ORDER_ATOMIC);
    if (!value) {
        throw Error(translate(`${field} cannot be empty`));
    }
    return value;
};

export const fieldGeneratorMapping = {};

const getActiveSymbols = symbols =>
    Object.keys(symbols).reduce(
        (acc, symbol) =>
            symbolApi.getAllowedCategories(symbol).length ? { ...acc, [symbol]: symbols[symbol] } : { ...acc },
        {}
    );

const getActiveSubMarket = submarkets =>
    Object.keys(submarkets).reduce(
        (acc, submarket) =>
            Object.keys(getActiveSymbols(submarkets[submarket].symbols)).length
                ? { ...acc, [submarket]: submarkets[submarket] }
                : { ...acc },
        {}
    );

const getActiveMarket = markets =>
    Object.keys(markets).reduce(
        (acc, market) =>
            Object.keys(getActiveSubMarket(markets[market].submarkets)).length
                ? { ...acc, [market]: markets[market] }
                : { ...acc },
        {}
    );

fieldGeneratorMapping.MARKET_LIST = () => {
    const markets = getActiveMarket(symbolApi.activeSymbols.getMarkets());
    return Object.keys(markets).map(e => [markets[e].name, e]);
};

fieldGeneratorMapping.SUBMARKET_LIST = block => () => {
    const markets = getActiveMarket(symbolApi.activeSymbols.getMarkets());
    const marketName = block.getFieldValue('MARKET_LIST');
    if (!marketName || marketName === 'Invalid') {
        return [['', 'Invalid']];
    }
    const submarkets = getActiveSubMarket(markets[marketName].submarkets);
    return Object.keys(submarkets).map(e => [submarkets[e].name, e]);
};

fieldGeneratorMapping.SYMBOL_LIST = block => () => {
    const markets = getActiveMarket(symbolApi.activeSymbols.getMarkets());
    const submarketName = block.getFieldValue('SUBMARKET_LIST');
    if (!submarketName || submarketName === 'Invalid') {
        return [['', '']];
    }
    const marketName = block.getFieldValue('MARKET_LIST');
    const submarkets = getActiveSubMarket(markets[marketName].submarkets);
    const symbols = getActiveSymbols(submarkets[submarketName].symbols);
    return Object.keys(symbols).map(e => [symbols[e].display, symbols[e].symbol]);
};

fieldGeneratorMapping.TRADETYPECAT_LIST = block => () => {
    const symbol = block.getFieldValue('SYMBOL_LIST');
    if (!symbol) {
        return [['', '']];
    }
    const allowedCategories = symbolApi.getAllowedCategories(symbol.toLowerCase());
    return Object.keys(config.conditionsCategoryName)
        .filter(e => allowedCategories.indexOf(e) >= 0)
        .map(e => [config.conditionsCategoryName[e], e]);
};

fieldGeneratorMapping.TRADETYPE_LIST = block => () => {
    const tradeTypeCat = block.getFieldValue('TRADETYPECAT_LIST');
    if (!tradeTypeCat) {
        return [['', '']];
    }
    return config.conditionsCategory[tradeTypeCat].map(e => [
        config.opposites[e.toUpperCase()].map(c => c[Object.keys(c)[0]]).join('/'),
        e,
    ]);
};

export const dependentFieldMapping = {
    MARKET_LIST      : 'SUBMARKET_LIST',
    SUBMARKET_LIST   : 'SYMBOL_LIST',
    SYMBOL_LIST      : 'TRADETYPECAT_LIST',
    TRADETYPECAT_LIST: 'TRADETYPE_LIST',
};

export const getAvailableDurations = (symbol, selectedContractType) => {
    const contractsForStore = JSON.parse(getStorage('contractsForStore') || '[]');
    const defaultDurations = [
        [translate('Ticks'), 't'],
        [translate('Seconds'), 's'],
        [translate('Minutes'), 'm'],
        [translate('Hours'), 'h'],
        [translate('Days'), 'd'],
    ];
    const getContractsForSymbolFromApi = async underlyingSymbol => {
        // Refactor this when reducing WS connections
        let api = generateLiveApiInstance();
        const response = await api.getContractsForSymbol(underlyingSymbol);
        const contractsForSymbol = {};
        if (response.contracts_for) {
            Object.assign(contractsForSymbol, {
                symbol   : underlyingSymbol,
                available: response.contracts_for.available,
                timestamp: Date.now(),
            });
            contractsForStore.push(contractsForSymbol);
            setStorage('contractsForStore', JSON.stringify(contractsForStore));
        }
        api.disconnect();
        api = null;
        return contractsForSymbol;
    };
    const getDurationsForContract = contractsForSymbol => {
        if (!contractsForSymbol) return defaultDurations;

        // Resolve contract_category (e.g. risefall = callput)
        const contractCategory = Object.keys(config.conditionsCategory).find(
            c => c === selectedContractType || config.conditionsCategory[c].includes(selectedContractType)
        );

        // Get contracts based on `contract_category` and `barrier_category`
        const contractsForContractCategory = contractsForSymbol.filter(c => {
            const meetsBarrierConditions = () => {
                const conditions = [];
                Object.keys(config.barrierCategories).some(barrierCategory => {
                    if (config.barrierCategories[barrierCategory].includes(selectedContractType)) {
                        conditions.push(c.barrier_category === barrierCategory);
                    }
                    return conditions.length;
                });
                // If `barrierCategory` for `selectedContractType` not found fallback to all contracts for durations
                return !conditions.includes(false);
            };
            return c.contract_category === contractCategory && meetsBarrierConditions();
        });

        const getDurationIndex = input => defaultDurations.findIndex(d => d[1] === input.replace(/\d+/g, ''));

        // Generate list of available durations from filtered contracts
        const offeredDurations = [];
        contractsForContractCategory.forEach(c => {
            const startIndex = getDurationIndex(c.min_contract_duration);
            const endIndex = getDurationIndex(c.max_contract_duration);
            defaultDurations.slice(startIndex, endIndex + 1).forEach(duration => {
                if (!offeredDurations.includes(duration)) {
                    offeredDurations.push(duration);
                }
            });
        });
        const isIntraday = contractsForContractCategory.every(c => c.expiry_type === 'intraday');
        if (isIntraday) {
            const dayDurationIndex = offeredDurations.findIndex(d => d[1] === 'd');
            if (dayDurationIndex) {
                offeredDurations.splice(dayDurationIndex, 1);
            }
        }
        if (offeredDurations.length) {
            offeredDurations.sort((a, b) => getDurationIndex(a[1]) - getDurationIndex(b[1]));
            return offeredDurations;
        }
        return config.durationTypes[selectedContractType.toUpperCase()];
    };
    // Check if we have local data to get durations from
    const contractsForSymbol = contractsForStore.find(c => c.symbol === symbol);
    if (contractsForSymbol) {
        // If `contracts_for` data is expired, request new data in background but return current cached data
        if (Math.floor((Date.now() - contractsForSymbol.timestamp) / 1000) > 600) {
            getContractsForSymbolFromApi(symbol);
        }
        return Promise.resolve(getDurationsForContract(contractsForSymbol.available));
    }
    return new Promise(resolve => {
        getContractsForSymbolFromApi(symbol).then(contractsForSymbolFromApi => {
            resolve(getDurationsForContract(contractsForSymbolFromApi.available));
        });
    });
};
<|endoftext|>


<commit_before>require('./sinq.js')()

var meuArray = [];
meuArray.push({
  meuNome: 'Luana',
  meuCurso: 'Engenharia'
});

meuArray.push({
  meuNome: 'Pedro',
  meuCurso: 'Engenharia'
});

meuArray.push({
  meuNome: 'Fernanda',
  meuCurso: 'Engenharia'
});

meuArray.push({
  meuNome: 'Ana',
  meuCurso: 'Matemática'
});

console.log('\n#meuArray')
console.log(meuArray)

meuArray.orderBy('meuNome')

console.log('\n#OrderBy')
console.log(meuArray)

console.log('\n#select')
console.log(meuArray.select( m => { return { Nome: m.meuNome } }))

console.log('\n#groupBy')
console.log(meuArray.groupBy( m => m.meuCurso ))

console.log('\n#all')
console.log(meuArray.all(m => m.meuCurso))
<commit_msg>removing demo file<commit_after><|endoftext|>


<commit_before>const globImporter = require('node-sass-glob-importer');

const ignore = [
  `**/dist`,
  `**/helpers`,
  `**/scripts`,
  `**/styles`,
  `**/build`,
  `**/utils`,
  `**/test-helpers`,
  /.*react-styles.*/,
  /.*react-docs.*/,
  /.*react-integration.*/,
  `**/\..*`, // dotfiles
  `**/*.d.ts`,
  `**/*.test.*`,
  `**/tsconfig.*`,
  `**/tslint.*`,
  `**/README.*`,
  `**/CHANGELOG.*`,
];

module.exports = {
  pathPrefix: '/v4',
  siteMetadata: {
    title: 'PatternFly 4',
    description: 'Documentation for PatternFly 4',
    author: 'Red Hat',
    siteUrl: 'https://www.patternfly.org'
  },
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `content-pages`,
        path: `${__dirname}/content`
      }
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `react-pages`,
        path: `${__dirname}/_repos/react-core`,
        ignore: ignore.concat(`**/*.json`, `**/index.*`)
      }
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `react-pages`,
        path: `${__dirname}/_repos/react-charts`,
        ignore: ignore.concat(`**/*.json`, `**/index.*`)
      }
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `react-pages`,
        path: `${__dirname}/_repos/react-table`,
        ignore: ignore.concat(`**/*.json`, `**/index.*`)
      }
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `core-pages`,
        path: `${__dirname}/_repos/core/src`,
        ignore: [`**/*.scss`, `**/*.md`]
      }
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/images`,
      },
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `previews`,
        path: `${__dirname}/previews`,
      },
    },
    'gatsby-plugin-no-sourcemaps',
    'gatsby-transformer-json',
    'gatsby-plugin-react-helmet',
    'gatsby-transformer-sharp',
    'gatsby-plugin-sharp',
    'gatsby-plugin-sitemap',
    'gatsby-plugin-emotion',
    'gatsby-plugin-offline', // this plugin enables Progressive Web App + Offline functionality https://gatsby.app/offline
    {
      // Our custom plugin for *.js?x *.ts?x files to get prop types
      resolve: require.resolve(`${__dirname}/plugins/gatsby-transformer-react-docgen-typescript`),
    },
    {
      resolve: 'gatsby-plugin-robots-txt',
      options: {
        policy: [{ userAgent: '*', allow: '/' }]
      }
    },
    {
      resolve: `gatsby-mdx`,
      options: {
        extensions: ['.mdx', '.md'],
        gatsbyRemarkPlugins: [
          'gatsby-remark-autolink-headers',
          {
            resolve: `gatsby-remark-images`,
            options: {
              maxWidth: 700
            }
          }
        ]
      }
    },
    {
      resolve: `gatsby-plugin-sass`,
      options: {
        importer: globImporter(),
        postCssPlugins: [],
        precision: 5
      }
    },
    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: 'PatternFly',
        short_name: 'PatternFly',
        start_url: '/',
        background_color: '#663399',
        theme_color: '#663399',
        display: 'minimal-ui'
      },
    }
  ],
}
<commit_msg>chore(links): fix link catcher<commit_after>const globImporter = require('node-sass-glob-importer');

const ignore = [
  `**/dist`,
  `**/helpers`,
  `**/scripts`,
  `**/styles`,
  `**/build`,
  `**/utils`,
  `**/test-helpers`,
  /.*react-styles.*/,
  /.*react-docs.*/,
  /.*react-integration.*/,
  `**/\..*`, // dotfiles
  `**/*.d.ts`,
  `**/*.test.*`,
  `**/tsconfig.*`,
  `**/tslint.*`,
  `**/README.*`,
  `**/CHANGELOG.*`,
];

module.exports = {
  pathPrefix: '/v4',
  siteMetadata: {
    title: 'PatternFly 4',
    description: 'Documentation for PatternFly 4',
    author: 'Red Hat',
    siteUrl: 'https://www.patternfly.org'
  },
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `content-pages`,
        path: `${__dirname}/content`
      }
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `react-pages`,
        path: `${__dirname}/_repos/react-core`,
        ignore: ignore.concat(`**/*.json`, `**/index.*`)
      }
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `react-pages`,
        path: `${__dirname}/_repos/react-charts`,
        ignore: ignore.concat(`**/*.json`, `**/index.*`)
      }
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `react-pages`,
        path: `${__dirname}/_repos/react-table`,
        ignore: ignore.concat(`**/*.json`, `**/index.*`)
      }
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `core-pages`,
        path: `${__dirname}/_repos/core/src`,
        ignore: [`**/*.scss`, `**/*.md`]
      }
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/images`,
      },
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `previews`,
        path: `${__dirname}/previews`,
      },
    },
    'gatsby-plugin-no-sourcemaps',
    'gatsby-transformer-json',
    'gatsby-plugin-react-helmet',
    'gatsby-transformer-sharp',
    'gatsby-plugin-catch-links',
    'gatsby-plugin-sharp',
    'gatsby-plugin-sitemap',
    'gatsby-plugin-emotion',
    'gatsby-plugin-offline', // this plugin enables Progressive Web App + Offline functionality https://gatsby.app/offline
    {
      // Our custom plugin for *.js?x *.ts?x files to get prop types
      resolve: require.resolve(`${__dirname}/plugins/gatsby-transformer-react-docgen-typescript`),
    },
    {
      resolve: 'gatsby-plugin-robots-txt',
      options: {
        policy: [{ userAgent: '*', allow: '/' }]
      }
    },
    {
      resolve: `gatsby-mdx`,
      options: {
        extensions: ['.mdx', '.md'],
        gatsbyRemarkPlugins: [
          'gatsby-remark-autolink-headers',
          {
            resolve: `gatsby-remark-images`,
            options: {
              maxWidth: 700
            }
          }
        ]
      }
    },
    {
      resolve: `gatsby-plugin-sass`,
      options: {
        importer: globImporter(),
        postCssPlugins: [],
        precision: 5
      }
    },
    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: 'PatternFly',
        short_name: 'PatternFly',
        start_url: '/',
        background_color: '#663399',
        theme_color: '#663399',
        display: 'minimal-ui'
      },
    }
  ],
}
<|endoftext|>


<commit_before>import React, { useContext, useEffect } from 'react';
import { IntlProvider } from 'react-intl'
import { Provider, connect } from 'react-redux'
import {
  Provider as Session,
  Context as SessionContext,
} from 'bonde-core-tools';

import AppRouting from 'pages/app';

import * as t from 'community/action-types';

const Portal = ({ dispatch }) => {
  const { communities } = useContext(SessionContext);

  useEffect(() => {
    if (communities?.length > 0) {
      dispatch({ type: t.FETCH_SUCCESS, payload: communities });
    }
  }, [communities, dispatch])

  return (
    <AppRouting />
  );
}

const ConnectedPortal = connect(undefined, (dispatch) => ({
  dispatch
}))(Portal)

const App = ({ messages, locale, store }) => {
  // Environment to use for configure bonde-core-tools
  const envConfig =
    (process.env.REACT_APP_ENVIRONMENT || "development");

  console.info('Build environment:', envConfig);

  return (
    <IntlProvider messages={messages} locale={locale}>
      <Provider store={store}>
        <Session
          uri={process.env.REACT_APP_DOMAIN_API_GRAPHQL}
          environment={envConfig}
          fetchData
        >
          <ConnectedPortal />
        </Session>
      </Provider>
    </IntlProvider>
  )

  // return (
  //
Welcome to {envConfig}!

  // );
}

export default App;<commit_msg>fix(admin): not selected community<commit_after>import React, { useContext, useEffect } from 'react';
import { IntlProvider } from 'react-intl'
import { Provider, connect } from 'react-redux'
import {
  Provider as Session,
  Context as SessionContext,
} from 'bonde-core-tools';

import AppRouting from 'pages/app';

import * as t from 'community/action-types';

const Portal = ({ dispatch }) => {
  const { communities, community } = useContext(SessionContext);

  useEffect(() => {
    if (communities?.length > 0) {
      dispatch({ type: t.FETCH_SUCCESS, payload: communities });
    }
  }, [communities, dispatch])

  useEffect(() => {
    if (!community) {
      const appDomain = process.env.REACT_APP_ENVIRONMENT === 'production' ? 'bonde.org' : 'staging.bonde.org';

      window.location.href =  `https://admin-canary.${appDomain}`;
    }
  }, [community])

  return (
    <AppRouting />
  );
}

const ConnectedPortal = connect(undefined, (dispatch) => ({
  dispatch
}))(Portal)

const App = ({ messages, locale, store }) => {
  // Environment to use for configure bonde-core-tools
  const envConfig =
    (process.env.REACT_APP_ENVIRONMENT || "development");

  console.info('Build environment:', envConfig);

  return (
    <IntlProvider messages={messages} locale={locale}>
      <Provider store={store}>
        <Session
          uri={process.env.REACT_APP_DOMAIN_API_GRAPHQL}
          environment={envConfig}
          fetchData
        >
          <ConnectedPortal />
        </Session>
      </Provider>
    </IntlProvider>
  )

  // return (
  //
Welcome to {envConfig}!

  // );
}

export default App;<|endoftext|>


<commit_before>var util = require('util')
var css = require('dom-css')
var grid = require('./index')
var parse = require('parse-color')
var position = require('mouse-position')

document.body.style.transition = '0.3s all'

var rows = Math.floor(window.innerHeight * 0.97 / 16) - 2
var columns = Math.floor(window.innerWidth * 0.97 / 16) - 1

var link = document.createElement('a')
css(link, {
  width: 160,
  height: 160,
  position: 'fixed',
  right: window.innerWidth * 0.03,
  bottom: window.innerHeight * 0.03,
  cursor: 'pointer'
})
link.href = 'https://github.com/freeman-lab/pixel-grid'
document.body.appendChild(link)

var data = []

for (var i = 0; i < rows; i++) {
  for (var j = 0; j < columns; j++) {
    data.push([0, 0, 0])
  }
}

var letters = [
  [10, 10], [11, 10], [12, 10], [13, 10], [14, 10], [15, 10], [16, 10],
  [10, 11], [10, 12], [10, 13], [11, 13], [12, 13], [13, 13], [14, 13],
  [15, 13], [16, 13], [10, 14], [10, 15], [10, 16], [11, 16], [12, 16],
  [13, 16], [14, 16], [15, 16], [16, 16],
  [10, 19], [10, 20], [10, 21], [10, 22], [10, 23], [10, 24],
  [11, 24], [12, 24], [13, 24], [14, 24], [15, 24], [16, 24],
  [11, 19], [12, 19], [13, 19], [14, 19], [15, 19], [16, 19],
  [16, 20], [16, 21], [16, 22], [16, 23],
  [10, 27], [11, 27], [12, 28], [13, 28], [14, 29], [15, 29], [16, 30],
  [15, 31], [14, 31], [13, 32], [12, 32], [11, 33], [10, 33],
  [10, 36], [11, 36], [12, 36], [13, 36], [14, 36], [15, 36], [16, 36],
  [10, 37], [10, 38], [10, 39], [10, 40],
  [13, 37], [13, 38], [13, 39], [13, 40],
  [16, 37], [16, 38], [16, 39], [16, 40]
]

letters = letters.map(function (letter) {
  return [letter[0] - 15 + Math.floor(rows / 2), letter[1] - 25 + Math.floor(columns / 2)]
})

function drawOverlay(array) {
  array.forEach(function (el) {
    data[(el[0]) * columns + el[1]] = [1, 1, 1]
  })
}

var arrow = [
  [5, 0], [5, 1], [5, 2], [5, 3], [5, 4], [5, 5],
  [4, 4], [3, 3], [6, 4], [7, 3]
]

arrow = arrow.map(function (el) {
  return [el[0] + Math.floor(rows - 10), el[1] + Math.floor(columns - 8)]
})

var pixels = grid(data, {
  root: document.body,
  rows: rows,
  columns: columns,
  size: 15,
  padding: 1,
  background: [0, 0, 0],
  formatted: true
})

pixels.canvas.style.marginLeft = (window.innerWidth * 0.03) / 2 + 'px'
pixels.canvas.style.marginTop = (window.innerHeight * 0.04) / 2 + 'px'

var mouse = position(pixels.canvas)

var row, column, rand, color
var hue = 0

var started = false

mouse.on('move', function () {
  if (!started) started = true
  row = Math.floor(mouse[1] / 16)
  column = Math.floor(mouse[0] / 16)
  if (row < rows && column < columns) {
    hue = (hue + 1) % 360
    color = parse('hsl(' + hue + ',50, 50)').rgb
    document.body.style.background = util.format('rgb(%s,%s,%s)', color[0], color[1], color[2])
    color = color.map(function (d) { return d / 50 })

    for (var i = -1; i < 2; i++) {
      for (var j = -1; j < 2; j++) {
        data[Math.min((row + i) * columns + (column + j), data.length)] = color
        data[Math.min((row + i + 1) * columns - (column + j), data.length)] = color
      }
    }
  }
})

pixels.frame(function () {
  if (!started) {
    drawOverlay(letters)
  }
  drawOverlay(arrow)
  for (var i = 0; i < data.length; i++) {
    rand = Math.random() * 0.02
    data[i] = [
      data[i][0] * 0.95 + rand,
      data[i][1] * 0.95 + rand,
      data[i][2] * 0.95 + rand
    ]
  }
  pixels.update(data)
})
<commit_msg>fix standard<commit_after>var util = require('util')
var css = require('dom-css')
var grid = require('./index')
var parse = require('parse-color')
var position = require('mouse-position')

document.body.style.transition = '0.3s all'

var rows = Math.floor(window.innerHeight * 0.97 / 16) - 2
var columns = Math.floor(window.innerWidth * 0.97 / 16) - 1

var link = document.createElement('a')
css(link, {
  width: 160,
  height: 160,
  position: 'fixed',
  right: window.innerWidth * 0.03,
  bottom: window.innerHeight * 0.03,
  cursor: 'pointer'
})
link.href = 'https://github.com/freeman-lab/pixel-grid'
document.body.appendChild(link)

var data = []

for (var i = 0; i < rows; i++) {
  for (var j = 0; j < columns; j++) {
    data.push([0, 0, 0])
  }
}

var letters = [
  [10, 10], [11, 10], [12, 10], [13, 10], [14, 10], [15, 10], [16, 10],
  [10, 11], [10, 12], [10, 13], [11, 13], [12, 13], [13, 13], [14, 13],
  [15, 13], [16, 13], [10, 14], [10, 15], [10, 16], [11, 16], [12, 16],
  [13, 16], [14, 16], [15, 16], [16, 16],
  [10, 19], [10, 20], [10, 21], [10, 22], [10, 23], [10, 24],
  [11, 24], [12, 24], [13, 24], [14, 24], [15, 24], [16, 24],
  [11, 19], [12, 19], [13, 19], [14, 19], [15, 19], [16, 19],
  [16, 20], [16, 21], [16, 22], [16, 23],
  [10, 27], [11, 27], [12, 28], [13, 28], [14, 29], [15, 29], [16, 30],
  [15, 31], [14, 31], [13, 32], [12, 32], [11, 33], [10, 33],
  [10, 36], [11, 36], [12, 36], [13, 36], [14, 36], [15, 36], [16, 36],
  [10, 37], [10, 38], [10, 39], [10, 40],
  [13, 37], [13, 38], [13, 39], [13, 40],
  [16, 37], [16, 38], [16, 39], [16, 40]
]

letters = letters.map(function (letter) {
  return [letter[0] - 15 + Math.floor(rows / 2), letter[1] - 25 + Math.floor(columns / 2)]
})

function drawOverlay (array) {
  array.forEach(function (el) {
    data[(el[0]) * columns + el[1]] = [1, 1, 1]
  })
}

var arrow = [
  [5, 0], [5, 1], [5, 2], [5, 3], [5, 4], [5, 5],
  [4, 4], [3, 3], [6, 4], [7, 3]
]

arrow = arrow.map(function (el) {
  return [el[0] + Math.floor(rows - 10), el[1] + Math.floor(columns - 8)]
})

var pixels = grid(data, {
  root: document.body,
  rows: rows,
  columns: columns,
  size: 15,
  padding: 1,
  background: [0, 0, 0],
  formatted: true
})

pixels.canvas.style.marginLeft = (window.innerWidth * 0.03) / 2 + 'px'
pixels.canvas.style.marginTop = (window.innerHeight * 0.04) / 2 + 'px'

var mouse = position(pixels.canvas)

var row, column, rand, color
var hue = 0

var started = false

mouse.on('move', function () {
  if (!started) started = true
  row = Math.floor(mouse[1] / 16)
  column = Math.floor(mouse[0] / 16)
  if (row < rows && column < columns) {
    hue = (hue + 1) % 360
    color = parse('hsl(' + hue + ',50, 50)').rgb
    document.body.style.background = util.format('rgb(%s,%s,%s)', color[0], color[1], color[2])
    color = color.map(function (d) { return d / 50 })

    for (var i = -1; i < 2; i++) {
      for (var j = -1; j < 2; j++) {
        data[Math.min((row + i) * columns + (column + j), data.length)] = color
        data[Math.min((row + i + 1) * columns - (column + j), data.length)] = color
      }
    }
  }
})

pixels.frame(function () {
  if (!started) {
    drawOverlay(letters)
  }
  drawOverlay(arrow)
  for (var i = 0; i < data.length; i++) {
    rand = Math.random() * 0.02
    data[i] = [
      data[i][0] * 0.95 + rand,
      data[i][1] * 0.95 + rand,
      data[i][2] * 0.95 + rand
    ]
  }
  pixels.update(data)
})
<|endoftext|>


<commit_before>#!/usr/bin/env node
require('date-utils');

var pingdom = require('./lib/pingdom');
var config = require('./config');

main();

function main() {
    var api = pingdom(config);

    api.checks(function(err, checks) {
        if(err) return console.error(err);

        getPerformanceSummary(api, checks[0].id);
    });
}

function getPerformanceSummary(api, check) {
    var now = Date.today();
    var weekAgo = now.clone().addWeeks(-1);

    api['summary.performance'](function(err, data, res) {
        if(err) return console.error(err);

        console.log(data, res.headers);
    }, {
        target: check,
        qs: {
            from: weekAgo,
            to: now,
            resolution: 'day',
            includeuptime: true
        }
    });
}
<commit_msg>Improve demo<commit_after>#!/usr/bin/env node
require('date-utils');

var pingdom = require('./lib/pingdom');
var config = require('./config');

main();

function main() {
    var api = pingdom(config);

    api.checks(function(err, checks) {
        var id;

        if(err) return console.error(err);

        id = checks[0].id;

        getResults(api, id)
        getPerformanceSummary(api, id);
    });
}

function getResults(api, check) {
    api.results(function(err, data, res) {
        if(err) return console.error(err);

        console.log('results', data, res.headers);
    }, {
        target: check,
        qs: {
            limit: 10
        }
    })
}

function getPerformanceSummary(api, check) {
    var now = Date.today();
    var weekAgo = now.clone().addWeeks(-1);

    api['summary.performance'](function(err, data, res) {
        if(err) return console.error(err);

        console.log('performance summary', data, res.headers);
    }, {
        target: check,
        qs: {
            from: weekAgo,
            to: now,
            resolution: 'day',
            includeuptime: true
        }
    });
}
<|endoftext|>


<commit_before>import path from 'path';
import {babel} from '@rollup/plugin-babel';
import {nodeResolve} from '@rollup/plugin-node-resolve';
import replace from '@rollup/plugin-replace';
import {terser} from 'rollup-plugin-terser';
import commonjs from '@rollup/plugin-commonjs';

const input = path.join(__dirname, 'src/index.ts');

const bundles = [
  {
    input,
    output: {
      file: path.join(__dirname, 'dist/floating-ui.react-native.esm.js'),
      format: 'esm',
    },
  },
  {
    input,
    output: {
      name: 'FloatingUIReactNative',
      file: path.join(__dirname, 'dist/floating-ui.react-native.js'),
      format: 'cjs',
      globals: {
        react: 'React',
        'react-native': 'ReactNative',
        '@floating-ui/core': 'FloatingUICore',
      },
    },
  },
];

const buildExport = bundles.map(({input, output}) => ({
  input,
  output,
  external: [
    'react',
    'react-native',
    '@floating-ui/core/dist/floating-ui.core',
  ],
  plugins: [
    commonjs(),
    nodeResolve({extensions: ['.ts', '.js']}),
    babel({
      babelHelpers: 'bundled',
      extensions: ['.ts'],
      plugins: ['annotate-pure-calls'],
    }),
    replace({
      __DEV__: output.file.includes('.min.')
        ? 'false'
        : 'process.env.NODE_ENV !== "production"',
      preventAssignment: true,
    }),
    output.file.includes('.min.') && terser(),
  ],
}));

export default buildExport;
<commit_msg>build(react-native): fix external key<commit_after>import path from 'path';
import {babel} from '@rollup/plugin-babel';
import {nodeResolve} from '@rollup/plugin-node-resolve';
import replace from '@rollup/plugin-replace';
import {terser} from 'rollup-plugin-terser';
import commonjs from '@rollup/plugin-commonjs';

const input = path.join(__dirname, 'src/index.ts');

const bundles = [
  {
    input,
    output: {
      file: path.join(__dirname, 'dist/floating-ui.react-native.esm.js'),
      format: 'esm',
    },
  },
  {
    input,
    output: {
      name: 'FloatingUIReactNative',
      file: path.join(__dirname, 'dist/floating-ui.react-native.js'),
      format: 'cjs',
      globals: {
        react: 'React',
        'react-native': 'ReactNative',
        '@floating-ui/core': 'FloatingUICore',
      },
    },
  },
];

const buildExport = bundles.map(({input, output}) => ({
  input,
  output,
  external: ['react', 'react-native', '@floating-ui/core'],
  plugins: [
    commonjs(),
    nodeResolve({extensions: ['.ts', '.js']}),
    babel({
      babelHelpers: 'bundled',
      extensions: ['.ts'],
      plugins: ['annotate-pure-calls'],
    }),
    replace({
      __DEV__: output.file.includes('.min.')
        ? 'false'
        : 'process.env.NODE_ENV !== "production"',
      preventAssignment: true,
    }),
    output.file.includes('.min.') && terser(),
  ],
}));

export default buildExport;
<|endoftext|>


<commit_before>// @remove-on-eject-begin
/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */
// @remove-on-eject-end
'use strict';

// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = 'test';
process.env.NODE_ENV = 'test';
process.env.PUBLIC_URL = '';

// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
// terminate the Node.js process with a non-zero exit code.
process.on('unhandledRejection', err => {
  throw err;
});

// Ensure environment variables are read.
require('../config/env');
// @remove-on-eject-begin
// Do the preflight check (only happens before eject).
const verifyPackageTree = require('./utils/verifyPackageTree');
if (process.env.SKIP_PREFLIGHT_CHECK !== 'true') {
  verifyPackageTree();
}
const verifyTypeScriptSetup = require('./utils/verifyTypeScriptSetup');
verifyTypeScriptSetup();
// @remove-on-eject-end

const jest = require('jest');
const execSync = require('child_process').execSync;
let argv = process.argv.slice(2);

function isInGitRepository() {
  try {
    execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' });
    return true;
  } catch (e) {
    return false;
  }
}

function isInMercurialRepository() {
  try {
    execSync('hg --cwd . root', { stdio: 'ignore' });
    return true;
  } catch (e) {
    return false;
  }
}

// Watch unless on CI or explicitly running all tests
if (
  !process.env.CI &&
  argv.indexOf('--watchAll') === -1
) {
  // https://github.com/facebook/create-react-app/issues/5210
  const hasSourceControl = isInGitRepository() || isInMercurialRepository();
  argv.push(hasSourceControl ? '--watch' : '--watchAll');
}

// @remove-on-eject-begin
// This is not necessary after eject because we embed config into package.json.
const createJestConfig = require('./utils/createJestConfig');
const path = require('path');
const paths = require('../config/paths');
argv.push(
  '--config',
  JSON.stringify(
    createJestConfig(
      relativePath => path.resolve(__dirname, '..', relativePath),
      path.resolve(paths.appSrc, '..'),
      false
    )
  )
);

// This is a very dirty workaround for https://github.com/facebook/jest/issues/5913.
// We're trying to resolve the environment ourselves because Jest does it incorrectly.
// TODO: remove this as soon as it's fixed in Jest.
const resolve = require('resolve');
function resolveJestDefaultEnvironment(name) {
  const jestDir = path.dirname(
    resolve.sync('jest', {
      basedir: __dirname,
    })
  );
  const jestCLIDir = path.dirname(
    resolve.sync('jest-cli', {
      basedir: jestDir,
    })
  );
  const jestConfigDir = path.dirname(
    resolve.sync('jest-config', {
      basedir: jestCLIDir,
    })
  );
  return resolve.sync(name, {
    basedir: jestConfigDir,
  });
}
let cleanArgv = [];
let env = 'jsdom';
let next;
do {
  next = argv.shift();
  if (next === '--env') {
    env = argv.shift();
  } else if (next.indexOf('--env=') === 0) {
    env = next.substring('--env='.length);
  } else {
    cleanArgv.push(next);
  }
} while (argv.length > 0);
argv = cleanArgv;
let resolvedEnv;
try {
  resolvedEnv = resolveJestDefaultEnvironment(`jest-environment-${env}`);
} catch (e) {
  // ignore
}
if (!resolvedEnv) {
  try {
    resolvedEnv = resolveJestDefaultEnvironment(env);
  } catch (e) {
    // ignore
  }
}
const testEnvironment = resolvedEnv || env;
argv.push('--env', testEnvironment);
// @remove-on-eject-end
jest.run(argv);
<commit_msg>Add explicit check for --watchAll=false (#7433)<commit_after>// @remove-on-eject-begin
/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */
// @remove-on-eject-end
'use strict';

// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = 'test';
process.env.NODE_ENV = 'test';
process.env.PUBLIC_URL = '';

// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
// terminate the Node.js process with a non-zero exit code.
process.on('unhandledRejection', err => {
  throw err;
});

// Ensure environment variables are read.
require('../config/env');
// @remove-on-eject-begin
// Do the preflight check (only happens before eject).
const verifyPackageTree = require('./utils/verifyPackageTree');
if (process.env.SKIP_PREFLIGHT_CHECK !== 'true') {
  verifyPackageTree();
}
const verifyTypeScriptSetup = require('./utils/verifyTypeScriptSetup');
verifyTypeScriptSetup();
// @remove-on-eject-end

const jest = require('jest');
const execSync = require('child_process').execSync;
let argv = process.argv.slice(2);

function isInGitRepository() {
  try {
    execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' });
    return true;
  } catch (e) {
    return false;
  }
}

function isInMercurialRepository() {
  try {
    execSync('hg --cwd . root', { stdio: 'ignore' });
    return true;
  } catch (e) {
    return false;
  }
}

// Watch unless on CI or explicitly running all tests
if (
  !process.env.CI &&
  argv.indexOf('--watchAll') === -1 &&
  argv.indexOf('--watchAll=false') === -1
) {
  // https://github.com/facebook/create-react-app/issues/5210
  const hasSourceControl = isInGitRepository() || isInMercurialRepository();
  argv.push(hasSourceControl ? '--watch' : '--watchAll');
}

// @remove-on-eject-begin
// This is not necessary after eject because we embed config into package.json.
const createJestConfig = require('./utils/createJestConfig');
const path = require('path');
const paths = require('../config/paths');
argv.push(
  '--config',
  JSON.stringify(
    createJestConfig(
      relativePath => path.resolve(__dirname, '..', relativePath),
      path.resolve(paths.appSrc, '..'),
      false
    )
  )
);

// This is a very dirty workaround for https://github.com/facebook/jest/issues/5913.
// We're trying to resolve the environment ourselves because Jest does it incorrectly.
// TODO: remove this as soon as it's fixed in Jest.
const resolve = require('resolve');
function resolveJestDefaultEnvironment(name) {
  const jestDir = path.dirname(
    resolve.sync('jest', {
      basedir: __dirname,
    })
  );
  const jestCLIDir = path.dirname(
    resolve.sync('jest-cli', {
      basedir: jestDir,
    })
  );
  const jestConfigDir = path.dirname(
    resolve.sync('jest-config', {
      basedir: jestCLIDir,
    })
  );
  return resolve.sync(name, {
    basedir: jestConfigDir,
  });
}
let cleanArgv = [];
let env = 'jsdom';
let next;
do {
  next = argv.shift();
  if (next === '--env') {
    env = argv.shift();
  } else if (next.indexOf('--env=') === 0) {
    env = next.substring('--env='.length);
  } else {
    cleanArgv.push(next);
  }
} while (argv.length > 0);
argv = cleanArgv;
let resolvedEnv;
try {
  resolvedEnv = resolveJestDefaultEnvironment(`jest-environment-${env}`);
} catch (e) {
  // ignore
}
if (!resolvedEnv) {
  try {
    resolvedEnv = resolveJestDefaultEnvironment(env);
  } catch (e) {
    // ignore
  }
}
const testEnvironment = resolvedEnv || env;
argv.push('--env', testEnvironment);
// @remove-on-eject-end
jest.run(argv);
<|endoftext|>


<commit_before>/* -*- js2-basic-offset: 2; indent-tabs-mode: nil; -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80; */
"use strict";

let {addMethod} = require("genfun"),
    {clone, init} = require("../../lib/proto");

let can = require("../../shims/can");
require("../../shims/can.view.mustache");

let style = require("../../lib/ensureStyle"),
    viewCss = require("./chatInput.styl");

let {submitMessage} = require("../../models/chatlog"),
    {EventListener, listen} = require("../../lib/eventListener");

/**
 * ChatInput Controller
 */
let ChatInput = clone();

let listener = clone(EventListener, {
  "form submit": sendMessage,
  keydown: keyPressed,
  "select change": selectChanged
});

// NOTE: Yeah, it has to be added in multiple places.
let inputTypes = ["line", "system"];
let inputTemplates = {
  line: require("./inputs/line.mustache"),
  system: require("./inputs/system.mustache")
};

let chatInputTemplate = require("./chatInput.mustache");

addMethod(init, [ChatInput], function(chatInput, el, chatlog) {
  chatInput.el = el;
  chatInput.log = chatlog;
  chatInput.type = can.compute(inputTypes[0]);
  initDom(chatInput);
  style(viewCss);
});

function initDom(chatInput) {
  chatInput.el.html(
    chatInputTemplate({ types: inputTypes, type: chatInput.type },
                      { renderInput: renderInput, isSelected: isSelected }));
  chatInput.listenerHandle = listen(listener, chatInput, chatInput.el);
  chatInput.el.find(".content").focus();
}

/*
 * Chat message handling
 */
function sendMessage(chatInput, _el, event) {
  event.preventDefault();
  let input = chatInput.el.find(".content");
  submitMessage(chatInput.log, chatInput.type(), input.val());
  input.val("");
}

/*
 * Cycle between input types
 */
const TAB = 9;
function keyPressed(chatInput, _el, event) {
  if (event.keyCode === TAB) {
    event.preventDefault();
    cycleInputType(chatInput);
  }
}

function cycleInputType(chatInput) {
  let typeIndex = inputTypes.indexOf(chatInput.type());
  chatInput.type(inputTypes[(typeIndex + 1) % inputTypes.length]);
  chatInput.el.find(".content").focus();
}

function selectChanged(chatInput, select) {
  chatInput.type(select.val());
}

function isSelected(type) {
  if (this === type()) {
    return "selected";
  }
}

function renderInput(type) {
  return inputTemplates[type()]();
}

/*
 * Exports
 */
module.exports.ChatInput = ChatInput;
<commit_msg>Silencing jshint<commit_after>/* -*- js2-basic-offset: 2; indent-tabs-mode: nil; -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80; */
"use strict";

let {addMethod} = require("genfun"),
    {clone, init} = require("../../lib/proto");

let can = require("../../shims/can");
require("../../shims/can.view.mustache");

let style = require("../../lib/ensureStyle"),
    viewCss = require("./chatInput.styl");

let {submitMessage} = require("../../models/chatlog"),
    {EventListener, listen} = require("../../lib/eventListener");

/**
 * ChatInput Controller
 */
let ChatInput = clone();

let listener = clone(EventListener, {
  "form submit": sendMessage,
  keydown: keyPressed,
  "select change": selectChanged
});

// NOTE: Yeah, it has to be added in multiple places.
let inputTypes = ["line", "system"];
let inputTemplates = {
  line: require("./inputs/line.mustache"),
  system: require("./inputs/system.mustache")
};

let chatInputTemplate = require("./chatInput.mustache");

addMethod(init, [ChatInput], function(chatInput, el, chatlog) {
  chatInput.el = el;
  chatInput.log = chatlog;
  chatInput.type = can.compute(inputTypes[0]);
  initDom(chatInput);
  style(viewCss);
});

function initDom(chatInput) {
  chatInput.el.html(
    chatInputTemplate({ types: inputTypes, type: chatInput.type },
                      { renderInput: renderInput, isSelected: isSelected }));
  chatInput.listenerHandle = listen(listener, chatInput, chatInput.el);
  chatInput.el.find(".content").focus();
}

/*
 * Chat message handling
 */
function sendMessage(chatInput, _el, event) {
  event.preventDefault();
  let input = chatInput.el.find(".content");
  submitMessage(chatInput.log, chatInput.type(), input.val());
  input.val("");
}

/*
 * Cycle between input types
 */
const TAB = 9;
function keyPressed(chatInput, _el, event) {
  if (event.keyCode === TAB) {
    event.preventDefault();
    cycleInputType(chatInput);
  }
}

function cycleInputType(chatInput) {
  let typeIndex = inputTypes.indexOf(chatInput.type());
  chatInput.type(inputTypes[(typeIndex + 1) % inputTypes.length]);
  chatInput.el.find(".content").focus();
}

function selectChanged(chatInput, select) {
  chatInput.type(select.val());
}

function isSelected(type) {
  /*jshint validthis:true*/
  if (this === type()) {
    return "selected";
  }
}

function renderInput(type) {
  return inputTemplates[type()]();
}

/*
 * Exports
 */
module.exports.ChatInput = ChatInput;
<|endoftext|>