<commit_before>import { BaseComponent } from '../base/Base';
import Flatpickr from 'flatpickr';
import _get from 'lodash/get';
import _each from 'lodash/each';
import { getDateSetting } from '../../utils';
export class DateTimeComponent extends BaseComponent {
  constructor(component, options, data) {
    super(component, options, data);
    this.validators.push('date');
    this.closedOn = 0;
  }

  elementInfo() {
    let info = super.elementInfo();
    info.type = 'input';
    info.attr.type = 'text';
    info.changeEvent = 'input';
    this.component.suffix = true;
    return info;
  }

  /**
   * Get the default date for the calendar.
   * @return {*}
   */
  get defaultDate() {
    return getDateSetting(this.component.defaultDate);
  }

  // This select component can handle multiple items on its own.
  createWrapper() {
    return false;
  }

  /**
   * Convert the format from the angular-datepicker module.
   * @param format
   * @return {string|XML|*}
   */
  convertFormat(format) {
    // Year conversion.
    format = format.replace(/y/g, 'Y');
    format = format.replace('YYYY', 'Y');
    format = format.replace('YY', 'y');

    // Month conversion.
    format = format.replace('MMMM', 'F');
    format = format.replace(/M/g, 'n');
    format = format.replace('nnn', 'M');
    format = format.replace('nn', 'm');

    // Day in month.
    format = format.replace(/d/g, 'j');
    format = format.replace('jj', 'd');

    // Day in week.
    format = format.replace('EEEE', 'l');
    format = format.replace('EEE', 'D');

    // Hours, minutes, seconds
    format = format.replace('HH', 'H');
    format = format.replace('hh', 'h');
    format = format.replace('mm', 'i');
    format = format.replace('ss', 'S');
    format = format.replace(/a/g, 'K');
    return format;
  }

  get config() {
    return {
      altInput: true,
      clickOpens: true,
      enableDate: true,
      mode: this.component.multiple ? 'multiple' : 'single',
      enableTime: _get(this.component, 'enableTime', true),
      noCalendar: !_get(this.component, 'enableDate', true),
      altFormat: this.convertFormat(_get(this.component, 'format', '')),
      dateFormat: 'U',
      defaultDate: this.defaultDate,
      hourIncrement: _get(this.component, 'timePicker.hourStep', 1),
      minuteIncrement: _get(this.component, 'timePicker.minuteStep', 5),
      minDate: getDateSetting(_get(this.component, 'datePicker.minDate')),
      maxDate: getDateSetting(_get(this.component, 'datePicker.maxDate')),
      onChange: () => this.onChange(),
      onClose: () => (this.closedOn = Date.now())
    };
  }

  set disabled(disabled) {
    super.disabled = disabled;
    _each(this.inputs, (input) => {
      let calendar = this.getCalendar(input);
      if (calendar) {
        if (disabled) {
          calendar._input.setAttribute('disabled', 'disabled');
        }
        else {
          calendar._input.removeAttribute('disabled');
        }
        calendar.redraw();
      }
    });
  }

  addSuffix(input, inputGroup) {
    let suffix = this.ce('span', {
      class: 'input-group-addon',
      style: 'cursor: pointer'
    });
    suffix.appendChild(this.getIcon(this.component.enableDate ? 'calendar' : 'time'));
    let calendar = this.getCalendar(input);
    if (calendar) {
      this.addEventListener(suffix, 'click', () => {
        // Make sure the calendar is not already open and that it did not just close (like from blur event).
        if (!calendar.isOpen && ((Date.now() - this.closedOn) > 200)) {
          calendar.open();
        }
      });
    }
    inputGroup.appendChild(suffix);
    return suffix;
  }

  /**
   * Get the calendar or create an instance of one.
   * @param input
   * @return {Flatpickr|flatpickr}
   */
  getCalendar(input) {
    if (!input.calendar && !this.options.noCalendar) {
      input.calendar = new Flatpickr(input, this.config);
    }
    return input.calendar;
  }

  getDate(value) {
    let timestamp = parseInt(value, 10);
    if (!timestamp) {
      return null;
    }
    return (new Date(timestamp * 1000));
  }

  getRawValue() {
    let values = [];
    for (let i in this.inputs) {
      if (this.inputs.hasOwnProperty(i)) {
        if (!this.component.multiple) {
          return this.getDate(this.inputs[i].value);
        }
        values.push(this.getDate(this.inputs[i].value));
      }
    }
    return values;
  }

  getValueAt(index) {
    if (!this.inputs[index]) {
      return '';
    }

    let calendar = this.getCalendar(this.inputs[index]);
    if (!calendar) {
      return super.getValueAt(index);
    }

    let dates = calendar.selectedDates;
    if (!dates || !dates.length) {
      return '';
    }

    return dates[0].toISOString();
  }

  setValueAt(index, value) {
    if (value) {
      let calendar = this.getCalendar(this.inputs[index]);
      if (!calendar) {
        return super.setValueAt(index, value);
      }

      calendar.setDate(value ? new Date(value) : new Date(), false);
    }
  }
}
<commit_msg>ViewAsHtml: Fixed DateTime component.<commit_after>import { BaseComponent } from '../base/Base';
import Flatpickr from 'flatpickr';
import _get from 'lodash/get';
import _each from 'lodash/each';
import { getDateSetting } from '../../utils';
import moment from 'moment';
export class DateTimeComponent extends BaseComponent {
  constructor(component, options, data) {
    super(component, options, data);
    this.validators.push('date');
    this.closedOn = 0;
  }

  elementInfo() {
    let info = super.elementInfo();
    info.type = 'input';
    info.attr.type = 'text';
    info.changeEvent = 'input';
    this.component.suffix = true;
    return info;
  }

  /**
   * Get the default date for the calendar.
   * @return {*}
   */
  get defaultDate() {
    return getDateSetting(this.component.defaultDate);
  }

  // This select component can handle multiple items on its own.
  createWrapper() {
    return false;
  }

  /**
   * Convert the format from the angular-datepicker module to flatpickr format.
   * @param format
   * @return {string|XML|*}
   */
  convertFormatToFlatpickr(format) {
    return format
      // Year conversion.
      .replace(/y/g, 'Y')
      .replace('YYYY', 'Y')
      .replace('YY', 'y')

      // Month conversion.
      .replace('MMMM', 'F')
      .replace(/M/g, 'n')
      .replace('nnn', 'M')
      .replace('nn', 'm')

      // Day in month.
      .replace(/d/g, 'j')
      .replace('jj', 'd')

      // Day in week.
      .replace('EEEE', 'l')
      .replace('EEE', 'D')

      // Hours, minutes, seconds
      .replace('HH', 'H')
      .replace('hh', 'h')
      .replace('mm', 'i')
      .replace('ss', 'S')
      .replace(/a/g, 'K');
  }

  /**
   * Convert the format from the angular-datepicker module to moment format.
   * @param format
   * @return {string}
   */
  convertFormatToMoment(format) {
    return format
    // Year conversion.
    .replace(/y/g, 'Y')
    // Day in month.
    .replace(/d/g, 'D')
    // Day in week.
    .replace(/E/g, 'd')
    // AM/PM marker
    .replace(/a/g, 'A');
  }

  get config() {
    return {
      altInput: true,
      clickOpens: true,
      enableDate: true,
      mode: this.component.multiple ? 'multiple' : 'single',
      enableTime: _get(this.component, 'enableTime', true),
      noCalendar: !_get(this.component, 'enableDate', true),
      altFormat: this.convertFormatToFlatpickr(_get(this.component, 'format', '')),
      dateFormat: 'U',
      defaultDate: this.defaultDate,
      hourIncrement: _get(this.component, 'timePicker.hourStep', 1),
      minuteIncrement: _get(this.component, 'timePicker.minuteStep', 5),
      minDate: getDateSetting(_get(this.component, 'datePicker.minDate')),
      maxDate: getDateSetting(_get(this.component, 'datePicker.maxDate')),
      onChange: () => this.onChange(),
      onClose: () => (this.closedOn = Date.now())
    };
  }

  set disabled(disabled) {
    super.disabled = disabled;
    _each(this.inputs, (input) => {
      let calendar = this.getCalendar(input);
      if (calendar) {
        if (disabled) {
          calendar._input.setAttribute('disabled', 'disabled');
        }
        else {
          calendar._input.removeAttribute('disabled');
        }
        calendar.redraw();
      }
    });
  }

  addSuffix(input, inputGroup) {
    let suffix = this.ce('span', {
      class: 'input-group-addon',
      style: 'cursor: pointer'
    });
    suffix.appendChild(this.getIcon(this.component.enableDate ? 'calendar' : 'time'));
    let calendar = this.getCalendar(input);
    if (calendar) {
      this.addEventListener(suffix, 'click', () => {
        // Make sure the calendar is not already open and that it did not just close (like from blur event).
        if (!calendar.isOpen && ((Date.now() - this.closedOn) > 200)) {
          calendar.open();
        }
      });
    }
    inputGroup.appendChild(suffix);
    return suffix;
  }

  /**
   * Get the calendar or create an instance of one.
   * @param input
   * @return {Flatpickr|flatpickr}
   */
  getCalendar(input) {
    if (!input.calendar && !this.options.noCalendar) {
      input.calendar = new Flatpickr(input, this.config);
    }
    return input.calendar;
  }

  getDate(value) {
    let timestamp = parseInt(value, 10);
    if (!timestamp) {
      return null;
    }
    return (new Date(timestamp * 1000));
  }

  getRawValue() {
    let values = [];
    for (let i in this.inputs) {
      if (this.inputs.hasOwnProperty(i)) {
        if (!this.component.multiple) {
          return this.getDate(this.inputs[i].value);
        }
        values.push(this.getDate(this.inputs[i].value));
      }
    }
    return values;
  }

  getValueAt(index) {
    if (!this.inputs[index]) {
      return '';
    }

    let calendar = this.getCalendar(this.inputs[index]);
    if (!calendar) {
      return super.getValueAt(index);
    }

    let dates = calendar.selectedDates;
    if (!dates || !dates.length) {
      return '';
    }

    return dates[0].toISOString();
  }

  get viewOnlyValue() {
    const value = this.getValue();
    return value ? moment(value).format(this.convertFormatToMoment(_get(this.component, 'format', ''))) : null;
  }

  setValueAt(index, value) {
    if (value) {
      let calendar = this.getCalendar(this.inputs[index]);
      if (!calendar) {
        return super.setValueAt(index, value);
      }

      calendar.setDate(value ? new Date(value) : new Date(), false);
    }
  }
}
<|endoftext|>


<commit_before>import styled, { css } from 'styled-components';
import { ToastStyle } from '../toast/toast.style';

const colors = {
  warning: '#FF7D00',
  default: '#335B6D',
  error: '#c7384f',
  info: '#1573E6',
  new: '#663399',
  success: '#50B848',
  help: '#FFAB00',
  maintenance: '#FF7D00'
};

const requireWhiteTextColor = [
  'error',
  'new',
  'info'
];

const sliderAnimation = `
  .carbon-flash__slider-appear,
  .carbon-flash__slider-enter {
    left: 50%;
    opacity: 0;
    right: 50%;
  }

  .carbon-flash__slider-appear-active,
  .carbon-flash__slider-enter-active {
    left: 0%;
    opacity: 1;
    right: 0%;
    transition: 500ms ease 100ms;
  }

  .carbon-flash__slider-leave {
    opacity: 1;
  }

  .carbon-flash__slider-leave-active  {
    opacity: 0;
    transition: 500ms ease 100ms;
  }
`;

