<commit_before>class App extends HTMLElement {
  constructor(playbackData, initialMode) {
    super();
    //create the main playback 'engine' which drives the ui
    this.playbackEngine = new PlaybackEngine(playbackData);

    this.initialMode = initialMode;
    this.activeMode = '';
    this.playbackNavigatorWidth = window.innerWidth * .27;
    this.editorProperties = {
      fontSize: 20,
      //potential ace editor themes: monokai, gruvbox, idle_fingers, pastel_on_dark, tomorrow_night, tomorrow_night_eighties, twilight
      aceTheme: 'ace/theme/tomorrow_night_eighties',
    };

    this.autoPlayback = {
      isPaused: true,
      playTimer: null,
      playbackSpeedMs: 75,
    };

    this.attachShadow({ mode: 'open' });
    this.shadowRoot.appendChild(this.getTemplate());
  }

  getTemplate() {
    const template = document.createElement('template');
    template.innerHTML = `

`;

    return template.content.cloneNode(true);
  }

  connectedCallback() {
    //change the page's title
    document.title = this.playbackEngine.playbackData.playbackTitle;

    //create the initial components
    //title bar
    const titleBar = this.shadowRoot.querySelector('.titleBar');
    titleBar.appendChild(new TitleBar(this.playbackEngine.playbackData.playbackTitle, this.initialMode, this.playbackEngine));

    //set the initial mode ('code' or 'blog')
    this.changeMode(this.initialMode);

    //setup the custom event listeners
    this.addEventListeners();
  }

  disconnectedCallback() {
  }

  changeMode(newMode) {
    //if the mode has changed
    if(this.activeMode !== newMode) {
      //make sure playback is paused
      this.togglePlayPause(true);

      //clear out the old view
      const playbackContent = this.shadowRoot.querySelector('.playbackContent');
      playbackContent.innerHTML = '';

      let newView;
      //create the requested view
      if(newMode === 'code') {
        newView = new CodeView({
          editorProperties: this.editorProperties,
          playbackNavigatorWidth: this.playbackNavigatorWidth,
          playbackEngine: this.playbackEngine
        });
      } else { //blog view
        newView = new BlogView({
          editorProperties: this.editorProperties,
          playbackEngine: this.playbackEngine
        });
      }

      //add the new view
      playbackContent.appendChild(newView);

      //store the current mode
      this.activeMode = newMode;
    }
  }

  addEventListeners() {
    //code mode to blog mode or vice versa
    this.shadowRoot.addEventListener('mode-change', event => {
      //switch to a different mode ('code' or 'blog')
      this.changeMode(event.detail.mode);
      event.preventDefault();
    });

    //a comment was selected
    this.shadowRoot.addEventListener('active-comment', event => {
      //move to the selected comment
      this.moveToSelectedComment(event.detail.activeCommentId);
      event.preventDefault();
    });

    //the width of the code view has changed
    this.shadowRoot.addEventListener('code-view-width-change', event => {
      //set the width of the pb nav and editor view
      this.setplaybackNavigatorWidth(event.detail.width);
      event.preventDefault();
    });

    //play
    this.shadowRoot.addEventListener('play-button-click', event => {
      //begin animated playback
      this.togglePlayPause(false);
      event.preventDefault();
    });

    //pause
    this.shadowRoot.addEventListener('pause-button-click', event => {
      //pause animated playback
      this.togglePlayPause(true);
      event.preventDefault();
    });

    //display next comment
    this.shadowRoot.addEventListener('next-comment-button-click', event => {
      //move to the next comment
      this.moveToNextComment();
      event.preventDefault();
    });

    //slider has changed
    this.shadowRoot.addEventListener('slide-to-position', event => {
      this.sliderUpdate(event.detail.newPosition);
      event.preventDefault();
    });

    //a file has been selected
    this.shadowRoot.addEventListener('active-file', event => {
      this.changeActiveFile(event.detail.activeFileId);
      event.preventDefault();
    });

    //playback nav tab switch
    this.shadowRoot.addEventListener('playback-navigator-tab-switch', event => {
      this.changePlaybackNavigatorTab(event.detail.newPlaybackNavTab)
      event.preventDefault();
    });

    //new search bar text entered
    this.shadowRoot.addEventListener('search', event => {
      const eventText = event.detail.searchText;
      this.handleSearch(eventText);
    });

    //request an increase in the editor font size
    this.shadowRoot.addEventListener('increase-font', event => {
      this.increaseEditorFontSize();
    });

    //request a decrease in the editor font size
    this.shadowRoot.addEventListener('decrease-font', event => {
      this.decreaseEditorFontSize();
    });

    document.addEventListener('keydown', event => {
      //get the state of the keys
      const keyPressed = event.key;
      const shiftPressed = event.shiftKey;
      const ctrlPressed = event.ctrlKey;

      //keyboard controls
      if (ctrlPressed && shiftPressed && keyPressed === 'ArrowRight') { //ctrl + shift + right arrow press
        this.moveToEndOfPlayback();
        event.preventDefault();
      } else if(shiftPressed && keyPressed === 'ArrowRight') { //shift + right arrow press
        this.moveToNextComment();
        event.preventDefault();
      } else if(keyPressed === 'ArrowRight') { //right arrow press
        //move to the next event
        this.togglePlayPause(true);
        this.playNextEvent();
        event.preventDefault();
      } else if (ctrlPressed && shiftPressed && keyPressed === 'ArrowLeft') { //ctrl + shift + left arrow press
        this.moveToBeginningOfPlayback();
        event.preventDefault();
      } else if (shiftPressed && keyPressed === 'ArrowLeft') { //shift + left arrow press
        this.moveToPreviousComment();
        event.preventDefault();
      } else if (keyPressed === 'ArrowLeft') {//left arrow press
          //move to the previous event
          this.togglePlayPause(true);
          this.playPreviousEvent();
          event.preventDefault();
      } else if (ctrlPressed && keyPressed === '=') { //ctrl + plus button press (the + is a key combo shift + =)
        //make the font bigger
        increaseEditorFontSize();
        event.preventDefault();
      } else if (ctrlPressed && keyPressed === '-') { //ctrl + minus button press
        //make the font smaller
        decreaseEditorFontSize();
        event.preventDefault();
      } else if (event.code === "Space") {
        //toggle play/pause
        this.togglePlayPause(!this.autoPlayback.isPaused);
        event.preventDefault();
      }
    });
  }

  //handles the search from the search bar
  handleSearch(searchText) {
    //get the search results and then display them
    const searchResults = this.playbackEngine.performSearch(searchText);

    //display results in code/blog mode
    if (this.activeMode === 'code') {
      const codeView = this.shadowRoot.querySelector('st-code-view');
      codeView.displaySearchResults(searchResults);
    } else {
      const blogView = this.shadowRoot.querySelector('st-blog-view');
      blogView.displaySearchResults(searchResults);
    }

    //display search results in the title bar
    const titleBar = this.shadowRoot.querySelector('st-title-bar');
    titleBar.displaySearchResults(searchResults);
  }

  //used to switch from play->pause and pause->play
  togglePlayPause = (newIsPaused) => {
    if (newIsPaused === true) { //starting pause
      //cancel timer
      clearInterval(this.autoPlayback.playTimer);
      this.autoPlayback.playTimer = null;
    } else { //starting play
      //start timer
      if (this.autoPlayback.playTimer === null) {
        //increment one event per interval
        this.autoPlayback.playTimer = setInterval(this.playNextEvent, this.autoPlayback.playbackSpeedMs);
      }
    }
    this.autoPlayback.isPaused = newIsPaused;
  }

  //interval function used to animate the events during a playback when the play button is pressed
  playNextEvent = () => {
    //move forward one step
    this.playbackEngine.stepForward(1);

    //update the code view
    const codeView = this.shadowRoot.querySelector('st-code-view');
    if (this.playbackEngine.activeComment.pausedOnComment) {
      //pause
      this.togglePlayPause(true);
      //display the new comment
      codeView.updateSelectedComment();
    } else if(this.playbackEngine.currentEventIndex === this.playbackEngine.playbackData.events.length - 1) {
      //if there are no more events, pause and update the editor
      this.togglePlayPause(true);
      codeView.updateSliderMoved();
    } else {
      //update the editor and keep moving
      codeView.updateSliderMoved(false);
    }
  }

  //used to take one step backward
  playPreviousEvent = () => {
    //make sure playback is paused
    this.togglePlayPause(true);

    //move backward one step
    this.playbackEngine.stepBackward(1);

    //update the code view
    const codeView = this.shadowRoot.querySelector('st-code-view');
    //update the editor
    codeView.updateSliderMoved(false);
  }

  //used when a file tab is selected or a file is chosen in the file system view
  changeActiveFile = (fileId) => {
    //make sure playback is paused
    this.togglePlayPause(true);

    //update the active file
    this.playbackEngine.changeActiveFile(fileId);

    //update the editor
    const codeView = this.shadowRoot.querySelector('st-code-view');
    codeView.updateActiveFile();
  }

  //used when the slider moves
  sliderUpdate = (newPosition) => {
    //make sure playback is paused
    this.togglePlayPause(true);

    //move to the new position
    this.playbackEngine.stepToEventNumber(newPosition);

    const codeView = this.shadowRoot.querySelector('st-code-view');
    //if there is a comment at the new event
    if (this.playbackEngine.activeComment.pausedOnComment) {
      codeView.updateSelectedComment();
    } else {
      codeView.updateSliderMoved();
    }
  }

  //used when a comment is clicked on, this can happen in either 'code' or 'blog' mode
  moveToSelectedComment = (commentId) => {
    //if this requires some movement
    //was previously not on a comment OR a new comment was selected
    if(this.playbackEngine.activeComment.pausedOnComment === false || this.playbackEngine.activeComment.comment.id !== commentId) {
      //make sure playback is paused
      this.togglePlayPause(true);

      //move to the selected comment
      this.playbackEngine.stepToCommentById(commentId);

      //this can happen in either 'code' or 'blog' mode so check which one the app is in
      if(this.activeMode === 'code') {
        const codeView = this.shadowRoot.querySelector('st-code-view');
        codeView.updateSelectedComment();
      } else { //blog mode
        const blogView = this.shadowRoot.querySelector('st-blog-view');
        blogView.updateSelectedComment();
      }
    }
  }

  //used when the user clicks the button to move to the next comment
  moveToNextComment = () => {
    //make sure playback is paused
    this.togglePlayPause(true);

    //move to the next comment
    this.playbackEngine.stepToNextComment();

    //update the editor
    const codeView = this.shadowRoot.querySelector('st-code-view');
    codeView.updateSelectedComment();
  }

  //used when the user wants to move to the previous comment
  moveToPreviousComment = () => {
    //make sure playback is paused
    this.togglePlayPause(true);

    //move to the next comment
    this.playbackEngine.stepToPreviousComment();

    //update the editor
    const codeView = this.shadowRoot.querySelector('st-code-view');
    codeView.updateSelectedComment();
  }

  //used when the user wants to move to the end of the playback
  moveToEndOfPlayback = () => {
    //make sure playback is paused
    this.togglePlayPause(true);

    //move to the end of the playback
    this.playbackEngine.stepToEnd();

    //update the editor
    const codeView = this.shadowRoot.querySelector('st-code-view');
    codeView.updateSelectedComment();
  }

  //used when the user wants to move to the beginning of the playback
  moveToBeginningOfPlayback = () => {
    //make sure playback is paused
    this.togglePlayPause(true);

    //move to the beginning of the playback
    this.playbackEngine.stepToBeginning();

    //update the editor
    const codeView = this.shadowRoot.querySelector('st-code-view');
    codeView.updateSelectedComment();
  }

  changePlaybackNavigatorTab = (newPlaybackNavigatorTab) => {
    //make sure playback is paused
    this.togglePlayPause(true);
  }

  setplaybackNavigatorWidth(newWidth) {
    this.playbackNavigatorWidth = newWidth;
  }

  increaseEditorFontSize() {
    //make the font bigger
    this.editorProperties.fontSize = this.editorProperties.fontSize + 4;
    const codeView = this.shadowRoot.querySelector('st-code-view');
    //update the editor
    codeView.updateEditorFontSize(this.editorProperties.fontSize);
  }

  decreaseEditorFontSize() {
    //make the font smaller
    this.editorProperties.fontSize = this.editorProperties.fontSize - 2;
    const codeView = this.shadowRoot.querySelector('st-code-view');
    //update the editor
    codeView.updateEditorFontSize(this.editorProperties.fontSize);
  }
}

