<commit_before>"use strict";
var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var base_1 = require('./base');
var RDSInstance = (function (_super) {
    __extends(RDSInstance, _super);
    function RDSInstance(infra, physical_id) {
        _super.call(this);
        this.infra = infra;
        this.physical_id = physical_id;
        this.params = {
            physical_id: physical_id,
            id: infra.id,
        };
    }
    RDSInstance.prototype.show = function () {
        var _this = this;
        return this.WrapAndResolveReject(function () {
            return RDSInstance.ajax_infra.show_rds(_this.params);
        });
    };
    RDSInstance.prototype.change_scale = function (type) {
        var _this = this;
        return this.WrapAndResolveReject(function () {
            return RDSInstance.ajax_infra.change_rds_scale(_.merge(_this.params, { instance_type: type }));
        });
    };
    RDSInstance.prototype.gen_serverspec = function (parameter) {
        var _this = this;
        return this.WrapAndResolveReject(function () {
            return RDSInstance.ajax_serverspec.create_for_rds(_.merge({ physical_id: _this.physical_id, infra_id: _this.infra.id }, parameter));
        });
    };
    RDSInstance.prototype.rds_submit_groups = function (group_ids) {
        var _this = this;
        return this.WrapAndResolveReject(function () {
            return RDSInstance.ajax_infra.rds_submit_groups(_.merge(_this.params, { group_ids: group_ids }));
        });
    };
    RDSInstance.prototype.start_rds = function () {
        var _this = this;
        return this.WrapAndResolveReject(function () {
            return RDSInstance.ajax_infra.start_rds(_this.params);
        });
    };
    RDSInstance.prototype.stop_rds = function () {
        var _this = this;
        return this.WrapAndResolveReject(function () {
            return RDSInstance.ajax_infra.stop_rds(_this.params);
        });
    };
    RDSInstance.prototype.reboot_rds = function () {
        var _this = this;
        return this.WrapAndResolveReject(function () {
            return RDSInstance.ajax_infra.reboot_rds(_this.params);
        });
    };
    RDSInstance.ajax_infra = new AjaxSet.Resources('infrastructures');
    RDSInstance.ajax_serverspec = new AjaxSet.Resources('serverspecs');
    return RDSInstance;
}(base_1.default));
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = RDSInstance;
RDSInstance.ajax_infra.add_member('show_rds', 'GET');
RDSInstance.ajax_infra.add_member('change_rds_scale', 'POST');
RDSInstance.ajax_infra.add_member('rds_submit_groups', 'POST');
RDSInstance.ajax_infra.add_member('start_rds', 'POST');
RDSInstance.ajax_infra.add_member('stop_rds', 'POST');
RDSInstance.ajax_infra.add_member('reboot_rds', 'POST');
RDSInstance.ajax_serverspec.add_collection('create_for_rds', 'PUT');
<commit_msg>Update: RDSインスタンスのリファクタリング<commit_after>const ModelBase = require('./base').default;

const RDSInstance = class RDSInstance extends ModelBase {
  constructor(infra, physicalId) {
    super();
    this.infra = infra;
    this.physicalId = physicalId;
    this.params = {
      physical_id: physicalId,
      id: infra.id,
    };
    this.ajax_infra = new AjaxSet.Resources('infrastructures');
    this.ajax_serverspec = new AjaxSet.Resources('serverspecs');
    this.ajax_infra.add_member('show_rds', 'GET');
    this.ajax_infra.add_member('change_rds_scale', 'POST');
    this.ajax_infra.add_member('rds_submit_groups', 'POST');
    this.ajax_infra.add_member('start_rds', 'POST');
    this.ajax_infra.add_member('stop_rds', 'POST');
    this.ajax_infra.add_member('reboot_rds', 'POST');
    this.ajax_serverspec.add_collection('create_for_rds', 'PUT');
  }

  show() {
    const self = this;
    return this.WrapAndResolveReject(
      () => this.ajax_infra.show_rds(self.params),
    );
  }

  change_scale(type) {
    const self = this;
    return this.WrapAndResolveReject(
      () => this.ajax_infra.change_rds_scale(
        Object.entries(self.params, { instance_type: type }),
      ),
    );
  }

  gen_serverspec(parameter) {
    const self = this;
    return this.WrapAndResolveReject(
      () => this.ajax_serverspec.create_for_rds(
        Object.entries({ physical_id: self.physical_id, infra_id: self.infra.id }, parameter),
      ),
    );
  }

  rds_submit_groups(groupIds) {
    const self = this;
    return this.WrapAndResolveReject(
      () => this.ajax_infra.rds_submit_groups(
        Object.entries(self.params, { group_ids: groupIds }),
      ),
    );
  }

  start_rds() {
    const self = this;
    return this.WrapAndResolveReject(
      () => this.ajax_infra.start_rds(self.params),
    );
  }

  stop_rds() {
    const self = this;
    return this.WrapAndResolveReject(
      () => this.ajax_infra.stop_rds(self.params),
    );
  }

  reboot_rds() {
    const self = this;
    return this.WrapAndResolveReject(
      () => this.ajax_infra.reboot_rds(self.params),
    );
  }
};
Object.defineProperty(exports, '__esModule', { value: true });
exports.default = RDSInstance;
<|endoftext|>


<commit_before>import React from 'react';
import lbry from '../lbry.js';
import {Link} from '../component/link.js';
import {Icon} from '../component/common.js';
import Modal from './modal.js';
import FormField from './form.js';
import {ToolTip} from '../component/tooltip.js';
import {DropDownMenu, DropDownMenuItem} from './menu.js';

const {shell} = require('electron');

let WatchLink = React.createClass({
  propTypes: {
    streamName: React.PropTypes.string,
    downloadStarted: React.PropTypes.bool,
  },
  startVideo: function() {
    window.location = '?watch=' + this.props.streamName;
  },
  handleClick: function() {
    this.setState({
      loading: true,
    });

    if (this.props.downloadStarted) {
      this.startVideo();
    } else {
      lbry.getCostInfoForName(this.props.streamName, ({cost}) => {
        lbry.getBalance((balance) => {
          if (cost > balance) {
            this.setState({
              modal: 'notEnoughCredits',
              loading: false,
            });
          } else {
            this.startVideo();
          }
        });
      });
    }
  },
  getInitialState: function() {
    return {
      modal: null,
      loading: false,
    };
  },
  closeModal: function() {
    this.setState({
      modal: null,
    });
  },
  render: function() {
    return (

        <Link button="primary" disabled={this.state.loading} label="Watch" icon="icon-play" onClick={this.handleClick} />
        <Modal contentLabel="Not enough credits" isOpen={this.state.modal == 'notEnoughCredits'} onConfirmed={this.closeModal}>
          You don't have enough LBRY credits to pay for this stream.
        </Modal>

    );
  }
});

let FileActionsRow = React.createClass({
  _isMounted: false,
  _fileInfoSubscribeId: null,

  propTypes: {
    streamName: React.PropTypes.string,
    outpoint: React.PropTypes.string.isRequired,
    metadata: React.PropTypes.oneOfType([React.PropTypes.object, React.PropTypes.string]),
  },
  getInitialState: function() {
    return {
      fileInfo: null,
      modal: null,
      menuOpen: false,
      deleteChecked: false,
      attemptingDownload: false,
      attemptingRemove: false
    }
  },
  onFileInfoUpdate: function(fileInfo) {
    if (this._isMounted) {
      this.setState({
        fileInfo: fileInfo ? fileInfo : false,
        attemptingDownload: fileInfo ? false : this.state.attemptingDownload
      });
    }
  },
  tryDownload: function() {
    this.setState({
      attemptingDownload: true,
      attemptingRemove: false
    });
    lbry.getCostInfoForName(this.props.streamName, ({cost}) => {
      lbry.getBalance((balance) => {
        if (cost > balance) {
          this.setState({
            modal: 'notEnoughCredits',
            attemptingDownload: false,
          });
        } else {
          lbry.getStream(this.props.streamName, (streamInfo) => {
            if (streamInfo === null || typeof streamInfo !== 'object') {
              this.setState({
                modal: 'timedOut',
                attemptingDownload: false,
              });
            }
          });
        }
      });
    });
  },
  closeModal: function() {
    this.setState({
      modal: null,
    })
  },
  onDownloadClick: function() {
    if (!this.state.fileInfo && !this.state.attemptingDownload) {
      this.tryDownload();
    }
  },
  onOpenClick: function() {
    if (this.state.fileInfo && this.state.fileInfo.download_path) {
      shell.openItem(this.state.fileInfo.download_path);
    }
  },
  handleDeleteCheckboxClicked: function(event) {
    this.setState({
      deleteChecked: event.target.checked,
    });
  },
  handleRevealClicked: function() {
    if (this.state.fileInfo && this.state.fileInfo.download_path) {
      shell.showItemInFolder(this.state.fileInfo.download_path);
    }
  },
  handleRemoveClicked: function() {
    this.setState({
      modal: 'confirmRemove',
    });
  },
  handleRemoveConfirmed: function() {
    lbry.removeFile(this.props.outpoint, this.state.deleteChecked);
    this.setState({
      modal: null,
      fileInfo: false,
      attemptingDownload: false
    });
  },
  openMenu: function() {
    this.setState({
      menuOpen: !this.state.menuOpen,
    });
  },
  componentDidMount: function() {
    this._isMounted = true;
    this._fileInfoSubscribeId = lbry.fileInfoSubscribe(this.props.outpoint, this.onFileInfoUpdate);
  },
  componentWillUnmount: function() {
    this._isMounted = false;
    if (this._fileInfoSubscribeId) {
      lbry.fileInfoUnsubscribe(this.props.outpoint, this._fileInfoSubscribeId);
    }
  },
  render: function() {
    if (this.state.fileInfo === null)
    {
      return null;
    }

    const openInFolderMessage = window.navigator.platform.startsWith('Mac') ? 'Open in Finder' : 'Open in Folder',
      showMenu = !!this.state.fileInfo;

    let linkBlock;
    if (this.state.fileInfo === false && !this.state.attemptingDownload) {
      linkBlock = <Link button="text" label="Download" icon="icon-download" onClick={this.onDownloadClick} />;
    } else if (this.state.attemptingDownload || !this.state.fileInfo.completed) {
      const
        progress = this.state.fileInfo ? this.state.fileInfo.written_bytes / this.state.fileInfo.total_bytes * 100 : 0,
        label = this.state.fileInfo ? progress.toFixed(0) + '% complete' : 'Connecting...',
        labelWithIcon = <Icon icon="icon-download" />{label};

      linkBlock = (

{labelWithIcon}

          {labelWithIcon}

      );
    } else {
      linkBlock = <Link label="Open" button="text" icon="icon-folder-open" onClick={this.onOpenClick} />;
    }

    return (

        {this.props.metadata.content_type && this.props.metadata.content_type.startsWith('video/')
          ? <WatchLink streamName={this.props.streamName} downloadStarted={!!this.state.fileInfo} />
          : null}
        {this.state.fileInfo !== null || this.state.fileInfo.isMine
          ? linkBlock
          : null}
        { showMenu ?
          <DropDownMenu>
            <DropDownMenuItem key={0} onClick={this.handleRevealClicked} label={openInFolderMessage} />
            <DropDownMenuItem key={1} onClick={this.handleRemoveClicked} label="Remove..." />
          </DropDownMenu> : '' }
        <Modal isOpen={this.state.modal == 'notEnoughCredits'} contentLabel="Not enough credits"
               onConfirmed={this.closeModal}>
          You don't have enough LBRY credits to pay for this stream.
        </Modal>
        <Modal isOpen={this.state.modal == 'timedOut'} contentLabel="Download failed"
               onConfirmed={this.closeModal}>
          LBRY was unable to download the stream lbry://{this.props.streamName}.
        </Modal>
        <Modal isOpen={this.state.modal == 'confirmRemove'} contentLabel="Not enough credits"
               type="confirm" confirmButtonLabel="Remove" onConfirmed={this.handleRemoveConfirmed}
               onAborted={this.closeModal}>

Are you sure you'd like to remove {this.props.metadata.title} from LBRY?

          <FormField type="checkbox" checked={this.state.deleteChecked} onClick={this.handleDeleteCheckboxClicked} /> Delete this file from my computer
        </Modal>

    );
  }
});