const contentAnimation = `
  .carbon-flash__content-appear,
  .carbon-flash__content-enter {
    opacity: 0;
  }

  .carbon-flash__content-appear-active,
  .carbon-flash__content-enter-active {
    opacity: 1;
    transition: 400ms ease 400ms;
  }

  .carbon-flash__content-leave {
    opacity: 1;
  }

  .carbon-flash__content-leave-active  {
    opacity: 0;
    transition: 400ms ease-out 100ms;
  }
`;

const FlashMessageStyle = styled.div`
  color: rgba(0,0,0,0.85);
  font-size: 14px;
  font-weight: 700;
  margin: 20px 70px;
  position: relative;
  text-align: left;
`;

const FlashContentStyle = styled.div`
  background-color: transparent ;
  margin: 0 auto;
  max-width: 1600px;
  min-width: 958px;
  position: relative;
`;

const FlashSliderStyle = styled.div`
  content: 'h';
  display: inline-block;
  font-size: 13px;
  height: 100%;
  left: 0;
  line-height: 18px;
  position: absolute;
  right: 0;
`;

const FlashStyle = styled.div`
  bottom: 0px;
  overflow: hidden;
  position: fixed;
  right: 0;
  text-align: center;
  width: 100%;

  // tag added by CSSTransitionGroup
    > div {
    display: inline-block;
    height: 100%;
    width: 100%;
  };

    ${({ variant }) => variant && css`
        ${FlashSliderStyle} {
          background: ${colors[variant]};
        };

        ${requireWhiteTextColor.includes(variant) && `

          ${FlashMessageStyle},
          .carbon-flash__close,
          .carbon-flash__icon:before {
            color: white;
          };

        `}
    `};

    ${sliderAnimation};
    ${contentAnimation};
`;

export {
  FlashStyle,
  FlashSliderStyle,
  FlashContentStyle,
  FlashMessageStyle
};
<commit_msg>remove never used import<commit_after>import styled, { css } from 'styled-components';

const colors = {
  warning: '#FF7D00',
  default: '#335B6D',
  error: '#c7384f',
  info: '#1573E6',
  new: '#663399',
  success: '#50B848',
  help: '#FFAB00',
  maintenance: '#FF7D00'
};

const requireWhiteTextColor = [
  'error',
  'new',
  'info'
];

const sliderAnimation = `
  .carbon-flash__slider-appear,
  .carbon-flash__slider-enter {
    left: 50%;
    opacity: 0;
    right: 50%;
  }

  .carbon-flash__slider-appear-active,
  .carbon-flash__slider-enter-active {
    left: 0%;
    opacity: 1;
    right: 0%;
    transition: 500ms ease 100ms;
  }

  .carbon-flash__slider-leave {
    opacity: 1;
  }

  .carbon-flash__slider-leave-active  {
    opacity: 0;
    transition: 500ms ease 100ms;
  }
`;

const contentAnimation = `
  .carbon-flash__content-appear,
  .carbon-flash__content-enter {
    opacity: 0;
  }

  .carbon-flash__content-appear-active,
  .carbon-flash__content-enter-active {
    opacity: 1;
    transition: 400ms ease 400ms;
  }

  .carbon-flash__content-leave {
    opacity: 1;
  }

  .carbon-flash__content-leave-active  {
    opacity: 0;
    transition: 400ms ease-out 100ms;
  }
`;

const FlashMessageStyle = styled.div`
  color: rgba(0,0,0,0.85);
  font-size: 14px;
  font-weight: 700;
  margin: 20px 70px;
  position: relative;
  text-align: left;
`;

const FlashContentStyle = styled.div`
  background-color: transparent ;
  margin: 0 auto;
  max-width: 1600px;
  min-width: 958px;
  position: relative;
`;

const FlashSliderStyle = styled.div`
  content: 'h';
  display: inline-block;
  font-size: 13px;
  height: 100%;
  left: 0;
  line-height: 18px;
  position: absolute;
  right: 0;
`;

const FlashStyle = styled.div`
  bottom: 0px;
  overflow: hidden;
  position: fixed;
  right: 0;
  text-align: center;
  width: 100%;

  // tag added by CSSTransitionGroup
    > div {
    display: inline-block;
    height: 100%;
    width: 100%;
  };

    ${({ variant }) => variant && css`
        ${FlashSliderStyle} {
          background: ${colors[variant]};
        };

        ${requireWhiteTextColor.includes(variant) && `

          ${FlashMessageStyle},
          .carbon-flash__close,
          .carbon-flash__icon:before {
            color: white;
          };

        `}
    `};

    ${sliderAnimation};
    ${contentAnimation};
`;

export {
  FlashStyle,
  FlashSliderStyle,
  FlashContentStyle,
  FlashMessageStyle
};
<|endoftext|>


<commit_before>// @flow

declare module "debugger-html" {
  /**
 * Breakpoint ID
 *
 * @memberof types
 * @static
 */
  declare type BreakpointId = string;

  /**
 * Source ID
 *
 * @memberof types
 * @static
 */
  declare type SourceId = string;

  /**
 * Actor ID
 *
 * @memberof types
 * @static
 */
  declare type ActorId = string;

  /**
 * Source File Location
 *
 * @memberof types
 * @static
 */
  declare type Location = {
    sourceId: SourceId,
    line: number,
    column: ?number,
    sourceUrl?: string
  };

  declare type PendingLocation = {
    line: number,
    column: ?number,
    sourceUrl?: string
  };

  declare type ASTLocation = {|
    name: ?string,
    offset: {
      column: ?number,
      line: number
    }
  |};

  /**
 * Breakpoint
 *
 * @memberof types
 * @static
 */
  declare type Breakpoint = {
    id: BreakpointId,
    location: Location,
    astLocation: ?ASTLocation,
    generatedLocation: Location,
    loading: boolean,
    disabled: boolean,
    hidden: boolean,
    text: string,
    condition: ?string
  };

  /**
 * Breakpoint sync data
 *
 * @memberof types
 * @static
 */
  declare type BreakpointSyncData = {
    previousLocation: Location | null,
    breakpoint: Breakpoint
  };

  /**
 * Breakpoint Result is the return from an add/modify Breakpoint request
 *
 * @memberof types
 * @static
 */
  declare type BreakpointResult = {
    id: ActorId,
    actualLocation: Location
  };

  /**
 * PendingBreakpoint
 *
 * @memberof types
 * @static
 */
  declare type PendingBreakpoint = {
    location: PendingLocation,
    astLocation: ASTLocation,
    generatedLocation: PendingLocation,
    loading: boolean,
    disabled: boolean,
    text: string,
    condition: ?string
  };

  /**
 * Frame ID
 *
 * @memberof types
 * @static
 */
  declare type FrameId = string;

  /**
 * Frame
 * @memberof types
 * @static
 */
  declare type Frame = {
    id: FrameId,
    displayName: string,
    location: Location,
    generatedLocation: Location,
    source?: Source,
    scope: Scope,
    // FIXME Define this type more clearly
    this: Object,
    framework?: string
  };

  /**
   * ContextMenuItem
   *
   * @memberof types
   * @static
   */
  declare type ContextMenuItem = {
    id: string,
    label: string,
    accesskey: string,
    disabled: boolean,
    click: Function
  };

  /**
 * why
 * @memberof types
 * @static
 */
  declare type Why =
    | {|
        exception: string | Grip,
        type: "exception",
        frameFinished?: Object
      |}
    | {
        type: string,
        frameFinished?: Object
      };

  /**
 * Why is the Debugger Paused?
 * This is the generic state handling the reason the debugger is paused.
 * Reasons are usually related to "breakpoint" or "debuggerStatement"
 * and should eventually be specified here as an enum.  For now we will
 * just offer it as a string.
 * @memberof types
 * @static
 */
  declare type WhyPaused = {
    type: string
  };

  declare type LoadedObject = {
    objectId: string,
    parentId: string,
    name: string,
    value: any
  };

  /**
 * Pause
 * @memberof types
 * @static
 */
  declare type Pause = {
    frame: Frame,
    frames: Frame[],
    why: Why,
    loadedObjects?: LoadedObject[]
  };
  /**
 * Expression
 * @memberof types
 * @static
 */
  declare type Expression = {
    input: string,
    value: Object,
    from: string
  };

  /**
  * Grip
  * @memberof types
  * @static
  */
  declare type Grip = {
    actor: string,
    class: string,
    extensible: boolean,
    frozen: boolean,
    isGlobal: boolean,
    ownPropertyLength: number,
    preview: {
      kind: string,
      url: string,
      fileName: string
    },
    sealed: boolean,
    type: string
  };

  /**
   * Source
   *
   * @memberof types
   * @static
   */
  declare type Source = {
    id: SourceId,
    url: string,
    sourceMapURL?: string,
    isBlackBoxed: boolean,
    isPrettyPrinted: boolean,
    isWasm: boolean,
    text?: string,
    contentType?: string,
    error?: string,
    loadedState: "unloaded" | "loading" | "loaded"
  };

  /**
   * SourceScope
   * @memberof types
   * @static
   */
  declare type SourceScope = {
    type: string,
    start: Location,
    end: Location,
    bindings: {
      [name: string]: Location[]
    }
  };

  /*
   * MappedScopeBindings
   * @memberof types
   * @static
   */
  declare type MappedScopeBindings = {
    type: string,
    bindings: {
      [originalName: string]: string
    }
  };

  /**
 * Script
 * This describes scripts which are sent to the debug server to be eval'd
 * @memberof types
 * @static
 * FIXME: This needs a real type definition
 */
  declare type Script = any;

  /**
 * Describes content of the binding.
 * FIXME Define these type more clearly
 */
  declare type BindingContents = {
    value: any
  };

  /**
 * Defines map of binding name to its content.
 */
  declare type ScopeBindings = {
    [name: string]: BindingContents
  };

  declare type SyntheticScope = {
    type: string,
    bindingsNames: string[]
  };