window.customElements.define('st-app', App);<commit_msg>Fixed small bug I missed in the merge<commit_after>class App extends HTMLElement {
  constructor(playbackData, initialMode) {
    super();
    //create the main playback 'engine' which drives the ui
    this.playbackEngine = new PlaybackEngine(playbackData);

    this.initialMode = initialMode;
    this.activeMode = '';
    this.playbackNavigatorWidth = window.innerWidth * .27;
    this.editorProperties = {
      fontSize: 20,
      //potential ace editor themes: monokai, gruvbox, idle_fingers, pastel_on_dark, tomorrow_night, tomorrow_night_eighties, twilight
      aceTheme: 'ace/theme/tomorrow_night_eighties',
    };

    this.autoPlayback = {
      isPaused: true,
      playTimer: null,
      playbackSpeedMs: 75,
    };

    this.attachShadow({ mode: 'open' });
    this.shadowRoot.appendChild(this.getTemplate());
  }

  getTemplate() {
    const template = document.createElement('template');
    template.innerHTML = `

`;

    return template.content.cloneNode(true);
  }

  connectedCallback() {
    //change the page's title
    document.title = this.playbackEngine.playbackData.playbackTitle;

    //create the initial components
    //title bar
    const titleBar = this.shadowRoot.querySelector('.titleBar');
    titleBar.appendChild(new TitleBar(this.playbackEngine.playbackData.playbackTitle, this.initialMode, this.playbackEngine));

    //set the initial mode ('code' or 'blog')
    this.changeMode(this.initialMode);

    //setup the custom event listeners
    this.addEventListeners();
  }

  disconnectedCallback() {
  }

  changeMode(newMode) {
    //if the mode has changed
    if(this.activeMode !== newMode) {
      //make sure playback is paused
      this.togglePlayPause(true);

      //clear out the old view
      const playbackContent = this.shadowRoot.querySelector('.playbackContent');
      playbackContent.innerHTML = '';

      let newView;
      //create the requested view
      if(newMode === 'code') {
        newView = new CodeView({
          editorProperties: this.editorProperties,
          playbackNavigatorWidth: this.playbackNavigatorWidth,
          playbackEngine: this.playbackEngine
        });
      } else { //blog view
        newView = new BlogView({
          editorProperties: this.editorProperties,
          playbackEngine: this.playbackEngine
        });
      }

      //add the new view
      playbackContent.appendChild(newView);

      //store the current mode
      this.activeMode = newMode;
    }
  }

  addEventListeners() {
    //code mode to blog mode or vice versa
    this.shadowRoot.addEventListener('mode-change', event => {
      //switch to a different mode ('code' or 'blog')
      this.changeMode(event.detail.mode);
      event.preventDefault();
    });

    //a comment was selected
    this.shadowRoot.addEventListener('active-comment', event => {
      //move to the selected comment
      this.moveToSelectedComment(event.detail.activeCommentId);
      event.preventDefault();
    });

    //the width of the code view has changed
    this.shadowRoot.addEventListener('code-view-width-change', event => {
      //set the width of the pb nav and editor view
      this.setplaybackNavigatorWidth(event.detail.width);
      event.preventDefault();
    });

    //play
    this.shadowRoot.addEventListener('play-button-click', event => {
      //begin animated playback
      this.togglePlayPause(false);
      event.preventDefault();
    });

    //pause
    this.shadowRoot.addEventListener('pause-button-click', event => {
      //pause animated playback
      this.togglePlayPause(true);
      event.preventDefault();
    });

    //display next comment
    this.shadowRoot.addEventListener('next-comment-button-click', event => {
      //move to the next comment
      this.moveToNextComment();
      event.preventDefault();
    });

    //slider has changed
    this.shadowRoot.addEventListener('slide-to-position', event => {
      this.sliderUpdate(event.detail.newPosition);
      event.preventDefault();
    });

    //a file has been selected
    this.shadowRoot.addEventListener('active-file', event => {
      this.changeActiveFile(event.detail.activeFileId);
      event.preventDefault();
    });

    //playback nav tab switch
    this.shadowRoot.addEventListener('playback-navigator-tab-switch', event => {
      this.changePlaybackNavigatorTab(event.detail.newPlaybackNavTab)
      event.preventDefault();
    });

    //new search bar text entered
    this.shadowRoot.addEventListener('search', event => {
      const eventText = event.detail.searchText;
      this.handleSearch(eventText);
    });

    //request an increase in the editor font size
    this.shadowRoot.addEventListener('increase-font', event => {
      this.increaseEditorFontSize();
    });

    //request a decrease in the editor font size
    this.shadowRoot.addEventListener('decrease-font', event => {
      this.decreaseEditorFontSize();
    });

    document.addEventListener('keydown', event => {
      //get the state of the keys
      const keyPressed = event.key;
      const shiftPressed = event.shiftKey;
      const ctrlPressed = event.ctrlKey;

      //keyboard controls
      if (ctrlPressed && shiftPressed && keyPressed === 'ArrowRight') { //ctrl + shift + right arrow press
        this.moveToEndOfPlayback();
        event.preventDefault();
      } else if(shiftPressed && keyPressed === 'ArrowRight') { //shift + right arrow press
        this.moveToNextComment();
        event.preventDefault();
      } else if(keyPressed === 'ArrowRight') { //right arrow press
        //move to the next event
        this.togglePlayPause(true);
        this.playNextEvent();
        event.preventDefault();
      } else if (ctrlPressed && shiftPressed && keyPressed === 'ArrowLeft') { //ctrl + shift + left arrow press
        this.moveToBeginningOfPlayback();
        event.preventDefault();
      } else if (shiftPressed && keyPressed === 'ArrowLeft') { //shift + left arrow press
        this.moveToPreviousComment();
        event.preventDefault();
      } else if (keyPressed === 'ArrowLeft') {//left arrow press
          //move to the previous event
          this.togglePlayPause(true);
          this.playPreviousEvent();
          event.preventDefault();
      } else if (ctrlPressed && keyPressed === '=') { //ctrl + plus button press (the + is a key combo shift + =)
        //make the font bigger
        this.increaseEditorFontSize();
        event.preventDefault();
      } else if (ctrlPressed && keyPressed === '-') { //ctrl + minus button press
        //make the font smaller
        this.decreaseEditorFontSize();
        event.preventDefault();
      } else if (event.code === "Space") {
        //toggle play/pause
        this.togglePlayPause(!this.autoPlayback.isPaused);
        event.preventDefault();
      }
    });
  }

  //handles the search from the search bar
  handleSearch(searchText) {
    //get the search results and then display them
    const searchResults = this.playbackEngine.performSearch(searchText);

    //display results in code/blog mode
    if (this.activeMode === 'code') {
      const codeView = this.shadowRoot.querySelector('st-code-view');
      codeView.displaySearchResults(searchResults);
    } else {
      const blogView = this.shadowRoot.querySelector('st-blog-view');
      blogView.displaySearchResults(searchResults);
    }

    //display search results in the title bar
    const titleBar = this.shadowRoot.querySelector('st-title-bar');
    titleBar.displaySearchResults(searchResults);
  }

  //used to switch from play->pause and pause->play
  togglePlayPause = (newIsPaused) => {
    if (newIsPaused === true) { //starting pause
      //cancel timer
      clearInterval(this.autoPlayback.playTimer);
      this.autoPlayback.playTimer = null;
    } else { //starting play
      //start timer
      if (this.autoPlayback.playTimer === null) {
        //increment one event per interval
        this.autoPlayback.playTimer = setInterval(this.playNextEvent, this.autoPlayback.playbackSpeedMs);
      }
    }
    this.autoPlayback.isPaused = newIsPaused;
  }

  //interval function used to animate the events during a playback when the play button is pressed
  playNextEvent = () => {
    //move forward one step
    this.playbackEngine.stepForward(1);

    //update the code view
    const codeView = this.shadowRoot.querySelector('st-code-view');
    if (this.playbackEngine.activeComment.pausedOnComment) {
      //pause
      this.togglePlayPause(true);
      //display the new comment
      codeView.updateSelectedComment();
    } else if(this.playbackEngine.currentEventIndex === this.playbackEngine.playbackData.events.length - 1) {
      //if there are no more events, pause and update the editor
      this.togglePlayPause(true);
      codeView.updateSliderMoved();
    } else {
      //update the editor and keep moving
      codeView.updateSliderMoved(false);
    }
  }

  //used to take one step backward
  playPreviousEvent = () => {
    //make sure playback is paused
    this.togglePlayPause(true);

    //move backward one step
    this.playbackEngine.stepBackward(1);

    //update the code view
    const codeView = this.shadowRoot.querySelector('st-code-view');
    //update the editor
    codeView.updateSliderMoved(false);
  }

  //used when a file tab is selected or a file is chosen in the file system view
  changeActiveFile = (fileId) => {
    //make sure playback is paused
    this.togglePlayPause(true);

    //update the active file
    this.playbackEngine.changeActiveFile(fileId);

    //update the editor
    const codeView = this.shadowRoot.querySelector('st-code-view');
    codeView.updateActiveFile();
  }

  //used when the slider moves
  sliderUpdate = (newPosition) => {
    //make sure playback is paused
    this.togglePlayPause(true);

    //move to the new position
    this.playbackEngine.stepToEventNumber(newPosition);

    const codeView = this.shadowRoot.querySelector('st-code-view');
    //if there is a comment at the new event
    if (this.playbackEngine.activeComment.pausedOnComment) {
      codeView.updateSelectedComment();
    } else {
      codeView.updateSliderMoved();
    }
  }

  //used when a comment is clicked on, this can happen in either 'code' or 'blog' mode
  moveToSelectedComment = (commentId) => {
    //if this requires some movement
    //was previously not on a comment OR a new comment was selected
    if(this.playbackEngine.activeComment.pausedOnComment === false || this.playbackEngine.activeComment.comment.id !== commentId) {
      //make sure playback is paused
      this.togglePlayPause(true);

      //move to the selected comment
      this.playbackEngine.stepToCommentById(commentId);

      //this can happen in either 'code' or 'blog' mode so check which one the app is in
      if(this.activeMode === 'code') {
        const codeView = this.shadowRoot.querySelector('st-code-view');
        codeView.updateSelectedComment();
      } else { //blog mode
        const blogView = this.shadowRoot.querySelector('st-blog-view');
        blogView.updateSelectedComment();
      }
    }
  }

  //used when the user clicks the button to move to the next comment
  moveToNextComment = () => {
    //make sure playback is paused
    this.togglePlayPause(true);

    //move to the next comment
    this.playbackEngine.stepToNextComment();

    //update the editor
    const codeView = this.shadowRoot.querySelector('st-code-view');
    codeView.updateSelectedComment();
  }

  //used when the user wants to move to the previous comment
  moveToPreviousComment = () => {
    //make sure playback is paused
    this.togglePlayPause(true);

    //move to the next comment
    this.playbackEngine.stepToPreviousComment();

    //update the editor
    const codeView = this.shadowRoot.querySelector('st-code-view');
    codeView.updateSelectedComment();
  }

  //used when the user wants to move to the end of the playback
  moveToEndOfPlayback = () => {
    //make sure playback is paused
    this.togglePlayPause(true);

    //move to the end of the playback
    this.playbackEngine.stepToEnd();

    //update the editor
    const codeView = this.shadowRoot.querySelector('st-code-view');
    codeView.updateSelectedComment();
  }

  //used when the user wants to move to the beginning of the playback
  moveToBeginningOfPlayback = () => {
    //make sure playback is paused
    this.togglePlayPause(true);

    //move to the beginning of the playback
    this.playbackEngine.stepToBeginning();

    //update the editor
    const codeView = this.shadowRoot.querySelector('st-code-view');
    codeView.updateSelectedComment();
  }

  changePlaybackNavigatorTab = (newPlaybackNavigatorTab) => {
    //make sure playback is paused
    this.togglePlayPause(true);
  }

  setplaybackNavigatorWidth(newWidth) {
    this.playbackNavigatorWidth = newWidth;
  }

  increaseEditorFontSize() {
    //make the font bigger
    this.editorProperties.fontSize = this.editorProperties.fontSize + 4;
    const codeView = this.shadowRoot.querySelector('st-code-view');
    //update the editor
    codeView.updateEditorFontSize(this.editorProperties.fontSize);
  }

  decreaseEditorFontSize() {
    //make the font smaller
    this.editorProperties.fontSize = this.editorProperties.fontSize - 2;
    const codeView = this.shadowRoot.querySelector('st-code-view');
    //update the editor
    codeView.updateEditorFontSize(this.editorProperties.fontSize);
  }
}