export let FileActions = React.createClass({
  _isMounted: false,
  _fileInfoSubscribeId: null,

  propTypes: {
    streamName: React.PropTypes.string,
    outpoint: React.PropTypes.string.isRequired,
    metadata: React.PropTypes.oneOfType([React.PropTypes.object, React.PropTypes.string]),
  },
  getInitialState: function() {
    return {
      available: true,
      forceShowActions: false,
      fileInfo: null,
    }
  },
  onShowFileActionsRowClicked: function() {
    this.setState({
      forceShowActions: true,
    });
  },
  onFileInfoUpdate: function(fileInfo) {
    if (this.isMounted) {
      this.setState({
        fileInfo: fileInfo,
      });
    }
  },
  componentDidMount: function() {
    this._isMounted = true;
    this._fileInfoSubscribeId = lbry.fileInfoSubscribe(this.props.outpoint, this.onFileInfoUpdate);
    lbry.getStreamAvailability(this.props.streamName, (availability) => {
      if (this._isMounted) {
        this.setState({
          available: availability > 0,
        });
      }
    }, () => {
      // Take any error to mean the file is unavailable
      if (this._isMounted) {
        this.setState({
          available: false,
        });
      }
    });
  },
  componentWillUnmount: function() {
    this._isMounted = false;
    if (this._fileInfoSubscribeId) {
      lbry.fileInfoUnsubscribe(this.props.outpoint, this._fileInfoSubscribeId);
    }
  },
  render: function() {
    const fileInfo = this.state.fileInfo;
    if (fileInfo === null) {
      return null;
    }

    return (

      {
        fileInfo || this.state.available || this.state.forceShowActions
          ? <FileActionsRow outpoint={this.props.outpoint} metadata={this.props.metadata} streamName={this.props.streamName} />
          :

This file is not currently available.

              <ToolTip label="Why?"
                       body="The content on LBRY is hosted by its users. It appears there are no users connected that have this file at the moment."
                       className="button-set-item" />
              <Link label="Try Anyway" onClick={this.onShowFileActionsRowClicked} className="button-text button-set-item" />

      }

);
  }
});
<commit_msg>Don't display Downloading bar on published files<commit_after>import React from 'react';
import lbry from '../lbry.js';
import {Link} from '../component/link.js';
import {Icon} from '../component/common.js';
import Modal from './modal.js';
import FormField from './form.js';
import {ToolTip} from '../component/tooltip.js';
import {DropDownMenu, DropDownMenuItem} from './menu.js';

const {shell} = require('electron');

let WatchLink = React.createClass({
  propTypes: {
    streamName: React.PropTypes.string,
    downloadStarted: React.PropTypes.bool,
  },
  startVideo: function() {
    window.location = '?watch=' + this.props.streamName;
  },
  handleClick: function() {
    this.setState({
      loading: true,
    });

    if (this.props.downloadStarted) {
      this.startVideo();
    } else {
      lbry.getCostInfoForName(this.props.streamName, ({cost}) => {
        lbry.getBalance((balance) => {
          if (cost > balance) {
            this.setState({
              modal: 'notEnoughCredits',
              loading: false,
            });
          } else {
            this.startVideo();
          }
        });
      });
    }
  },
  getInitialState: function() {
    return {
      modal: null,
      loading: false,
    };
  },
  closeModal: function() {
    this.setState({
      modal: null,
    });
  },
  render: function() {
    return (

        <Link button="primary" disabled={this.state.loading} label="Watch" icon="icon-play" onClick={this.handleClick} />
        <Modal contentLabel="Not enough credits" isOpen={this.state.modal == 'notEnoughCredits'} onConfirmed={this.closeModal}>
          You don't have enough LBRY credits to pay for this stream.
        </Modal>

    );
  }
});

let FileActionsRow = React.createClass({
  _isMounted: false,
  _fileInfoSubscribeId: null,

  propTypes: {
    streamName: React.PropTypes.string,
    outpoint: React.PropTypes.string.isRequired,
    metadata: React.PropTypes.oneOfType([React.PropTypes.object, React.PropTypes.string]),
  },
  getInitialState: function() {
    return {
      fileInfo: null,
      modal: null,
      menuOpen: false,
      deleteChecked: false,
      attemptingDownload: false,
      attemptingRemove: false
    }
  },
  onFileInfoUpdate: function(fileInfo) {
    if (this._isMounted) {
      this.setState({
        fileInfo: fileInfo ? fileInfo : false,
        attemptingDownload: fileInfo ? false : this.state.attemptingDownload
      });
    }
  },
  tryDownload: function() {
    this.setState({
      attemptingDownload: true,
      attemptingRemove: false
    });
    lbry.getCostInfoForName(this.props.streamName, ({cost}) => {
      lbry.getBalance((balance) => {
        if (cost > balance) {
          this.setState({
            modal: 'notEnoughCredits',
            attemptingDownload: false,
          });
        } else {
          lbry.getStream(this.props.streamName, (streamInfo) => {
            if (streamInfo === null || typeof streamInfo !== 'object') {
              this.setState({
                modal: 'timedOut',
                attemptingDownload: false,
              });
            }
          });
        }
      });
    });
  },
  closeModal: function() {
    this.setState({
      modal: null,
    })
  },
  onDownloadClick: function() {
    if (!this.state.fileInfo && !this.state.attemptingDownload) {
      this.tryDownload();
    }
  },
  onOpenClick: function() {
    if (this.state.fileInfo && this.state.fileInfo.download_path) {
      shell.openItem(this.state.fileInfo.download_path);
    }
  },
  handleDeleteCheckboxClicked: function(event) {
    this.setState({
      deleteChecked: event.target.checked,
    });
  },
  handleRevealClicked: function() {
    if (this.state.fileInfo && this.state.fileInfo.download_path) {
      shell.showItemInFolder(this.state.fileInfo.download_path);
    }
  },
  handleRemoveClicked: function() {
    this.setState({
      modal: 'confirmRemove',
    });
  },
  handleRemoveConfirmed: function() {
    lbry.removeFile(this.props.outpoint, this.state.deleteChecked);
    this.setState({
      modal: null,
      fileInfo: false,
      attemptingDownload: false
    });
  },
  openMenu: function() {
    this.setState({
      menuOpen: !this.state.menuOpen,
    });
  },
  componentDidMount: function() {
    this._isMounted = true;
    this._fileInfoSubscribeId = lbry.fileInfoSubscribe(this.props.outpoint, this.onFileInfoUpdate);
  },
  componentWillUnmount: function() {
    this._isMounted = false;
    if (this._fileInfoSubscribeId) {
      lbry.fileInfoUnsubscribe(this.props.outpoint, this._fileInfoSubscribeId);
    }
  },
  render: function() {
    if (this.state.fileInfo === null)
    {
      return null;
    }

    const openInFolderMessage = window.navigator.platform.startsWith('Mac') ? 'Open in Finder' : 'Open in Folder',
      showMenu = !!this.state.fileInfo;

    let linkBlock;
    if (this.state.fileInfo === false && !this.state.attemptingDownload) {
      linkBlock = <Link button="text" label="Download" icon="icon-download" onClick={this.onDownloadClick} />;
    } else if (this.state.attemptingDownload || (!this.state.fileInfo.completed && !this.state.fileInfo.isMine)) {
      const
        progress = this.state.fileInfo ? this.state.fileInfo.written_bytes / this.state.fileInfo.total_bytes * 100 : 0,
        label = this.state.fileInfo ? progress.toFixed(0) + '% complete' : 'Connecting...',
        labelWithIcon = <Icon icon="icon-download" />{label};

      linkBlock = (

{labelWithIcon}

          {labelWithIcon}

      );
    } else {
      linkBlock = <Link label="Open" button="text" icon="icon-folder-open" onClick={this.onOpenClick} />;
    }

    return (

        {this.props.metadata.content_type && this.props.metadata.content_type.startsWith('video/')
          ? <WatchLink streamName={this.props.streamName} downloadStarted={!!this.state.fileInfo} />
          : null}
        {this.state.fileInfo !== null || this.state.fileInfo.isMine
          ? linkBlock
          : null}
        { showMenu ?
          <DropDownMenu>
            <DropDownMenuItem key={0} onClick={this.handleRevealClicked} label={openInFolderMessage} />
            <DropDownMenuItem key={1} onClick={this.handleRemoveClicked} label="Remove..." />
          </DropDownMenu> : '' }
        <Modal isOpen={this.state.modal == 'notEnoughCredits'} contentLabel="Not enough credits"
               onConfirmed={this.closeModal}>
          You don't have enough LBRY credits to pay for this stream.
        </Modal>
        <Modal isOpen={this.state.modal == 'timedOut'} contentLabel="Download failed"
               onConfirmed={this.closeModal}>
          LBRY was unable to download the stream lbry://{this.props.streamName}.
        </Modal>
        <Modal isOpen={this.state.modal == 'confirmRemove'} contentLabel="Not enough credits"
               type="confirm" confirmButtonLabel="Remove" onConfirmed={this.handleRemoveConfirmed}
               onAborted={this.closeModal}>

Are you sure you'd like to remove {this.props.metadata.title} from LBRY?

          <FormField type="checkbox" checked={this.state.deleteChecked} onClick={this.handleDeleteCheckboxClicked} /> Delete this file from my computer
        </Modal>

    );
  }
});