  /**
 * Scope
 * @memberof types
 * @static
 */
  declare type Scope = {
    actor: ActorId,
    parent: ?Scope,
    bindings: {
      arguments: Array<ScopeBindings>,
      variables: ScopeBindings
    },
    sourceBindings?: {
      [originalName: string]: string
    },
    object: Object,
    function: {
      actor: ActorId,
      class: string,
      displayName: string,
      location: Location,
      parameterNames: string[]
    },
    syntheticScopes?: {
      scopes: SyntheticScope[],
      groupIndex: number,
      groupLength: number
    },
    type: string
  };
}
<commit_msg>Prettify types (#4973)<commit_after>// @flow

declare module "debugger-html" {
  /**
   * Breakpoint ID
   *
   * @memberof types
   * @static
   */
  declare type BreakpointId = string;

  /**
   * Source ID
   *
   * @memberof types
   * @static
   */
  declare type SourceId = string;

  /**
   * Actor ID
   *
   * @memberof types
   * @static
   */
  declare type ActorId = string;

  /**
   * Source File Location
   *
   * @memberof types
   * @static
   */
  declare type Location = {
    sourceId: SourceId,
    line: number,
    column: ?number,
    sourceUrl?: string
  };

  declare type PendingLocation = {
    line: number,
    column: ?number,
    sourceUrl?: string
  };

  declare type ASTLocation = {|
    name: ?string,
    offset: {
      column: ?number,
      line: number
    }
  |};

  /**
   * Breakpoint
   *
   * @memberof types
   * @static
   */
  declare type Breakpoint = {
    id: BreakpointId,
    location: Location,
    astLocation: ?ASTLocation,
    generatedLocation: Location,
    loading: boolean,
    disabled: boolean,
    hidden: boolean,
    text: string,
    condition: ?string
  };

  /**
   * Breakpoint sync data
   *
   * @memberof types
   * @static
   */
  declare type BreakpointSyncData = {
    previousLocation: Location | null,
    breakpoint: Breakpoint
  };

  /**
   * Breakpoint Result is the return from an add/modify Breakpoint request
   *
   * @memberof types
   * @static
   */
  declare type BreakpointResult = {
    id: ActorId,
    actualLocation: Location
  };

  /**
   * PendingBreakpoint
   *
   * @memberof types
   * @static
   */
  declare type PendingBreakpoint = {
    location: PendingLocation,
    astLocation: ASTLocation,
    generatedLocation: PendingLocation,
    loading: boolean,
    disabled: boolean,
    text: string,
    condition: ?string
  };

  /**
   * Frame ID
   *
   * @memberof types
   * @static
   */
  declare type FrameId = string;

  /**
   * Frame
   * @memberof types
   * @static
   */
  declare type Frame = {
    id: FrameId,
    displayName: string,
    location: Location,
    generatedLocation: Location,
    source?: Source,
    scope: Scope,
    // FIXME Define this type more clearly
    this: Object,
    framework?: string
  };

  /**
   * ContextMenuItem
   *
   * @memberof types
   * @static
   */
  declare type ContextMenuItem = {
    id: string,
    label: string,
    accesskey: string,
    disabled: boolean,
    click: Function
  };

  /**
   * why
   * @memberof types
   * @static
   */
  declare type Why =
    | {|
        exception: string | Grip,
        type: "exception",
        frameFinished?: Object
      |}
    | {
        type: string,
        frameFinished?: Object
      };

  /**
   * Why is the Debugger Paused?
   * This is the generic state handling the reason the debugger is paused.
   * Reasons are usually related to "breakpoint" or "debuggerStatement"
   * and should eventually be specified here as an enum.  For now we will
   * just offer it as a string.
   * @memberof types
   * @static
   */
  declare type WhyPaused = {
    type: string
  };

  declare type LoadedObject = {
    objectId: string,
    parentId: string,
    name: string,
    value: any
  };

  /**
   * Pause
   * @memberof types
   * @static
   */
  declare type Pause = {
    frame: Frame,
    frames: Frame[],
    why: Why,
    loadedObjects?: LoadedObject[]
  };
  /**
   * Expression
   * @memberof types
   * @static
   */
  declare type Expression = {
    input: string,
    value: Object,
    from: string
  };

  /**
   * Grip
   * @memberof types
   * @static
   */
  declare type Grip = {
    actor: string,
    class: string,
    extensible: boolean,
    frozen: boolean,
    isGlobal: boolean,
    ownPropertyLength: number,
    preview: {
      kind: string,
      url: string,
      fileName: string
    },
    sealed: boolean,
    type: string
  };

  /**
   * Source
   *
   * @memberof types
   * @static
   */
  declare type Source = {
    id: SourceId,
    url: string,
    sourceMapURL?: string,
    isBlackBoxed: boolean,
    isPrettyPrinted: boolean,
    isWasm: boolean,
    text?: string,
    contentType?: string,
    error?: string,
    loadedState: "unloaded" | "loading" | "loaded"
  };

  /**
   * SourceScope
   * @memberof types
   * @static
   */
  declare type SourceScope = {
    type: string,
    start: Location,
    end: Location,
    bindings: {
      [name: string]: Location[]
    }
  };

  /*
   * MappedScopeBindings
   * @memberof types
   * @static
   */
  declare type MappedScopeBindings = {
    type: string,
    bindings: {
      [originalName: string]: string
    }
  };

  /**
   * Script
   * This describes scripts which are sent to the debug server to be eval'd
   * @memberof types
   * @static
   * FIXME: This needs a real type definition
   */
  declare type Script = any;

  /**
   * Describes content of the binding.
   * FIXME Define these type more clearly
   */
  declare type BindingContents = {
    value: any
  };

  /**
   * Defines map of binding name to its content.
   */
  declare type ScopeBindings = {
    [name: string]: BindingContents
  };

  declare type SyntheticScope = {
    type: string,
    bindingsNames: string[]
  };

  /**
   * Scope
   * @memberof types
   * @static
   */
  declare type Scope = {
    actor: ActorId,
    parent: ?Scope,
    bindings: {
      arguments: Array<ScopeBindings>,
      variables: ScopeBindings
    },
    sourceBindings?: {
      [originalName: string]: string
    },
    object: Object,
    function: {
      actor: ActorId,
      class: string,
      displayName: string,
      location: Location,
      parameterNames: string[]
    },
    syntheticScopes?: {
      scopes: SyntheticScope[],
      groupIndex: number,
      groupLength: number
    },
    type: string
  };
}
<|endoftext|>


<commit_before>import { useEffect, useState } from 'react'
import lightTheme from 'styles/theme/light'
import darkTheme from 'styles/theme/dark'

const modes = {
  LIGHT: 'LIGHT',
  DARK: 'DARK',
}

export const useDarkMode = () => {
  // 기본은 다크모드
  const [mode, setMode] = useState(modes.DARK)
  const [theme, setTheme] = useState(darkTheme)
  const [isThemeInit, setIsThemeInit] = useState(false)

  // 로컬스토리지에 저장
  const changeMode = mode => {
    window.localStorage.setItem('theme', mode)
    setMode(mode)
    setTheme(mode === modes.LIGHT ? lightTheme : darkTheme)
  }

  const toggleTheme = () => {
    if (mode === modes.LIGHT) {
      changeMode(modes.DARK)
    } else {
      changeMode(modes.LIGHT)
    }
  }

  useEffect(() => {
    const localTheme = window.localStorage.getItem('theme')
    localTheme && changeMode(localTheme)
    setIsThemeInit(true)
  }, [])

  return { mode, theme, toggleTheme, isThemeInit }
}
<commit_msg>init theme with system preference<commit_after>import { useEffect, useState } from 'react'
import lightTheme from 'styles/theme/light'
import darkTheme from 'styles/theme/dark'

const modes = {
  LIGHT: 'LIGHT',
  DARK: 'DARK',
}

export const useDarkMode = () => {
  // 기본은 다크모드
  const [mode, setMode] = useState(modes.DARK)
  const [theme, setTheme] = useState(darkTheme)
  const [isThemeInit, setIsThemeInit] = useState(false)

  // 로컬스토리지에 저장
  const changeMode = mode => {
    window.localStorage.setItem('theme', mode)
    setMode(mode)
    setTheme(mode === modes.LIGHT ? lightTheme : darkTheme)
  }

  const toggleTheme = () => {
    if (mode === modes.LIGHT) {
      changeMode(modes.DARK)
    } else {
      changeMode(modes.LIGHT)
    }
  }

  useEffect(() => {
    // 시스템 다크 모드 확인
    const isSystemDarkMode =
      window.matchMedia &&
      window.matchMedia('(prefers-color-scheme: dark)').matches

    let localTheme = window.localStorage.getItem('theme')

    if (!localTheme) {
      localTheme = isSystemDarkMode ? modes.DARK : modes.LIGHT
      window.localStorage.setItem('theme', localTheme)
    }

    changeMode(localTheme)
    setIsThemeInit(true)
  }, [])

  return { mode, theme, toggleTheme, isThemeInit }
}
<|endoftext|>


<commit_before>import $ from '../../utils/dom';
import Utils from '../../utils/utils';

const Parallax = {
  setTransform(el, progress) {
    const swiper = this;
    const { rtl } = swiper;

    const $el = $(el);
    const rtlFactor = rtl ? -1 : 1;

    const p = $el.attr('data-swiper-parallax') || '0';
    let pX = $el.attr('data-swiper-parallax-x');
    let pY = $el.attr('data-swiper-parallax-y');

    if (pX || pY) {
      pX = pX || '0';
      pY = pY || '0';
    } else if (swiper.isHorizontal()) {
      pX = p;
      pY = '0';
    } else {
      pY = p;
      pX = '0';
    }

    if ((pX).indexOf('%') >= 0) {
      pX = `${parseInt(pX, 10) * progress * rtlFactor}%`;
    } else {
      pX = `${pX * progress * rtlFactor}px`;
    }
    if ((pY).indexOf('%') >= 0) {
      pY = `${parseInt(pY, 10) * progress}%`;
    } else {
      pY = `${pY * progress}px`;
    }

    $el.transform(`translate3d(${pX}, ${pY}, 0px)`);
  },
  setTranslate() {
    const swiper = this;
    const { $el, slides, progress } = swiper;
    $el.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]')
      .each((index, el) => {
        Parallax.setTransform(el, progress);
      });
    slides.each((slideIndex, slideEl) => {
      $(slideEl).find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]')
        .each((index, el) => {
          const slideProgress = Math.min(Math.max(slideEl.progress, -1), 1);
          Parallax.setTransform(el, slideProgress);
        });
    });
  },
  setTransition(duration = this.params.speed) {
    const swiper = this;
    const { $el } = swiper;
    $el.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]')
      .each((index, parallaxEl) => {
        const $parallaxEl = $(parallaxEl);
        let parallaxDuration = parseInt($parallaxEl.attr('data-swiper-parallax-duration'), 10) || duration;
        if (duration === 0) parallaxDuration = 0;
        $parallaxEl.transition(parallaxDuration);
      });
  },
};

export default {
  name: 'parallax',
  create() {
    const swiper = this;
    Utils.extend(swiper, {
      parallax: {
        setTransform: Parallax.setTransform.bind(swiper),
        setTranslate: Parallax.setTranslate.bind(swiper),
        setTransition: Parallax.setTransition.bind(swiper),
      },
    });
  },
  on: {
    init() {
      const swiper = this;
      swiper.parallax.setTranslate();
    },
    setTranslate() {
      const swiper = this;
      swiper.parallax.setTranslate();
    },
    setTransition(duration) {
      const swiper = this;
      swiper.parallax.setTransition(duration);
    },
  },
};
<commit_msg>Parallax params<commit_after>import $ from '../../utils/dom';
import Utils from '../../utils/utils';

const Parallax = {
  setTransform(el, progress) {
    const swiper = this;
    const { rtl } = swiper;

    const $el = $(el);
    const rtlFactor = rtl ? -1 : 1;

    const p = $el.attr('data-swiper-parallax') || '0';
    let pX = $el.attr('data-swiper-parallax-x');
    let pY = $el.attr('data-swiper-parallax-y');

    if (pX || pY) {
      pX = pX || '0';
      pY = pY || '0';
    } else if (swiper.isHorizontal()) {
      pX = p;
      pY = '0';
    } else {
      pY = p;
      pX = '0';
    }

    if ((pX).indexOf('%') >= 0) {
      pX = `${parseInt(pX, 10) * progress * rtlFactor}%`;
    } else {
      pX = `${pX * progress * rtlFactor}px`;
    }
    if ((pY).indexOf('%') >= 0) {
      pY = `${parseInt(pY, 10) * progress}%`;
    } else {
      pY = `${pY * progress}px`;
    }

    $el.transform(`translate3d(${pX}, ${pY}, 0px)`);
  },
  setTranslate() {
    const swiper = this;
    const { $el, slides, progress } = swiper;
    $el.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]')
      .each((index, el) => {
        Parallax.setTransform(el, progress);
      });
    slides.each((slideIndex, slideEl) => {
      $(slideEl).find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]')
        .each((index, el) => {
          const slideProgress = Math.min(Math.max(slideEl.progress, -1), 1);
          Parallax.setTransform(el, slideProgress);
        });
    });
  },
  setTransition(duration = this.params.speed) {
    const swiper = this;
    const { $el } = swiper;
    $el.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]')
      .each((index, parallaxEl) => {
        const $parallaxEl = $(parallaxEl);
        let parallaxDuration = parseInt($parallaxEl.attr('data-swiper-parallax-duration'), 10) || duration;
        if (duration === 0) parallaxDuration = 0;
        $parallaxEl.transition(parallaxDuration);
      });
  },
};