window.customElements.define('st-app', App);<|endoftext|>


<commit_before>module.exports = function(code) {
  return {
    name: 'code',
    process: function(str, lang) {
      return code(str, true, lang);
    }
  };
};<commit_msg>fix(ngdoc/code filter): use code was renamed to encodeCodeBlock<commit_after>module.exports = function(encodeCodeBlock) {
  return {
    name: 'code',
    process: function(str, lang) {
      return encodeCodeBlock(str, true, lang);
    }
  };
};<|endoftext|>


<commit_before>const BinaryPjax   = require('../../base/binary_pjax');
const Client       = require('../../base/client');
const BinarySocket = require('../../base/socket');
const urlForStatic = require('../../../_common/url').urlForStatic;

const PaymentAgentList = (() => {
    let $pa_list_container,
        $agent_template;

    const onLoad = () => {
        $(() => {
            $('#accordion').accordion({
                heightStyle: 'content',
                collapsible: true,
                active     : false,
            });
        });

        $pa_list_container = $('#pa_list');
        $agent_template    = $pa_list_container.find('#accordion').html();

        const residence = Client.get('residence');
        if (!residence || residence.length === 0) {
            BinaryPjax.loadPreviousUrl();
            return;
        }

        sendRequest(residence, true);
    };

    const sendRequest = (country) => {
        const currency = Client.get('currency');
        BinarySocket.send({
            paymentagent_list: country,
            ...(currency && { currency }),
        }).then((response) => {
            if (response.paymentagent_list) {
                populateAgentsList(response.paymentagent_list.list);
            }
        });
    };

    // -----------------------
    // ----- Agents List -----
    // -----------------------
    const populateAgentsList = (list) => {
        if (!list || list.length === 0) {
            showEmptyListMsg();
            return;
        }

        const $accordion = $('<div/>', { id: 'accordion' });

        list.map((agent) => {
            let supported_banks = '';
            if (agent.supported_banks && agent.supported_banks.length > 0) {
                const banks = agent.supported_banks.split(',');
                banks.map((bank) => {
                    supported_banks += bank.length === 0 ?
                        '' :
                        `<img src="${urlForStatic(`images/pages/payment_agent/banks/${bank.toLowerCase()}.png`)}" alt="${bank}" title="${bank}" />`;
                });
            }

            $accordion.append(
                $agent_template
                    .replace(/%name/g, agent.name)
                    .replace(/%currency/g, agent.currencies)
                    .replace(/%minmax/g, `${agent.min_withdrawal} / ${agent.max_withdrawal}`)
                    .replace(/%summary/g, agent.summary)
                    .replace(/%deposit_commission/g, agent.deposit_commission)
                    .replace(/%withdrawal_commission/g, agent.withdrawal_commission)
                    .replace(/%url/g, agent.url)
                    .replace(/%email/g, agent.email)
                    .replace(/%telephone/g, agent.telephone)
                    .replace(/%further_information/g, agent.further_information)
                    .replace(/%supported_banks/g, supported_banks));
        });

        $('.barspinner').setVisibility(0);

        $pa_list_container.empty().append($accordion);

        $('#accordion').accordion({
            heightStyle: 'content',
            collapsible: true,
            active     : false,
        });
    };

    const showEmptyListMsg = () => {
        $('.barspinner').setVisibility(0);
        $('#no_paymentagent').setVisibility(1);
    };

    return {
        onLoad,
    };
})();

module.exports = PaymentAgentList;
<commit_msg>Redirect to set_currency page when currency not set in payment agent deposit page<commit_after>const BinaryPjax   = require('../../base/binary_pjax');
const Client       = require('../../base/client');
const BinarySocket = require('../../base/socket');
const Url          = require('../../../_common/url');
const urlForStatic = require('../../../_common/url').urlForStatic;

const PaymentAgentList = (() => {
    let $pa_list_container,
        $agent_template;

    const onLoad = () => {
        $(() => {
            $('#accordion').accordion({
                heightStyle: 'content',
                collapsible: true,
                active     : false,
            });
        });

        if (!Client.get('currency')) {
            BinaryPjax.load(`${Url.urlFor('user/set-currency')}`);
            return;
        }

        $pa_list_container = $('#pa_list');
        $agent_template    = $pa_list_container.find('#accordion').html();

        const residence = Client.get('residence');
        if (!residence || residence.length === 0) {
            BinaryPjax.loadPreviousUrl();
            return;
        }

        sendRequest(residence, true);
    };

    const sendRequest = (country) => {
        const currency = Client.get('currency');
        BinarySocket.send({
            paymentagent_list: country,
            ...(currency && { currency }),
        }).then((response) => {
            if (response.paymentagent_list) {
                populateAgentsList(response.paymentagent_list.list);
            }
        });
    };

    // -----------------------
    // ----- Agents List -----
    // -----------------------
    const populateAgentsList = (list) => {
        if (!list || list.length === 0) {
            showEmptyListMsg();
            return;
        }

        const $accordion = $('<div/>', { id: 'accordion' });

        list.map((agent) => {
            let supported_banks = '';
            if (agent.supported_banks && agent.supported_banks.length > 0) {
                const banks = agent.supported_banks.split(',');
                banks.map((bank) => {
                    supported_banks += bank.length === 0 ?
                        '' :
                        `<img src="${urlForStatic(`images/pages/payment_agent/banks/${bank.toLowerCase()}.png`)}" alt="${bank}" title="${bank}" />`;
                });
            }

            $accordion.append(
                $agent_template
                    .replace(/%name/g, agent.name)
                    .replace(/%currency/g, agent.currencies)
                    .replace(/%minmax/g, `${agent.min_withdrawal} / ${agent.max_withdrawal}`)
                    .replace(/%summary/g, agent.summary)
                    .replace(/%deposit_commission/g, agent.deposit_commission)
                    .replace(/%withdrawal_commission/g, agent.withdrawal_commission)
                    .replace(/%url/g, agent.url)
                    .replace(/%email/g, agent.email)
                    .replace(/%telephone/g, agent.telephone)
                    .replace(/%further_information/g, agent.further_information)
                    .replace(/%supported_banks/g, supported_banks));
        });

        $('.barspinner').setVisibility(0);

        $pa_list_container.empty().append($accordion);

        $('#accordion').accordion({
            heightStyle: 'content',
            collapsible: true,
            active     : false,
        });
    };

    const showEmptyListMsg = () => {
        $('.barspinner').setVisibility(0);
        $('#no_paymentagent').setVisibility(1);
    };

    return {
        onLoad,
    };
})();

module.exports = PaymentAgentList;
<|endoftext|>


<commit_before>import { caution } from '../images';
import { fieldGeneratorMapping } from '../shared';
import { oppositesToDropdown } from '../../utils';
import config from '../../../../common/const';
import { translate } from '../../../../../common/i18n';

export const marketDropdown = block => {
    block
        .appendDummyInput('MARKETDEFINITION')
        .appendField(`${translate('Market')}:`)
        .appendField(new Blockly.FieldDropdown(fieldGeneratorMapping.MARKET_LIST), 'MARKET_LIST')
        .appendField('>')
        .appendField(new Blockly.FieldDropdown(fieldGeneratorMapping.SUBMARKET_LIST(block)), 'SUBMARKET_LIST')
        .appendField('>')
        .appendField(new Blockly.FieldDropdown(fieldGeneratorMapping.SYMBOL_LIST(block)), 'SYMBOL_LIST');
};

export const tradeTypeDropdown = block => {
    block
        .appendDummyInput('TRADETYPEDEFINITION')
        .appendField(`${translate('Trade Type')}:`)
        .appendField(new Blockly.FieldDropdown(fieldGeneratorMapping.TRADETYPECAT_LIST(block)), 'TRADETYPECAT_LIST')
        .appendField('>')
        .appendField(new Blockly.FieldDropdown(fieldGeneratorMapping.TRADETYPE_LIST(block)), 'TRADETYPE_LIST');
};

export const contractTypes = block => {
    if (!block.getInput('CONTRACT_TYPE')) {
        const getContractTypes = () => {
            const tradeType = block.getFieldValue('TRADETYPE_LIST');
            if (tradeType) {
                return [[translate('Both'), 'both'], ...oppositesToDropdown(config.opposites[tradeType.toUpperCase()])];
            }
            return [['', '']];
        };
        block
            .appendDummyInput('CONTRACT_TYPE')
            .appendField(translate('Contract Type:'))
            .appendField(new Blockly.FieldDropdown(getContractTypes), 'TYPE_LIST');
    }
};

export const candleInterval = block => {
    if (!block.getInput('CANDLE_INTERVAL')) {
        block
            .appendDummyInput('CANDLE_INTERVAL')
            .appendField(translate('Default Candle Interval:'))
            .appendField(new Blockly.FieldDropdown(config.candleIntervals.slice(1)), 'CANDLEINTERVAL_LIST');
    }
};

export const duration = block => {
    if (!block.getInput('DURATION')) {
        block
            .appendValueInput('DURATION')
            .setCheck('Number')
            .appendField(translate('Duration:'))
            .appendField(new Blockly.FieldDropdown([['', '']]), 'DURATIONTYPE_LIST');
    }
};

export const payout = block => {
    if (!block.getInput('AMOUNT')) {
        block
            .appendValueInput('AMOUNT')
            .setCheck('Number')
            .appendField(`${translate('Stake')}:`)
            .appendField(new Blockly.FieldDropdown(config.lists.CURRENCY), 'CURRENCY_LIST');
    }
};

const barrierOffsetGenerator = (inputName, block) => {
    if (!block.getInput(inputName)) {
        // Determine amount of barrier-blocks on workspace
        const labelPrefix = translate('Barrier Offset');
        const barrierNumber = block.inputList.filter(input => /BARRIEROFFSET$/.test(input.name)).length;

        // Set barrier options according to barrierNumber (i.e. + and -)
        const barrierOffsetList = new Blockly.FieldDropdown(config.barrierTypes);
        barrierOffsetList.setValue(config.barrierTypes[barrierNumber % config.barrierTypes.length][1]);

        block
            .appendValueInput(inputName)
            .setCheck('Number')
            .appendField(`${labelPrefix} ${barrierNumber + 1}:`)
            .appendField(barrierOffsetList, `${inputName}TYPE_LIST`);

        const input = block.getInput(inputName);
        input.setVisible(false);
    }
};