export let FileActions = React.createClass({
  _isMounted: false,
  _fileInfoSubscribeId: null,

  propTypes: {
    streamName: React.PropTypes.string,
    outpoint: React.PropTypes.string.isRequired,
    metadata: React.PropTypes.oneOfType([React.PropTypes.object, React.PropTypes.string]),
  },
  getInitialState: function() {
    return {
      available: true,
      forceShowActions: false,
      fileInfo: null,
    }
  },
  onShowFileActionsRowClicked: function() {
    this.setState({
      forceShowActions: true,
    });
  },
  onFileInfoUpdate: function(fileInfo) {
    if (this.isMounted) {
      this.setState({
        fileInfo: fileInfo,
      });
    }
  },
  componentDidMount: function() {
    this._isMounted = true;
    this._fileInfoSubscribeId = lbry.fileInfoSubscribe(this.props.outpoint, this.onFileInfoUpdate);
    lbry.getStreamAvailability(this.props.streamName, (availability) => {
      if (this._isMounted) {
        this.setState({
          available: availability > 0,
        });
      }
    }, () => {
      // Take any error to mean the file is unavailable
      if (this._isMounted) {
        this.setState({
          available: false,
        });
      }
    });
  },
  componentWillUnmount: function() {
    this._isMounted = false;
    if (this._fileInfoSubscribeId) {
      lbry.fileInfoUnsubscribe(this.props.outpoint, this._fileInfoSubscribeId);
    }
  },
  render: function() {
    const fileInfo = this.state.fileInfo;
    if (fileInfo === null) {
      return null;
    }

    return (

      {
        fileInfo || this.state.available || this.state.forceShowActions
          ? <FileActionsRow outpoint={this.props.outpoint} metadata={this.props.metadata} streamName={this.props.streamName} />
          :

This file is not currently available.

              <ToolTip label="Why?"
                       body="The content on LBRY is hosted by its users. It appears there are no users connected that have this file at the moment."
                       className="button-set-item" />
              <Link label="Try Anyway" onClick={this.onShowFileActionsRowClicked} className="button-text button-set-item" />

      }

);
  }
});
<|endoftext|>


<commit_before>/**
 * Created by TT on 2016/1/11.
 */
function $a(element){
    return element = document.getElementById(element);
}
function $D(elementid){
    var d=$a(elementid);
    var h=d.offsetHeight;
    var maxh=300;
    function dmove(){
        h+=50; //层展开速度
        if(h>=maxh){
            clearInterval(iIntervalId);
        }else{
            d.style.display='block';
        }
    }
    iIntervalId=setInterval(dmove,2);
}
function $D2(elementid){
    var d=$a(elementid);
    var h=d.offsetHeight;
    function dmove(){
        h-=50;//层收缩速度
        if(h<=0){
            d.style.display='none';
            clearInterval(iIntervalId);
        }else{
        }
    }
    iIntervalId=setInterval(dmove,2);
}
function $use(elementid,jumpId,searchAToZ){
    if(elementid=='class1content'){
        var layWidth = $("#area1").width();
        $("#searchBrandName").css('height','40px');
        var d=$a(elementid);
        if(d.style.display=='none'){
            document.getElementById("bg").style.display ="block";
            $D(elementid);
            $("#bg").css("height",document.body.scrollHeight);
            $("#bg").css("width",layWidth);
        }else{
            document.getElementById("bg").style.display ='none';
            $D2(elementid);
            $("#bg").css("height",document.body.scrollHeight);
            $("#bg").css("width",layWidth);
        }
    }else{
        var d=$a(elementid);
        if(d.style.display=='none'){

            $D(elementid);
            $("#bg").css("height",document.body.scrollHeight);
            $("#"+jumpId).removeClass('glyphicon glyphicon-chevron-right');
            $("#"+jumpId).addClass('glyphicon glyphicon-chevron-down');
            if(searchAToZ == undefined){
            }else{
                $("#"+searchAToZ).css("display",'block');
                $("#searchBrandName").css('height','60px');
            }
        }else{
            $D2(elementid);
            $("#bg").css("height",document.body.scrollHeight);
            $("#"+jumpId).removeClass('glyphicon glyphicon-chevron-down');
            $("#"+jumpId).addClass('glyphicon glyphicon-chevron-right');
            $("#"+searchAToZ).css("display",'none');
            if(elementid != 'class2content'){
                if($a("class2content").style.display== 'block'){
                    $("#searchBrandName").css('height','60px');
                }else{
                    $("#searchBrandName").css('height','40px');
                }
            }else{
                $("#searchBrandName").css('height','40px');
            }
        }
    }
}
function $hideSearchItem(elementid){
    document.getElementById("bg").style.display ='none';
    $D2(elementid);
    $("#bg").css("height",document.body.scrollHeight);
}
function $removesingle(id){
    var div=$a('searchdetailarea');
    var div2=$a(id);
    $a(div2.id.split('___')[0]).checked=false;
    div.removeChild(div2);
    $("#bg").css("height",document.body.scrollHeight);
}

function $addcontent(oid){
    var div=$a('searchdetailarea');
    var checkbox=$a(oid);
    div.innerHTML +=""+checkbox.value+"";
    $("#bg").css("height",document.body.scrollHeight);
}
function $removecontent(oid){
    var div=$a('searchdetailarea');
    var checkbox=$a(oid);
    var div2 =$a(oid+'___'+checkbox.value);
    div.removeChild(div2);
    $("#bg").css("height",document.body.scrollHeight);
}

function $searchcontent(oid){
    var checkbox=$a(oid);
    if(checkbox.checked){
        $addcontent(oid);
        $("#bg").css("height",document.body.scrollHeight);
    }else{
        $removecontent(oid);
        $("#bg").css("height",document.body.scrollHeight);
    }
}

function $reset(){
    var div=$a('searchdetailarea');
    var divlist = div.childNodes;
    for(var i=divlist.length-1;i>=0;i--){
        if(divlist[i].id!='searchreset'&&divlist[i].id!='searchcommit'&&divlist[i].id!='searchinput'&&divlist[i].id)
        {
            $a(divlist[i].id.split('___')[0]).checked=false;
            div.removeChild(divlist[i]);
            $("#bg").css("height",document.body.scrollHeight);
        }
    }
    $("#bg").css("height",document.body.scrollHeight);
}

function $departmentajax(id){
    $.ajax({
        type:"post",
        data: "job_id=" + id,
        url:"Join/getJobInfo",
        success: function(result)
        {
            var submitbutton='
<button class="btn btn-primary btn-lg jobcommitbtn" data-toggle="modal" data-target="#myModal">点击申请</button>
';
            var modal =
            '
'+
                '
'+
                    '
'+
                        '
'+
                            '
发送电子邮件
'+
                   //         '
'+
                            '
如有疑问或需要帮助，请填写下面表格
'+
                            '
填写信息
'+
                            '
<textarea id="remarkinfo" style=" width: 530px;resize:none; height:100px;" ></textarea>
'+
                            '
称呼（非必须）
'+
                            '
<input type="text" name="call" id="call"  style=" width: 530px;height:40px">
'+
                            '
姓名
'+
                            '
<input type="text" name="name" id="name"  style=" width: 530px;height:40px">
'+
                            '
联系电话（非必须）
'+
                            '
<input type="text" name="phoneno" id="phoneno"  style=" width: 530px;height:40px">
'+
                            '
您的电子邮件地址
'+
                            '
<input type="email" name="email" id="email"  style=" width: 530px;height:40px">
'+
                        '
'+
                        '
'+'
'+
                            '<button type="button" class="btn btn-primary sendcommitbtn"onclick="$ask4job(\''+id+'\')">发送</button>'+
                            '<button type="button" class="btn btn-default sendcanclebtn" data-dismiss="modal" style="border:0;">关闭</button>'+'
'+
                        '
'+
                    '
'+
                '
'
            $("#departmentdetailarea").html(result+submitbutton+modal);
        },
        error: function()
        {
            $("#departmentdetailarea").html('error');
            alert("ajax error");
        }
    });
}

function $ask4job(id){
    var remark=$('#remarkinfo').val();
    var call=$('#call').val();
    var name=$('#name').val();
    var phoneno=$('#phoneno').val();
    var email=$('#email').val();
    $.ajax({
        type:"post",
        data: "job_id=" + id + '&remark='+remark+'&call='+call+'&name='+name+'&phoneno='+phoneno+'&email='+email,
        url:"Join/ask4job",
        success: function(result)
        {
           alert(result);
        },

        error: function()
        {
            $("#departmentdetailarea").html('error');
            alert("ajax error");
        }
    });
}

function $searchresult(){
    if($("#searchinput").val()){
        var div=$a('searchdetailarea');
        var divlist = div.childNodes;
        var tags = '';
        for(var i=divlist.length-1;i>=0;i--){
            if(divlist[i].id!='searchreset'&&divlist[i].id!='searchcommit'&&divlist[i].id!='searchinput'&&divlist[i].id)
            {
                tags+=divlist[i].id.split('__')[0];
                if(i>0){
                    tags+='|||';
                }
            }
        }
        console.log(tags);
        var reg = /([^\s])\s+([^\s\b])/g;
        var searchinput = $("#searchinput").val();
        searchinput = searchinput.replace(reg, "$1|||$2");
        console.log(searchinput);
        $.ajax({
            type:"post",
            data: "tags=" + tags + '&searchinput='+searchinput,
            url:"Search/globalSearch",
            success: function(result)
            {
                $("#searchresults").html(result);
                $("#bg").css("height",document.body.scrollHeight);
            },
            error: function()
            {
                alert("ajax error");
                $("#bg").css("height",document.body.scrollHeight);
            }
        });
    }else{
        alert('请输入搜索内容');
        $("#bg").css("height",document.body.scrollHeight);
    }
}

function $changelanguage($url,$language){
    console.log($url);
    $.ajax({
        type:"post",
        data: "language=" + $language,
        url:$url+"/changelanguage",
        success: function(result)
        {
            location.reload(true);
        },
        error: function()
        {
            alert("ajax error");
        }
    });
}

function $searchrelatedvideo($keyword_id){
    $.ajax({
        type:"post",
        data: "keyword_id=" + $keyword_id,
        url:"Search/searchrelatedvideo",
        success: function(result)
        {
            $('#relatedvideoarea').html(result);
        },
        error: function()
        {
            alert("ajax error");
        }
    });
}

function $searchbrandname($brandtype){
    $.ajax({
        type:"post",
        data: "brandtype=" + $brandtype,
        url:"Search/searchbrandname",
        success: function(result)
        {
            $('#class2content').html(result);
        },
        error: function()
        {
            alert("ajax error");
        }
    });
}<commit_msg>update search<commit_after>/**
 * Created by TT on 2016/1/11.
 */