export default {
  name: 'parallax',
  params: {
    parallax: false,
  },
  create() {
    const swiper = this;
    Utils.extend(swiper, {
      parallax: {
        setTransform: Parallax.setTransform.bind(swiper),
        setTranslate: Parallax.setTranslate.bind(swiper),
        setTransition: Parallax.setTransition.bind(swiper),
      },
    });
  },
  on: {
    init() {
      const swiper = this;
      if (!swiper.params.parallax) return;
      swiper.parallax.setTranslate();
    },
    setTranslate() {
      const swiper = this;
      if (!swiper.params.parallax) return;
      swiper.parallax.setTranslate();
    },
    setTransition(duration) {
      const swiper = this;
      if (!swiper.params.parallax) return;
      swiper.parallax.setTransition(duration);
    },
  },
};
<|endoftext|>


<commit_before>import React from 'react'
import PropTypes from 'prop-types'
import { Button, Icon, List, Loader, Message } from 'semantic-ui-react'
import { FormattedMessage } from 'react-intl'
import { Query } from 'react-apollo'

import { QUESTION_TYPES } from '../../lib'
import { TagListQuery } from '../../graphql'

const propTypes = {
  activeTags: PropTypes.array.isRequired,
  activeType: PropTypes.string.isRequired,
  handleReset: PropTypes.func.isRequired,
  handleTagClick: PropTypes.func.isRequired,
  handleToggleArchive: PropTypes.func.isRequired,
  isArchiveActive: PropTypes.bool,
}

const defaultProps = {
  isArchiveActive: false,
}

export const TagListPres = ({
  activeTags,
  isArchiveActive,
  activeType,
  handleTagClick,
  handleReset,
  handleToggleArchive,
}) => (

    <Button basic fluid onClick={() => handleReset()}>
      <Icon name="remove circle" />
      <FormattedMessage defaultMessage="Reset filters" id="tagList.button.reset" />
    </Button>
    <List selection size="large">
      <List.Header className="listHeader archive">
        <FormattedMessage defaultMessage="Archive" id="tagList.header.archive" />
      </List.Header>
      <List.Item active={isArchiveActive} className="listItem archiveItem" onClick={() => handleToggleArchive(true)}>
        <List.Icon name="archive" />
        <List.Content>
          <FormattedMessage defaultMessage="Show Archive" id="tagList.string.showArchive" />
        </List.Content>
      </List.Item>
      <List.Item active={!isArchiveActive} className="listItem archiveItem" onClick={() => handleToggleArchive(false)}>
        <List.Icon name="list" />
        <List.Content>
          <FormattedMessage defaultMessage="Show Pool" id="tagList.string.showPool" />
        </List.Content>
      </List.Item>
      <List.Header className="listHeader types">
        <FormattedMessage defaultMessage="Types" id="tagList.header.types" />
      </List.Header>
      <List.Item
        active={activeType === QUESTION_TYPES.SC}
        className="listItem"
        key="SC"
        onClick={() => handleTagClick('SC', true)}
      >
        <List.Icon name={activeType === QUESTION_TYPES.SC ? 'folder' : 'folder outline'} />
        <List.Content>
          <FormattedMessage defaultMessage="Single Choice (SC)" id="common.SC.label" />
        </List.Content>
      </List.Item>
      <List.Item
        active={activeType === QUESTION_TYPES.MC}
        className="listItem"
        key="MC"
        onClick={() => handleTagClick('MC', true)}
      >
        <List.Icon name={activeType === QUESTION_TYPES.MC ? 'folder' : 'folder outline'} />
        <List.Content>
          <FormattedMessage defaultMessage="Multiple Choice (MC)" id="common.MC.label" />
        </List.Content>
      </List.Item>
      <List.Item
        active={activeType === QUESTION_TYPES.FREE}
        className="listItem"
        key="FREE"
        onClick={() => handleTagClick('FREE', true)}
      >
        <List.Icon name={activeType === QUESTION_TYPES.FREE ? 'folder' : 'folder outline'} />
        <List.Content>
          <FormattedMessage defaultMessage="Free Text (FT)" id="common.FREE.label" />
        </List.Content>
      </List.Item>
      <List.Item
        active={activeType === QUESTION_TYPES.FREE_RANGE}
        className="listItem"
        key="FREE_RANGE"
        onClick={() => handleTagClick('FREE_RANGE', true)}
      >
        <List.Icon name={activeType === QUESTION_TYPES.FREE_RANGE ? 'folder' : 'folder outline'} />
        <List.Content>
          <FormattedMessage defaultMessage="Number Range (NR)" id="common.FREE_RANGE.label" />
        </List.Content>
      </List.Item>
      <List.Header className="listHeader tags">
        <FormattedMessage defaultMessage="Tags" id="tagList.header.tags" />
      </List.Header>

      <Query query={TagListQuery}>
        {({ data: { tags }, error, loading }) => {
          if (loading) {
            return <Loader active />
          }

          if (error) {
            return <Message error>{error.message}</Message>
          }

          if (tags.length === 0) {
            return <FormattedMessage defaultMessage="No tags available." id="tagList.string.noTags" />
          }

          return tags.map(({ id, name }) => (
            <List.Item
              active={activeTags.includes(name)}
              className="listItem"
              key={id}
              onClick={() => handleTagClick(name)}
            >
              <List.Icon name="tag" />
              <List.Content>{name}</List.Content>
            </List.Item>
          ))
        }}
      </Query>
    </List>

)

TagListPres.propTypes = propTypes
TagListPres.defaultProps = defaultProps

export default TagListPres
<commit_msg>Optimize archive distinction<commit_after>import React from 'react'
import PropTypes from 'prop-types'
import { Button, Icon, List, Loader, Message } from 'semantic-ui-react'
import { FormattedMessage } from 'react-intl'
import { Query } from 'react-apollo'

import { QUESTION_TYPES } from '../../lib'
import { TagListQuery } from '../../graphql'

const propTypes = {
  activeTags: PropTypes.array.isRequired,
  activeType: PropTypes.string.isRequired,
  handleReset: PropTypes.func.isRequired,
  handleTagClick: PropTypes.func.isRequired,
  handleToggleArchive: PropTypes.func.isRequired,
  isArchiveActive: PropTypes.bool,
}

const defaultProps = {
  isArchiveActive: false,
}

export const TagListPres = ({
  activeTags,
  isArchiveActive,
  activeType,
  handleTagClick,
  handleReset,
  handleToggleArchive,
}) => (

    <Button basic fluid onClick={() => handleReset()}>
      <Icon name="remove circle" />
      <FormattedMessage defaultMessage="Reset filters" id="tagList.button.reset" />
    </Button>
    <List selection size="large">
      <List.Item active={isArchiveActive} className="listItem archiveItem" onClick={() => handleToggleArchive(true)}>
        <List.Icon name="archive" />
        <List.Content>
          <FormattedMessage defaultMessage="Question Archive" id="tagList.string.showArchive" />
        </List.Content>
      </List.Item>
      <List.Item active={!isArchiveActive} className="listItem archiveItem" onClick={() => handleToggleArchive(false)}>
        <List.Icon name="list" />
        <List.Content>
          <FormattedMessage defaultMessage="Question Pool" id="tagList.string.showPool" />
        </List.Content>
      </List.Item>
      <List.Header className="listHeader types">
        <FormattedMessage defaultMessage="Types" id="tagList.header.types" />
      </List.Header>
      <List.Item
        active={activeType === QUESTION_TYPES.SC}
        className="listItem"
        key="SC"
        onClick={() => handleTagClick('SC', true)}
      >
        <List.Icon name={activeType === QUESTION_TYPES.SC ? 'folder' : 'folder outline'} />
        <List.Content>
          <FormattedMessage defaultMessage="Single Choice (SC)" id="common.SC.label" />
        </List.Content>
      </List.Item>
      <List.Item
        active={activeType === QUESTION_TYPES.MC}
        className="listItem"
        key="MC"
        onClick={() => handleTagClick('MC', true)}
      >
        <List.Icon name={activeType === QUESTION_TYPES.MC ? 'folder' : 'folder outline'} />
        <List.Content>
          <FormattedMessage defaultMessage="Multiple Choice (MC)" id="common.MC.label" />
        </List.Content>
      </List.Item>
      <List.Item
        active={activeType === QUESTION_TYPES.FREE}
        className="listItem"
        key="FREE"
        onClick={() => handleTagClick('FREE', true)}
      >
        <List.Icon name={activeType === QUESTION_TYPES.FREE ? 'folder' : 'folder outline'} />
        <List.Content>
          <FormattedMessage defaultMessage="Free Text (FT)" id="common.FREE.label" />
        </List.Content>
      </List.Item>
      <List.Item
        active={activeType === QUESTION_TYPES.FREE_RANGE}
        className="listItem"
        key="FREE_RANGE"
        onClick={() => handleTagClick('FREE_RANGE', true)}
      >
        <List.Icon name={activeType === QUESTION_TYPES.FREE_RANGE ? 'folder' : 'folder outline'} />
        <List.Content>
          <FormattedMessage defaultMessage="Number Range (NR)" id="common.FREE_RANGE.label" />
        </List.Content>
      </List.Item>
      <List.Header className="listHeader tags">
        <FormattedMessage defaultMessage="Tags" id="tagList.header.tags" />
      </List.Header>

      <Query query={TagListQuery}>
        {({ data: { tags }, error, loading }) => {
          if (loading) {
            return <Loader active />
          }

          if (error) {
            return <Message error>{error.message}</Message>
          }

          if (tags.length === 0) {
            return <FormattedMessage defaultMessage="No tags available." id="tagList.string.noTags" />
          }

          return tags.map(({ id, name }) => (
            <List.Item
              active={activeTags.includes(name)}
              className="listItem"
              key={id}
              onClick={() => handleTagClick(name)}
            >
              <List.Icon name="tag" />
              <List.Content>{name}</List.Content>
            </List.Item>
          ))
        }}
      </Query>
    </List>

)

TagListPres.propTypes = propTypes
TagListPres.defaultProps = defaultProps

export default TagListPres
<|endoftext|>