export const barrierOffset = block => {
    barrierOffsetGenerator('BARRIEROFFSET', block);
};

export const secondBarrierOffset = block => {
    barrierOffsetGenerator('SECONDBARRIEROFFSET', block);
};

export const prediction = block => {
    const inputName = 'PREDICTION';
    if (!block.getInput(inputName)) {
        block
            .appendValueInput(inputName)
            .setCheck('Number')
            .appendField(`${translate('Prediction')}:`);

        const input = block.getInput(inputName);
        input.setVisible(false);
    }
};

export const restart = block => {
    block
        .appendDummyInput()
        .appendField(`${translate('Restart buy/sell on error')}`)
        .appendField(`(${translate('disable for better performance')}):`)
        .appendField(new Blockly.FieldCheckbox('FALSE'), 'TIME_MACHINE_ENABLED');
    block
        .appendDummyInput()
        .appendField(`${translate('Restart last trade on error')}`)
        .appendField(`(${translate('bot ignores the unsuccessful trade')}):`)
        .appendField(new Blockly.FieldCheckbox('TRUE'), 'RESTARTONERROR')
        .appendField(new Blockly.FieldImage(caution, 15, 15, '!'));
};
<commit_msg>Small refactor<commit_after>import { caution } from '../images';
import { fieldGeneratorMapping } from '../shared';
import { oppositesToDropdown } from '../../utils';
import config from '../../../../common/const';
import { translate } from '../../../../../common/i18n';

export const marketDropdown = block => {
    block
        .appendDummyInput('MARKETDEFINITION')
        .appendField(`${translate('Market')}:`)
        .appendField(new Blockly.FieldDropdown(fieldGeneratorMapping.MARKET_LIST), 'MARKET_LIST')
        .appendField('>')
        .appendField(new Blockly.FieldDropdown(fieldGeneratorMapping.SUBMARKET_LIST(block)), 'SUBMARKET_LIST')
        .appendField('>')
        .appendField(new Blockly.FieldDropdown(fieldGeneratorMapping.SYMBOL_LIST(block)), 'SYMBOL_LIST');
};

export const tradeTypeDropdown = block => {
    block
        .appendDummyInput('TRADETYPEDEFINITION')
        .appendField(`${translate('Trade Type')}:`)
        .appendField(new Blockly.FieldDropdown(fieldGeneratorMapping.TRADETYPECAT_LIST(block)), 'TRADETYPECAT_LIST')
        .appendField('>')
        .appendField(new Blockly.FieldDropdown(fieldGeneratorMapping.TRADETYPE_LIST(block)), 'TRADETYPE_LIST');
};

export const contractTypes = block => {
    if (!block.getInput('CONTRACT_TYPE')) {
        const getContractTypes = () => {
            const tradeType = block.getFieldValue('TRADETYPE_LIST');
            if (tradeType) {
                return [[translate('Both'), 'both'], ...oppositesToDropdown(config.opposites[tradeType.toUpperCase()])];
            }
            return [['', '']];
        };
        block
            .appendDummyInput('CONTRACT_TYPE')
            .appendField(translate('Contract Type:'))
            .appendField(new Blockly.FieldDropdown(getContractTypes), 'TYPE_LIST');
    }
};

export const candleInterval = block => {
    if (!block.getInput('CANDLE_INTERVAL')) {
        block
            .appendDummyInput('CANDLE_INTERVAL')
            .appendField(translate('Default Candle Interval:'))
            .appendField(new Blockly.FieldDropdown(config.candleIntervals.slice(1)), 'CANDLEINTERVAL_LIST');
    }
};

export const duration = block => {
    if (!block.getInput('DURATION')) {
        block
            .appendValueInput('DURATION')
            .setCheck('Number')
            .appendField(translate('Duration:'))
            .appendField(new Blockly.FieldDropdown([['', '']]), 'DURATIONTYPE_LIST');
    }
};

export const payout = block => {
    if (!block.getInput('AMOUNT')) {
        block
            .appendValueInput('AMOUNT')
            .setCheck('Number')
            .appendField(`${translate('Stake')}:`)
            .appendField(new Blockly.FieldDropdown(config.lists.CURRENCY), 'CURRENCY_LIST');
    }
};

const barrierOffsetGenerator = (inputName, block) => {
    if (!block.getInput(inputName)) {
        // Determine amount of barrier-blocks on workspace
        const barrierNumber = block.inputList.filter(input => /BARRIEROFFSET$/.test(input.name)).length;

        // Set barrier options according to barrierNumber (i.e. + and -)
        const barrierOffsetList = new Blockly.FieldDropdown(config.barrierTypes);
        barrierOffsetList.setValue(config.barrierTypes[barrierNumber % config.barrierTypes.length][1]);

        block
            .appendValueInput(inputName)
            .setCheck('Number')
            .appendField(`${translate('Barrier Offset')} ${barrierNumber + 1}:`)
            .appendField(barrierOffsetList, `${inputName}TYPE_LIST`);

        const input = block.getInput(inputName);
        input.setVisible(false);
    }
};

export const barrierOffset = block => {
    barrierOffsetGenerator('BARRIEROFFSET', block);
};

export const secondBarrierOffset = block => {
    barrierOffsetGenerator('SECONDBARRIEROFFSET', block);
};

export const prediction = block => {
    const inputName = 'PREDICTION';
    if (!block.getInput(inputName)) {
        block
            .appendValueInput(inputName)
            .setCheck('Number')
            .appendField(`${translate('Prediction')}:`);

        const input = block.getInput(inputName);
        input.setVisible(false);
    }
};

export const restart = block => {
    block
        .appendDummyInput()
        .appendField(`${translate('Restart buy/sell on error')}`)
        .appendField(`(${translate('disable for better performance')}):`)
        .appendField(new Blockly.FieldCheckbox('FALSE'), 'TIME_MACHINE_ENABLED');
    block
        .appendDummyInput()
        .appendField(`${translate('Restart last trade on error')}`)
        .appendField(`(${translate('bot ignores the unsuccessful trade')}):`)
        .appendField(new Blockly.FieldCheckbox('TRUE'), 'RESTARTONERROR')
        .appendField(new Blockly.FieldImage(caution, 15, 15, '!'));
};
<|endoftext|>


<commit_before>goog.provide('ol.MapBrowserEvent');
goog.provide('ol.MapBrowserEvent.EventType');
goog.provide('ol.MapBrowserEventHandler');

goog.require('goog.asserts');
goog.require('goog.events.BrowserEvent');
goog.require('goog.events.EventTarget');
goog.require('goog.events.EventType');
goog.require('goog.style');
goog.require('ol.Coordinate');
goog.require('ol.MapEvent');
goog.require('ol.Pixel');

/**
 * @constructor
 * @extends {ol.MapEvent}
 * @param {string} type Event type.
 * @param {ol.Map} map Map.
 * @param {goog.events.BrowserEvent} browserEvent Browser event.
 */
ol.MapBrowserEvent = function(type, map, browserEvent) {

  goog.base(this, type, map);

  /**
   * @type {goog.events.BrowserEvent}
   */
  this.browserEvent = browserEvent;

  /**
   * @private
   * @type {ol.Coordinate|undefined}
   */
  this.coordinate_ = undefined;

};
goog.inherits(ol.MapBrowserEvent, ol.MapEvent);

/**
 * @return {ol.Coordinate|undefined} Coordinate.
 */
ol.MapBrowserEvent.prototype.getCoordinate = function() {
  if (goog.isDef(this.coordinate_)) {
    return this.coordinate_;
  } else {
    var map = this.map;
    var browserEvent = this.browserEvent;
    var eventPosition = goog.style.getRelativePosition(
        browserEvent, map.getViewport());
    var pixel = new ol.Pixel(eventPosition.x, eventPosition.y);
    var coordinate = map.getCoordinateFromPixel(pixel);
    this.coordinate_ = coordinate;
    return coordinate;
  }
};

/**
 * @return {boolean} Do we have a left click?
 */
ol.MapBrowserEvent.prototype.isMouseActionButton = function() {
  // always assume a left-click on touch devices
  return ('ontouchstart' in document.documentElement) ||
      this.browserEvent.isMouseActionButton();
};

/**
 * @param {ol.Map} map The map with the viewport to listen to events on.
 * @constructor
 * @extends {goog.events.EventTarget}
 */
ol.MapBrowserEventHandler = function(map) {

  /**
   * This is the element that we will listen to the real events on.
   * @type {ol.Map}
   * @private
   */
  this.map_ = map;

  /**
   * @type {Object}
   * @private
   */
  this.previous_ = null;

  /**
   * @type {boolean}
   * @private
   */
  this.dragged_ = false;

  /**
   * @type {number}
   * @private
   */
  this.timestamp_ = 0;

  /**
   * @type {Array.<number>}
   * @private
   */
  this.dragListenerKeys_ = null;

  /**
   * @type {goog.events.BrowserEvent}
   * @private
   */
  this.down_ = null;

  /**
   * @type {boolean}
   * @private
   */
  this.isTouch_ = document && ('ontouchstart' in document.documentElement);

  var element = this.map_.getViewport();
  goog.events.listen(element,
      this.isTouch_ ?
          goog.events.EventType.TOUCHSTART :
          goog.events.EventType.MOUSEDOWN,
      this.dragstart_, false, this);
  goog.events.listen(element,
      this.isTouch_ ?
          goog.events.EventType.TOUCHEND :
          goog.events.EventType.MOUSEUP,
      this.dblclick_, false, this);
  goog.events.listen(element,
      goog.events.EventType.CLICK, this.click_, false, this);
};
goog.inherits(ol.MapBrowserEventHandler, goog.events.EventTarget);

/**
 * @param {goog.events.BrowserEvent} browserEvent Browser event.
 * @private
 */
ol.MapBrowserEventHandler.prototype.touchEnableBrowserEvent_ =
    function(browserEvent) {
  if (this.isTouch_) {
    goog.asserts.assert(browserEvent instanceof goog.events.BrowserEvent);
    var nativeEvent = browserEvent.getBrowserEvent();
    if (nativeEvent.touches && nativeEvent.touches.length) {
      var nativeTouch = nativeEvent.touches[0];
      browserEvent.clientX = nativeTouch.clientX;
      browserEvent.clientY = nativeTouch.clientY;
    }
  }
};

/**
 * @param {goog.events.BrowserEvent} browserEvent Browser event.
 * @private
 */
ol.MapBrowserEventHandler.prototype.click_ = function(browserEvent) {
  if (!this.dragged_) {
    this.touchEnableBrowserEvent_(this.down_);
    var newEvent = new ol.MapBrowserEvent(
        ol.MapBrowserEvent.EventType.CLICK, this.map_, this.down_);
    this.down_ = null;
    this.dispatchEvent(newEvent);
  }
};

/**
 * @param {goog.events.BrowserEvent} browserEvent Browser event.
 * @private
 */
ol.MapBrowserEventHandler.prototype.dblclick_ = function(browserEvent) {
  if (!this.dragged_) {
    var now = new Date().getTime();
    if (!this.timestamp_ || now - this.timestamp_ > 250) {
      this.timestamp_ = now;
    } else {
      this.timestamp_ = 0;
      this.touchEnableBrowserEvent_(this.down_);
      var newEvent = new ol.MapBrowserEvent(
          ol.MapBrowserEvent.EventType.DBLCLICK, this.map_, this.down_);
      this.down_ = null;
      this.dispatchEvent(newEvent);
    }
  }
};

/**
 * @param {goog.events.BrowserEvent} browserEvent Browser event.
 * @private
 */