function $a(element){
    return element = document.getElementById(element);
}
function $D(elementid){
    var d=$a(elementid);
    var h=d.offsetHeight;
    var maxh=300;
    function dmove(){
        h+=50; //层展开速度
        if(h>=maxh){
            clearInterval(iIntervalId);
        }else{
            d.style.display='block';
        }
    }
    iIntervalId=setInterval(dmove,2);
}
function $D2(elementid){
    var d=$a(elementid);
    var h=d.offsetHeight;
    function dmove(){
        h-=50;//层收缩速度
        if(h<=0){
            d.style.display='none';
            clearInterval(iIntervalId);
        }else{
        }
    }
    iIntervalId=setInterval(dmove,2);
}
function $use(elementid,jumpId,searchAToZ){
    if(elementid=='class1content'){
        var layWidth = $("#area1").width();
        $("#searchBrandName").css('height','40px');
        var d=$a(elementid);
        if(d.style.display=='none'){
            document.getElementById("bg").style.display ="block";
            $D(elementid);
            $searchbrandname('A');
            $("#bg").css("height",document.body.scrollHeight);
            $("#bg").css("width",layWidth);
        }else{
            document.getElementById("bg").style.display ='none';
            $D2(elementid);
            $("#bg").css("height",document.body.scrollHeight);
            $("#bg").css("width",layWidth);
        }
    }else{
        var d=$a(elementid);
        if(d.style.display=='none'){

            $D(elementid);
            $("#bg").css("height",document.body.scrollHeight);
            $("#"+jumpId).removeClass('glyphicon glyphicon-chevron-right');
            $("#"+jumpId).addClass('glyphicon glyphicon-chevron-down');
            if(searchAToZ == undefined){
            }else{
                $("#"+searchAToZ).css("display",'block');
                $("#searchBrandName").css('height','60px');
            }
        }else{
            $D2(elementid);
            $("#bg").css("height",document.body.scrollHeight);
            $("#"+jumpId).removeClass('glyphicon glyphicon-chevron-down');
            $("#"+jumpId).addClass('glyphicon glyphicon-chevron-right');
            $("#"+searchAToZ).css("display",'none');
            if(elementid != 'class2content'){
                if($a("class2content").style.display== 'block'){
                    $("#searchBrandName").css('height','60px');
                }else{
                    $("#searchBrandName").css('height','40px');
                }
            }else{
                $("#searchBrandName").css('height','40px');
            }
        }
    }
}
function $hideSearchItem(elementid){
    document.getElementById("bg").style.display ='none';
    $D2(elementid);
    $("#bg").css("height",document.body.scrollHeight);
}
function $removesingle(id){
    var div=$a('searchdetailarea');
    var div2=$a(id);
    $a(div2.id.split('___')[0]).checked=false;
    div.removeChild(div2);
    $("#bg").css("height",document.body.scrollHeight);
}

function $addcontent(oid){
    var div=$a('searchdetailarea');
    var checkbox=$a(oid);
    div.innerHTML +=""+checkbox.value+"";
    $("#bg").css("height",document.body.scrollHeight);
}
function $removecontent(oid){
    var div=$a('searchdetailarea');
    var checkbox=$a(oid);
    var div2 =$a(oid+'___'+checkbox.value);
    div.removeChild(div2);
    $("#bg").css("height",document.body.scrollHeight);
}

function $searchcontent(oid){
    var checkbox=$a(oid);
    if(checkbox.checked){
        $addcontent(oid);
        $("#bg").css("height",document.body.scrollHeight);
    }else{
        $removecontent(oid);
        $("#bg").css("height",document.body.scrollHeight);
    }
}

function $reset(){
    var div=$a('searchdetailarea');
    var divlist = div.childNodes;
    for(var i=divlist.length-1;i>=0;i--){
        if(divlist[i].id!='searchreset'&&divlist[i].id!='searchcommit'&&divlist[i].id!='searchinput'&&divlist[i].id)
        {
            $a(divlist[i].id.split('___')[0]).checked=false;
            div.removeChild(divlist[i]);
            $("#bg").css("height",document.body.scrollHeight);
        }
    }
    $("#bg").css("height",document.body.scrollHeight);
}

function $departmentajax(id){
    $.ajax({
        type:"post",
        data: "job_id=" + id,
        url:"Join/getJobInfo",
        success: function(result)
        {
            var submitbutton='
<button class="btn btn-primary btn-lg jobcommitbtn" data-toggle="modal" data-target="#myModal">点击申请</button>
';
            var modal =
            '
'+
                '
'+
                    '
'+
                        '
'+
                            '
发送电子邮件
'+
                   //         '
'+
                            '
如有疑问或需要帮助，请填写下面表格
'+
                            '
填写信息
'+
                            '
<textarea id="remarkinfo" style=" width: 530px;resize:none; height:100px;" ></textarea>
'+
                            '
称呼（非必须）
'+
                            '
<input type="text" name="call" id="call"  style=" width: 530px;height:40px">
'+
                            '
姓名
'+
                            '
<input type="text" name="name" id="name"  style=" width: 530px;height:40px">
'+
                            '
联系电话（非必须）
'+
                            '
<input type="text" name="phoneno" id="phoneno"  style=" width: 530px;height:40px">
'+
                            '
您的电子邮件地址
'+
                            '
<input type="email" name="email" id="email"  style=" width: 530px;height:40px">
'+
                        '
'+
                        '
'+'
'+
                            '<button type="button" class="btn btn-primary sendcommitbtn"onclick="$ask4job(\''+id+'\')">发送</button>'+
                            '<button type="button" class="btn btn-default sendcanclebtn" data-dismiss="modal" style="border:0;">关闭</button>'+'
'+
                        '
'+
                    '
'+
                '
'
            $("#departmentdetailarea").html(result+submitbutton+modal);
        },
        error: function()
        {
            $("#departmentdetailarea").html('error');
            alert("ajax error");
        }
    });
}

function $ask4job(id){
    var remark=$('#remarkinfo').val();
    var call=$('#call').val();
    var name=$('#name').val();
    var phoneno=$('#phoneno').val();
    var email=$('#email').val();
    $.ajax({
        type:"post",
        data: "job_id=" + id + '&remark='+remark+'&call='+call+'&name='+name+'&phoneno='+phoneno+'&email='+email,
        url:"Join/ask4job",
        success: function(result)
        {
           alert(result);
        },

        error: function()
        {
            $("#departmentdetailarea").html('error');
            alert("ajax error");
        }
    });
}

function $searchresult(){
    if($("#searchinput").val()){
        var div=$a('searchdetailarea');
        var divlist = div.childNodes;
        var tags = '';
        for(var i=divlist.length-1;i>=0;i--){
            if(divlist[i].id!='searchreset'&&divlist[i].id!='searchcommit'&&divlist[i].id!='searchinput'&&divlist[i].id)
            {
                tags+=divlist[i].id.split('__')[0];
                if(i>0){
                    tags+='|||';
                }
            }
        }
        console.log(tags);
        var reg = /([^\s])\s+([^\s\b])/g;
        var searchinput = $("#searchinput").val();
        searchinput = searchinput.replace(reg, "$1|||$2");
        console.log(searchinput);
        $.ajax({
            type:"post",
            data: "tags=" + tags + '&searchinput='+searchinput,
            url:"Search/globalSearch",
            success: function(result)
            {
                $("#searchresults").html(result);
                $("#bg").css("height",document.body.scrollHeight);
            },
            error: function()
            {
                alert("ajax error");
                $("#bg").css("height",document.body.scrollHeight);
            }
        });
    }else{
        alert('请输入搜索内容');
        $("#bg").css("height",document.body.scrollHeight);
    }
}

function $changelanguage($url,$language){
    console.log($url);
    $.ajax({
        type:"post",
        data: "language=" + $language,
        url:$url+"/changelanguage",
        success: function(result)
        {
            location.reload(true);
        },
        error: function()
        {
            alert("ajax error");
        }
    });
}

function $searchrelatedvideo($keyword_id){
    $.ajax({
        type:"post",
        data: "keyword_id=" + $keyword_id,
        url:"Search/searchrelatedvideo",
        success: function(result)
        {
            $('#relatedvideoarea').html(result);
        },
        error: function()
        {
            alert("ajax error");
        }
    });
}

function $searchbrandname($brandtype){
    $.ajax({
        type:"post",
        data: "brandtype=" + $brandtype,
        url:"Search/searchbrandname",
        success: function(result)
        {
            $('#class2content').html(result);
            var div=$a('searchdetailarea');
            var divlist = div.childNodes;
            for(var i=divlist.length-1;i>=0;i--){
                if(divlist[i].id!='searchreset'&&divlist[i].id!='searchcommit'&&divlist[i].id!='searchinput'&&divlist[i].id)
                {
                    $('#'+divlist[i].id.split('___')[0]).attr("checked",'true');
                }
            }
        },
        error: function()
        {
            alert("ajax error");
        }
    });
}<|endoftext|>