<commit_before>// Based loosely around work by Witold Szczerba - https://github.com/witoldsz/angular-http-auth
(function() {
  'use strict';
  angular.module('civic.security.service', [
    'civic.security.retryQueue',
    'civic.security.login',
    'dialogs.main'
  ])
    .factory('Security', Security);

// @ngInject
  function Security($http, $q, $location, $state, RetryQueue, dialogs, $log) {
    // Redirect to the given url (defaults to '/')
    function redirect(url) {
      url = url || '/';
      $location.url(url);
      $state.reload();
    }

    // Login form dialog stuff
    var loginDialog = null;
    function openLoginDialog() {
      if ( loginDialog ) {
        throw new Error('Trying to open a dialog that is already open!');
      }
      loginDialog= dialogs.create('components/security/login/LoginForm.tpl.html','LoginFormController',{},{backdrop: 'static'});
      loginDialog.result.then(onLoginDialogClose);
    }
    function closeLoginDialog(success) {
      $log.info('Security.closeLoginDialog() called.');
      if (loginDialog) {
        loginDialog.close(success);
      }
    }
    function onLoginDialogClose(success) {
      loginDialog = null;
      if ( success ) {
        RetryQueue.retryAll();
      } else {
        RetryQueue.cancelAll();
        // redirect();
      }
    }

    // Register a handler for when an item is added to the retry queue
    RetryQueue.onItemAddedCallbacks.push(function() {
      if ( RetryQueue.hasMore() ) {
        service.showLogin();
      }
    });

    // The public API of the service
    var service = {

      // Get the first reason for needing a login
      getLoginReason: function() {
        return RetryQueue.retryReason();
      },

      // Show the modal login dialog
      showLogin: function() {
        openLoginDialog();
      },

      // Attempt to authenticate a user by the given email and password
      login: function() {
        var request = $http.get('/api/current_user.json');
        return request.then(function(response) {
          service.currentUser = response.data.user;
          if ( service.isAuthenticated() ) {
            closeLoginDialog(true);
          }
          return service.isAuthenticated();
        });
      },

      // Give up trying to login and clear the retry queue
      cancelLogin: function(url) {
        closeLoginDialog(false);
        redirect(url);
      },

      // Logout the current user and redirect
      logout: function(redirectTo) {
        $http.get('/api/sign_out').then(function() { // success
          service.currentUser = null;
          redirect(redirectTo);
        }, function(response) { // failure
          $log.warn('COULD NOT LOG OUT' + JSON.stringify(response));
        });
      },

      // Ask the backend to see if a user is already authenticated - this may be from a previous session.
      requestCurrentUser: function() {
        if ( service.isAuthenticated() ) {
          return $q.when(service.currentUser);
        } else {
          return $http.get('/api/current_user.json').then(function(response) {
            // unauthenticated request returns an empty JSON object, so we count the keys
            // and if there are any we assume an authenticated user
            if(Object.keys(response.data).length > 0) {
              service.currentUser = response.data;
            } else {
              service.currentUser = null;
            }
            return service.currentUser;
          });
        }
      },

      reloadCurrentUser: function() {
        return $http.get('/api/current_user.json').then(function(response) {
          // unauthenticated request returns an empty JSON object, so we count the keys
          // and if there are any we assume an authenticated user
          if(Object.keys(response.data).length > 0) {
            service.currentUser = response.data;
          } else {
            service.currentUser = null;
          }
          return service.currentUser;
        });
      },

      // Information about the current user
      currentUser: null,

      // Is the current user authenticated?
      isAuthenticated: function(){
        return !!service.currentUser;
      },

      // Is the current user an admin?
      isAdmin: function() {
        return !!(service.currentUser && service.currentUser.role === 'admin');
      },

      // Is the current user an editor?
      isEditor: function() {
        return !!(service.currentUser && service.currentUser.role === 'editor');
      },

      // Is the current user an editor?
      isCurator: function() {
        return !!(service.currentUser && (service.currentUser.role === 'curator' || service.currentUser.role === 'editor'));
      }
    };

    return service;
  }
})();
<commit_msg>isEditor now returns true for admins - better name would be now be hasEditorPrivileges<commit_after>// Based loosely around work by Witold Szczerba - https://github.com/witoldsz/angular-http-auth
(function() {
  'use strict';
  angular.module('civic.security.service', [
    'civic.security.retryQueue',
    'civic.security.login',
    'dialogs.main'
  ])
    .factory('Security', Security);

// @ngInject
  function Security($http, $q, $location, $state, RetryQueue, dialogs, $log) {
    // Redirect to the given url (defaults to '/')
    function redirect(url) {
      url = url || '/';
      $location.url(url);
      $state.reload();
    }

    // Login form dialog stuff
    var loginDialog = null;
    function openLoginDialog() {
      if ( loginDialog ) {
        throw new Error('Trying to open a dialog that is already open!');
      }
      loginDialog= dialogs.create('components/security/login/LoginForm.tpl.html','LoginFormController',{},{backdrop: 'static'});
      loginDialog.result.then(onLoginDialogClose);
    }
    function closeLoginDialog(success) {
      $log.info('Security.closeLoginDialog() called.');
      if (loginDialog) {
        loginDialog.close(success);
      }
    }
    function onLoginDialogClose(success) {
      loginDialog = null;
      if ( success ) {
        RetryQueue.retryAll();
      } else {
        RetryQueue.cancelAll();
        // redirect();
      }
    }

    // Register a handler for when an item is added to the retry queue
    RetryQueue.onItemAddedCallbacks.push(function() {
      if ( RetryQueue.hasMore() ) {
        service.showLogin();
      }
    });

    // The public API of the service
    var service = {

      // Get the first reason for needing a login
      getLoginReason: function() {
        return RetryQueue.retryReason();
      },

      // Show the modal login dialog
      showLogin: function() {
        openLoginDialog();
      },

      // Attempt to authenticate a user by the given email and password
      login: function() {
        var request = $http.get('/api/current_user.json');
        return request.then(function(response) {
          service.currentUser = response.data.user;
          if ( service.isAuthenticated() ) {
            closeLoginDialog(true);
          }
          return service.isAuthenticated();
        });
      },

      // Give up trying to login and clear the retry queue
      cancelLogin: function(url) {
        closeLoginDialog(false);
        redirect(url);
      },

      // Logout the current user and redirect
      logout: function(redirectTo) {
        $http.get('/api/sign_out').then(function() { // success
          service.currentUser = null;
          redirect(redirectTo);
        }, function(response) { // failure
          $log.warn('COULD NOT LOG OUT' + JSON.stringify(response));
        });
      },

      // Ask the backend to see if a user is already authenticated - this may be from a previous session.
      requestCurrentUser: function() {
        if ( service.isAuthenticated() ) {
          return $q.when(service.currentUser);
        } else {
          return $http.get('/api/current_user.json').then(function(response) {
            // unauthenticated request returns an empty JSON object, so we count the keys
            // and if there are any we assume an authenticated user
            if(Object.keys(response.data).length > 0) {
              service.currentUser = response.data;
            } else {
              service.currentUser = null;
            }
            return service.currentUser;
          });
        }
      },

      reloadCurrentUser: function() {
        return $http.get('/api/current_user.json').then(function(response) {
          // unauthenticated request returns an empty JSON object, so we count the keys
          // and if there are any we assume an authenticated user
          if(Object.keys(response.data).length > 0) {
            service.currentUser = response.data;
          } else {
            service.currentUser = null;
          }
          return service.currentUser;
        });
      },

      // Information about the current user
      currentUser: null,

      // Is the current user authenticated?
      isAuthenticated: function(){
        return !!service.currentUser;
      },

      // Does the current user have admin privileges?
      isAdmin: function() {
        return !!(service.currentUser && service.currentUser.role === 'admin');
      },

      // Does the current user have editor privileges?
      isEditor: function() {
        return !!(service.currentUser && service.currentUser.role === 'editor' || service.currentUser && service.currentUser.role === 'admin');
      },

      // Is the current user an editor?
      isCurator: function() {
        return !!(service.currentUser && (service.currentUser.role === 'curator'));
      }
    };

    return service;
  }
})();
<|endoftext|>


<commit_before>import React from 'react'

import { translate } from 'react-i18next'

const MainSkills = ({ t }) => (

        {t('progLang')} /

        {t('platforms')}

            JavaScript ({t('incl')} ES 20XX) ({t('9years')})

TypeScript ({t('couple of months')})

Node.js ({t('3years')})

Go ({t('xmonths')})

Python ({t('3years')})

UNIX shell scripting ({t('4years')})

Frameworks

qooxdoo (JS - {t('formerCoreTeam')})

Django (Python)

Flask (Python)

Libraries

React,

React Native,

React Router,

Redux,

Redux Form,

Redux-Saga

{t('databases')}

Redis,

MongoDB,

MySQL,

SQLite

          {/*
RethinkDB
 */}
          {/*
Realm
 */}

Server

nginx

          {/*
traefik
 */}

)

export default translate('skills')(MainSkills)
<commit_msg>minor fix<commit_after>import React from 'react'

import { translate } from 'react-i18next'

const MainSkills = ({ t }) => (

        {t('progLang')} /

        {t('platforms')}

            JavaScript ({t('incl')} ES 20XX) ({t('9years')})

TypeScript ({t('months')})

Node.js ({t('3years')})

Go ({t('xmonths')})

Python ({t('3years')})

UNIX shell scripting ({t('4years')})

Frameworks

qooxdoo (JS - {t('formerCoreTeam')})

Django (Python)

Flask (Python)

Libraries

React,

React Native,

React Router,

Redux,

Redux Form,

Redux-Saga

{t('databases')}

Redis,

MongoDB,

MySQL,

SQLite

          {/*
RethinkDB
 */}
          {/*
Realm
 */}

Server

nginx

          {/*
traefik
 */}

)

export default translate('skills')(MainSkills)
<|endoftext|>


<commit_before>/**
 * @ngdoc module
 * @name material.components.truncate
 */
angular.module('material.components.truncate', ['material.core'])
  .directive('mdTruncate', MdTruncateDirective);

/**
 * @ngdoc directive
 * @name mdTruncate
 * @module material.components.truncate
 * @restrict AE
 * @description
 *
 * The `md-truncate` component displays a label that will automatically clip text which is wider
 * than the component. By default, it displays an ellipsis, but you may apply the `md-clip` CSS
 * class to override this default and use a standard "clipping" approach.
 *
 * Note: The `md-truncate` component does not automatically adjust it's width. You must
 * provide the `flex` attribute, or some other CSS-based width management. See the
 * demos for examples.
 *
 * @usage
 *
 * ### As an Element
 *
 * <hljs lang="html">
 *

 *     <md-button>Back</md-button>
 *
 *     <md-truncate flex>Chapter 1 - The Way of the Old West</md-truncate>
 *
 *     <md-button>Forward</md-button>
 *

 * </hljs>
 *
 * ### As an Attribute
 *
 * <hljs lang="html">
 *
Some Title With a Lot of Text

 * </hljs>
 *
 * ## CSS & Styles
 *
 * `<md-truncate>` provides two CSS classes that you may use to control the type of clipping.
 *
 * Note: The `md-truncate` also applies a setting of `width: 0;` when used with the `flex`
 * attribute to fix an issue with the flex element not shrinking properly.
 *
 *

 * <docs-css-api-table>
 *
 *   <docs-css-selector code=".md-ellipsis">
 *     Assigns the "ellipsis" behavior (default) which will cut off mid-word and append an ellipsis
 *     (…) to the end of the text.
 *   </docs-css-selector>
 *
 *   <docs-css-selector code=".md-clip">
 *     Assigns the "clipping" behavior which will simply chop off the text. This may happen
 *     mid-word or even mid-character.
 *   </docs-css-selector>
 *
 * </docs-css-api-table>
 *

 */
function MdTruncateDirective() {
  return {
    restrict: 'AE',

    controller: MdTruncateController,
    controllerAs: '$ctrl',
    bindToController: true
  }
}

/**
 * Controller for the <md-truncate> component.
 *
 * @param $element The md-truncate element.
 *
 * @constructor
 * @ngInject
 */