ol.MapBrowserEventHandler.prototype.dragstart_ = function(browserEvent) {
  if (!this.previous_) {
    this.down_ = new goog.events.BrowserEvent(browserEvent.getBrowserEvent());
    this.touchEnableBrowserEvent_(browserEvent);
    this.previous_ = {
      clientX: browserEvent.clientX,
      clientY: browserEvent.clientY
    };
    this.dragged_ = false;
    this.dragListenerKeys_ = [
      goog.events.listen(document,
          this.isTouch_ ?
              goog.events.EventType.TOUCHMOVE :
              goog.events.EventType.MOUSEMOVE,
          this.drag_, false, this),
      goog.events.listen(document,
          this.isTouch_ ?
              goog.events.EventType.TOUCHEND :
              goog.events.EventType.MOUSEUP,
          this.dragend_, false, this)
    ];
    var newEvent = new ol.MapBrowserEvent(
        ol.MapBrowserEvent.EventType.DRAGSTART, this.map_, browserEvent);
    this.dispatchEvent(newEvent);
  }
};

/**
 * @param {goog.events.BrowserEvent} browserEvent Browser event.
 * @private
 */
ol.MapBrowserEventHandler.prototype.drag_ = function(browserEvent) {
  this.dragged_ = true;
  this.touchEnableBrowserEvent_(browserEvent);
  this.previous_ = {
    clientX: browserEvent.clientX,
    clientY: browserEvent.clientY
  };
  // prevent viewport dragging on touch devices
  browserEvent.preventDefault();
  var newEvent = new ol.MapBrowserEvent(
      ol.MapBrowserEvent.EventType.DRAG, this.map_, browserEvent);
  this.dispatchEvent(newEvent);
};

/**
 * @param {goog.events.BrowserEvent} browserEvent Browser event.
 * @private
 */
ol.MapBrowserEventHandler.prototype.dragend_ = function(browserEvent) {
  if (this.previous_) {
    goog.array.forEach(this.dragListenerKeys_, goog.events.unlistenByKey);
    this.dragListenerKeys_ = null;
    this.previous_ = null;
    var newEvent = new ol.MapBrowserEvent(
        ol.MapBrowserEvent.EventType.DRAGEND, this.map_, browserEvent);
    this.down_ = null;
    this.dispatchEvent(newEvent);
  }
};

/** @override */
ol.MapBrowserEventHandler.prototype.disposeInternal = function() {
  var element = this.map_.getViewport();
  goog.events.unlisten(element,
      this.isTouch_ ?
          goog.events.EventType.TOUCHSTART :
          goog.events.EventType.MOUSEDOWN,
      this.dragstart_, false, this);
  goog.events.unlisten(element,
      this.isTouch_ ?
          goog.events.EventType.TOUCHEND :
          goog.events.EventType.MOUSEUP,
      this.dblclick_, false, this);
  goog.events.unlisten(element,
      goog.events.EventType.CLICK, this.click_, false, this);
  goog.asserts.assert(goog.isDef(this.dragListenerKeys_));
  goog.array.forEach(this.dragListenerKeys_, goog.events.unlistenByKey);
  this.dragListenerKeys_ = null;
};

/**
 * Constants for event names.
 * @enum {string}
 */
ol.MapBrowserEvent.EventType = {
  CLICK: goog.events.EventType.CLICK,
  DBLCLICK: goog.events.EventType.DBLCLICK,
  DRAGSTART: 'dragstart',
  DRAG: 'drag',
  DRAGEND: 'dragend'
};
<commit_msg>We can rely on the click event<commit_after>goog.provide('ol.MapBrowserEvent');
goog.provide('ol.MapBrowserEvent.EventType');
goog.provide('ol.MapBrowserEventHandler');

goog.require('goog.asserts');
goog.require('goog.events.BrowserEvent');
goog.require('goog.events.EventTarget');
goog.require('goog.events.EventType');
goog.require('goog.style');
goog.require('ol.Coordinate');
goog.require('ol.MapEvent');
goog.require('ol.Pixel');

/**
 * @constructor
 * @extends {ol.MapEvent}
 * @param {string} type Event type.
 * @param {ol.Map} map Map.
 * @param {goog.events.BrowserEvent} browserEvent Browser event.
 */
ol.MapBrowserEvent = function(type, map, browserEvent) {

  goog.base(this, type, map);

  /**
   * @type {goog.events.BrowserEvent}
   */
  this.browserEvent = browserEvent;

  /**
   * @private
   * @type {ol.Coordinate|undefined}
   */
  this.coordinate_ = undefined;

};
goog.inherits(ol.MapBrowserEvent, ol.MapEvent);

/**
 * @return {ol.Coordinate|undefined} Coordinate.
 */
ol.MapBrowserEvent.prototype.getCoordinate = function() {
  if (goog.isDef(this.coordinate_)) {
    return this.coordinate_;
  } else {
    var map = this.map;
    var browserEvent = this.browserEvent;
    var eventPosition = goog.style.getRelativePosition(
        browserEvent, map.getViewport());
    var pixel = new ol.Pixel(eventPosition.x, eventPosition.y);
    var coordinate = map.getCoordinateFromPixel(pixel);
    this.coordinate_ = coordinate;
    return coordinate;
  }
};

/**
 * @return {boolean} Do we have a left click?
 */
ol.MapBrowserEvent.prototype.isMouseActionButton = function() {
  // always assume a left-click on touch devices
  return ('ontouchstart' in document.documentElement) ||
      this.browserEvent.isMouseActionButton();
};

/**
 * @param {ol.Map} map The map with the viewport to listen to events on.
 * @constructor
 * @extends {goog.events.EventTarget}
 */
ol.MapBrowserEventHandler = function(map) {

  /**
   * This is the element that we will listen to the real events on.
   * @type {ol.Map}
   * @private
   */
  this.map_ = map;

  /**
   * @type {Object}
   * @private
   */
  this.previous_ = null;

  /**
   * @type {boolean}
   * @private
   */
  this.dragged_ = false;

  /**
   * @type {number}
   * @private
   */
  this.timestamp_ = 0;

  /**
   * @type {Array.<number>}
   * @private
   */
  this.dragListenerKeys_ = null;

  /**
   * @type {goog.events.BrowserEvent}
   * @private
   */
  this.down_ = null;

  /**
   * @type {boolean}
   * @private
   */
  this.isTouch_ = document && ('ontouchstart' in document.documentElement);

  var element = this.map_.getViewport();
  goog.events.listen(element,
      this.isTouch_ ?
          goog.events.EventType.TOUCHSTART :
          goog.events.EventType.MOUSEDOWN,
      this.dragstart_, false, this);
  goog.events.listen(element,
      this.isTouch_ ?
          goog.events.EventType.TOUCHEND :
          goog.events.EventType.MOUSEUP,
      this.dblclick_, false, this);
  goog.events.listen(element,
      goog.events.EventType.CLICK, this.click_, false, this);
};
goog.inherits(ol.MapBrowserEventHandler, goog.events.EventTarget);

/**
 * @param {goog.events.BrowserEvent} browserEvent Browser event.
 * @private
 */
ol.MapBrowserEventHandler.prototype.touchEnableBrowserEvent_ =
    function(browserEvent) {
  if (this.isTouch_) {
    goog.asserts.assert(browserEvent instanceof goog.events.BrowserEvent);
    var nativeEvent = browserEvent.getBrowserEvent();
    if (nativeEvent.touches && nativeEvent.touches.length) {
      var nativeTouch = nativeEvent.touches[0];
      browserEvent.clientX = nativeTouch.clientX;
      browserEvent.clientY = nativeTouch.clientY;
    }
  }
};

/**
 * @param {goog.events.BrowserEvent} browserEvent Browser event.
 * @private
 */
ol.MapBrowserEventHandler.prototype.click_ = function(browserEvent) {
  if (!this.dragged_) {
    this.touchEnableBrowserEvent_(browserEvent);
    var newEvent = new ol.MapBrowserEvent(
        ol.MapBrowserEvent.EventType.CLICK, this.map_, browserEvent);
    this.down_ = null;
    this.dispatchEvent(newEvent);
  }
};

/**
 * @param {goog.events.BrowserEvent} browserEvent Browser event.
 * @private
 */
ol.MapBrowserEventHandler.prototype.dblclick_ = function(browserEvent) {
  if (!this.dragged_) {
    var now = new Date().getTime();
    if (!this.timestamp_ || now - this.timestamp_ > 250) {
      this.timestamp_ = now;
    } else {
      this.timestamp_ = 0;
      this.touchEnableBrowserEvent_(this.down_);
      var newEvent = new ol.MapBrowserEvent(
          ol.MapBrowserEvent.EventType.DBLCLICK, this.map_, this.down_);
      this.down_ = null;
      this.dispatchEvent(newEvent);
    }
  }
};

/**
 * @param {goog.events.BrowserEvent} browserEvent Browser event.
 * @private
 */
ol.MapBrowserEventHandler.prototype.dragstart_ = function(browserEvent) {
  if (!this.previous_) {
    this.down_ = new goog.events.BrowserEvent(browserEvent.getBrowserEvent());
    this.touchEnableBrowserEvent_(browserEvent);
    this.previous_ = {
      clientX: browserEvent.clientX,
      clientY: browserEvent.clientY
    };
    this.dragged_ = false;
    this.dragListenerKeys_ = [
      goog.events.listen(document,
          this.isTouch_ ?
              goog.events.EventType.TOUCHMOVE :
              goog.events.EventType.MOUSEMOVE,
          this.drag_, false, this),
      goog.events.listen(document,
          this.isTouch_ ?
              goog.events.EventType.TOUCHEND :
              goog.events.EventType.MOUSEUP,
          this.dragend_, false, this)
    ];
    var newEvent = new ol.MapBrowserEvent(
        ol.MapBrowserEvent.EventType.DRAGSTART, this.map_, browserEvent);
    this.dispatchEvent(newEvent);
  }
};

/**
 * @param {goog.events.BrowserEvent} browserEvent Browser event.
 * @private
 */
ol.MapBrowserEventHandler.prototype.drag_ = function(browserEvent) {
  this.dragged_ = true;
  this.touchEnableBrowserEvent_(browserEvent);
  this.previous_ = {
    clientX: browserEvent.clientX,
    clientY: browserEvent.clientY
  };
  // prevent viewport dragging on touch devices
  browserEvent.preventDefault();
  var newEvent = new ol.MapBrowserEvent(
      ol.MapBrowserEvent.EventType.DRAG, this.map_, browserEvent);
  this.dispatchEvent(newEvent);
};

/**
 * @param {goog.events.BrowserEvent} browserEvent Browser event.
 * @private
 */
ol.MapBrowserEventHandler.prototype.dragend_ = function(browserEvent) {
  if (this.previous_) {
    goog.array.forEach(this.dragListenerKeys_, goog.events.unlistenByKey);
    this.dragListenerKeys_ = null;
    this.previous_ = null;
    var newEvent = new ol.MapBrowserEvent(
        ol.MapBrowserEvent.EventType.DRAGEND, this.map_, browserEvent);
    this.down_ = null;
    this.dispatchEvent(newEvent);
  }
};

/** @override */
ol.MapBrowserEventHandler.prototype.disposeInternal = function() {
  var element = this.map_.getViewport();
  goog.events.unlisten(element,
      this.isTouch_ ?
          goog.events.EventType.TOUCHSTART :
          goog.events.EventType.MOUSEDOWN,
      this.dragstart_, false, this);
  goog.events.unlisten(element,
      this.isTouch_ ?
          goog.events.EventType.TOUCHEND :
          goog.events.EventType.MOUSEUP,
      this.dblclick_, false, this);
  goog.events.unlisten(element,
      goog.events.EventType.CLICK, this.click_, false, this);
  goog.asserts.assert(goog.isDef(this.dragListenerKeys_));
  goog.array.forEach(this.dragListenerKeys_, goog.events.unlistenByKey);
  this.dragListenerKeys_ = null;
};