<commit_before>function initMap() {
    var mapDiv = document.getElementById('map');
    var LatLng = {lat: 43.115767, lng: 12.388208};
    var map = new google.maps.Map(mapDiv, {
        center: LatLng,
        zoom: 17,
        scrollwheel: false,
        mapTypeControl: false,
        styles: [
            {
                featureType: 'water',
                elementType: 'geometry',
                stylers: [
                    {
                        color: '#e9e9e9'
                    },
                    {
                        lightness: 17
                    }
                ]
            },
            {
                featureType: 'landscape',
                elementType: 'geometry',
                stylers: [
                    {
                        color: '#f5f5f5'
                    },
                    {
                        lightness: 20
                    }
                ]
            },
            {
                featureType: 'road.highway',
                elementType: 'geometry.fill',
                stylers: [
                    {
                        color: '#ffffff'
                    },
                    {
                        lightness: 17
                    }
                ]
            },
            {
                featureType: 'road.highway',
                elementType: 'geometry.stroke',
                stylers: [
                    {
                        color: '#ffffff'
                    },
                    {
                        lightness: 29
                    },
                    {
                        weight: 0.2
                    }
                ]
            },
            {
                featureType: 'road.arterial',
                elementType: 'geometry',
                stylers: [
                    {
                        color: '#ffffff'
                    },
                    {
                        lightness: 18
                    }
                ]
            },
            {
                featureType: 'road.local',
                elementType: 'geometry',
                stylers: [
                    {
                        color: '#ffffff'
                    },
                    {
                        lightness: 16
                    }
                ]
            },
            {
                featureType: 'poi',
                elementType: 'geometry',
                stylers: [
                    {
                        color: '#f5f5f5'
                    },
                    {
                        lightness: 21
                    }
                ]
            },
            {
                featureType: 'poi.park',
                elementType: 'geometry',
                stylers: [
                    {
                        color: '#dedede'
                    },
                    {
                        lightness: 21
                    }
                ]
            },
            {
                elementType: 'labels.text.stroke',
                stylers: [
                    {
                        visibility: 'on'
                    },
                    {
                        color: '#ffffff'
                    },
                    {
                        lightness: 16
                    }
                ]
            },
            {
                elementType: 'labels.text.fill',
                stylers: [
                    {
                        saturation: 36
                    },
                    {
                        color: '#333333'
                    },
                    {
                        lightness: 40
                    }
                ]
            },
            {
                elementType: 'labels.icon',
                stylers: [
                    {
                        visibility: 'off'
                    }
                ]
            },
            {
                featureType: 'transit',
                elementType: 'geometry',
                stylers: [
                    {
                        color: '#f2f2f2'
                    },
                    {
                        lightness: 19
                    }
                ]
            },
            {
                featureType: 'administrative',
                elementType: 'geometry.fill',
                stylers: [
                    {
                        color: '#fefefe'
                    },
                    {
                        lightness: 20
                    }
                ]
            },
            {
                featureType: 'administrative',
                elementType: 'geometry.stroke',
                stylers: [
                    {
                        color: '#fefefe'
                    },
                    {
                        lightness: 17
                    },
                    {
                        weight: 1.2
                    }
                ]
            }
        ]
    });

    var iconMarker = '/static/images/marker.png';
    var marker = new google.maps.Marker({
        position: LatLng,
        map: map,
        icon: iconMarker
    });
}
<commit_msg>remove the draggable feature from the map<commit_after>function initMap() {
    var mapDiv = document.getElementById('map');
    var LatLng = {lat: 43.115767, lng: 12.388208};
    var map = new google.maps.Map(mapDiv, {
        center: LatLng,
        zoom: 17,
        scrollwheel: false,
        mapTypeControl: false,
        draggable: false,
        styles: [
            {
                featureType: 'water',
                elementType: 'geometry',
                stylers: [
                    {
                        color: '#e9e9e9'
                    },
                    {
                        lightness: 17
                    }
                ]
            },
            {
                featureType: 'landscape',
                elementType: 'geometry',
                stylers: [
                    {
                        color: '#f5f5f5'
                    },
                    {
                        lightness: 20
                    }
                ]
            },
            {
                featureType: 'road.highway',
                elementType: 'geometry.fill',
                stylers: [
                    {
                        color: '#ffffff'
                    },
                    {
                        lightness: 17
                    }
                ]
            },
            {
                featureType: 'road.highway',
                elementType: 'geometry.stroke',
                stylers: [
                    {
                        color: '#ffffff'
                    },
                    {
                        lightness: 29
                    },
                    {
                        weight: 0.2
                    }
                ]
            },
            {
                featureType: 'road.arterial',
                elementType: 'geometry',
                stylers: [
                    {
                        color: '#ffffff'
                    },
                    {
                        lightness: 18
                    }
                ]
            },
            {
                featureType: 'road.local',
                elementType: 'geometry',
                stylers: [
                    {
                        color: '#ffffff'
                    },
                    {
                        lightness: 16
                    }
                ]
            },
            {
                featureType: 'poi',
                elementType: 'geometry',
                stylers: [
                    {
                        color: '#f5f5f5'
                    },
                    {
                        lightness: 21
                    }
                ]
            },
            {
                featureType: 'poi.park',
                elementType: 'geometry',
                stylers: [
                    {
                        color: '#dedede'
                    },
                    {
                        lightness: 21
                    }
                ]
            },
            {
                elementType: 'labels.text.stroke',
                stylers: [
                    {
                        visibility: 'on'
                    },
                    {
                        color: '#ffffff'
                    },
                    {
                        lightness: 16
                    }
                ]
            },
            {
                elementType: 'labels.text.fill',
                stylers: [
                    {
                        saturation: 36
                    },
                    {
                        color: '#333333'
                    },
                    {
                        lightness: 40
                    }
                ]
            },
            {
                elementType: 'labels.icon',
                stylers: [
                    {
                        visibility: 'off'
                    }
                ]
            },
            {
                featureType: 'transit',
                elementType: 'geometry',
                stylers: [
                    {
                        color: '#f2f2f2'
                    },
                    {
                        lightness: 19
                    }
                ]
            },
            {
                featureType: 'administrative',
                elementType: 'geometry.fill',
                stylers: [
                    {
                        color: '#fefefe'
                    },
                    {
                        lightness: 20
                    }
                ]
            },
            {
                featureType: 'administrative',
                elementType: 'geometry.stroke',
                stylers: [
                    {
                        color: '#fefefe'
                    },
                    {
                        lightness: 17
                    },
                    {
                        weight: 1.2
                    }
                ]
            }
        ]
    });

    var iconMarker = '/static/images/marker.png';
    var marker = new google.maps.Marker({
        position: LatLng,
        map: map,
        icon: iconMarker
    });
}
<|endoftext|>


<commit_before>'use strict';

[{
  zoneRegex: /The Binding Coil Of Bahamut - Turn \(4\)/,
  timelineFile: 't4.txt',
  triggers: [
    {
      id: 'T4 Gravity Thrust',
      regex: / 14:4D4:Spinner-Rook starts using Gravity Thrust on (\y{Name})\./,
      condition: function(data, matches) {
        return data.me == matches[1];
      },
      alertText: {
        en: 'LOS Thrust',
      },
    },
    {
      id: 'T4 Pox',
      regex: / 14:4D5:Spinner-Rook starts using Pox on (\y{Name})\./,
      condition: function(data, matches) {
        return data.me == matches[1];
      },
      alarmText: {
        en: 'LOS Pox',
      },
    },
  ],
}];
<commit_msg>raidboss: add t4 knight/soldier reminder<commit_after>'use strict';

[{
  zoneRegex: /The Binding Coil Of Bahamut - Turn \(4\)/,
  timelineFile: 't4.txt',
  triggers: [
    {
      id: 'T4 Gravity Thrust',
      regex: / 14:4D4:Spinner-Rook starts using Gravity Thrust on (\y{Name})\./,
      condition: function(data, matches) {
        return data.me == matches[1];
      },
      alertText: {
        en: 'LOS Thrust',
      },
    },
    {
      id: 'T4 Pox',
      regex: / 14:4D5:Spinner-Rook starts using Pox on (\y{Name})\./,
      condition: function(data, matches) {
        return data.me == matches[1];
      },
      alarmText: {
        en: 'LOS Pox',
      },
    },
    {
      id: 'T4 Reminder',
      regex: / 03:Added new combatant Clockwork Knight/,
      suppressSeconds: 100000,
      infoText: {
        en: 'Magic on Soldier, Physical on Knights',
      },
    },
  ],
}];
<|endoftext|>


<commit_before>//----------------------------------------------------------------------------
//  Copyright (C) 2008-2012  The IPython Development Team
//
//  Distributed under the terms of the BSD License.  The full license is in
//  the file COPYING, distributed as part of this software.
//----------------------------------------------------------------------------

//============================================================================
// Utilities
//============================================================================
IPython.namespace('IPython.utils');