function MdTruncateController($element) {
  $element.addClass('md-truncate');
}
<commit_msg>fix(truncate): remove controllerAs and bindToController directive attributes (#10798)<commit_after>/**
 * @ngdoc module
 * @name material.components.truncate
 */
angular.module('material.components.truncate', ['material.core'])
  .directive('mdTruncate', MdTruncateDirective);

/**
 * @ngdoc directive
 * @name mdTruncate
 * @module material.components.truncate
 * @restrict AE
 * @description
 *
 * The `md-truncate` component displays a label that will automatically clip text which is wider
 * than the component. By default, it displays an ellipsis, but you may apply the `md-clip` CSS
 * class to override this default and use a standard "clipping" approach.
 *
 * Note: The `md-truncate` component does not automatically adjust it's width. You must
 * provide the `flex` attribute, or some other CSS-based width management. See the
 * demos for examples.
 *
 * @usage
 *
 * ### As an Element
 *
 * <hljs lang="html">
 *

 *     <md-button>Back</md-button>
 *
 *     <md-truncate flex>Chapter 1 - The Way of the Old West</md-truncate>
 *
 *     <md-button>Forward</md-button>
 *

 * </hljs>
 *
 * ### As an Attribute
 *
 * <hljs lang="html">
 *
Some Title With a Lot of Text

 * </hljs>
 *
 * ## CSS & Styles
 *
 * `<md-truncate>` provides two CSS classes that you may use to control the type of clipping.
 *
 * Note: The `md-truncate` also applies a setting of `width: 0;` when used with the `flex`
 * attribute to fix an issue with the flex element not shrinking properly.
 *
 *

 * <docs-css-api-table>
 *
 *   <docs-css-selector code=".md-ellipsis">
 *     Assigns the "ellipsis" behavior (default) which will cut off mid-word and append an ellipsis
 *     (…) to the end of the text.
 *   </docs-css-selector>
 *
 *   <docs-css-selector code=".md-clip">
 *     Assigns the "clipping" behavior which will simply chop off the text. This may happen
 *     mid-word or even mid-character.
 *   </docs-css-selector>
 *
 * </docs-css-api-table>
 *

 */
function MdTruncateDirective() {
  return {
    restrict: 'AE',

    controller: MdTruncateController
  }
}

/**
 * Controller for the <md-truncate> component.
 *
 * @param $element The md-truncate element.
 *
 * @constructor
 * @ngInject
 */
function MdTruncateController($element) {
  $element.addClass('md-truncate');
}
<|endoftext|>


<commit_before>/**
 * Created by Mihail on 1/7/2017.
 */
import React, { Component } from 'react';
import { flickrImages, shutterStockVideos } from '../API/api';

// MediaGalleryPage Component
class MediaGalleryPage extends Component {

	// We want to get images and videos from the API right after our component renders.
	componentDidMount() {
		flickrImages('rain').then(images => console.log(images, 'Images'));
		shutterStockVideos('rain').then(videos => console.log(videos, 'Videos'));
	}

	render() {
		// TODO: Render videos and images here
		return (

)
	}
}

export default MediaGalleryPage;<commit_msg>Connected MediaGalleryPage react component to use the store.<commit_after>/**
 * Created by Mihail on 1/7/2017.
 */
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { searchMediaAction } from '../actions/mediaActions';

// MediaGalleryPage Component
class MediaGalleryPage extends Component {

	// Dispatches *searchMediaAction*  immediately after initial rendering.
	// Note that we are using the dispatch method from the store to execute this task, courtesy of react-redux
	componentDidMount() {
		this.props.dispatch(searchMediaAction('rain'));
	}

	render() {
		console.log(this.props.images, 'Images');
		console.log(this.props.videos, 'Videos');
		console.log(this.props.selecteImage, 'SelectedImage');
		console.log(this.props.selectedVideo, 'SelectedVideo');
		return (

)
	}
}

// Define PropTypes
MediaGalleryPage.propTypes = {
// Define your PropTypes here
};

// Subscribe component to redux store and merge the state into
// component's props
const mapStateToProps = ({ images, videos }) => ({
	images: images[0],
	selectedImage: images.selectedImage,
	videos: videos[0],
	selectedVideo: videos.selectedVideo
});

// connect method from react-router connects the component with redux store
export default connect(mapStateToProps)(MediaGalleryPage);<|endoftext|>


<commit_before><commit_msg>refactor: delete empty file<commit_after><|endoftext|>


<commit_before>var reportController = (function(){

	chrome.runtime.onMessage.addListener(function(request) {
	  if (request.method === 'resize') {
	   	var values = request.colSizes.split(',');
	   	createReport(values.length, values);
	  }
	});

	var createReport = function(columns, valuesArray){
		var output = '';

		if(valuesArray){
			for(var i = 0; i <= columns; i++){
				if(valuesArray[i]){
					output = output + '
' + (i + 1) + '	' + valuesArray[i] + 'px
';
				}
			}
		}

		document.getElementById('report').innerHTML = output;
	}

	var calculateReport = function(tabId){
		chrome.tabs.query({ currentWindow: true, active: true }, function (tabs) {
			chrome.tabs.sendMessage(tabs[0].id, {method: "fireCalc", tabId: tabs[0].id});
		});
	}

	return {
		createReport:createReport,
		calculateReport:calculateReport
	}
})();<commit_msg>Adding comments to reportController.js<commit_after>var reportController = (function(){

	/**
	 * Listens for the event that adds the report to popup
	 */
	chrome.runtime.onMessage.addListener(function(request) {
	  if (request.method === 'resize') {
	   	var values = request.colSizes.split(',');
	   	createReport(values.length, values);
	  }
	});

	/**
	 * Creates the report
	 *
	 * @param {int} columns - The numbers of columns of the grid
	 * @param {Array} valuesArray - the array of values for the table
	 */
	var createReport = function(columns, valuesArray){
		var output = '';

		if(valuesArray){
			for(var i = 0; i <= columns; i++){
				if(valuesArray[i]){
					output = output + '
' + (i + 1) + '	' + valuesArray[i] + 'px
';
				}
			}
		}

		document.getElementById('report').innerHTML = output;
	}

	/**
	 * Sends a message to get the column pixel widths
	 *
	 * @param {int} tabId - The id of the current tab
	 */
	var calculateReport = function(tabId){
		chrome.tabs.query({ currentWindow: true, active: true }, function (tabs) {
			chrome.tabs.sendMessage(tabs[0].id, {method: "fireCalc", tabId: tabs[0].id});
		});
	}

	/**
	 * Publicly accessible methods
	 */
	return {
		createReport:createReport,
		calculateReport:calculateReport
	}
})();<|endoftext|>


<commit_before>import PropTypes from 'prop-types';
import React from 'react';
import { injectIntl, FormattedMessage } from 'react-intl';
import { Row, Col } from 'react-flexbox-grid/lib';
import DataCard from '../../../common/DataCard';
import StorySentencePreview from '../../../common/StorySentencePreview';
import OrderedWordCloud from '../../../vis/OrderedWordCloud';
import { CloseButton } from '../../../common/IconButton';
import messages from '../../../../resources/messages';

const localMessages = {
  attention: { id: 'explorer.results.attention.title', defaultMessage: 'Attention' },
  language: { id: 'explorer.results.language.title', defaultMessage: 'Language' },
  people: { id: 'explorer.results.people.title', defaultMessage: 'People & Places' },
  detailsSingular: { id: 'explorer.attention.drillDown.details', defaultMessage: 'Details for {date1}' },
  detailsRange: { id: 'explorer.attention.drillDown.details', defaultMessage: 'Details for {date1} to {date2}' },
  sampleStories: { id: 'explorer.attention.drillDown.sampleStories', defaultMessage: 'Sample Stories' },
  topWords: { id: 'explorer.attention.drillDown.topWords', defaultMessage: 'Top Words' },
};

const QueryAttentionOverTimeDrillDownDataCard = (props) => {
  const { stories, words, info, onClose } = props;
  const { formatMessage } = props.intl;
  const date1 = info ? info.start_date : '';
  const date2 = info ? info.end_date : '';
  const color = info ? info.color : '';
  const hexToRGBArray = clr => clr.match(/[A-Za-z0-9]{2}/g).map(v => parseInt(v, 16));
  const rgbColor = color ? hexToRGBArray(color) : '#000000';
  const dateTitle = info.dayGap ?
<FormattedMessage {...localMessages.detailsSingular} values={{ date1 }} />
 :
<FormattedMessage {...localMessages.detailsRange} values={{ date1, date2 }} />
;
  return (
    <DataCard>
      <Row>
        <Col lg={12}>
          <CloseButton
            onClick={onClose}
            tooltip={formatMessage(messages.close)}
            backgroundColor="#000000"
          />
          {dateTitle}
        </Col>
      </Row>
      <Row>
        <Col lg={6}>

<FormattedMessage {...localMessages.sampleStories} />

          <StorySentencePreview sentences={stories.slice(0, 8)} />
        </Col>
        <Col lg={6}>

<FormattedMessage {...localMessages.topWords} />

          <OrderedWordCloud words={words} textColor={`rgb(${rgbColor[0]}, ${rgbColor[1]}, ${rgbColor[2]})`} />
        </Col>
      </Row>
    </DataCard>
  );
};

QueryAttentionOverTimeDrillDownDataCard.propTypes = {
  // from parent
  stories: PropTypes.array,
  words: PropTypes.array,
  info: PropTypes.object,
  queries: PropTypes.array,
  onClose: PropTypes.func.isRequired,
  // from compositional chain
  intl: PropTypes.object.isRequired,
};

export default
  injectIntl(
    QueryAttentionOverTimeDrillDownDataCard
  );
<commit_msg>Remove unused localMessages<commit_after>import PropTypes from 'prop-types';
import React from 'react';
import { injectIntl, FormattedMessage } from 'react-intl';
import { Row, Col } from 'react-flexbox-grid/lib';
import DataCard from '../../../common/DataCard';
import StorySentencePreview from '../../../common/StorySentencePreview';
import OrderedWordCloud from '../../../vis/OrderedWordCloud';
import { CloseButton } from '../../../common/IconButton';
import messages from '../../../../resources/messages';

const localMessages = {
  detailsSingular: { id: 'explorer.attention.drillDown.details', defaultMessage: 'Details for {date1}' },
  detailsRange: { id: 'explorer.attention.drillDown.details', defaultMessage: 'Details for {date1} to {date2}' },
  sampleStories: { id: 'explorer.attention.drillDown.sampleStories', defaultMessage: 'Sample Stories' },
  topWords: { id: 'explorer.attention.drillDown.topWords', defaultMessage: 'Top Words' },
};

const QueryAttentionOverTimeDrillDownDataCard = (props) => {
  const { stories, words, info, onClose } = props;
  const { formatMessage } = props.intl;
  const date1 = info ? info.start_date : '';
  const date2 = info ? info.end_date : '';
  const color = info ? info.color : '';
  const hexToRGBArray = clr => clr.match(/[A-Za-z0-9]{2}/g).map(v => parseInt(v, 16));
  const rgbColor = color ? hexToRGBArray(color) : '#000000';
  const dateTitle = info.dayGap ?
<FormattedMessage {...localMessages.detailsSingular} values={{ date1 }} />
 :
<FormattedMessage {...localMessages.detailsRange} values={{ date1, date2 }} />
;
  return (
    <DataCard>
      <Row>
        <Col lg={12}>
          <CloseButton
            onClick={onClose}
            tooltip={formatMessage(messages.close)}
            backgroundColor="#000000"
          />
          {dateTitle}
        </Col>
      </Row>
      <Row>
        <Col lg={6}>

<FormattedMessage {...localMessages.sampleStories} />

          <StorySentencePreview sentences={stories.slice(0, 8)} />
        </Col>
        <Col lg={6}>

<FormattedMessage {...localMessages.topWords} />

          <OrderedWordCloud words={words} textColor={`rgb(${rgbColor[0]}, ${rgbColor[1]}, ${rgbColor[2]})`} />
        </Col>
      </Row>
    </DataCard>
  );
};

QueryAttentionOverTimeDrillDownDataCard.propTypes = {
  // from parent
  stories: PropTypes.array,
  words: PropTypes.array,
  info: PropTypes.object,
  queries: PropTypes.array,
  onClose: PropTypes.func.isRequired,
  // from compositional chain
  intl: PropTypes.object.isRequired,
};

export default
  injectIntl(
    QueryAttentionOverTimeDrillDownDataCard
  );
<|endoftext|>


<commit_before>// PLUGIN: OPENMAP
( function ( Popcorn ) {

  /**
   * openmap popcorn plug-in
   * Adds an OpenLayers map and open map tiles (OpenStreetMap [default], NASA WorldWind, or USGS Topographic)
   * Based on the googlemap popcorn plug-in. No StreetView support
   * Options parameter will need a start, end, target, type, zoom, lat and lng
   * -Start is the time that you want this plug-in to execute
   * -End is the time that you want this plug-in to stop executing
   * -Target is the id of the DOM element that you want the map to appear in. This element must be in the DOM
   * -Type [optional] either: ROADMAP (OpenStreetMap), SATELLITE (NASA WorldWind / LandSat), or TERRAIN (USGS).  ROADMAP/OpenStreetMap is the default.
   * -Zoom [optional] defaults to 2
   * -Lat and Lng are the coordinates of the map if location is not named
   * -Location is a name of a place to center the map, geocoded to coordinates using TinyGeocoder.com
   * -Markers [optional] is an array of map marker objects, with the following properties:
   * --Icon is the URL of a map marker image
   * --Size [optional] is the radius in pixels of the scaled marker image (default is 14)
   * --Text [optional] is the HTML content of the map marker -- if your popcorn instance is named 'popped', use <script>popped.currentTime(10);</script> to control the video
   * --Lat and Lng are coordinates of the map marker if location is not specified
   * --Location is a name of a place for the map marker, geocoded to coordinates using TinyGeocoder.com
   *  Note: using location requires extra loading time, also not specifying both lat/lng and location will
   * cause a JavaScript error.
   * @param {Object} options
   *
   * Example:
     var p = Popcorn( '#video' )
        .openmap({
          start: 5,
          end: 15,
          type: 'ROADMAP',
          target: 'map',
          lat: 43.665429,
          lng: -79.403323
        } )
   *
   */
  var newdiv,
      i = 1,
      _mapFired = false,
      _mapLoaded = false;

  // insert openlayers api script once
  if ( !_mapFired ) {
    _mapFired = true;
    Popcorn.getScript( "http://openlayers.org/api/OpenLayers.js",
    function() {
      _mapLoaded = true;
    });
  }

  function toggle( container, display ) {
    if ( container.map ) {

      container.map.div.style.display = display;
      return;
    }

    setTimeout(function() {
      toggle( container, display );
    }, 10 );
  }

  Popcorn.plugin( "openmap" , function( options ){
    var newdiv,
        centerlonlat,
        projection,
        displayProjection,
        pointLayer,
        selectControl,
        popup,
        isGeoReady;

    // create a new div within the target div
    // this is later passed on to the maps api
    newdiv               = document.createElement( 'div' );
    newdiv.id            = "openmapdiv" + i;
    newdiv.style.width   = "100%";
    newdiv.style.height  = "100%";
    i++;

    document.getElementById( options.target ) && document.getElementById( options.target ).appendChild( newdiv );

    // callback function fires when the script is run
    isGeoReady = function() {
      if ( !_mapLoaded ) {
        setTimeout( function () {
          isGeoReady();
        }, 50);
      } else {
        if( options.location ){
          // set a dummy center at start
          location = new OpenLayers.LonLat( 0, 0 );
          // query TinyGeocoder and re-center in callback
          Popcorn.getJSONP(
            "http://tinygeocoder.com/create-api.php?q=" + options.location + "&callback=jsonp",
            function( latlng ) {
              centerlonlat = new OpenLayers.LonLat( latlng[1], latlng[0] );
              options.map.setCenter( centerlonlat );
            }
          );
        } else {
          centerlonlat = new OpenLayers.LonLat( options.lng, options.lat );
        }
        options.type = options.type || "ROADMAP";
        if( options.type === "SATELLITE" ) {
          // add NASA WorldWind / LANDSAT map
          options.map = new OpenLayers.Map( { div: newdiv, "maxResolution": 0.28125, tileSize: new OpenLayers.Size( 512, 512 ) } );
          var worldwind = new OpenLayers.Layer.WorldWind( "LANDSAT", "http://worldwind25.arc.nasa.gov/tile/tile.aspx", 2.25, 4, { T: "105" } );
          options.map.addLayer( worldwind );
          displayProjection = new OpenLayers.Projection( "EPSG:4326" );
          projection = new OpenLayers.Projection( "EPSG:4326" );
        }
        else if( options.type === "TERRAIN" ) {
          // add terrain map ( USGS )
          displayProjection = new OpenLayers.Projection( "EPSG:4326" );
          projection = new OpenLayers.Projection( "EPSG:4326" );
          options.map = new OpenLayers.Map( {div: newdiv, projection: projection } );
          var relief = new OpenLayers.Layer.WMS( "USGS Terraserver", "http://terraserver-usa.org/ogcmap.ashx?", { layers: 'DRG' } );
          options.map.addLayer( relief );
        }
        else {
          // add OpenStreetMap layer
          projection = new OpenLayers.Projection( 'EPSG:900913' );
          displayProjection = new OpenLayers.Projection( 'EPSG:4326' );
          centerlonlat = centerlonlat.transform( displayProjection, projection );
          options.map = new OpenLayers.Map( { div: newdiv, projection: projection, "displayProjection": displayProjection } );
          var osm = new OpenLayers.Layer.OSM();
          options.map.addLayer( osm );
        }
        if( options.map ) {
          options.map.div.style.display = "none";
        }
      }
    };

    isGeoReady();

    return {

      /**
       * @member openmap
       * The setup function will be executed when the plug-in is instantiated
       */
      _setup: function( options ) {

        var isReady = function () {
          // wait until OpenLayers has been loaded, and the start function is run, before adding map
          if ( !options.map ) {
            setTimeout( function () {
              isReady();
            }, 13 );
          } else {

            // default zoom is 2
            options.zoom = options.zoom || 2;

            // make sure options.zoom is a number
            if ( options.zoom && typeof options.zoom !== "number" ) {
              options.zoom = +options.zoom;
            }

            // reset the location and zoom just in case the user played with the map
            options.map.setCenter( centerlonlat, options.zoom );
            if( options.markers ){
              var layerStyle = OpenLayers.Util.extend( {} , OpenLayers.Feature.Vector.style[ 'default' ] ),
                  featureSelected = function( clickInfo ) {
                    clickedFeature = clickInfo.feature;
                    if( !clickedFeature.attributes.text ){
                      return;
                    }
                    popup = new OpenLayers.Popup.FramedCloud(
                      "featurePopup",
                      clickedFeature.geometry.getBounds().getCenterLonLat(),
                      new OpenLayers.Size( 120, 250 ),
                      clickedFeature.attributes.text,
                      null,
                      true,
                      function( closeInfo ) {
                        selectControl.unselect( this.feature );
                      }
                    );
                    clickedFeature.popup = popup;
                    popup.feature = clickedFeature;
                    options.map.addPopup( popup );
                  },
                  featureUnSelected = function( clickInfo ) {
                    feature = clickInfo.feature;
                    if ( feature.popup ) {
                      popup.feature = null;
                      options.map.removePopup( feature.popup );
                      feature.popup.destroy();
                      feature.popup = null;
                    }
                  },
                  gcThenPlotMarker = function( myMarker ){
                    Popcorn.getJSONP(
                      "http://tinygeocoder.com/create-api.php?q=" + myMarker.location + "&callback=jsonp",
                      function( latlng ){
                        var myPoint = new OpenLayers.Geometry.Point( latlng[1], latlng[0] ).transform( displayProjection, projection ),
                            myPointStyle = OpenLayers.Util.extend( {}, layerStyle );
                        if( !myMarker.size || isNaN( myMarker.size ) ) {
                          myMarker.size = 14;
                        }
                        myPointStyle.pointRadius = myMarker.size;
                        myPointStyle.graphicOpacity = 1;
                        myPointStyle.externalGraphic = myMarker.icon;
                        var myPointFeature = new OpenLayers.Feature.Vector( myPoint, null, myPointStyle );
                        if( myMarker.text ) {
                          myPointFeature.attributes = {
                            text: myMarker.text
                          };
                        }
                        pointLayer.addFeatures( [ myPointFeature ] );
                      }
                    );
                  };
              pointLayer = new OpenLayers.Layer.Vector( "Point Layer", { style: layerStyle } );
              options.map.addLayer( pointLayer );
              for( var m = 0; m < options.markers.length; m++ ) {
                var myMarker = options.markers[ m ];
                if( myMarker.text ){
                  if( !selectControl ){
                    selectControl = new OpenLayers.Control.SelectFeature( pointLayer );
                    options.map.addControl( selectControl );
                    selectControl.activate();
                    pointLayer.events.on( {
                      "featureselected": featureSelected,
                      "featureunselected": featureUnSelected
                    } );
                  }
                }
                if( myMarker.location ){
                  var geocodeThenPlotMarker = gcThenPlotMarker;
                  geocodeThenPlotMarker(myMarker);
                } else {
                  var myPoint = new OpenLayers.Geometry.Point( myMarker.lng, myMarker.lat ).transform( displayProjection, projection ),
                      myPointStyle = OpenLayers.Util.extend( {}, layerStyle );
                  if( !myMarker.size || isNaN( myMarker.size ) ) {
                    myMarker.size = 14;
                  }
                  myPointStyle.pointRadius = myMarker.size;
                  myPointStyle.graphicOpacity = 1;
                  myPointStyle.externalGraphic = myMarker.icon;
                  var myPointFeature = new OpenLayers.Feature.Vector( myPoint, null, myPointStyle );
                  if( myMarker.text ) {
                    myPointFeature.attributes = {
                      text: myMarker.text
                    };
                  }
                  pointLayer.addFeatures( [ myPointFeature ] );
                }
              }
            }
          }
        };

        isReady();
      },

      /**
       * @member openmap
       * The start function will be executed when the currentTime
       * of the video  reaches the start time provided by the
       * options variable
       */
      start: function( event, options ) {
        toggle( options, "block" );
      },

      /**
       * @member openmap
       * The end function will be executed when the currentTime
       * of the video reaches the end time provided by the
       * options variable
       */
      end: function( event, options ) {
          toggle( options, "none" );
      },

      _teardown: function( options ) {

        document.getElementById( options.target ) && document.getElementById( options.target ).removeChild( newdiv );
        newdiv = map = centerlonlat = projection = displayProjection = pointLayer = selectControl = popup = null;
      }
    };
  },
  {
    about:{
      name: "Popcorn OpenMap Plugin",
      version: "0.3",
      author: "@mapmeld",
      website: "mapadelsur.blogspot.com"
    },
    options:{
      start    : { elem: 'input', type: 'text', label: 'In'},
      end      : { elem: 'input', type: 'text', label: 'Out'},
      target   : 'map-container',
      type     : { elem: 'select', options:[ 'ROADMAP', 'SATELLITE', 'TERRAIN' ], label: 'Type' },
      zoom     : { elem: 'input', type: 'text', label: 'Zoom'},
      lat      : { elem: 'input', type: 'text', label: 'Lat'},
      lng      : { elem: 'input', type: 'text', label: 'Lng'},
      location : { elem: 'input', type: 'text', label: 'Location'},
      markers  : { elem: 'input', type: 'text', label: 'List Markers'}
    }
  } );
} ) ( Popcorn );
<commit_msg>fixed style issues. cached options.target, cached length in a for loop, lots of style fixes<commit_after>// PLUGIN: OPENMAP
( function ( Popcorn ) {

  /**
   * openmap popcorn plug-in
   * Adds an OpenLayers map and open map tiles (OpenStreetMap [default], NASA WorldWind, or USGS Topographic)
   * Based on the googlemap popcorn plug-in. No StreetView support
   * Options parameter will need a start, end, target, type, zoom, lat and lng
   * -Start is the time that you want this plug-in to execute
   * -End is the time that you want this plug-in to stop executing
   * -Target is the id of the DOM element that you want the map to appear in. This element must be in the DOM
   * -Type [optional] either: ROADMAP (OpenStreetMap), SATELLITE (NASA WorldWind / LandSat), or TERRAIN (USGS).  ROADMAP/OpenStreetMap is the default.
   * -Zoom [optional] defaults to 2
   * -Lat and Lng are the coordinates of the map if location is not named
   * -Location is a name of a place to center the map, geocoded to coordinates using TinyGeocoder.com
   * -Markers [optional] is an array of map marker objects, with the following properties:
   * --Icon is the URL of a map marker image
   * --Size [optional] is the radius in pixels of the scaled marker image (default is 14)
   * --Text [optional] is the HTML content of the map marker -- if your popcorn instance is named 'popped', use <script>popped.currentTime(10);</script> to control the video
   * --Lat and Lng are coordinates of the map marker if location is not specified
   * --Location is a name of a place for the map marker, geocoded to coordinates using TinyGeocoder.com
   *  Note: using location requires extra loading time, also not specifying both lat/lng and location will
   * cause a JavaScript error.
   * @param {Object} options
   *
   * Example:
     var p = Popcorn( '#video' )
        .openmap({
          start: 5,
          end: 15,
          type: 'ROADMAP',
          target: 'map',
          lat: 43.665429,
          lng: -79.403323
        })
   *
   */
  var newdiv,
      i = 1;

  // insert openlayers api script once
  if ( !window.OpenLayers ) {
    Popcorn.getScript( "http://openlayers.org/api/OpenLayers.js", function() {});
  }

  function toggle( container, display ) {
    if ( container.map ) {

      container.map.div.style.display = display;
      return;
    }

    setTimeout(function() {
      toggle( container, display );
    }, 10 );
  }

  Popcorn.plugin( "openmap", function( options ){
    var newdiv,
        centerlonlat,
        projection,
        displayProjection,
        pointLayer,
        selectControl,
        popup,
        isGeoReady,
        target;

    target = document.getElementById( options.target );

    // create a new div within the target div
    // this is later passed on to the maps api
    newdiv = document.createElement( "div" );
    newdiv.id = "openmapdiv" + i;
    newdiv.style.width = "100%";
    newdiv.style.height = "100%";
    i++;

    target && target.appendChild( newdiv );

    // callback function fires when the script is run
    isGeoReady = function() {
      if ( !window.OpenLayers ) {
        setTimeout(function() {
          isGeoReady();
        }, 50);
      } else {
        if ( options.location ) {
          // set a dummy center at start
          location = new OpenLayers.LonLat( 0, 0 );
          // query TinyGeocoder and re-center in callback
          Popcorn.getJSONP(
            "http://tinygeocoder.com/create-api.php?q=" + options.location + "&callback=jsonp",
            function( latlng ) {
              centerlonlat = new OpenLayers.LonLat( latlng[1], latlng[0] );
              options.map.setCenter( centerlonlat );
            }
          );
        } else {
          centerlonlat = new OpenLayers.LonLat( options.lng, options.lat );
        }
        options.type = options.type || "ROADMAP";
        if ( options.type === "SATELLITE" ) {
          // add NASA WorldWind / LANDSAT map
          options.map = new OpenLayers.Map( { div: newdiv, "maxResolution": 0.28125, tileSize: new OpenLayers.Size( 512, 512 ) } );
          var worldwind = new OpenLayers.Layer.WorldWind( "LANDSAT", "http://worldwind25.arc.nasa.gov/tile/tile.aspx", 2.25, 4, { T: "105" } );
          options.map.addLayer( worldwind );
          displayProjection = new OpenLayers.Projection( "EPSG:4326" );
          projection = new OpenLayers.Projection( "EPSG:4326" );
        }
        else if ( options.type === "TERRAIN" ) {
          // add terrain map ( USGS )
          displayProjection = new OpenLayers.Projection( "EPSG:4326" );
          projection = new OpenLayers.Projection( "EPSG:4326" );
          options.map = new OpenLayers.Map( {div: newdiv, projection: projection } );
          var relief = new OpenLayers.Layer.WMS( "USGS Terraserver", "http://terraserver-usa.org/ogcmap.ashx?", { layers: 'DRG' } );
          options.map.addLayer( relief );
        } else {
          // add OpenStreetMap layer
          projection = new OpenLayers.Projection( 'EPSG:900913' );
          displayProjection = new OpenLayers.Projection( 'EPSG:4326' );
          centerlonlat = centerlonlat.transform( displayProjection, projection );
          options.map = new OpenLayers.Map( { div: newdiv, projection: projection, "displayProjection": displayProjection } );
          var osm = new OpenLayers.Layer.OSM();
          options.map.addLayer( osm );
        }
        if ( options.map ) {
          options.map.div.style.display = "none";
        }
      }
    };

    isGeoReady();

    return {

      /**
       * @member openmap
       * The setup function will be executed when the plug-in is instantiated
       */
      _setup: function( options ) {

        var isReady = function() {
          // wait until OpenLayers has been loaded, and the start function is run, before adding map
          if ( !options.map ) {
            setTimeout(function() {
              isReady();
            }, 13 );
          } else {

            // default zoom is 2
            options.zoom = options.zoom || 2;

            // make sure options.zoom is a number
            if ( options.zoom && typeof options.zoom !== "number" ) {
              options.zoom = +options.zoom;
            }

            // reset the location and zoom just in case the user played with the map
            options.map.setCenter( centerlonlat, options.zoom );
            if ( options.markers ) {
              var layerStyle = OpenLayers.Util.extend( {} , OpenLayers.Feature.Vector.style[ 'default' ] ),
                  featureSelected = function( clickInfo ) {
                    clickedFeature = clickInfo.feature;
                    if ( !clickedFeature.attributes.text ) {
                      return;
                    }
                    popup = new OpenLayers.Popup.FramedCloud(
                      "featurePopup",
                      clickedFeature.geometry.getBounds().getCenterLonLat(),
                      new OpenLayers.Size( 120, 250 ),
                      clickedFeature.attributes.text,
                      null,
                      true,
                      function( closeInfo ) {
                        selectControl.unselect( this.feature );
                      }
                    );
                    clickedFeature.popup = popup;
                    popup.feature = clickedFeature;
                    options.map.addPopup( popup );
                  },
                  featureUnSelected = function( clickInfo ) {
                    feature = clickInfo.feature;
                    if ( feature.popup ) {
                      popup.feature = null;
                      options.map.removePopup( feature.popup );
                      feature.popup.destroy();
                      feature.popup = null;
                    }
                  },
                  gcThenPlotMarker = function( myMarker ) {
                    Popcorn.getJSONP(
                      "http://tinygeocoder.com/create-api.php?q=" + myMarker.location + "&callback=jsonp",
                      function( latlng ) {
                        var myPoint = new OpenLayers.Geometry.Point( latlng[1], latlng[0] ).transform( displayProjection, projection ),
                            myPointStyle = OpenLayers.Util.extend( {}, layerStyle );
                        if ( !myMarker.size || isNaN( myMarker.size ) ) {
                          myMarker.size = 14;
                        }
                        myPointStyle.pointRadius = myMarker.size;
                        myPointStyle.graphicOpacity = 1;
                        myPointStyle.externalGraphic = myMarker.icon;
                        var myPointFeature = new OpenLayers.Feature.Vector( myPoint, null, myPointStyle );
                        if ( myMarker.text ) {
                          myPointFeature.attributes = {
                            text: myMarker.text
                          };
                        }
                        pointLayer.addFeatures( [ myPointFeature ] );
                      }
                    );
                  };
              pointLayer = new OpenLayers.Layer.Vector( "Point Layer", { style: layerStyle } );
              options.map.addLayer( pointLayer );
              for ( var m = 0, l = options.markers.length; m < l ; m++ ) {
                var myMarker = options.markers[ m ];
                if( myMarker.text ){
                  if( !selectControl ){
                    selectControl = new OpenLayers.Control.SelectFeature( pointLayer );
                    options.map.addControl( selectControl );
                    selectControl.activate();
                    pointLayer.events.on({
                      "featureselected": featureSelected,
                      "featureunselected": featureUnSelected
                    });
                  }
                }
                if ( myMarker.location ) {
                  var geocodeThenPlotMarker = gcThenPlotMarker;
                  geocodeThenPlotMarker(myMarker);
                } else {
                  var myPoint = new OpenLayers.Geometry.Point( myMarker.lng, myMarker.lat ).transform( displayProjection, projection ),
                      myPointStyle = OpenLayers.Util.extend( {}, layerStyle );
                  if ( !myMarker.size || isNaN( myMarker.size ) ) {
                    myMarker.size = 14;
                  }
                  myPointStyle.pointRadius = myMarker.size;
                  myPointStyle.graphicOpacity = 1;
                  myPointStyle.externalGraphic = myMarker.icon;
                  var myPointFeature = new OpenLayers.Feature.Vector( myPoint, null, myPointStyle );
                  if ( myMarker.text ) {
                    myPointFeature.attributes = {
                      text: myMarker.text
                    };
                  }
                  pointLayer.addFeatures( [ myPointFeature ] );
                }
              }
            }
          }
        };

        isReady();
      },

      /**
       * @member openmap
       * The start function will be executed when the currentTime
       * of the video  reaches the start time provided by the
       * options variable
       */
      start: function( event, options ) {
        toggle( options, "block" );
      },

      /**
       * @member openmap
       * The end function will be executed when the currentTime
       * of the video reaches the end time provided by the
       * options variable
       */
      end: function( event, options ) {
          toggle( options, "none" );
      },

      _teardown: function( options ) {

        target && target.removeChild( newdiv );
        newdiv = map = centerlonlat = projection = displayProjection = pointLayer = selectControl = popup = null;
      }
    };
  },
  {
    about:{
      name: "Popcorn OpenMap Plugin",
      version: "0.3",
      author: "@mapmeld",
      website: "mapadelsur.blogspot.com"
    },
    options:{
      start    : { elem: 'input', type: 'text', label: 'In'},
      end      : { elem: 'input', type: 'text', label: 'Out'},
      target   : 'map-container',
      type     : { elem: 'select', options:[ 'ROADMAP', 'SATELLITE', 'TERRAIN' ], label: 'Type' },
      zoom     : { elem: 'input', type: 'text', label: 'Zoom'},
      lat      : { elem: 'input', type: 'text', label: 'Lat'},
      lng      : { elem: 'input', type: 'text', label: 'Lng'},
      location : { elem: 'input', type: 'text', label: 'Location'},
      markers  : { elem: 'input', type: 'text', label: 'List Markers'}
    }
  });
}) ( Popcorn );
<|endoftext|>