/**
 * Constants for event names.
 * @enum {string}
 */
ol.MapBrowserEvent.EventType = {
  CLICK: goog.events.EventType.CLICK,
  DBLCLICK: goog.events.EventType.DBLCLICK,
  DRAGSTART: 'dragstart',
  DRAG: 'drag',
  DRAGEND: 'dragend'
};
<|endoftext|>


<commit_before>(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(["chartist"], function (Chartist) {
      return (root.returnExportsGlobal = factory(Chartist));
    });
  } else if (typeof exports === 'object') {
    // Node. Does not work with strict CommonJS, but
    // only CommonJS-like enviroments that support module.exports,
    // like Node.
    module.exports = factory(require("chartist"));
  } else {
    root['Chartist.plugins.verticalhint'] = factory(Chartist);
  }
}(this, function (Chartist) {

  /**
  * Chartist.js plugin to display a data label on top of the points in a line chart.
  *
  */
  /* global Chartist */
  (function (window, document, Chartist) {
    'use strict';

    var defaultOptions = {
      valuePrefix: '',
      valueSuffix: '',
      customSelector: '',
      verticalhintOffset: {
        x: 0,
        y: 0
      }
    };

    Chartist.plugins = Chartist.plugins || {};
    Chartist.plugins.verticalhint = function (options) {
      options = Chartist.extend({}, defaultOptions, options);

      return function verticalhint(chart) {
        if (options.customSelector) {
          var verticalhintSelector = options.customSelector;
        }
        else {
          var verticalhintSelector = 'ct-horizontal';
        }
        var $chart = chart.container;

        // this apply chartist default class ct-series-[alphabetical] based on index number
        var classes = Array(26).fill().map((_, i) => String.fromCharCode('a'.charCodeAt(0) + i));

        // chart grid labels
        var horizontalLabels = chart.data.labels.map(function(x){ return x.toString();});

        // custom labels for series, each line should have one
        var seriesLabel = options.seriesLabel;

        // series data
        var series = chart.data.series;

        var $verticalhint = $chart.querySelector('.chartist-verticalhint');
        if (!$verticalhint) {
          $verticalhint = document.createElement('div');
          $verticalhint.className = (!options.class) ? 'chartist-verticalhint' : 'chartist-verticalhint ' + options.class;
          $chart.appendChild($verticalhint);
        }
        var $verticalhintHighlight = $chart.querySelector('.chartist-verticalhint-highlight');
        if (!$verticalhintHighlight) {
          $verticalhintHighlight = document.createElement('div');
          $verticalhintHighlight.className = (!options.class) ? 'chartist-verticalhint-highlight' : 'chartist-verticalhint-highlight ' + options.class;
          $chart.appendChild($verticalhintHighlight);
          $verticalhintHighlight.style.height = '100px';
        }
        var height = $verticalhint.offsetHeight;
        var width = $verticalhint.offsetWidth;

        hide($verticalhint);
        hide($verticalhintHighlight);

        function on(event, selector, callback) {
          $chart.addEventListener(event, function (e) {
            if (!selector || hasClass(e.target, selector))
            callback(e);
          });
        }

        on('mouseover', verticalhintSelector, function (event) {
          var pointText = event.target.innerHTML;
          var $grid = chart.container.querySelector('.ct-grids');
          var index = horizontalLabels.indexOf(pointText);
          if (index === -1) {
            return;
          }
          var value = 0;
          var verticalhintText = '';
          var verticalhintText = addContent(index);

          if (value) {
            value = '' + value + '';
            verticalhintText += value;
          }

          if(verticalhintText) {
            var wid, hei, position, padding;
            wid = (event.target.offsetParent.attributes.width.value / 3);
            hei = $grid.getBBox().height;
            position = setPosition(event, wid, hei+5);
            $verticalhintHighlight.style.width = wid + 'px';
            $verticalhintHighlight.style.height = hei + 'px';
            $verticalhintHighlight.style.left = position.x + 'px';
            $verticalhintHighlight.style.top = position.y + 'px';

            $verticalhint.innerHTML = verticalhintText;
            padding = 10;
            position = setPosition(event, width, height+20);
            $verticalhint.style.left = position.x+width/2+wid/2 + padding + 'px';
            $verticalhint.style.top = position.y + 'px';

            show($verticalhint);
            show($verticalhintHighlight);

            // Remember height and width to avoid wrong position in IE
            height = $verticalhint.offsetHeight;
            width = $verticalhint.offsetWidth;
          }
        });

        on('mouseout', verticalhintSelector, function () {
          hide($verticalhint);
          hide($verticalhintHighlight);
        });

        function addContent(idx) {
          if (typeof series !== 'undefined') {
            var seriesValue = [];
            if (series[0].constructor === Array) { // multidimensional
              for (var key in series) {
                var val = series[key];
                if (typeof val[idx].value !== 'undefined') {
                  seriesValue[key] = val[idx].value;
                }
                else {
                  seriesValue[key] = val[idx];
                }
              }
            }
            else {
              if (typeof series[idx].value !== 'undefined') {
                seriesValue[0] = series[idx].value;
              }
              else {
                seriesValue[0] = series[idx];
              }
            }
            if (seriesValue.length > 0 && seriesValue.length === seriesLabel.length) {
              if (options.contentCallback && typeof options.contentCallback === 'function') {
                return options.contentCallback(seriesLabel, seriesValue, chart);
              }
              else {
                var content = '';
                for (var key in seriesLabel) {
                  content += '
';
                  content += '<svg style="width:15px;height:10px;" class="ct-series-'+classes[key]+'"><line x1="5" y1="5" x2="5" y2="5" class="ct-point"></line></svg>';
                  content += ''+seriesLabel[key]+': ';
                  content += ' '+options.valuePrefix+'';
                  content += ''+seriesValue[key]+'';
                  content += ''+options.valueSuffix+' ';
                  content += '
';
                }
                return content;
              }
            }
          }
        }

        function setPosition(event, width, height) {
          var offsetX = - width / 2 + options.verticalhintOffset.x
          var offsetY = - height + options.verticalhintOffset.y;
          var x = parseInt(event.target.offsetParent.attributes.x.value);
          var y = parseInt(event.target.offsetParent.attributes.y.value);

          return {
            x: x + offsetX,
            y: y + offsetY
          };
        }
      }
    };

    function show(element) {
      if(!hasClass(element, 'verticalhint-show')) {
        element.className = element.className + ' verticalhint-show';
      }
    }

    function hide(element) {
      var regex = new RegExp('verticalhint-show' + '\\s*', 'gi');
      element.className = element.className.replace(regex, '').trim();
    }

    function hasClass(element, className) {
      return (' ' + element.getAttribute('class') + ' ').indexOf(' ' + className + ' ') > -1;
    }

    function next(element, className) {
      do {
        element = element.nextSibling;
      } while (element && !hasClass(element, className));
      return element;
    }

    function text(element) {
      return element.innerText || element.textContent;
    }

  } (window, document, Chartist));

  return Chartist.plugins.verticalhint;

}));
<commit_msg>Add support of bar<commit_after>(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(["chartist"], function (Chartist) {
      return (root.returnExportsGlobal = factory(Chartist));
    });
  } else if (typeof exports === 'object') {
    // Node. Does not work with strict CommonJS, but
    // only CommonJS-like enviroments that support module.exports,
    // like Node.
    module.exports = factory(require("chartist"));
  } else {
    root['Chartist.plugins.verticalhint'] = factory(Chartist);
  }
}(this, function (Chartist) {

  /**
  * Chartist.js plugin to display a data label on top of the points in a line chart.
  *
  */
  /* global Chartist */
  (function (window, document, Chartist) {
    'use strict';

    var defaultOptions = {
      valuePrefix: '',
      valueSuffix: '',
      customSelector: '',
      verticalhintOffset: {
        x: 0,
        y: 0
      }
    };

    Chartist.plugins = Chartist.plugins || {};
    Chartist.plugins.verticalhint = function (options) {
      options = Chartist.extend({}, defaultOptions, options);

      return function verticalhint(chart) {
        if (options.customSelector) {
          var verticalhintSelector = options.customSelector;
        }
        else {
          var verticalhintSelector = 'ct-horizontal';
        }
        var $chart = chart.container;

        // this apply chartist default class ct-series-[alphabetical] based on index number
        var classes = Array(26).fill().map((_, i) => String.fromCharCode('a'.charCodeAt(0) + i));

        // chart grid labels
        var horizontalLabels = chart.data.labels.map(function(x){ return x.toString();});

        // custom labels for series, each line should have one
        var seriesLabel = options.seriesLabel;

        // series data
        var series = chart.data.series;

        var $verticalhint = $chart.querySelector('.chartist-verticalhint');
        if (!$verticalhint) {
          $verticalhint = document.createElement('div');
          $verticalhint.className = (!options.class) ? 'chartist-verticalhint' : 'chartist-verticalhint ' + options.class;
          $chart.appendChild($verticalhint);
        }
        var $verticalhintHighlight = $chart.querySelector('.chartist-verticalhint-highlight');
        if (!$verticalhintHighlight) {
          $verticalhintHighlight = document.createElement('div');
          $verticalhintHighlight.className = (!options.class) ? 'chartist-verticalhint-highlight' : 'chartist-verticalhint-highlight ' + options.class;
          $chart.appendChild($verticalhintHighlight);
          $verticalhintHighlight.style.height = '100px';
        }
        var height = $verticalhint.offsetHeight;
        var width = $verticalhint.offsetWidth;

        hide($verticalhint);
        hide($verticalhintHighlight);

        function on(event, selector, callback) {
          $chart.addEventListener(event, function (e) {
            if (!selector || hasClass(e.target, selector))
            callback(e);
          });
        }

        on('mouseover', verticalhintSelector, function (event) {
          var pointText = event.target.innerHTML;
          var $grid = chart.container.querySelector('.ct-grids');
          var index = horizontalLabels.indexOf(pointText);
          if (index === -1) {
            return;
          }
          var value = 0;
          var verticalhintText = '';
          var verticalhintText = addContent(index);

          if (value) {
            value = '' + value + '';
            verticalhintText += value;
          }

          if(verticalhintText) {
            var wid, hei, position, padding;

            if (chart instanceof Chartist.Bar) {
              wid = event.target.offsetParent.attributes.width.value;
            }
            else {
              wid = (event.target.offsetParent.attributes.width.value / 3);
            }
            hei = $grid.getBBox().height;
            position = setPosition(event, wid, hei+5);
            $verticalhintHighlight.style.width = wid + 'px';
            $verticalhintHighlight.style.height = hei + 'px';
            $verticalhintHighlight.style.left = position.x + 'px';
            $verticalhintHighlight.style.top = position.y + 'px';

            $verticalhint.innerHTML = verticalhintText;
            padding = 10;
            position = setPosition(event, width, height+20);
            $verticalhint.style.left = position.x+width/2+wid/2 + padding + 'px';
            $verticalhint.style.top = position.y + 'px';

            show($verticalhint);
            show($verticalhintHighlight);

            // Remember height and width to avoid wrong position in IE
            height = $verticalhint.offsetHeight;
            width = $verticalhint.offsetWidth;
          }
        });

        on('mouseout', verticalhintSelector, function () {
          hide($verticalhint);
          hide($verticalhintHighlight);
        });

        function addContent(idx) {
          if (typeof series !== 'undefined') {
            var seriesValue = [];
            if (series[0].constructor === Array) { // multidimensional
              for (var key in series) {
                var val = series[key];
                if (typeof val[idx].value !== 'undefined') {
                  seriesValue[key] = val[idx].value;
                }
                else {
                  seriesValue[key] = val[idx];
                }
              }
            }
            else {
              if (typeof series[idx].value !== 'undefined') {
                seriesValue[0] = series[idx].value;
              }
              else {
                seriesValue[0] = series[idx];
              }
            }
            if (seriesValue.length > 0 && seriesValue.length === seriesLabel.length) {
              if (options.contentCallback && typeof options.contentCallback === 'function') {
                return options.contentCallback(seriesLabel, seriesValue, chart);
              }
              else {
                var content = '';
                for (var key in seriesLabel) {
                  content += '
';
                  content += '<svg style="width:15px;height:10px;" class="ct-series-'+classes[key]+'"><line x1="5" y1="5" x2="5" y2="5" class="ct-point"></line></svg>';
                  content += ''+seriesLabel[key]+': ';
                  content += ' '+options.valuePrefix+'';
                  content += ''+seriesValue[key]+'';
                  content += ''+options.valueSuffix+' ';
                  content += '
';
                }
                return content;
              }
            }
          }
        }

        function setPosition(event, width, height) {
          if (chart instanceof Chartist.Bar) {
            var offsetX = options.verticalhintOffset.x
          }
          else {
            var offsetX = - width / 2 + options.verticalhintOffset.x
          }
          var offsetY = - height + options.verticalhintOffset.y;
          var x = parseInt(event.target.offsetParent.attributes.x.value);
          var y = parseInt(event.target.offsetParent.attributes.y.value);

          return {
            x: x + offsetX,
            y: y + offsetY
          };
        }
      }
    };

    function show(element) {
      if(!hasClass(element, 'verticalhint-show')) {
        element.className = element.className + ' verticalhint-show';
      }
    }

    function hide(element) {
      var regex = new RegExp('verticalhint-show' + '\\s*', 'gi');
      element.className = element.className.replace(regex, '').trim();
    }

    function hasClass(element, className) {
      return (' ' + element.getAttribute('class') + ' ').indexOf(' ' + className + ' ') > -1;
    }

    function next(element, className) {
      do {
        element = element.nextSibling;
      } while (element && !hasClass(element, className));
      return element;
    }

    function text(element) {
      return element.innerText || element.textContent;
    }

  } (window, document, Chartist));

  return Chartist.plugins.verticalhint;

}));
<|endoftext|>