IPython.utils = (function (IPython) {

    //============================================================================
    // Cross-browser RegEx Split
    //============================================================================

    // This code has been MODIFIED from the code licensed below to not replace the
    // default browser split.  The license is reproduced here.

    // see http://blog.stevenlevithan.com/archives/cross-browser-split for more info:
    /*!
     * Cross-Browser Split 1.1.1
     * Copyright 2007-2012 Steven Levithan <stevenlevithan.com>
     * Available under the MIT License
     * ECMAScript compliant, uniform cross-browser split method
     */

    /**
     * Splits a string into an array of strings using a regex or string
     * separator. Matches of the separator are not included in the result array.
     * However, if `separator` is a regex that contains capturing groups,
     * backreferences are spliced into the result each time `separator` is
     * matched. Fixes browser bugs compared to the native
     * `String.prototype.split` and can be used reliably cross-browser.
     * @param {String} str String to split.
     * @param {RegExp|String} separator Regex or string to use for separating
     *     the string.
     * @param {Number} [limit] Maximum number of items to include in the result
     *     array.
     * @returns {Array} Array of substrings.
     * @example
     *
     * // Basic use
     * regex_split('a b c d', ' ');
     * // -> ['a', 'b', 'c', 'd']
     *
     * // With limit
     * regex_split('a b c d', ' ', 2);
     * // -> ['a', 'b']
     *
     * // Backreferences in result array
     * regex_split('..word1 word2..', /([a-z]+)(\d+)/i);
     * // -> ['..', 'word', '1', ' ', 'word', '2', '..']
     */
    var regex_split = function (str, separator, limit) {
        // If `separator` is not a regex, use `split`
        if (Object.prototype.toString.call(separator) !== "[object RegExp]") {
            return split.call(str, separator, limit);
        }
        var output = [],
            flags = (separator.ignoreCase ? "i" : "") +
                    (separator.multiline  ? "m" : "") +
                    (separator.extended   ? "x" : "") + // Proposed for ES6
                    (separator.sticky     ? "y" : ""), // Firefox 3+
            lastLastIndex = 0,
            // Make `global` and avoid `lastIndex` issues by working with a copy
            separator = new RegExp(separator.source, flags + "g"),
            separator2, match, lastIndex, lastLength;
        str += ""; // Type-convert

        var compliantExecNpcg = typeof(/()??/.exec("")[1]) === "undefined";
        if (!compliantExecNpcg) {
            // Doesn't need flags gy, but they don't hurt
            separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags);
        }
        /* Values for `limit`, per the spec:
         * If undefined: 4294967295 // Math.pow(2, 32) - 1
         * If 0, Infinity, or NaN: 0
         * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
         * If negative number: 4294967296 - Math.floor(Math.abs(limit))
         * If other: Type-convert, then use the above rules
         */
        limit = typeof(limit) === "undefined" ?
            -1 >>> 0 : // Math.pow(2, 32) - 1
            limit >>> 0; // ToUint32(limit)
        while (match = separator.exec(str)) {
            // `separator.lastIndex` is not reliable cross-browser
            lastIndex = match.index + match[0].length;
            if (lastIndex > lastLastIndex) {
                output.push(str.slice(lastLastIndex, match.index));
                // Fix browsers whose `exec` methods don't consistently return `undefined` for
                // nonparticipating capturing groups
                if (!compliantExecNpcg && match.length > 1) {
                    match[0].replace(separator2, function () {
                        for (var i = 1; i < arguments.length - 2; i++) {
                            if (typeof(arguments[i]) === "undefined") {
                                match[i] = undefined;
                            }
                        }
                    });
                }
                if (match.length > 1 && match.index < str.length) {
                    Array.prototype.push.apply(output, match.slice(1));
                }
                lastLength = match[0].length;
                lastLastIndex = lastIndex;
                if (output.length >= limit) {
                    break;
                }
            }
            if (separator.lastIndex === match.index) {
                separator.lastIndex++; // Avoid an infinite loop
            }
        }
        if (lastLastIndex === str.length) {
            if (lastLength || !separator.test("")) {
                output.push("");
            }
        } else {
            output.push(str.slice(lastLastIndex));
        }
        return output.length > limit ? output.slice(0, limit) : output;
    };

    //============================================================================
    // End contributed Cross-browser RegEx Split
    //============================================================================

    var uuid = function () {
        // http://www.ietf.org/rfc/rfc4122.txt
        var s = [];
        var hexDigits = "0123456789ABCDEF";
        for (var i = 0; i < 32; i++) {
            s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
        }
        s[12] = "4";  // bits 12-15 of the time_hi_and_version field to 0010
        s[16] = hexDigits.substr((s[16] & 0x3) | 0x8, 1);  // bits 6-7 of the clock_seq_hi_and_reserved to 01

        var uuid = s.join("");
        return uuid;
    };

    //Fix raw text to parse correctly in crazy XML
    function xmlencode(string) {
        return string.replace(/\&/g,'&'+'amp;')
            .replace(/</g,'&'+'lt;')
            .replace(/>/g,'&'+'gt;')
            .replace(/\'/g,'&'+'apos;')
            .replace(/\"/g,'&'+'quot;')
            .replace(/`/g,'&'+'#96;');
    }

    //Map from terminal commands to CSS classes
    var ansi_colormap = {
        "01":"ansibold",

        "30":"ansiblack",
        "31":"ansired",
        "32":"ansigreen",
        "33":"ansiyellow",
        "34":"ansiblue",
        "35":"ansipurple",
        "36":"ansicyan",
        "37":"ansigray",

        "40":"ansibgblack",
        "41":"ansibgred",
        "42":"ansibggreen",
        "44":"ansibgyellow",
        "44":"ansibgblue",
        "45":"ansibgpurple",
        "46":"ansibgcyan",
        "47":"ansibggray"
    };

    function _process_numbers(attrs, numbers) {
        // process ansi escapes
        var n = numbers.shift();
        if (ansi_colormap[n]) {
            if ( ! attrs["class"] ) {
                attrs["class"] = ansi_colormap[n];
            } else {
                attrs["class"] += " " + ansi_colormap[n];
            }
        } else if (n == "38" || n == "48") {
            // 256-color
            if (numbers.length < 2) {
                console.log("Not enough fields for 256-color escapes", numbers);
                return;
            }

            var index_or_rgb = numbers.shift();
            var r,g,b;
            if (index_or_rgb == "5") {
                var idx = parseInt(numbers.shift());
                if (idx < 16) {
                    // indexed color, not supported
                } else if (idx < 232) {
                    // 216 color 6x6x6
                    idx = idx - 16;
                    b = idx % 6;
                    g = Math.floor(idx / 6) % 6;
                    r = Math.floor(idx / 36) % 6;
                    // convert to rgb
                    r = (r * 51);
                    g = (g * 51);
                    b = (b * 51);
                } else {
                    // grayscale
                    idx = idx - 231;
                    // it's 1-24 and should *not* include black or white,
                    // so a 26 point scale
                    r = g = b = idx * 256 / 26;
                }
            } else if (index_or_rgb == "2") {
                if (numbers.length > 3) {
                    console.log("Not enough fields for RGB", numbers);
                    return;
                }
                // simple rgb
                r = numbers.shift();
                g = numbers.shift();
                b = numbers.shift();
            } else {
                console.log("unrecognized control", numbers);
                return;
            }
            if (r !== undefined) {
                // apply the rgb color
                var line;
                if (n == "38") {
                    line = "color: ";
                } else {
                    line = "background-color: ";
                }
                line = line + "rgb(" + r + "," + g + "," + b + ");"
                if ( !attrs["style"] ) {
                    attrs["style"] = line;
                } else {
                    attrs["style"] += " " + line;
                }
            }
        }
    }

    function ansispan(str) {
        // ansispan function adapted from github.com/mmalecki/ansispan (MIT License)
        // regular ansi escapes (using the table above)
        return str.replace(/\033\[(0?[01]|22|39)?([;\d]+)?m/g, function(match, prefix, pattern) {
            if (!pattern) {
                // [(01|22|39|)m close spans
                return "";
            }
            // consume sequence of color escapes
            var numbers = pattern.match(/\d+/g);
            var attrs = {};
            while (numbers.length > 0) {
                _process_numbers(attrs, numbers);
            }

            var span = "";
        });
    };

    // Transform ANSI color escape codes into HTML  tags with css
    // classes listed in the above ansi_colormap object. The actual color used
    // are set in the css file.
    function fixConsole(txt) {
        txt = xmlencode(txt);
        var re = /\033\[([\dA-Fa-f;]*?)m/;
        var opened = false;
        var cmds = [];
        var opener = "";
        var closer = "";

        // Strip all ANSI codes that are not color related.  Matches
        // all ANSI codes that do not end with "m".
        var ignored_re = /(?=(\033\[[\d;=]*[a-ln-zA-Z]{1}))\1(?!m)/g;
        txt = txt.replace(ignored_re, "");

        // color ansi codes
        txt = ansispan(txt);
        return txt;
    }

    // Remove chunks that should be overridden by the effect of
    // carriage return characters
    function fixCarriageReturn(txt) {
        var tmp = txt;
        do {
            txt = tmp;
            tmp = txt.replace(/\r+\n/gm, '\n'); // \r followed by \n --> newline
            tmp = tmp.replace(/^.*\r+/gm, '');  // Other \r --> clear line
        } while (tmp.length < txt.length);
        return txt;
    }

    // Locate any URLs and convert them to a anchor tag
    function autoLinkUrls(txt) {
        return txt.replace(/(^|\s)(https?|ftp)(:[^'">\s]+)/gi,
            "$1$2$3");
    }

    // some keycodes that seem to be platform/browser independent
    var keycodes = {
                BACKSPACE:  8,
                TAB      :  9,
                ENTER    : 13,
                SHIFT    : 16,
                CTRL     : 17,
                CONTROL  : 17,
                ALT      : 18,
                CAPS_LOCK: 20,
                ESC      : 27,
                SPACE    : 32,
                PGUP     : 33,
                PGDOWN   : 34,
                END      : 35,
                HOME     : 36,
                LEFT_ARROW: 37,
                LEFTARROW: 37,
                LEFT     : 37,
                UP_ARROW : 38,
                UPARROW  : 38,
                UP       : 38,
                RIGHT_ARROW:39,
                RIGHTARROW:39,
                RIGHT    : 39,
                DOWN_ARROW: 40,
                DOWNARROW: 40,
                DOWN     : 40,
                // all three of these keys may be COMMAND on OS X:
                LEFT_SUPER : 91,
                RIGHT_SUPER : 92,
                COMMAND  : 93,
    };

    var points_to_pixels = function (points) {
        // A reasonably good way of converting between points and pixels.
        var test = $('

');
        $(body).append(test);
        var pixel_per_point = test.width()/10000;
        test.remove();
        return Math.floor(points*pixel_per_point);
    };

    // http://stackoverflow.com/questions/2400935/browser-detection-in-javascript
    browser = (function() {
        var N= navigator.appName, ua= navigator.userAgent, tem;
        var M= ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
        if (M && (tem= ua.match(/version\/([\.\d]+)/i))!= null) M[2]= tem[1];
        M= M? [M[1], M[2]]: [N, navigator.appVersion,'-?'];
        return M;
    })();

    return {
        regex_split : regex_split,
        uuid : uuid,
        fixConsole : fixConsole,
        keycodes : keycodes,
        fixCarriageReturn : fixCarriageReturn,
        autoLinkUrls : autoLinkUrls,
        points_to_pixels : points_to_pixels,
        browser : browser
    };

}(IPython));

<commit_msg>add indexed-color in 256-color support<commit_after>//----------------------------------------------------------------------------
//  Copyright (C) 2008-2012  The IPython Development Team
//
//  Distributed under the terms of the BSD License.  The full license is in
//  the file COPYING, distributed as part of this software.
//----------------------------------------------------------------------------

//============================================================================
// Utilities
//============================================================================
IPython.namespace('IPython.utils');

IPython.utils = (function (IPython) {

    //============================================================================
    // Cross-browser RegEx Split
    //============================================================================

    // This code has been MODIFIED from the code licensed below to not replace the
    // default browser split.  The license is reproduced here.

    // see http://blog.stevenlevithan.com/archives/cross-browser-split for more info:
    /*!
     * Cross-Browser Split 1.1.1
     * Copyright 2007-2012 Steven Levithan <stevenlevithan.com>
     * Available under the MIT License
     * ECMAScript compliant, uniform cross-browser split method
     */

    /**
     * Splits a string into an array of strings using a regex or string
     * separator. Matches of the separator are not included in the result array.
     * However, if `separator` is a regex that contains capturing groups,
     * backreferences are spliced into the result each time `separator` is
     * matched. Fixes browser bugs compared to the native
     * `String.prototype.split` and can be used reliably cross-browser.
     * @param {String} str String to split.
     * @param {RegExp|String} separator Regex or string to use for separating
     *     the string.
     * @param {Number} [limit] Maximum number of items to include in the result
     *     array.
     * @returns {Array} Array of substrings.
     * @example
     *
     * // Basic use
     * regex_split('a b c d', ' ');
     * // -> ['a', 'b', 'c', 'd']
     *
     * // With limit
     * regex_split('a b c d', ' ', 2);
     * // -> ['a', 'b']
     *
     * // Backreferences in result array
     * regex_split('..word1 word2..', /([a-z]+)(\d+)/i);
     * // -> ['..', 'word', '1', ' ', 'word', '2', '..']
     */
    var regex_split = function (str, separator, limit) {
        // If `separator` is not a regex, use `split`
        if (Object.prototype.toString.call(separator) !== "[object RegExp]") {
            return split.call(str, separator, limit);
        }
        var output = [],
            flags = (separator.ignoreCase ? "i" : "") +
                    (separator.multiline  ? "m" : "") +
                    (separator.extended   ? "x" : "") + // Proposed for ES6
                    (separator.sticky     ? "y" : ""), // Firefox 3+
            lastLastIndex = 0,
            // Make `global` and avoid `lastIndex` issues by working with a copy
            separator = new RegExp(separator.source, flags + "g"),
            separator2, match, lastIndex, lastLength;
        str += ""; // Type-convert

        var compliantExecNpcg = typeof(/()??/.exec("")[1]) === "undefined";
        if (!compliantExecNpcg) {
            // Doesn't need flags gy, but they don't hurt
            separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags);
        }
        /* Values for `limit`, per the spec:
         * If undefined: 4294967295 // Math.pow(2, 32) - 1
         * If 0, Infinity, or NaN: 0
         * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
         * If negative number: 4294967296 - Math.floor(Math.abs(limit))
         * If other: Type-convert, then use the above rules
         */
        limit = typeof(limit) === "undefined" ?
            -1 >>> 0 : // Math.pow(2, 32) - 1
            limit >>> 0; // ToUint32(limit)
        while (match = separator.exec(str)) {
            // `separator.lastIndex` is not reliable cross-browser
            lastIndex = match.index + match[0].length;
            if (lastIndex > lastLastIndex) {
                output.push(str.slice(lastLastIndex, match.index));
                // Fix browsers whose `exec` methods don't consistently return `undefined` for
                // nonparticipating capturing groups
                if (!compliantExecNpcg && match.length > 1) {
                    match[0].replace(separator2, function () {
                        for (var i = 1; i < arguments.length - 2; i++) {
                            if (typeof(arguments[i]) === "undefined") {
                                match[i] = undefined;
                            }
                        }
                    });
                }
                if (match.length > 1 && match.index < str.length) {
                    Array.prototype.push.apply(output, match.slice(1));
                }
                lastLength = match[0].length;
                lastLastIndex = lastIndex;
                if (output.length >= limit) {
                    break;
                }
            }
            if (separator.lastIndex === match.index) {
                separator.lastIndex++; // Avoid an infinite loop
            }
        }
        if (lastLastIndex === str.length) {
            if (lastLength || !separator.test("")) {
                output.push("");
            }
        } else {
            output.push(str.slice(lastLastIndex));
        }
        return output.length > limit ? output.slice(0, limit) : output;
    };

    //============================================================================
    // End contributed Cross-browser RegEx Split
    //============================================================================

    var uuid = function () {
        // http://www.ietf.org/rfc/rfc4122.txt
        var s = [];
        var hexDigits = "0123456789ABCDEF";
        for (var i = 0; i < 32; i++) {
            s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
        }
        s[12] = "4";  // bits 12-15 of the time_hi_and_version field to 0010
        s[16] = hexDigits.substr((s[16] & 0x3) | 0x8, 1);  // bits 6-7 of the clock_seq_hi_and_reserved to 01

        var uuid = s.join("");
        return uuid;
    };

    //Fix raw text to parse correctly in crazy XML
    function xmlencode(string) {
        return string.replace(/\&/g,'&'+'amp;')
            .replace(/</g,'&'+'lt;')
            .replace(/>/g,'&'+'gt;')
            .replace(/\'/g,'&'+'apos;')
            .replace(/\"/g,'&'+'quot;')
            .replace(/`/g,'&'+'#96;');
    }

    //Map from terminal commands to CSS classes
    var ansi_colormap = {
        "01":"ansibold",

        "30":"ansiblack",
        "31":"ansired",
        "32":"ansigreen",
        "33":"ansiyellow",
        "34":"ansiblue",
        "35":"ansipurple",
        "36":"ansicyan",
        "37":"ansigray",

        "40":"ansibgblack",
        "41":"ansibgred",
        "42":"ansibggreen",
        "44":"ansibgyellow",
        "44":"ansibgblue",
        "45":"ansibgpurple",
        "46":"ansibgcyan",
        "47":"ansibggray"
    };

    function _process_numbers(attrs, numbers) {
        // process ansi escapes
        var n = numbers.shift();
        if (ansi_colormap[n]) {
            if ( ! attrs["class"] ) {
                attrs["class"] = ansi_colormap[n];
            } else {
                attrs["class"] += " " + ansi_colormap[n];
            }
        } else if (n == "38" || n == "48") {
            // 256-color
            if (numbers.length < 2) {
                console.log("Not enough fields for 256-color escapes", numbers);
                return;
            }

            var index_or_rgb = numbers.shift();
            var r,g,b;
            if (index_or_rgb == "5") {
                // indexed 256 color
                var idx = parseInt(numbers.shift());
                if (idx < 16) {
                    // indexed ANSI
                    // ignore bright / non-bright distinction
                    idx = idx % 8;
                    var ansiclass = ansi_colormap[n[0] + (idx % 8).toString()];
                    if ( ! attrs["class"] ) {
                        attrs["class"] = ansiclass;
                    } else {
                        attrs["class"] += " " + ansiclass;
                    }
                    return;
                } else if (idx < 232) {
                    // 216 color 6x6x6 RGB
                    idx = idx - 16;
                    b = idx % 6;
                    g = Math.floor(idx / 6) % 6;
                    r = Math.floor(idx / 36) % 6;
                    // convert to rgb
                    r = (r * 51);
                    g = (g * 51);
                    b = (b * 51);
                } else {
                    // grayscale
                    idx = idx - 231;
                    // it's 1-24 and should *not* include black or white,
                    // so a 26 point scale
                    r = g = b = Math.floor(idx * 256 / 26);
                }
            } else if (index_or_rgb == "2") {
                // Simple 24 bit RGB
                if (numbers.length > 3) {
                    console.log("Not enough fields for RGB", numbers);
                    return;
                }
                r = numbers.shift();
                g = numbers.shift();
                b = numbers.shift();
            } else {
                console.log("unrecognized control", numbers);
                return;
            }
            if (r !== undefined) {
                // apply the rgb color
                var line;
                if (n == "38") {
                    line = "color: ";
                } else {
                    line = "background-color: ";
                }
                line = line + "rgb(" + r + "," + g + "," + b + ");"
                if ( !attrs["style"] ) {
                    attrs["style"] = line;
                } else {
                    attrs["style"] += " " + line;
                }
            }
        }
    }

    function ansispan(str) {
        // ansispan function adapted from github.com/mmalecki/ansispan (MIT License)
        // regular ansi escapes (using the table above)
        return str.replace(/\033\[(0?[01]|22|39)?([;\d]+)?m/g, function(match, prefix, pattern) {
            if (!pattern) {
                // [(01|22|39|)m close spans
                return "";
            }
            // consume sequence of color escapes
            var numbers = pattern.match(/\d+/g);
            var attrs = {};
            while (numbers.length > 0) {
                _process_numbers(attrs, numbers);
            }

            var span = "";
        });
    };

    // Transform ANSI color escape codes into HTML  tags with css
    // classes listed in the above ansi_colormap object. The actual color used
    // are set in the css file.
    function fixConsole(txt) {
        txt = xmlencode(txt);
        var re = /\033\[([\dA-Fa-f;]*?)m/;
        var opened = false;
        var cmds = [];
        var opener = "";
        var closer = "";

        // Strip all ANSI codes that are not color related.  Matches
        // all ANSI codes that do not end with "m".
        var ignored_re = /(?=(\033\[[\d;=]*[a-ln-zA-Z]{1}))\1(?!m)/g;
        txt = txt.replace(ignored_re, "");

        // color ansi codes
        txt = ansispan(txt);
        return txt;
    }

    // Remove chunks that should be overridden by the effect of
    // carriage return characters
    function fixCarriageReturn(txt) {
        var tmp = txt;
        do {
            txt = tmp;
            tmp = txt.replace(/\r+\n/gm, '\n'); // \r followed by \n --> newline
            tmp = tmp.replace(/^.*\r+/gm, '');  // Other \r --> clear line
        } while (tmp.length < txt.length);
        return txt;
    }

    // Locate any URLs and convert them to a anchor tag
    function autoLinkUrls(txt) {
        return txt.replace(/(^|\s)(https?|ftp)(:[^'">\s]+)/gi,
            "$1$2$3");
    }

    // some keycodes that seem to be platform/browser independent
    var keycodes = {
                BACKSPACE:  8,
                TAB      :  9,
                ENTER    : 13,
                SHIFT    : 16,
                CTRL     : 17,
                CONTROL  : 17,
                ALT      : 18,
                CAPS_LOCK: 20,
                ESC      : 27,
                SPACE    : 32,
                PGUP     : 33,
                PGDOWN   : 34,
                END      : 35,
                HOME     : 36,
                LEFT_ARROW: 37,
                LEFTARROW: 37,
                LEFT     : 37,
                UP_ARROW : 38,
                UPARROW  : 38,
                UP       : 38,
                RIGHT_ARROW:39,
                RIGHTARROW:39,
                RIGHT    : 39,
                DOWN_ARROW: 40,
                DOWNARROW: 40,
                DOWN     : 40,
                // all three of these keys may be COMMAND on OS X:
                LEFT_SUPER : 91,
                RIGHT_SUPER : 92,
                COMMAND  : 93,
    };

    var points_to_pixels = function (points) {
        // A reasonably good way of converting between points and pixels.
        var test = $('

');
        $(body).append(test);
        var pixel_per_point = test.width()/10000;
        test.remove();
        return Math.floor(points*pixel_per_point);
    };

    // http://stackoverflow.com/questions/2400935/browser-detection-in-javascript
    browser = (function() {
        var N= navigator.appName, ua= navigator.userAgent, tem;
        var M= ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
        if (M && (tem= ua.match(/version\/([\.\d]+)/i))!= null) M[2]= tem[1];
        M= M? [M[1], M[2]]: [N, navigator.appVersion,'-?'];
        return M;
    })();

    return {
        regex_split : regex_split,
        uuid : uuid,
        fixConsole : fixConsole,
        keycodes : keycodes,
        fixCarriageReturn : fixCarriageReturn,
        autoLinkUrls : autoLinkUrls,
        points_to_pixels : points_to_pixels,
        browser : browser
    };

}(IPython));

<|endoftext|>


<commit_before>import React, { createRef } from 'react'
import { travelObjectStartDateComparator } from "../scripts/HelperFunctions"

/**
 * Props:
 * zoom : 13 - higher the number, the more zoomed the map is on center
 * center: {lat:0.0, lng:0.0} - coordinates for center of map
 */

class MapComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      finalizedMarkers: new Map(),
      unfinalizedMarkers: new Map(),
      geoPaths: []
    }
    this.googleMapRef = createRef();
    this.googleMap = undefined
  }

  componentDidMount() {
    this.googleMap = this.createMap();
    this.drawMap()
  }

  /*
   * Updates state with any changes in props
   */
  componentDidUpdate(prevProps) {
    if (prevProps !== this.props) {
      this.clearMap();
      let bounds = this.drawMap();
      this.googleMap.fitBounds(bounds);
    }
  }

  createMap() {
    return new window.google.maps.Map(this.googleMapRef.current, {
      zoom: this.props.zoom,
      center: this.props.center,
    })
  }

  addMarker(coordinates, type, label) {
    // TODO: firebase will provide coordinates as a GeoPoint --> convert to {lat, lng}
    // { lat: coordinates.lat(), lng: coordinates.lng() }

    var iconUrl;
    if (type === "flight") {
      iconUrl = "http://maps.google.com/mapfiles/ms/icons/blue-dot.png"
    } else if (type === "event") {
      iconUrl = "http://maps.google.com/mapfiles/ms/icons/green-dot.png"
    } else {
      iconUrl = "http://maps.google.com/mapfiles/ms/icons/red-dot.png"
    }

    var newMarker = new window.google.maps.Marker({
      position: coordinates,
      map: this.googleMap,
      animation: window.google.maps.Animation.DROP,
      icon: { url: iconUrl }
    })

    // zoom to marker when clicked
    newMarker.addListener('click', () => {
      this.googleMap.setZoom(15);
      this.googleMap.setCenter(newMarker.getPosition());

      // TODO: this.props.onMarkerClicked(id) --> notifies parent that marker clicked
    });

    return newMarker;
  }

  // constructs path object and places on map. Returns path object.
  addPath(map, path, color) {
    // TODO : change to show directions between paths
    // dotted line
    var lineSymbol = {
      path: 'M 0,-1 0,1',
      strokeOpacity: 1,
      scale: 4
    };

    let geoPath = new window.google.maps.Polyline({
      path: path,
      strokeColor: color,
      strokeOpacity: 0,
      strokeWeight: 5,
      icons: [{
        icon: lineSymbol,
        offset: '0',
        repeat: '20px'
      }]
    });

    geoPath.setMap(map);

    return geoPath;
  }

  /*
   * Given a list of travel object data, draws corresponding markers on map and
   * returns hash map containing marker objects
   */
  drawMarkers(list, bounds) {
    // construct hashmap with key: travelObject id, value: marker object
    return list.reduce((hashMap, item) => {
      if (item.type !== "flight") {
        hashMap.set(item.id, { marker: this.addMarker(item.coordinates, item.type, item.id), type: item.type });
        bounds.extend(item.coordinates);
      } else {
        hashMap.set(item.id, {
          marker: {
            departure: this.addMarker(item.departureCoordinates, item.type, item.id),
            arrival: this.addMarker(item.arrivalCoordinates, item.type, item.id)
          }, type: item.type
        });

        bounds.extend(item.departureCoordinates);
        bounds.extend(item.arrivalCoordinates);
      }
      return hashMap;
    }, new Map())
  }

  // splits finalized trips into segments of coordinate pairs
  getPathSegments() {
    var paths = [];
    var curPath = [];

    for (let i = 0; i < this.props.finalized.length; i++) {
      let item = this.props.finalized[i];
      // found flight -> create new path segment
      if (item.type === "flight") {
        if (paths.length !== 0) {
          curPath.push(item.departureCoordinates)
          paths.push(curPath);
        }
        curPath = [item.arrivalCoordinates];
      } else {
        curPath.push(item.coordinates);
        paths.push(curPath);
        curPath = [item.coordinates];
      }
    }

    // add remaining path, if any, to paths
    if (curPath.length > 1) {
      paths.push(curPath);
    }

    return paths;
  }

  sortList(list) {
    return list.sort(travelObjectStartDateComparator)
  }

  /*
   *  Draws path between all finalized travel objects, returns list of path objects
   */
  drawPaths() {
    let paths = this.getPathSegments();

    // add each path to the map and return array of path objects
    var red = 60;
    let change = paths.length === 0 ? 0 : red / (paths.length - 1);
    return paths.map((path) => {
      let color = "hsl(0, 100%, " + red + "%)";
      red -= change;
      return this.addPath(this.googleMap, path, color);
    })
  }

  drawMap() {
    var bounds = new window.google.maps.LatLngBounds();

    let unfinalizedMarkers = this.drawMarkers(this.props.unfinalized, bounds);
    let finalizedMarkers = this.drawMarkers(this.sortList(this.props.finalized), bounds);

    let pathArr = this.drawPaths();

    this.setState({
      unfinalizedMarkers: unfinalizedMarkers,
      finalizedMarkers: finalizedMarkers,
      geoPaths: pathArr
    });

    return bounds;
  }

  removeAllMarkers(hashMap) {
    for (const [key, value] of hashMap) {
      if (value.type !== "flight") {
        value.marker.setMap(null);
      } else {
        value.marker.departure.setMap(null);
        value.marker.arrival.setMap(null);
      }
    }
  }

  clearMap() {
    this.removeAllMarkers(this.state.unfinalizedMarkers);
    this.removeAllMarkers(this.state.finalizedMarkers);

    // remove all paths
    this.state.geoPaths.map((path) => path.setMap(null));
  }

  render() {
    return (
      <div
        id='map'
        ref={this.googleMapRef}
      />
    )
  }
}

export default MapComponent;<commit_msg>Fix map bounds<commit_after>import React, { createRef } from 'react'
import { travelObjectStartDateComparator } from "../scripts/HelperFunctions"

/**
 * Props:
 * zoom : 13 - higher the number, the more zoomed the map is on center
 * center: {lat:0.0, lng:0.0} - coordinates for center of map
 */

class MapComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      finalizedMarkers: new Map(),
      unfinalizedMarkers: new Map(),
      geoPaths: []
    }
    this.googleMapRef = createRef();
    this.googleMap = undefined
  }

  componentDidMount() {
    this.googleMap = this.createMap();
    let bounds = this.drawMap();
    this.googleMap.fitBounds(bounds);
  }

  /*
   * Updates state with any changes in props
   */
  componentDidUpdate(prevProps) {
    if (prevProps !== this.props) {
      this.clearMap();
      this.drawMap();
    }
  }

  createMap() {
    return new window.google.maps.Map(this.googleMapRef.current, {
      zoom: this.props.zoom,
      center: this.props.center,
    })
  }

  addMarker(coordinates, type, label) {
    // TODO: firebase will provide coordinates as a GeoPoint --> convert to {lat, lng}
    // { lat: coordinates.lat(), lng: coordinates.lng() }

    var iconUrl;
    if (type === "flight") {
      iconUrl = "http://maps.google.com/mapfiles/ms/icons/blue-dot.png"
    } else if (type === "event") {
      iconUrl = "http://maps.google.com/mapfiles/ms/icons/green-dot.png"
    } else {
      iconUrl = "http://maps.google.com/mapfiles/ms/icons/red-dot.png"
    }

    var newMarker = new window.google.maps.Marker({
      position: coordinates,
      map: this.googleMap,
      animation: window.google.maps.Animation.DROP,
      icon: { url: iconUrl }
    })

    // zoom to marker when clicked
    newMarker.addListener('click', () => {
      this.googleMap.setZoom(15);
      this.googleMap.setCenter(newMarker.getPosition());

      // TODO: this.props.onMarkerClicked(id) --> notifies parent that marker clicked
    });

    return newMarker;
  }

  // constructs path object and places on map. Returns path object.
  addPath(map, path, color) {
    // TODO : change to show directions between paths
    // dotted line
    var lineSymbol = {
      path: 'M 0,-1 0,1',
      strokeOpacity: 1,
      scale: 4
    };

    let geoPath = new window.google.maps.Polyline({
      path: path,
      strokeColor: color,
      strokeOpacity: 0,
      strokeWeight: 5,
      icons: [{
        icon: lineSymbol,
        offset: '0',
        repeat: '20px'
      }]
    });

    geoPath.setMap(map);

    return geoPath;
  }

  /*
   * Given a list of travel object data, draws corresponding markers on map and
   * returns hash map containing marker objects
   */
  drawMarkers(list, bounds) {
    // construct hashmap with key: travelObject id, value: marker object
    return list.reduce((hashMap, item) => {
      if (item.type !== "flight") {
        hashMap.set(item.id, { marker: this.addMarker(item.coordinates, item.type, item.id), type: item.type });
        bounds.extend(item.coordinates);
      } else {
        hashMap.set(item.id, {
          marker: {
            departure: this.addMarker(item.departureCoordinates, item.type, item.id),
            arrival: this.addMarker(item.arrivalCoordinates, item.type, item.id)
          }, type: item.type
        });

        bounds.extend(item.departureCoordinates);
        bounds.extend(item.arrivalCoordinates);
      }
      return hashMap;
    }, new Map())
  }

  // splits finalized trips into segments of coordinate pairs
  getPathSegments() {
    var paths = [];
    var curPath = [];

    for (let i = 0; i < this.props.finalized.length; i++) {
      let item = this.props.finalized[i];
      // found flight -> create new path segment
      if (item.type === "flight") {
        if (paths.length !== 0) {
          curPath.push(item.departureCoordinates)
          paths.push(curPath);
        }
        curPath = [item.arrivalCoordinates];
      } else {
        curPath.push(item.coordinates);
        paths.push(curPath);
        curPath = [item.coordinates];
      }
    }

    // add remaining path, if any, to paths
    if (curPath.length > 1) {
      paths.push(curPath);
    }

    return paths;
  }

  sortList(list) {
    return list.sort(travelObjectStartDateComparator)
  }

  /*
   *  Draws path between all finalized travel objects, returns list of path objects
   */
  drawPaths() {
    let paths = this.getPathSegments();

    // add each path to the map and return array of path objects
    var red = 60;
    let change = paths.length === 0 ? 0 : red / (paths.length - 1);
    return paths.map((path) => {
      let color = "hsl(0, 100%, " + red + "%)";
      red -= change;
      return this.addPath(this.googleMap, path, color);
    })
  }

  drawMap() {
    var bounds = new window.google.maps.LatLngBounds();

    let unfinalizedMarkers = this.drawMarkers(this.props.unfinalized, bounds);
    let finalizedMarkers = this.drawMarkers(this.sortList(this.props.finalized), bounds);

    let pathArr = this.drawPaths();

    this.setState({
      unfinalizedMarkers: unfinalizedMarkers,
      finalizedMarkers: finalizedMarkers,
      geoPaths: pathArr
    });

    return bounds;
  }

  removeAllMarkers(hashMap) {
    for (const [key, value] of hashMap) {
      if (value.type !== "flight") {
        value.marker.setMap(null);
      } else {
        value.marker.departure.setMap(null);
        value.marker.arrival.setMap(null);
      }
    }
  }

  clearMap() {
    this.removeAllMarkers(this.state.unfinalizedMarkers);
    this.removeAllMarkers(this.state.finalizedMarkers);

    // remove all paths
    this.state.geoPaths.map((path) => path.setMap(null));
  }

  render() {
    return (
      <div
        id='map'
        ref={this.googleMapRef}
      />
    )
  }
}

export default MapComponent;<|endoftext|>