<commit_before>/*
 @author Zakai Hamilton
 @component CoreProperty
 */

package.core.property = function CoreProperty(me) {
    me.init = function() {
        package.get = me.get;
        package.set = me.set;
        package.dirty = me.dirty;
    };
    me.fullname = function(object, name, default_name=null) {
        var separator = name.indexOf(".");
        var package_name = null;
        if(separator !== -1) {
            package_name = name.substr(0, separator);
        }
        if(!package_name || !(package_name in package)) {
            if(!object.component) {
                return default_name;
            }
            name = object.component + "." + name;
        }
        if(object.component) {
            var redirect = package[object.component].redirect;
            if(redirect) {
                if(name in redirect) {
                    name = me.fullname(object, redirect[name]);
                }
            }
        }
        return name;
    };
    me.get = function(object, name, method="get") {
        var result = undefined;
        if(object && name) {
            if(typeof name === "function") {
                result = name(object);
            }
            else {
                name = me.fullname(object, name);
                if(name) {
                    result = me.send(name + "." + method, object);
                }
            }
        }
        return result;
    };
    me.set = function(object, name, value=null, method="set") {
        var result = undefined;
        if (Array.isArray(object)) {
            var results = object.map(function (item) {
                return me.set(item, name, value, method);
            });
            return results;
        }
        if(object && name) {
            if(typeof value === "string" && value.startsWith("@")) {
                value = me.get(object, value.substring(1));
            }
            if(typeof name === "function") {
                result = name(object, value);
            }
            else {
                name = me.fullname(object, name);
                if(name) {
                    result = me.send(name + "." + method, object, value);
                }
            }
        }
        return result;
    };
    me.dirty = function(object, name) {
        me.get(object, name, "dirty");
    }

};
<commit_msg>Support for disabling properties<commit_after>/*
 @author Zakai Hamilton
 @component CoreProperty
 */

package.core.property = function CoreProperty(me) {
    me.init = function() {
        package.get = me.get;
        package.set = me.set;
        package.dirty = me.dirty;
    };
    me.fullname = function(object, name, default_name=null) {
        var separator = name.indexOf(".");
        var package_name = null;
        if(separator !== -1) {
            package_name = name.substr(0, separator);
        }
        if(!package_name || !(package_name in package)) {
            if(!object.component) {
                return default_name;
            }
            name = object.component + "." + name;
        }
        if(object.component) {
            var redirect = package[object.component].redirect;
            if(redirect) {
                if(name in redirect) {
                    name = me.fullname(object, redirect[name]);
                }
            }
        }
        return name;
    };
    me.get = function(object, name, method="get") {
        var result = undefined;
        if(object && name && !name.includes("!")) {
            if(typeof name === "function") {
                result = name(object);
            }
            else {
                name = me.fullname(object, name);
                if(name) {
                    result = me.send(name + "." + method, object);
                }
            }
        }
        return result;
    };
    me.set = function(object, name, value=null, method="set") {
        var result = undefined;
        if (Array.isArray(object)) {
            var results = object.map(function (item) {
                return me.set(item, name, value, method);
            });
            return results;
        }
        if(object && name && !name.includes("!")) {
            if(typeof value === "string" && value.startsWith("@")) {
                value = me.get(object, value.substring(1));
            }
            if(typeof name === "function") {
                result = name(object, value);
            }
            else {
                name = me.fullname(object, name);
                if(name) {
                    result = me.send(name + "." + method, object, value);
                }
            }
        }
        return result;
    };
    me.dirty = function(object, name) {
        me.get(object, name, "dirty");
    }

};
<|endoftext|>


<commit_before>var map = null;
var wmsLayer = null;
var animateLayer = null;
var animateURL = null;
var start_time, end_time;
var layerList;
var selectedLayer = null;
var selectedTimeIndex = null;
var layersLoading = 0;
var opacity = 0.7;

function initMap() {
  initGlobe();
  initGlobeButtons();
  initOpacitySlider();
  initLayerList();
}

function loadStarted() {
  layersLoading++;
  if (layersLoading > 0) {
    $('#loading-indicator').show();
  }
}

function loadFinished() {
  if (layersLoading > 0) {
    layersLoading--;
  }
  if (layersLoading == 0) {
    $('#loading-indicator').hide();
  }
}

function addLayer(layer) {
  map.addLayer(layer);
  layer.events.register('loadstart', layer, function(evt){
    loadStarted();
  });
  layer.events.register('loadend', layer, function(evt){
    loadFinished();
  });
}

function initBaseLayer() {
  var baseLayer = new OpenLayers.Layer.WMS(
    "Demis BlueMarble",
    "http://www2.demis.nl/wms/wms.ashx?WMS=BlueMarble" ,
    {layers: 'Earth Image,Borders,Coastlines'});
  addLayer(baseLayer);
}

function initGlobe(show3D) {
  show3D = show3D || false;

  if (map != null) {
    map.destroy();
  }

  //var mapOptions = { maxResolution: 256/512, numZoomLevels: 11, fractionalZoom: true};
  //map = new OpenLayers.Map('map',mapOptions);
  map = new OpenLayers.Map('map', { controls: [] });
  map.setupGlobe();
  //map.addControl(new OpenLayers.Control.LayerSwitcher());
  map.addControl(new OpenLayers.Control.Navigation());
  map.addControl(new OpenLayers.Control.PanZoom());
  //map.addControl(new OpenLayers.Control.Attribution());
  initBaseLayer();

  if (selectedLayer) {
    initWMSLayer(selectedLayer, selectedTimeIndex);
  }
  if (animateURL) {
    //initAnimateLayer(animateURL);
  }
  map.finishGlobe();

  if (show3D) {
    map.show3D();
  }
  else {
    map.show2D();
  }
}

function initLayerList() {
  wps = new SimpleWPS({
    process: "org.malleefowl.wms.layer",
    onSuccess: function(result) {
      //console.log(result);
      var output = [];
      layerList = []
      $.each(result, function(index, layer) {
        //output.push('<optgroup label="' + layer.service_name + '">');
        title = layer.title + " (" + layer.service_name + ")";
        output.push('<option label="' + title + '" value="'+ index +'">' + title +'</option>');
        //output.push('</optgroup>');
        layerList.push(layer);
      });
      $('#select').html(output.join(''));

      $('#select').change(function() {
        selectedLayer = layerList[this.selectedIndex];
        showWMSLayer(selectedLayer);
      });

      if (layerList.length > 0) {
        selectedLayer = layerList[0];
        showWMSLayer(selectedLayer);
      }
    },
  });
  wps.execute();
}

function initWMSLayer(layer, step) {
  wmsLayer = new OpenLayers.Layer.WMS(
    layer.title,
    layer.service,
    {
      layers: layer.name,
      transparent: 'true',
      format:'image/png',
      time: layer.timesteps[step],
    },
    {
      isBaseLayer: false,
      opacity: opacity,
    });
  addLayer(wmsLayer);
}

function showWMSLayer(layer) {
  if (wmsLayer != null) {
    map.removeLayer(wmsLayer);
  }
  initWMSLayer(layer, 0);
  initTimeSlider(layer);
}

function dateLabel(timestep) {
  return timestep.substring(0,16);
}

function initGlobeButtons() {
  // 2d button
  $("#2d").button({
    text: true,
  }).click(function( event ) {
    show2D();
  });

  // 3d button
  $("#3d").button({
    text: true,
  }).click(function( event ) {
    show3D();
  });
}

function show2D() {
  if (map.is3D) {
    map.show2D();
  }
}

function show3D() {
  if (!map.is3D) {
    initGlobe(true);
  }
}

function initOpacitySlider() {
  $("#opacity-slider").slider({
    value: opacity,
    min: 0.1,
    max: 1.0,
    step: 0.1,
    slide: function(e, ui) {
      //console.log("sliding ...");
      setOpacity(ui.value, false);
    },
    change: function(e, ui) {
      //console.log("sliding ...");
      setOpacity(ui.value, true);
    }
  });
  setOpacity(opacity, false);
}

function setOpacity(newOpacity, redraw) {
  opacity = newOpacity;
  if (wmsLayer != null) {
    console.log("ipdate layer");
    wmsLayer.setOpacity(opacity);
    if (redraw) wmsLayer.redraw();
  }
  if (animateLayer != null) {
    animateLayer.setOpacity(opacity);
    if (redraw) animateLayer.redraw();
  }

  $("#opacity-label").text("Overlay Opacity " + opacity*100 + "%");
}

function initTimeSlider(layer) {
  var max = layer.timesteps.length - 1;

  // slider
  $("#slider").slider({
    value: 0,
    min: 0,
    max: max,
    step: 1,
    slide: function(e, ui) {
      var step = parseInt(ui.value);
      //console.log("sliding ...");
      $("#time").text(dateLabel(layer.timesteps[step]));
    },
    change: function(e, ui) {
      show2D();
      //tds_wms.setOpacity(ui.value / 10);
      var step = parseInt(ui.value);
      //console.log("step: " + step);
      $("#time").text(dateLabel(layer.timesteps[step]));
      wmsLayer.mergeNewParams({'time': layer.timesteps[step]});
      selectedTimeIndex = step;
    }
  });
  $("#time").text(dateLabel(layer.timesteps[0]));

  // prev button
  $("#prev").button({
    text: false,
  }).click(function( event ) {
    //console.log('prev button clicked');
    current = $("#slider").slider( "values", 0 );
    if (current > 0 ) {
      show2D();
      $("#slider").slider( "value", current - 1 );
    }
  });

  // next button
  $("#next").button({
    text: false,
  }).click(function( event ) {
    //console.log('next button clicked');
    show2D();
    current = $("#slider").slider( "values", 0 );
    if (current < max ) {
      $("#slider").slider( "value", current + 1 );
    }
  });

  // play button
  $("#play").button({
    text: false,
  }).click(function( event ) {
    $("#dialog-play").dialog({
      resizable: false,
      height: 300,
      modal: true,
      buttons: {
        Ok: function() {
          $( this ).dialog( "close" );
          show2D();
          animate(selectedLayer);
        },
        Cancel: function() {
         $( this ).dialog( "close" );
        }
      }
    });
  });

  // stop button
  $("#stop").button({
    text: false,
  }).click(function( event ) {
    if (animateLayer != null) {
      map.removeLayer(animateLayer);
      animateLayer = null;
    }
  });

  // slider range
  $("#slider-range").slider({
    range: true,
    values: [0, max],
    min: 0,
    max: max,
    step: 1,
    slide: function(e, ui) {
      var step0 = parseInt(ui.values[0]);
      var step1 = parseInt(ui.values[1]);

      setTimeRange(layer, step0, step1);
    },
  });

  setTimeRange(layer, 0, layer.timesteps.length-1);
}

function setTimeRange(layer, min, max) {
  $("#time-range").text( dateLabel(layer.timesteps[min]) + " - " + dateLabel(layer.timesteps[max]) );
  start_time = layer.timesteps[min];
  end_time = layer.timesteps[max];
}

function initAnimateLayer(imageURL) {
  animateLayer = new OpenLayers.Layer.Image(
    "Animation", imageURL, map.getExtent(), map.getSize(), {
      isBaseLayer: false,
      alwaysInRange: true, // Necessary to always draw the image
      opacity: opacity,
    });
  addLayer(animateLayer);
}

function animate(layer) {
  if (animateLayer != null) {
    map.removeLayer(animateLayer);
    animateLayer = null;
  }

  loadStarted();
  wps = new SimpleWPS({
    process: "org.malleefowl.wms.animate",
    raw: false,
    format: 'xml',
    onSuccess: function(xmlDoc) {
      //console.log(xmlDoc);
      animateURL = $(xmlDoc).find("wps\\:Reference, Reference").first().attr('href');
      initAnimateLayer(animateURL);
      loadFinished();
    },
  });
  wps.execute({
    service_url: layer.service,
    layer: layer.name,
    start: start_time,
    end: end_time,
    resolution: $("#select-resolution").val(),
    delay: $("#delay").val(),
    width: map.getSize().w,
    height: map.getSize().h,
    bbox: map.getExtent().toBBOX(),
  });
}

/*
function animateSlow(step) {
  if (step < 10) {
    $("#slider").slider( "value", step );
    setTimeout(function() {animate(step+1);}, 500);
  }
}
*/
<commit_msg>fixed refresh of wms layer after update<commit_after>var map = null;
var wmsLayer = null;
var animateLayer = null;
var animateURL = null;
var start_time, end_time;
var layerList;
var selectedLayer = null;
var selectedTimeIndex = null;
var layersLoading = 0;
var opacity = 0.7;

function initMap() {
  initGlobe();
  initGlobeButtons();
  initOpacitySlider();
  initLayerList();
}

function loadStarted() {
  layersLoading++;
  if (layersLoading > 0) {
    $('#loading-indicator').show();
  }
}

function loadFinished() {
  if (layersLoading > 0) {
    layersLoading--;
  }
  if (layersLoading == 0) {
    $('#loading-indicator').hide();
  }
}

function addLayer(layer) {
  map.addLayer(layer);
  layer.events.register('loadstart', layer, function(evt){
    loadStarted();
  });
  layer.events.register('loadend', layer, function(evt){
    loadFinished();
  });
}

function initBaseLayer() {
  var baseLayer = new OpenLayers.Layer.WMS(
    "Demis BlueMarble",
    "http://www2.demis.nl/wms/wms.ashx?WMS=BlueMarble" ,
    {layers: 'Earth Image,Borders,Coastlines'});
  addLayer(baseLayer);
}

function initGlobe(show3D) {
  show3D = show3D || false;

  if (map != null) {
    map.destroy();
  }

  //var mapOptions = { maxResolution: 256/512, numZoomLevels: 11, fractionalZoom: true};
  //map = new OpenLayers.Map('map',mapOptions);
  map = new OpenLayers.Map('map', { controls: [] });
  map.setupGlobe();
  //map.addControl(new OpenLayers.Control.LayerSwitcher());
  map.addControl(new OpenLayers.Control.Navigation());
  map.addControl(new OpenLayers.Control.PanZoom());
  //map.addControl(new OpenLayers.Control.Attribution());
  initBaseLayer();

  if (selectedLayer) {
    initWMSLayer(selectedLayer, selectedTimeIndex);
  }
  if (animateURL) {
    //initAnimateLayer(animateURL);
  }
  map.finishGlobe();

  if (show3D) {
    map.show3D();
  }
  else {
    map.show2D();
  }
}

function initLayerList() {
  wps = new SimpleWPS({
    process: "org.malleefowl.wms.layer",
    onSuccess: function(result) {
      //console.log(result);
      var output = [];
      layerList = []
      $.each(result, function(index, layer) {
        //output.push('<optgroup label="' + layer.service_name + '">');
        title = layer.title + " (" + layer.service_name + ")";
        output.push('<option label="' + title + '" value="'+ index +'">' + title +'</option>');
        //output.push('</optgroup>');
        layerList.push(layer);
      });
      $('#select').html(output.join(''));

      $('#select').change(function() {
        selectedLayer = layerList[this.selectedIndex];
        showWMSLayer(selectedLayer);
      });

      if (layerList.length > 0) {
        selectedLayer = layerList[0];
        showWMSLayer(selectedLayer);
      }
    },
  });
  wps.execute();
}

function initWMSLayer(layer, step) {
  console.log("init wms layer: title=" + layer.name + ", time=" + layer.timesteps[step])

  wmsLayer = new OpenLayers.Layer.WMS(
    layer.title,
    layer.service,
    {
      layers: layer.name,
      transparent: 'true',
      format:'image/png',
      time: layer.timesteps[step],
    },
    {
      isBaseLayer: false,
      opacity: opacity,
    });
  addLayer(wmsLayer);
}

function showWMSLayer(layer) {
  if (wmsLayer != null) {
    //console.log("remove wms layer");
    map.removeLayer(wmsLayer);
    wmsLayer = null;
  }
  initWMSLayer(layer, 0);
  initTimeSlider(layer);
}

function dateLabel(timestep) {
  return timestep.substring(0,16);
}

function initGlobeButtons() {
  // 2d button
  $("#2d").button({
    text: true,
  }).click(function( event ) {
    show2D();
  });

  // 3d button
  $("#3d").button({
    text: true,
  }).click(function( event ) {
    show3D();
  });
}

function show2D() {
  if (map.is3D) {
    map.show2D();
  }
}

function show3D() {
  if (!map.is3D) {
    initGlobe(true);
  }
}

function initOpacitySlider() {
  $("#opacity-slider").slider({
    value: opacity,
    min: 0.1,
    max: 1.0,
    step: 0.1,
    slide: function(e, ui) {
      //console.log("sliding ...");
      setOpacity(ui.value, false);
    },
    change: function(e, ui) {
      //console.log("sliding ...");
      setOpacity(ui.value, true);
    }
  });
  setOpacity(opacity, false);
}

function setOpacity(newOpacity, redraw) {
  opacity = newOpacity;
  if (wmsLayer != null) {
    console.log("ipdate layer");
    wmsLayer.setOpacity(opacity);
    if (redraw) wmsLayer.redraw();
  }
  if (animateLayer != null) {
    animateLayer.setOpacity(opacity);
    if (redraw) animateLayer.redraw();
  }

  $("#opacity-label").text("Overlay Opacity " + opacity*100 + "%");
}

function initTimeSlider(layer) {
  var max = layer.timesteps.length - 1;

  // slider
  $("#slider").slider({
    value: 0,
    min: 0,
    max: max,
    step: 1,
    slide: function(e, ui) {
      var step = parseInt(ui.value);
      //console.log("sliding ...");
      $("#time").text(dateLabel(layer.timesteps[step]));
    },
    change: function(e, ui) {
      show2D();
      //tds_wms.setOpacity(ui.value / 10);
      var step = parseInt(ui.value);
      //console.log("step: " + step);
      $("#time").text(dateLabel(layer.timesteps[step]));
      wmsLayer.mergeNewParams({'time': layer.timesteps[step]});
      selectedTimeIndex = step;
    }
  });
  $("#time").text(dateLabel(layer.timesteps[0]));
  wmsLayer.mergeNewParams({'time': layer.timesteps[0]});
  selectedTimeIndex = 0;

  // prev button
  $("#prev").button({
    text: false,
  }).click(function( event ) {
    //console.log('prev button clicked');
    current = $("#slider").slider( "values", 0 );
    if (current > 0 ) {
      show2D();
      $("#slider").slider( "value", current - 1 );
    }
  });

  // next button
  $("#next").button({
    text: false,
  }).click(function( event ) {
    //console.log('next button clicked');
    show2D();
    current = $("#slider").slider( "values", 0 );
    if (current < max ) {
      $("#slider").slider( "value", current + 1 );
    }
  });

  // play button
  $("#play").button({
    text: false,
  }).click(function( event ) {
    $("#dialog-play").dialog({
      resizable: false,
      height: 300,
      modal: true,
      buttons: {
        Ok: function() {
          $( this ).dialog( "close" );
          show2D();
          animate(selectedLayer);
        },
        Cancel: function() {
         $( this ).dialog( "close" );
        }
      }
    });
  });

  // stop button
  $("#stop").button({
    text: false,
  }).click(function( event ) {
    if (animateLayer != null) {
      map.removeLayer(animateLayer);
      animateLayer = null;
    }
  });

  // slider range
  $("#slider-range").slider({
    range: true,
    values: [0, max],
    min: 0,
    max: max,
    step: 1,
    slide: function(e, ui) {
      var step0 = parseInt(ui.values[0]);
      var step1 = parseInt(ui.values[1]);

      setTimeRange(layer, step0, step1);
    },
  });

  setTimeRange(layer, 0, layer.timesteps.length-1);
}

function setTimeRange(layer, min, max) {
  $("#time-range").text( dateLabel(layer.timesteps[min]) + " - " + dateLabel(layer.timesteps[max]) );
  start_time = layer.timesteps[min];
  end_time = layer.timesteps[max];
}

function initAnimateLayer(imageURL) {
  animateLayer = new OpenLayers.Layer.Image(
    "Animation", imageURL, map.getExtent(), map.getSize(), {
      isBaseLayer: false,
      alwaysInRange: true, // Necessary to always draw the image
      opacity: opacity,
    });
  addLayer(animateLayer);
}

function animate(layer) {
  if (animateLayer != null) {
    map.removeLayer(animateLayer);
    animateLayer = null;
  }

  loadStarted();
  wps = new SimpleWPS({
    process: "org.malleefowl.wms.animate",
    raw: false,
    format: 'xml',
    onSuccess: function(xmlDoc) {
      //console.log(xmlDoc);
      animateURL = $(xmlDoc).find("wps\\:Reference, Reference").first().attr('href');
      initAnimateLayer(animateURL);
      loadFinished();
    },
  });
  wps.execute({
    service_url: layer.service,
    layer: layer.name,
    start: start_time,
    end: end_time,
    resolution: $("#select-resolution").val(),
    delay: $("#delay").val(),
    width: map.getSize().w,
    height: map.getSize().h,
    bbox: map.getExtent().toBBOX(),
  });
}

/*
function animateSlow(step) {
  if (step < 10) {
    $("#slider").slider( "value", step );
    setTimeout(function() {animate(step+1);}, 500);
  }
}
*/
<|endoftext|>