<commit_before>import React from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";

import {
  snapDiffManyToMany,
  boundingBox,
  snapWithinDiff,
  snap,
  traceConnection,
  applyDiff,
  applyMultipleDiffs
} from "../snapUtils";
import { getWindowsInfo, getWindowHidden, getWindowOpen } from "../selectors";
import { updateWindowPositions } from "../actionCreators";
import { WINDOW_HEIGHT, WINDOW_WIDTH } from "../constants";
import { calculateBoundingBox } from "../utils";

const abuts = (a, b) => {
  // TODO: This is kinda a hack. They should really be touching, not just within snapping distance.
  // Also, overlapping should not count.
  const wouldMoveTo = snap(a, b);
  return wouldMoveTo.x !== undefined || wouldMoveTo.y !== undefined;
};

class WindowManager extends React.Component {
  constructor(props) {
    super(props);
    this.handleMouseDown = this.handleMouseDown.bind(this);
    this.centerWindows = this.centerWindows.bind(this);
  }

  componentDidMount() {
    this.centerWindows();
  }

  centerWindows() {
    const { container } = this.props;

    const offsetLeft = container.offsetLeft;
    const offsetTop = container.offsetTop;
    const width = container.scrollWidth;
    const height = container.scrollHeight;

    if (this.props.windowsInfo.some(w => w.x == null || w.y == null)) {
      // Some windows do not have an initial position, so we'll come up
      // with your own layout.
      const windowPositions = {};
      const keys = this.windowKeys();
      const totalHeight = keys.length * WINDOW_HEIGHT;
      const globalOffsetLeft = Math.max(0, width / 2 - WINDOW_WIDTH / 2);
      const globalOffsetTop = Math.max(0, height / 2 - totalHeight / 2);
      keys.forEach((key, i) => {
        const offset = WINDOW_HEIGHT * i;
        windowPositions[key] = {
          x: Math.ceil(offsetLeft + globalOffsetLeft),
          y: Math.ceil(offsetTop + (globalOffsetTop + offset))
        };
      });
      this.props.updateWindowPositions(windowPositions);
    } else {
      // A layout has been suplied. We will compute the bounding box and
      // center the given layout.
      const bounding = calculateBoundingBox(
        this.props.windowsInfo.filter(w => this.props.getWindowOpen(w.key))
      );

      const boxHeight = bounding.bottom - bounding.top;
      const boxWidth = bounding.right - bounding.left;

      const move = {
        x: Math.ceil(offsetLeft + (width - boxWidth) / 2),
        y: Math.ceil(offsetTop + (height - boxHeight) / 2)
      };

      const newPositions = this.props.windowsInfo.reduce(
        (pos, w) => ({ ...pos, [w.key]: { x: move.x + w.x, y: move.y + w.y } }),
        {}
      );

      this.props.updateWindowPositions(newPositions);
    }
  }

  movingAndStationaryNodes(key) {
    const windows = this.props.windowsInfo.filter(
      w =>
        this.props.windows[w.key] != null && !this.props.getWindowHidden(w.key)
    );
    const targetNode = windows.find(node => node.key === key);

    let movingSet = new Set([targetNode]);
    // Only the main window brings other windows along.
    if (key === "main") {
      const findAllConnected = traceConnection(abuts);
      movingSet = findAllConnected(windows, targetNode);
    }

    const stationary = windows.filter(w => !movingSet.has(w));
    const moving = Array.from(movingSet);

    return [moving, stationary];
  }

  handleMouseDown(key, e) {
    if (!e.target.classList.contains("draggable")) {
      return;
    }
    // Prevent dragging from highlighting text.
    e.preventDefault();

    const [moving, stationary] = this.movingAndStationaryNodes(key);

    const mouseStart = { x: e.clientX, y: e.clientY };
    // Aparently this is crazy across browsers.
    const browserSize = {
      width: Math.max(
        document.body.scrollWidth,
        document.documentElement.scrollWidth,
        document.body.offsetWidth,
        document.documentElement.offsetWidth,
        document.body.clientWidth,
        document.documentElement.clientWidth
      ),
      height: Math.max(
        document.body.scrollHeight,
        document.documentElement.scrollHeight,
        document.body.offsetHeight,
        document.documentElement.offsetHeight,
        document.body.clientHeight,
        document.documentElement.clientHeight
      )
    };

    const box = boundingBox(moving);

    const handleMouseMove = ee => {
      const proposedDiff = {
        x: ee.clientX - mouseStart.x,
        y: ee.clientY - mouseStart.y
      };

      const proposedWindows = moving.map(node => ({
        ...node,
        ...applyDiff(node, proposedDiff)
      }));

      const proposedBox = {
        ...box,
        ...applyDiff(box, proposedDiff)
      };

      const snapDiff = snapDiffManyToMany(proposedWindows, stationary);

      const withinDiff = snapWithinDiff(proposedBox, browserSize);

      const finalDiff = applyMultipleDiffs(proposedDiff, snapDiff, withinDiff);

      const windowPositionDiff = moving.reduce((diff, window) => {
        diff[window.key] = applyDiff(window, finalDiff);
        return diff;
      }, {});

      this.props.updateWindowPositions(windowPositionDiff);
    };

    const removeListeners = () => {
      window.removeEventListener("mousemove", handleMouseMove);
      window.removeEventListener("mouseup", removeListeners);
    };

    window.addEventListener("mouseup", removeListeners);
    window.addEventListener("mousemove", handleMouseMove);
  }

  // Keys for the visible windows
  windowKeys() {
    // TODO: Iterables can probably do this better.
    return Object.keys(this.props.windows).filter(
      key => !!this.props.windows[key]
    );
  }

  render() {
    const style = {
      position: "absolute"
    };

    const parentStyle = {
      position: "absolute",
      width: 0,
      height: 0,
      top: 0,
      left: 0
    };
    return (

        {this.props.windowsInfo.map(w => (

 this.handleMouseDown(w.key, e)}
            style={{ ...style, left: w.x, top: w.y }}
            key={w.key}
          >
            {this.props.windows[w.key]}

        ))}

    );
  }
}

WindowManager.propTypes = {
  windows: PropTypes.object.isRequired,
  container: PropTypes.instanceOf(Element).isRequired
};

const mapStateToProps = state => ({
  windowsInfo: getWindowsInfo(state),
  getWindowHidden: getWindowHidden(state),
  getWindowOpen: getWindowOpen(state)
});

const mapDispatchToProps = {
  updateWindowPositions
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(WindowManager);
<commit_msg>Add logging to catch error<commit_after>import React from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";

import {
  snapDiffManyToMany,
  boundingBox,
  snapWithinDiff,
  snap,
  traceConnection,
  applyDiff,
  applyMultipleDiffs
} from "../snapUtils";
import { getWindowsInfo, getWindowHidden, getWindowOpen } from "../selectors";
import { updateWindowPositions } from "../actionCreators";
import { WINDOW_HEIGHT, WINDOW_WIDTH } from "../constants";
import { calculateBoundingBox } from "../utils";

const abuts = (a, b) => {
  // TODO: This is kinda a hack. They should really be touching, not just within snapping distance.
  // Also, overlapping should not count.
  const wouldMoveTo = snap(a, b);
  return wouldMoveTo.x !== undefined || wouldMoveTo.y !== undefined;
};

class WindowManager extends React.Component {
  constructor(props) {
    super(props);
    this.handleMouseDown = this.handleMouseDown.bind(this);
    this.centerWindows = this.centerWindows.bind(this);
  }

  componentDidMount() {
    this.centerWindows();
  }

  centerWindows() {
    const { container } = this.props;

    const offsetLeft = container.offsetLeft;
    const offsetTop = container.offsetTop;
    const width = container.scrollWidth;
    const height = container.scrollHeight;

    if (this.props.windowsInfo.some(w => w.x == null || w.y == null)) {
      // Some windows do not have an initial position, so we'll come up
      // with your own layout.
      const windowPositions = {};
      const keys = this.windowKeys();
      const totalHeight = keys.length * WINDOW_HEIGHT;
      const globalOffsetLeft = Math.max(0, width / 2 - WINDOW_WIDTH / 2);
      const globalOffsetTop = Math.max(0, height / 2 - totalHeight / 2);
      keys.forEach((key, i) => {
        const offset = WINDOW_HEIGHT * i;
        windowPositions[key] = {
          x: Math.ceil(offsetLeft + globalOffsetLeft),
          y: Math.ceil(offsetTop + (globalOffsetTop + offset))
        };
      });
      this.props.updateWindowPositions(windowPositions);
    } else {
      // A layout has been suplied. We will compute the bounding box and
      // center the given layout.
      const bounding = calculateBoundingBox(
        this.props.windowsInfo.filter(w => this.props.getWindowOpen(w.key))
      );

      const boxHeight = bounding.bottom - bounding.top;
      const boxWidth = bounding.right - bounding.left;

      const move = {
        x: Math.ceil(offsetLeft + (width - boxWidth) / 2),
        y: Math.ceil(offsetTop + (height - boxHeight) / 2)
      };

      const newPositions = this.props.windowsInfo.reduce(
        (pos, w) => ({ ...pos, [w.key]: { x: move.x + w.x, y: move.y + w.y } }),
        {}
      );

      this.props.updateWindowPositions(newPositions);
    }
  }

  movingAndStationaryNodes(key) {
    const windows = this.props.windowsInfo.filter(
      w =>
        this.props.windows[w.key] != null && !this.props.getWindowHidden(w.key)
    );
    const targetNode = windows.find(node => node.key === key);

    let movingSet = new Set([targetNode]);
    // Only the main window brings other windows along.
    if (key === "main") {
      const findAllConnected = traceConnection(abuts);
      movingSet = findAllConnected(windows, targetNode);
    }

    const stationary = windows.filter(w => !movingSet.has(w));
    const moving = Array.from(movingSet);

    return [moving, stationary];
  }

  handleMouseDown(key, e) {
    if (!e.target.classList.contains("draggable")) {
      return;
    }
    // Prevent dragging from highlighting text.
    e.preventDefault();

    const [moving, stationary] = this.movingAndStationaryNodes(key);

    const mouseStart = { x: e.clientX, y: e.clientY };
    // Aparently this is crazy across browsers.
    const browserSize = {
      width: Math.max(
        document.body.scrollWidth,
        document.documentElement.scrollWidth,
        document.body.offsetWidth,
        document.documentElement.offsetWidth,
        document.body.clientWidth,
        document.documentElement.clientWidth
      ),
      height: Math.max(
        document.body.scrollHeight,
        document.documentElement.scrollHeight,
        document.body.offsetHeight,
        document.documentElement.offsetHeight,
        document.body.clientHeight,
        document.documentElement.clientHeight
      )
    };

    let box;
    try {
      box = boundingBox(moving);
    } catch (err) {
      console.error(
        `Could not construct bounding box for key: ${key}. moving.length is: ${
          moving.length
        }`
      );
      throw err;
    }

    const handleMouseMove = ee => {
      const proposedDiff = {
        x: ee.clientX - mouseStart.x,
        y: ee.clientY - mouseStart.y
      };

      const proposedWindows = moving.map(node => ({
        ...node,
        ...applyDiff(node, proposedDiff)
      }));

      const proposedBox = {
        ...box,
        ...applyDiff(box, proposedDiff)
      };

      const snapDiff = snapDiffManyToMany(proposedWindows, stationary);

      const withinDiff = snapWithinDiff(proposedBox, browserSize);

      const finalDiff = applyMultipleDiffs(proposedDiff, snapDiff, withinDiff);

      const windowPositionDiff = moving.reduce((diff, window) => {
        diff[window.key] = applyDiff(window, finalDiff);
        return diff;
      }, {});

      this.props.updateWindowPositions(windowPositionDiff);
    };

    const removeListeners = () => {
      window.removeEventListener("mousemove", handleMouseMove);
      window.removeEventListener("mouseup", removeListeners);
    };

    window.addEventListener("mouseup", removeListeners);
    window.addEventListener("mousemove", handleMouseMove);
  }

  // Keys for the visible windows
  windowKeys() {
    // TODO: Iterables can probably do this better.
    return Object.keys(this.props.windows).filter(
      key => !!this.props.windows[key]
    );
  }

  render() {
    const style = {
      position: "absolute"
    };

    const parentStyle = {
      position: "absolute",
      width: 0,
      height: 0,
      top: 0,
      left: 0
    };
    return (

        {this.props.windowsInfo.map(w => (

 this.handleMouseDown(w.key, e)}
            style={{ ...style, left: w.x, top: w.y }}
            key={w.key}
          >
            {this.props.windows[w.key]}

        ))}

    );
  }
}

WindowManager.propTypes = {
  windows: PropTypes.object.isRequired,
  container: PropTypes.instanceOf(Element).isRequired
};

const mapStateToProps = state => ({
  windowsInfo: getWindowsInfo(state),
  getWindowHidden: getWindowHidden(state),
  getWindowOpen: getWindowOpen(state)
});

const mapDispatchToProps = {
  updateWindowPositions
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(WindowManager);
<|endoftext|>


<commit_before>/* eslint-env browser */

/* global Webex */

/* eslint-disable camelcase */
/* eslint-disable max-nested-callbacks */
/* eslint-disable no-alert */
/* eslint-disable no-console */
/* eslint-disable require-jsdoc */
/* eslint-disable arrow-body-style */
/* eslint-disable max-len */

// Declare some globals that we'll need throughout
let activeMeeting, webex;

// First, let's wire our form fields up to localStorage so we don't have to
// retype things everytime we reload the page.

[
  'access-token',
  'invitee'
].forEach((id) => {
  const el = document.getElementById(id);

  el.value = localStorage.getItem(id);
  el.addEventListener('change', (event) => {
    localStorage.setItem(id, event.target.value);
  });
});

// There's a few different events that'll let us know we should initialize
// Webex and start listening for incoming calls, so we'll wrap a few things
// up in a function.
function connect() {
  return new Promise((resolve) => {
    if (!webex) {
      // eslint-disable-next-line no-multi-assign
      webex = window.webex = Webex.init({
        config: {
          meetings: {
            deviceType: 'WEB'
          }
          // Any other sdk config we need
        },
        credentials: {
          access_token: document.getElementById('access-token').value
        }
      });
    }

    // Listen for added meetings
    webex.meetings.on('meeting:added', (addedMeetingEvent) => {
      if (addedMeetingEvent.type === 'INCOMING') {
        const addedMeeting = addedMeetingEvent.meeting;

        // Acknowledge to the server that we received the call on our device
        addedMeeting.acknowledge(addedMeetingEvent.type)
          .then(() => {
            if (confirm('Answer incoming call')) {
              joinMeeting(addedMeeting);
            }
            else {
              addedMeeting.decline();
            }
          });
      }
    });

    // Register our device with Webex cloud
    if (!webex.internal.device.registered) {
      webex.internal.device
        .register()
        // Connect to websockets after registering device
        .then(() => webex.internal.mercury.connect())
        // Sync our meetings with existing meetings on the server
        .then(() => webex.meetings.syncMeetings())
        .then(() => {
          // This is just a little helper for our selenium tests and doesn't
          // really matter for the example
          document.body.classList.add('listening');
          document.getElementById('connection-status').innerHTML = 'connected';
          // Our device is now connected
          resolve();
        })
        // This is a terrible way to handle errors, but anything more specific is
        // going to depend a lot on your app
        .catch((err) => {
          console.error(err);
          // we'll rethrow here since we didn't really *handle* the error, we just
          // reported it
          throw err;
        });
    }
    else {
      // Device was already connected
      resolve();
    }
  });
}

// Similarly, there are a few different ways we'll get a meeting Object, so let's
// put meeting handling inside its own function.
function bindMeetingEvents(meeting) {
  // meeting is a meeting instance, not a promise, so to know if things break,
  // we'll need to listen for the error event. Again, this is a rather naive
  // handler.
  meeting.on('error', (err) => {
    console.error(err);
  });

  // Handle media streams changes to ready state
  meeting.on('media:ready', (media) => {
    if (!media) {
      return;
    }
    console.log(`MEDIA:READY type:${media.type}`);
    if (media.type === 'local') {
      document.getElementById('self-view').srcObject = media.stream;
    }
    if (media.type === 'remoteVideo') {
      document.getElementById('remote-view-video').srcObject = media.stream;
    }
    if (media.type === 'remoteAudio') {
      document.getElementById('remote-view-audio').srcObject = media.stream;
    }
    if (media.type === 'remoteShare') {
      document.getElementById('remote-screen').srcObject = media.stream;
      document.getElementById('screenshare-tracks-remote').innerHTML = '1';
    }
    if (media.type === 'localShare') {
      document.getElementById('self-screen').srcObject = media.stream;
      document.getElementById('screenshare-tracks').innerHTML = '1';
    }
  });

  // Handle media streams stopping
  meeting.on('media:stopped', (media) => {
    // Remove media streams
    if (media.type === 'local') {
      document.getElementById('self-view').srcObject = null;
    }
    if (media.type === 'remoteVideo') {
      document.getElementById('remote-view-video').srcObject = null;
    }
    if (media.type === 'remoteAudio') {
      document.getElementById('remote-view-audio').srcObject = null;
    }
    if (media.type === 'remoteShare') {
      document.getElementById('remote-screen').srcObject = null;
      document.getElementById('screenshare-tracks-remote').innerHTML = '0';
    }
    if (media.type === 'localShare') {
      document.getElementById('self-screen').srcObject = null;
      document.getElementById('screenshare-tracks').innerHTML = '0';
    }
  });

  // Update participant info
  meeting.members.on('members:update', (delta) => {
    const {full: membersData} = delta;
    const memberIDs = Object.keys(membersData);

    memberIDs.forEach((memberID) => {
      const memberObject = membersData[memberID];

      // Devices are listed in the memberships object.
      // We are not concerned with them in this demo
      if (memberObject.isUser) {
        if (memberObject.isSelf) {
          document.getElementById('call-status-local').innerHTML = memberObject.status;
        }
        else {
          document.getElementById('call-status-remote').innerHTML = memberObject.status;
        }
      }
    });
  });

  // Of course, we'd also like to be able to end the meeting:
  document.getElementById('hangup').addEventListener('click', () => {
    meeting.leave();
  });

  meeting.on('all', (event) => {
    console.log(event);
  });
}

// Join the meeting and add media
function joinMeeting(meeting) {
  // Save meeting to global object
  activeMeeting = meeting;

  // Call our helper function for binding events to meetings
  bindMeetingEvents(meeting);

  return meeting.join().then(() => {
    const mediaSettings = {
      receiveVideo: true,
      receiveAudio: true,
      receiveShare: true,
      sendVideo: true,
      sendAudio: true,
      sendShare: false
    };

    return meeting.getMediaStreams(mediaSettings).then((mediaStreams) => {
      const [localStream, localShare] = mediaStreams;

      meeting.addMedia({
        localShare,
        localStream,
        mediaSettings
      });
    });
  });
}

// In order to simplify the state management needed to keep track of our button
// handlers, we'll rely on the current meeting global object and only hook up event
// handlers once.

document.getElementById('share-screen').addEventListener('click', () => {
  if (activeMeeting) {
    const mediaSettings = {
      receiveShare: true,
      sendShare: true
    };

    console.info('SHARE-SCREEN: Preparing to share screen via `getMediaStreams`');
    activeMeeting.getMediaStreams(mediaSettings)
      // `[, localShare]` is grabbing index 1 from the mediaSettingsResultsArray
      // and storing it in a variable called localShare.
      .then((mediaSettingsResultsArray) => {
        const [, localShare] = mediaSettingsResultsArray;

        console.info('SHARE-SCREEN: Add local share via `updateShare`');

        return activeMeeting.updateShare({
          sendShare: true,
          receiveShare: true,
          stream: localShare
        });
      })
      .then(() => {
        console.info('SHARE-SCREEN: Screen successfully added to meeting.');
      })
      .catch((e) => {
        console.error('SHARE-SCREEN: Unable to share screen, error:');
        console.error(e);
      });
  }
  else {
    console.error('No active meeting available to share screen.');
  }
});

document.getElementById('stop-screen-share').addEventListener('click', () => {
  if (activeMeeting) {
    activeMeeting.updateShare({
      sendShare: false,
      receiveShare: true
    })
      .then(() => {
        document.getElementById('screenshare-tracks').innerHTML = '0';
      });
  }
});

document.getElementById('hangup').addEventListener('click', () => {
  if (activeMeeting) {
    activeMeeting.leave();
  }
});

// Now, let's set up connection handling
document.getElementById('credentials').addEventListener('submit', (event) => {
  // let's make sure we don't reload the page when we submit the form
  event.preventDefault();

  // The rest of the connection setup happens in connect();
  connect();
});

// And finally, let's wire up dialing
document.getElementById('dialer').addEventListener('submit', (event) => {
  // again, we don't want to reload when we try to dial
  event.preventDefault();

  const destination = document.getElementById('invitee').value;

  // we'll use `connect()` (even though we might already be connected or
  // connecting) to make sure we've got a functional webex instance.
  connect()
    .then(() => {
      // Create the meeting
      return webex.meetings.create(destination).then((meeting) => {
        // Pass the meeting to our join meeting helper
        return joinMeeting(meeting);
      });
    })
    .catch((error) => {
      // Report the error
      console.error(error);

      // Implement error handling here
    });
});
<commit_msg>feat(samples): move share status to proper event<commit_after>/* eslint-env browser */

/* global Webex */

/* eslint-disable camelcase */
/* eslint-disable max-nested-callbacks */
/* eslint-disable no-alert */
/* eslint-disable no-console */
/* eslint-disable require-jsdoc */
/* eslint-disable arrow-body-style */
/* eslint-disable max-len */

// Declare some globals that we'll need throughout
let activeMeeting, webex;

// First, let's wire our form fields up to localStorage so we don't have to
// retype things everytime we reload the page.

[
  'access-token',
  'invitee'
].forEach((id) => {
  const el = document.getElementById(id);

  el.value = localStorage.getItem(id);
  el.addEventListener('change', (event) => {
    localStorage.setItem(id, event.target.value);
  });
});

// There's a few different events that'll let us know we should initialize
// Webex and start listening for incoming calls, so we'll wrap a few things
// up in a function.
function connect() {
  return new Promise((resolve) => {
    if (!webex) {
      // eslint-disable-next-line no-multi-assign
      webex = window.webex = Webex.init({
        config: {
          meetings: {
            deviceType: 'WEB'
          }
          // Any other sdk config we need
        },
        credentials: {
          access_token: document.getElementById('access-token').value
        }
      });
    }

    // Listen for added meetings
    webex.meetings.on('meeting:added', (addedMeetingEvent) => {
      if (addedMeetingEvent.type === 'INCOMING') {
        const addedMeeting = addedMeetingEvent.meeting;

        // Acknowledge to the server that we received the call on our device
        addedMeeting.acknowledge(addedMeetingEvent.type)
          .then(() => {
            if (confirm('Answer incoming call')) {
              joinMeeting(addedMeeting);
            }
            else {
              addedMeeting.decline();
            }
          });
      }
    });

    // Register our device with Webex cloud
    if (!webex.internal.device.registered) {
      webex.internal.device
        .register()
        // Connect to websockets after registering device
        .then(() => webex.internal.mercury.connect())
        // Sync our meetings with existing meetings on the server
        .then(() => webex.meetings.syncMeetings())
        .then(() => {
          // This is just a little helper for our selenium tests and doesn't
          // really matter for the example
          document.body.classList.add('listening');
          document.getElementById('connection-status').innerHTML = 'connected';
          // Our device is now connected
          resolve();
        })
        // This is a terrible way to handle errors, but anything more specific is
        // going to depend a lot on your app
        .catch((err) => {
          console.error(err);
          // we'll rethrow here since we didn't really *handle* the error, we just
          // reported it
          throw err;
        });
    }
    else {
      // Device was already connected
      resolve();
    }
  });
}

// Similarly, there are a few different ways we'll get a meeting Object, so let's
// put meeting handling inside its own function.
function bindMeetingEvents(meeting) {
  // meeting is a meeting instance, not a promise, so to know if things break,
  // we'll need to listen for the error event. Again, this is a rather naive
  // handler.
  meeting.on('error', (err) => {
    console.error(err);
  });

  // Handle media streams changes to ready state
  meeting.on('media:ready', (media) => {
    if (!media) {
      return;
    }
    console.log(`MEDIA:READY type:${media.type}`);
    if (media.type === 'local') {
      document.getElementById('self-view').srcObject = media.stream;
    }
    if (media.type === 'remoteVideo') {
      document.getElementById('remote-view-video').srcObject = media.stream;
    }
    if (media.type === 'remoteAudio') {
      document.getElementById('remote-view-audio').srcObject = media.stream;
    }
    if (media.type === 'remoteShare') {
      // Remote share streams become active immediately on join, even if nothing is being shared
      document.getElementById('remote-screen').srcObject = media.stream;
    }
    if (media.type === 'localShare') {
      document.getElementById('self-screen').srcObject = media.stream;
    }
  });

  // Handle media streams stopping
  meeting.on('media:stopped', (media) => {
    // Remove media streams
    if (media.type === 'local') {
      document.getElementById('self-view').srcObject = null;
    }
    if (media.type === 'remoteVideo') {
      document.getElementById('remote-view-video').srcObject = null;
    }
    if (media.type === 'remoteAudio') {
      document.getElementById('remote-view-audio').srcObject = null;
    }
    if (media.type === 'remoteShare') {
      document.getElementById('remote-screen').srcObject = null;
    }
    if (media.type === 'localShare') {
      document.getElementById('self-screen').srcObject = null;
    }
  });

  // Handle share specific events
  meeting.on('meeting:startedSharingLocal', () => {
    document.getElementById('screenshare-tracks').innerHTML = 'SHARING';
  });
  meeting.on('meeting:stoppedSharingLocal', () => {
    document.getElementById('screenshare-tracks').innerHTML = 'STOPPED';
  });

  // Update participant info
  meeting.members.on('members:update', (delta) => {
    const {full: membersData} = delta;
    const memberIDs = Object.keys(membersData);

    memberIDs.forEach((memberID) => {
      const memberObject = membersData[memberID];

      // Devices are listed in the memberships object.
      // We are not concerned with them in this demo
      if (memberObject.isUser) {
        if (memberObject.isSelf) {
          document.getElementById('call-status-local').innerHTML = memberObject.status;
        }
        else {
          document.getElementById('call-status-remote').innerHTML = memberObject.status;
        }
      }
    });
  });

  // Of course, we'd also like to be able to end the meeting:
  document.getElementById('hangup').addEventListener('click', () => {
    meeting.leave();
  });

  meeting.on('all', (event) => {
    console.log(event);
  });
}

// Join the meeting and add media
function joinMeeting(meeting) {
  // Save meeting to global object
  activeMeeting = meeting;

  // Call our helper function for binding events to meetings
  bindMeetingEvents(meeting);

  return meeting.join().then(() => {
    const mediaSettings = {
      receiveVideo: true,
      receiveAudio: true,
      receiveShare: true,
      sendVideo: true,
      sendAudio: true,
      sendShare: false
    };

    return meeting.getMediaStreams(mediaSettings).then((mediaStreams) => {
      const [localStream, localShare] = mediaStreams;

      meeting.addMedia({
        localShare,
        localStream,
        mediaSettings
      });
    });
  });
}

// In order to simplify the state management needed to keep track of our button
// handlers, we'll rely on the current meeting global object and only hook up event
// handlers once.

document.getElementById('share-screen').addEventListener('click', () => {
  if (activeMeeting) {
    const mediaSettings = {
      receiveShare: true,
      sendShare: true
    };

    console.info('SHARE-SCREEN: Preparing to share screen via `getMediaStreams`');
    activeMeeting.getMediaStreams(mediaSettings)
      // `[, localShare]` is grabbing index 1 from the mediaSettingsResultsArray
      // and storing it in a variable called localShare.
      .then((mediaSettingsResultsArray) => {
        const [, localShare] = mediaSettingsResultsArray;

        console.info('SHARE-SCREEN: Add local share via `updateShare`');

        return activeMeeting.updateShare({
          sendShare: true,
          receiveShare: true,
          stream: localShare
        });
      })
      .then(() => {
        console.info('SHARE-SCREEN: Screen successfully added to meeting.');
      })
      .catch((e) => {
        console.error('SHARE-SCREEN: Unable to share screen, error:');
        console.error(e);
      });
  }
  else {
    console.error('No active meeting available to share screen.');
  }
});

document.getElementById('stop-screen-share').addEventListener('click', () => {
  if (activeMeeting) {
    activeMeeting.updateShare({
      sendShare: false,
      receiveShare: true
    });
  }
});

document.getElementById('hangup').addEventListener('click', () => {
  if (activeMeeting) {
    activeMeeting.leave();
  }
});

// Now, let's set up connection handling
document.getElementById('credentials').addEventListener('submit', (event) => {
  // let's make sure we don't reload the page when we submit the form
  event.preventDefault();

  // The rest of the connection setup happens in connect();
  connect();
});

// And finally, let's wire up dialing
document.getElementById('dialer').addEventListener('submit', (event) => {
  // again, we don't want to reload when we try to dial
  event.preventDefault();

  const destination = document.getElementById('invitee').value;

  // we'll use `connect()` (even though we might already be connected or
  // connecting) to make sure we've got a functional webex instance.
  connect()
    .then(() => {
      // Create the meeting
      return webex.meetings.create(destination).then((meeting) => {
        // Pass the meeting to our join meeting helper
        return joinMeeting(meeting);
      });
    })
    .catch((error) => {
      // Report the error
      console.error(error);

      // Implement error handling here
    });
});
<|endoftext|>


<commit_before>function RenderEngine(debug, vr) {
  var self = this;

  this.controls = [];

  this.createScene();
  this.createCamera();
  this.createRenderer();
  this.addFloor();

  if(debug) {
    this.scene.add(new THREE.AxisHelper(100));
  }

  if(vr) {
    this.addVRControls();
    this.createVREffect();
  } else {
    this.addOrbitControls();
  }

  function onWindowResize() {
    self.renderer.setSize(window.innerWidth, window.innerHeight);
    self.camera.aspect = window.innerWidth / window.innerHeight;
    self.camera.updateProjectionMatrix();

    if(self.effect) {
      self.effect.setSize(window.innerWidth, window.innerHeight);
    }
  }

  window.addEventListener('resize', onWindowResize, false);

  this.enabled = true;

  window.addEventListener('keydown', function(event) {
    if (event.keyCode == 13) { // enter
      event.preventDefault();
      self.enabled = !self.enabled;
    }
  }, true);

  SimpleEmitter.call(this);
}

RenderEngine.prototype = Object.create(SimpleEmitter.prototype);

RenderEngine.prototype.createScene = function(){
  this.scene = new THREE.Scene();
  return this.scene;
};

RenderEngine.prototype.createCamera = function(){
  this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 10000);
  this.camera.position.set(20, 0, 0);
  //this.camera.lookAt(new THREE.Vector3(0, 0, 0));
  return this.camera;
};

RenderEngine.prototype.createRenderer = function(){
  this.renderer = new THREE.WebGLRenderer({ antialias: true });
  this.renderer.setSize(window.innerWidth, window.innerHeight);
  $('body').prepend(this.renderer.domElement);
  return this.renderer;
};

RenderEngine.prototype.addFloor = function(){
  var geometry = new THREE.CircleGeometry(1500, 100);
  var material = new THREE.MeshBasicMaterial({ color: 0x222222 });
  this.floor = new THREE.Mesh(geometry, material);
  this.floor.material.side = THREE.DoubleSide;
  this.floor.rotation.x = deg2rad(90);
  this.scene.add(this.floor);
};

RenderEngine.prototype.addOrbitControls = function(){
  var controls = new THREE.OrbitControls(this.camera);
  this.controls.push(controls);
};

RenderEngine.prototype.addVRControls = function(){
  var controls = new THREE.VRControls(this.camera);
  this.controls.push(controls);

  window.addEventListener('keydown', function(event) {
    if (event.keyCode == 32) { // space
      event.preventDefault();
      controls.resetSensor();
    }
  }, true);
};

RenderEngine.prototype.createVREffect = function(){
  var self = this;
  this.effect = new THREE.VREffect(this.renderer);
  this.effect.setSize(window.innerWidth, window.innerHeight);

  document.body.addEventListener('dblclick', function() {
    self.effect.setFullScreen(true);
  });
};

RenderEngine.prototype.render = function(){
  if(this.enabled) {
    if(this.effect) {
      this.effect.render(this.scene, this.camera);
    } else {
      this.renderer.render(this.scene, this.camera);
    }
    this.emit('render');
  }
};

RenderEngine.prototype.update = function(){
  requestAnimationFrame(this.update.bind(this));

  this.controls.forEach(function(controls){
    controls.update();
  });

  this.render();
};

RenderEngine.prototype.start = function(){
  this.update();
};
<commit_msg>improve positioning<commit_after>function RenderEngine(debug, vr) {
  var self = this;

  this.controls = [];

  this.createScene();
  this.createCamera();
  this.createRenderer();
  this.addFloor();

  if(debug) {
    this.scene.add(new THREE.AxisHelper(100));
  }

  if(vr) {
    this.addVRControls();
    this.createVREffect();
  } else {
    this.addOrbitControls();
  }

  function onWindowResize() {
    self.renderer.setSize(window.innerWidth, window.innerHeight);
    self.camera.aspect = window.innerWidth / window.innerHeight;
    self.camera.updateProjectionMatrix();

    if(self.effect) {
      self.effect.setSize(window.innerWidth, window.innerHeight);
    }
  }

  window.addEventListener('resize', onWindowResize, false);

  this.enabled = true;

  window.addEventListener('keydown', function(event) {
    if (event.keyCode == 13) { // enter
      event.preventDefault();
      self.enabled = !self.enabled;
    }
  }, true);

  SimpleEmitter.call(this);
}

RenderEngine.prototype = Object.create(SimpleEmitter.prototype);

RenderEngine.prototype.createScene = function(){
  this.scene = new THREE.Scene();
  return this.scene;
};

RenderEngine.prototype.createCamera = function(){
  this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.001, 10000);
  this.camera.position.set(0, 120, 0);
  return this.camera;
};

RenderEngine.prototype.createRenderer = function(){
  this.renderer = new THREE.WebGLRenderer({ antialias: true });
  this.renderer.setSize(window.innerWidth, window.innerHeight);
  $('body').prepend(this.renderer.domElement);
  return this.renderer;
};

RenderEngine.prototype.addFloor = function(){
  var geometry = new THREE.CircleGeometry(1500, 100);
  var material = new THREE.MeshBasicMaterial({ color: 0x222222 });
  this.floor = new THREE.Mesh(geometry, material);
  this.floor.material.side = THREE.DoubleSide;
  this.floor.rotation.x = deg2rad(90);
  this.scene.add(this.floor);
};

RenderEngine.prototype.addOrbitControls = function(){
  var controls = new THREE.OrbitControls(this.camera);
  controls.target.set(0, 0, 0);
  controls.rotateUp(deg2rad(-70));
  controls.rotateLeft(deg2rad(90));
  controls.dollyOut(5);
  controls.panUp(150);
  this.controls.push(controls);
};

RenderEngine.prototype.addVRControls = function(){
  var controls = new THREE.VRControls(this.camera);
  this.controls.push(controls);

  window.addEventListener('keydown', function(event) {
    if (event.keyCode == 32) { // space
      event.preventDefault();
      controls.resetSensor();
    }
  }, true);
};

RenderEngine.prototype.createVREffect = function(){
  var self = this;
  this.effect = new THREE.VREffect(this.renderer);
  this.effect.setSize(window.innerWidth, window.innerHeight);

  document.body.addEventListener('dblclick', function() {
    self.effect.setFullScreen(true);
  });
};

RenderEngine.prototype.render = function(){
  if(this.enabled) {
    if(this.effect) {
      this.effect.render(this.scene, this.camera);
    } else {
      this.renderer.render(this.scene, this.camera);
    }
    this.emit('render');
  }
};

RenderEngine.prototype.update = function(){
  requestAnimationFrame(this.update.bind(this));

  this.controls.forEach(function(controls){
    controls.update();
  });

  this.render();
};

RenderEngine.prototype.start = function(){
  this.update();
};
<|endoftext|>


<commit_before>const debug = require('ghost-ignition').debug('importer:settings'),
    Promise = require('bluebird'),
    _ = require('lodash'),
    BaseImporter = require('./base'),
    models = require('../../../../models'),
    defaultSettings = require('../../../schema').defaultSettings,
    labsDefaults = JSON.parse(defaultSettings.blog.labs.defaultValue);

class SettingsImporter extends BaseImporter {
    constructor(allDataFromFile) {
        super(allDataFromFile, {
            modelName: 'Settings',
            dataKeyToImport: 'settings'
        });

        this.errorConfig = {
            allowDuplicates: true,
            returnDuplicates: true,
            showNotFoundWarning: false
        };
    }

    /**
     * - 'core' and 'theme' are blacklisted
     * - handle labs setting
     */
    beforeImport() {
        debug('beforeImport');

        const activeTheme = _.find(this.dataToImport, {key: 'active_theme'});

        // We don't import themes. You have to upload the theme first.
        if (activeTheme) {
            this.problems.push({
                message: 'Theme not imported, please upload in Settings - Design',
                help: this.modelName,
                context: JSON.stringify(activeTheme)
            });
        }

        const permalinks = _.find(this.dataToImport, {key: 'permalinks'});

        if (permalinks) {
            this.problems.push({
                message: 'Permalink Setting was removed. Please configure permalinks in your routes.yaml.',
                help: this.modelName,
                context: JSON.stringify(permalinks)
            });

            this.dataToImport = _.filter(this.dataToImport, (data) => {
                return data.key !== 'permalinks';
            });
        }

        // Remove core and theme data types
        this.dataToImport = _.filter(this.dataToImport, (data) => {
            return ['core', 'theme'].indexOf(data.type) === -1;
        });

        _.each(this.dataToImport, (obj) => {
            if (obj.key === 'labs' && obj.value) {
                // Overwrite the labs setting with our current defaults
                // Ensures things that are enabled in new versions, are turned on
                obj.value = JSON.stringify(_.assign({}, JSON.parse(obj.value), labsDefaults));
            }

            // CASE: we do not import slack hooks, otherwise it can happen very fast that you are pinging someone's slack channel
            if (obj.key === 'slack') {
                obj.value = JSON.stringify([{url: ''}]);
            }
        });

        return super.beforeImport();
    }

    generateIdentifier() {
        return Promise.resolve();
    }

    doImport(options) {
        debug('doImport', this.dataToImport.length);

        let ops = [];

        _.each(this.dataToImport, (model) => {
            ops.push(
                models.Settings.edit(model, options)
                    .catch((err) => {
                        return this.handleError(err, model);
                    })
                    .reflect()
            );
        });

        return Promise.all(ops);
    }
}

module.exports = SettingsImporter;
<commit_msg>🐛 Fixed private blogging getting enabled after import<commit_after>const debug = require('ghost-ignition').debug('importer:settings'),
    Promise = require('bluebird'),
    _ = require('lodash'),
    BaseImporter = require('./base'),
    models = require('../../../../models'),
    defaultSettings = require('../../../schema').defaultSettings,
    labsDefaults = JSON.parse(defaultSettings.blog.labs.defaultValue);

class SettingsImporter extends BaseImporter {
    constructor(allDataFromFile) {
        super(allDataFromFile, {
            modelName: 'Settings',
            dataKeyToImport: 'settings'
        });

        this.errorConfig = {
            allowDuplicates: true,
            returnDuplicates: true,
            showNotFoundWarning: false
        };
    }

    /**
     * - 'core' and 'theme' are blacklisted
     * - handle labs setting
     */
    beforeImport() {
        debug('beforeImport');

        const activeTheme = _.find(this.dataToImport, {key: 'active_theme'});

        // We don't import themes. You have to upload the theme first.
        if (activeTheme) {
            this.problems.push({
                message: 'Theme not imported, please upload in Settings - Design',
                help: this.modelName,
                context: JSON.stringify(activeTheme)
            });
        }

        const permalinks = _.find(this.dataToImport, {key: 'permalinks'});

        if (permalinks) {
            this.problems.push({
                message: 'Permalink Setting was removed. Please configure permalinks in your routes.yaml.',
                help: this.modelName,
                context: JSON.stringify(permalinks)
            });

            this.dataToImport = _.filter(this.dataToImport, (data) => {
                return data.key !== 'permalinks';
            });
        }

        // Remove core and theme data types
        this.dataToImport = _.filter(this.dataToImport, (data) => {
            return ['core', 'theme'].indexOf(data.type) === -1;
        });

        _.each(this.dataToImport, (obj) => {
            if (obj.key === 'labs' && obj.value) {
                // Overwrite the labs setting with our current defaults
                // Ensures things that are enabled in new versions, are turned on
                obj.value = JSON.stringify(_.assign({}, JSON.parse(obj.value), labsDefaults));
            }

            // CASE: we do not import slack hooks, otherwise it can happen very fast that you are pinging someone's slack channel
            if (obj.key === 'slack') {
                obj.value = JSON.stringify([{url: ''}]);
            }

            // CASE: export files might contain "0" or "1" for booleans
            // transform "0" to false
            // transform "false" to false
            // transform "null" to null
            if (obj.value === '0' || obj.value === '1') {
                obj.value = !!+obj.value;
            }
        });

        return super.beforeImport();
    }

    generateIdentifier() {
        return Promise.resolve();
    }

    doImport(options) {
        debug('doImport', this.dataToImport.length);

        let ops = [];

        _.each(this.dataToImport, (model) => {
            ops.push(
                models.Settings.edit(model, options)
                    .catch((err) => {
                        return this.handleError(err, model);
                    })
                    .reflect()
            );
        });

        return Promise.all(ops);
    }
}

module.exports = SettingsImporter;
<|endoftext|>


<commit_before>describe('the canary spec', () => {
  it('shows the infrastructure works', () => {
    true.should.be.true();
  });
});
<commit_msg>testing the precommit hook<commit_after>describe('the canary spec', () => {
  it('shows the infrastructure works', () => {

    true.should.be.true();
  });
});
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016 Memorial Sloan-Kettering Cancer Center.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS
 * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder
 * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no
 * obligations to provide maintenance, support, updates, enhancements or
 * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be
 * liable to any party for direct, indirect, special, incidental or
 * consequential damages, including lost profits, arising out of the use of this
 * software and its documentation, even if Memorial Sloan-Kettering Cancer
 * Center has been advised of the possibility of such damage.
 */

/*
 * This file is part of cBioPortal Cancer Hotspots.
 *
 * cBioPortal is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * @author Selcuk Onur Sumer
 */
function ClusterRender(options)
{
    var _defaultOpts = {
        templateId: "cluster_column",
        dataManager: false
    };

    // merge options with default options to use defaults for missing values
    var _options = jQuery.extend(true, {}, _defaultOpts, options);

    function render(data, type)
    {
        if (type === 'sort')
        {
            return data;
        }
        else
        {
            var templateFn = _.template($("#" + _options.templateId).html());
            return templateFn({clusterId: data});
        }
    }

    function postRender(td, cellData, rowData, row, col)
    {
        addEventListeners(td, cellData);
    }

    function addEventListeners(td, cellData)
    {
        $(td).find('input').on('change', function ()
        {
            if (_options.dataManager)
            {
                if ($(this).is(":checked"))
                {
                    // filter all lollipops corresponding to this cluster
                    _options.dataManager.filterClusters([cellData]);
                }
                else
                {
                    // remove filters
                    _options.dataManager.unfilterClusters([cellData]);
                }
            }
        });
    }

    this.render = render;
    this.postRender = postRender;
}

<commit_msg>added tooltip for the cluster checkboxes<commit_after>/*
 * Copyright (c) 2016 Memorial Sloan-Kettering Cancer Center.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS
 * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder
 * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no
 * obligations to provide maintenance, support, updates, enhancements or
 * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be
 * liable to any party for direct, indirect, special, incidental or
 * consequential damages, including lost profits, arising out of the use of this
 * software and its documentation, even if Memorial Sloan-Kettering Cancer
 * Center has been advised of the possibility of such damage.
 */

/*
 * This file is part of cBioPortal Cancer Hotspots.
 *
 * cBioPortal is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * @author Selcuk Onur Sumer
 */
function ClusterRender(options)
{
    var _defaultOpts = {
        templateId: "cluster_column",
        dataManager: false
    };

    // merge options with default options to use defaults for missing values
    var _options = jQuery.extend(true, {}, _defaultOpts, options);

    function render(data, type)
    {
        if (type === 'sort')
        {
            return data;
        }
        else
        {
            var templateFn = _.template($("#" + _options.templateId).html());
            return templateFn({clusterId: data});
        }
    }

    function postRender(td, cellData, rowData, row, col)
    {
        var tooltipOpts = TooltipUtils.defaultTooltipOpts();
        tooltipOpts.content = "Check to highlight residues in the diagram";

        cbio.util.addTargetedQTip($(td).find('input'), tooltipOpts);

        addEventListeners(td, cellData);
    }

    function addEventListeners(td, cellData)
    {
        $(td).find('input').on('change', function ()
        {
            if (_options.dataManager)
            {
                if ($(this).is(":checked"))
                {
                    // filter all lollipops corresponding to this cluster
                    _options.dataManager.filterClusters([cellData]);
                }
                else
                {
                    // remove filters
                    _options.dataManager.unfilterClusters([cellData]);
                }
            }
        });
    }

    this.render = render;
    this.postRender = postRender;
}

<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash'),
    request = require('request'),
    SSH = require('simple-ssh'),
    async = require('async');
var Server = require('./server.model'),
    Script = require('../script/script.model'),
    Interval = require('./interval.model');
var config = require('../../config/environment');

exports.runningScripts = [];

// Start Intervals
exports.start = function (req, res) {
  Server.find({})
    .populate('activeScripts.script')
    .exec(function (err, servers) {
    if(err) { return handleError(res, err); }
    async.each(servers, function (server, serverCallback) {
      async.each(server.activeScripts, function (interval, intervalCallback) {
        new StartRunningScript(interval, server, intervalCallback);
        }, function (error) {
            serverCallback(error);
        });
    }, function (error) {
      if (error) { return handleError(res, error); }
      res.send(200);
    });
  });
};

exports.execute = function (req, res) {
  Server.findById(req.params.serverId, function (err, server) {
    if (err) { return handleError(res, err); }
    if (!server) { return res.send(404); }
    var intervalIndex = _.findIndex(server.activeScripts, function (activeScript) {
      return activeScript._id.toString() === req.params.intervalId.toString();
    });
    var interval = server.activeScripts[intervalIndex];

    Script.findById(interval.script, function (err, script) {
      if (err) { return handleError(res, err); }
      if (!script) { return handleError(res, 'The script for that interval could not be found.'); }
      new RunScript(server.hostname, server.username, script.command, function (err, results) {
        if (err) { return handleError(res, err); }
        res.send(200, results);
      });
    });
  });
};

// Get list of servers
exports.index = function(req, res) {
  Server.find()
    .exec(function (err, servers) {
      if(err) { return handleError(res, err); }
      return res.json(200, servers);
  });
};

exports.display = function (req, res) {
  Server.find()
    .populate('activeScripts.script')
    .sort({'activeScripts.results.timestamp': -1})
    .limit(10)
    .exec(function (err, servers) {
      if (err) { return handleError(res, err); }
      return res.json(200, servers);
    });
};

// Get a single server
exports.show = function(req, res) {
  Server.findById(req.params.id)
    .populate('activeScripts.script')
    .exec(function (err, server) {
      if(err) { return handleError(res, err); }
      if(!server) { return res.send(404); }
      return res.json(server);
    });
};

// Creates a new server in the DB.
exports.create = function(req, res) {
  Server.create(req.body, function(err, server) {
    if(err) { return handleError(res, err); }
    return res.json(201, server);
  });
};

// Updates an existing server in the DB.
exports.update = function(req, res) {
  if(req.body._id) { delete req.body._id; }
  for (var s = 0; s < req.body.activeScripts.length; ++s) {
    if (typeof(req.body.activeScripts[s].script) === typeof({})) {
      req.body.activeScripts[s].script = req.body.activeScripts[s].script._id;
    }
  }
  async.waterfall([
    function (callback) {
      // Get original server
      Server.findById(req.params.id, function (err, server) {
        if (err) { return callback(err); }
        if(!server) { return callback('404'); }
        callback(null, server, req.body);
      });
    }, function (oldServer, server, callback) {
      // turn off the old scripts
      async.each(oldServer.activeScripts, StopRunningScript, function (error) {
        callback(error, oldServer, server);
      });
    }, function (oldServer, server, callback) {
      // update server with new info; remove old intervals
      var oldIds = _.difference(oldServer.activeScripts, server.activeScripts);
      Server.update({ _id: oldServer._id },
        {
          hostname: server.hostname || oldServer.hostname,
          description: server.description || oldServer.description,
          username: server.username || oldServer.username,
          $pullAll: { activeScripts: oldIds }
        },
        function (err) {
          callback(err, oldServer, server);
      });
    }, function (oldServer, server, callback) {
      // update server with new info; add new intervals
      Server.update({ _id: oldServer._id },
        { $addToSet: { activeScripts: { $each: server.activeScripts } } },
        function (err) {
          callback(err, oldServer);
      });
    }, function (oldServer, callback) {
      Server.findById(oldServer._id)
        .populate('activeScripts.script')
        .exec(function (err, server) {
          callback(err, server);
      });
    }, function (updated, callback) {
      // start new scripts
      async.each(updated.activeScripts, function (interval, scriptCallback) {
        new StartRunningScript(interval, updated, function (error) {
          if (error) { return scriptCallback(error); }
          return scriptCallback();
        });
      }, function (error, result) {
        return callback(error, result);
      });
    }], function (error, result) {
      if (error === '404') {
        return res.send(404);
      }
      else if (error) {
        return handleError(res, error);
      }
      else {
        return res.json(200, result);
      }
    });
};

// Deletes a server from the DB.
exports.destroy = function(req, res) {
  Server.findById(req.params.id)
    .exec(function (err, server) {
    if(err) { return handleError(res, err); }
    if(!server) { return res.send(404); }
    server.remove(function(err) {
      if(err) { return handleError(res, err); }
      async.each(server.activeScripts, StopRunningScript, function (error) {
        if (error) { return handleError(res, error); }
        return res.send(204);
      });
    });
  });
};

function handleError(res, err) {
  console.error(err);
  return res.send(500, err);
}

function IsNumber(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

function RunScript (hostname, username, command, callback) {
  var ssh = new SSH({
    host: hostname,
    user: username,
    key: config.sshkey
    //timeout: 2000
  });

  ssh.exec(command, {
    out: function(stdout) {
      callback(null, stdout);
    },
    err: function(stderr) {
      console.error(stderr);
    }
  }).start();
}

function RunScriptOnServer (server, interval) {
  new RunScript(
    server.hostname,
    server.username,
    interval.script.command,
    function (err, results) {
      if (err) { return console.error(err); }
      if (new IsNumber(results)) {
        var intervalIndex = _.findIndex(server.activeScripts, function (activeScript) {
          return activeScript._id.toString() === interval._id.toString();
        });
        var intervalObject = {};
        intervalObject['activeScripts.' + intervalIndex + '.results'] = {
          value: parseFloat(results),
          timestamp: new Date()
        };

        Server.update({ _id: server._id }, {
          $push: intervalObject
        }, function (err) {
          if (err) { console.error(err); }
        });
      }
      else {
        console.error('stdout: ' + results +
          'is not a number! from Script: "' + interval.script.command + '" on Server ' + server);
      }
    });
}

function StartRunningScript (interval, server, callback) {
  async.waterfall([
    function (asyncCallback) {
      if (interval.script._id === undefined) {
        Script.findById(interval.script, function (err, script) {
          if (err) { return asyncCallback(err); }
          interval.script = script.toObject();
          asyncCallback(null, interval);
        });
      }
      else {
        asyncCallback(null, interval)
      }
    }],
    function (error, results) {
      if (error) { return callback(error); }

      var newInterval = setInterval(
        RunScriptOnServer,
        results.duration,
        server,
        results);
      exports.runningScripts.push({
        action: newInterval,
        id: results._id
      });
      callback();
    });
}

function StopRunningScript (interval, callback) {
  var data = interval._id;
  if (data === undefined) {
    data = interval;
  }
  var scriptIndex = _.findIndex(exports.runningScripts, function (script) {
    return script.id.toString() === data.toString();
  });

  if (scriptIndex === -1) {
    callback('That interval ID is not running.');
  }
  else {
    clearInterval(exports.runningScripts[scriptIndex].action);
    exports.runningScripts.splice(scriptIndex, 1);
    callback();
  }
}

exports.start(null, {
  send: function (value, object) {
    if (value === 200) {
      console.log('Intervals Started');
    }
    else {
      console.error(object);
    }
  }
});
<commit_msg>fixing bug in server display endpoint<commit_after>'use strict';

var _ = require('lodash'),
    request = require('request'),
    SSH = require('simple-ssh'),
    async = require('async');
var Server = require('./server.model'),
    Script = require('../script/script.model'),
    Interval = require('./interval.model');
var config = require('../../config/environment');

exports.runningScripts = [];

// Start Intervals
exports.start = function (req, res) {
  Server.find({})
    .populate('activeScripts.script')
    .exec(function (err, servers) {
    if(err) { return handleError(res, err); }
    async.each(servers, function (server, serverCallback) {
      async.each(server.activeScripts, function (interval, intervalCallback) {
        new StartRunningScript(interval, server, intervalCallback);
        }, function (error) {
            serverCallback(error);
        });
    }, function (error) {
      if (error) { return handleError(res, error); }
      res.send(200);
    });
  });
};

exports.execute = function (req, res) {
  Server.findById(req.params.serverId, function (err, server) {
    if (err) { return handleError(res, err); }
    if (!server) { return res.send(404); }
    var intervalIndex = _.findIndex(server.activeScripts, function (activeScript) {
      return activeScript._id.toString() === req.params.intervalId.toString();
    });
    var interval = server.activeScripts[intervalIndex];

    Script.findById(interval.script, function (err, script) {
      if (err) { return handleError(res, err); }
      if (!script) { return handleError(res, 'The script for that interval could not be found.'); }
      new RunScript(server.hostname, server.username, script.command, function (err, results) {
        if (err) { return handleError(res, err); }
        res.send(200, results);
      });
    });
  });
};

// Get list of servers
exports.index = function(req, res) {
  Server.find()
    .exec(function (err, servers) {
      if(err) { return handleError(res, err); }
      return res.json(200, servers);
  });
};

exports.display = function (req, res) {
  Server.find()
    .populate('activeScripts.script')
    .exec(function (err, servers) {
      if (err) { return handleError(res, err); }
      var displayServers = _.map(servers, function (server) {
        if (server.activeScripts.length <= 0) {
          return false;
        }
        server.activeScripts.sort(function (a, b) {
          return b.timestamp - a.timestamp
        });
        server.activeScripts = server.activeScripts.slice(0, 10);
        return server;
      });
      _.remove(displayServers, function (server) {
        return server === false;
      });
      return res.json(200, displayServers);
    });
};

// Get a single server
exports.show = function(req, res) {
  Server.findById(req.params.id)
    .populate('activeScripts.script')
    .exec(function (err, server) {
      if(err) { return handleError(res, err); }
      if(!server) { return res.send(404); }
      return res.json(server);
    });
};

// Creates a new server in the DB.
exports.create = function(req, res) {
  Server.create(req.body, function(err, server) {
    if(err) { return handleError(res, err); }
    return res.json(201, server);
  });
};

// Updates an existing server in the DB.
exports.update = function(req, res) {
  if(req.body._id) { delete req.body._id; }
  for (var s = 0; s < req.body.activeScripts.length; ++s) {
    if (typeof(req.body.activeScripts[s].script) === typeof({})) {
      req.body.activeScripts[s].script = req.body.activeScripts[s].script._id;
    }
  }
  async.waterfall([
    function (callback) {
      // Get original server
      Server.findById(req.params.id, function (err, server) {
        if (err) { return callback(err); }
        if(!server) { return callback('404'); }
        callback(null, server, req.body);
      });
    }, function (oldServer, server, callback) {
      // turn off the old scripts
      async.each(oldServer.activeScripts, StopRunningScript, function (error) {
        callback(error, oldServer, server);
      });
    }, function (oldServer, server, callback) {
      // update server with new info; remove old intervals
      var oldIds = _.difference(oldServer.activeScripts, server.activeScripts);
      Server.update({ _id: oldServer._id },
        {
          hostname: server.hostname || oldServer.hostname,
          description: server.description || oldServer.description,
          username: server.username || oldServer.username,
          $pullAll: { activeScripts: oldIds }
        },
        function (err) {
          callback(err, oldServer, server);
      });
    }, function (oldServer, server, callback) {
      // update server with new info; add new intervals
      Server.update({ _id: oldServer._id },
        { $addToSet: { activeScripts: { $each: server.activeScripts } } },
        function (err) {
          callback(err, oldServer);
      });
    }, function (oldServer, callback) {
      Server.findById(oldServer._id)
        .populate('activeScripts.script')
        .exec(function (err, server) {
          callback(err, server);
      });
    }, function (updated, callback) {
      // start new scripts
      async.each(updated.activeScripts, function (interval, scriptCallback) {
        new StartRunningScript(interval, updated, function (error) {
          if (error) { return scriptCallback(error); }
          return scriptCallback();
        });
      }, function (error, result) {
        return callback(error, result);
      });
    }], function (error, result) {
      if (error === '404') {
        return res.send(404);
      }
      else if (error) {
        return handleError(res, error);
      }
      else {
        return res.json(200, result);
      }
    });
};

// Deletes a server from the DB.
exports.destroy = function(req, res) {
  Server.findById(req.params.id)
    .exec(function (err, server) {
    if(err) { return handleError(res, err); }
    if(!server) { return res.send(404); }
    server.remove(function(err) {
      if(err) { return handleError(res, err); }
      async.each(server.activeScripts, StopRunningScript, function (error) {
        if (error) { return handleError(res, error); }
        return res.send(204);
      });
    });
  });
};

function handleError(res, err) {
  console.error(err);
  return res.send(500, err);
}

function IsNumber(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

function RunScript (hostname, username, command, callback) {
  var ssh = new SSH({
    host: hostname,
    user: username,
    key: config.sshkey
    //timeout: 2000
  });

  ssh.exec(command, {
    out: function(stdout) {
      callback(null, stdout);
    },
    err: function(stderr) {
      console.error(stderr);
    }
  }).start();
}

function RunScriptOnServer (server, interval) {
  new RunScript(
    server.hostname,
    server.username,
    interval.script.command,
    function (err, results) {
      if (err) { return console.error(err); }
      if (new IsNumber(results)) {
        var intervalIndex = _.findIndex(server.activeScripts, function (activeScript) {
          return activeScript._id.toString() === interval._id.toString();
        });
        var intervalObject = {};
        intervalObject['activeScripts.' + intervalIndex + '.results'] = {
          value: parseFloat(results),
          timestamp: new Date()
        };

        Server.update({ _id: server._id }, {
          $push: intervalObject
        }, function (err) {
          if (err) { console.error(err); }
        });
      }
      else {
        console.error('stdout: ' + results +
          'is not a number! from Script: "' + interval.script.command + '" on Server ' + server);
      }
    });
}

function StartRunningScript (interval, server, callback) {
  async.waterfall([
    function (asyncCallback) {
      if (interval.script._id === undefined) {
        Script.findById(interval.script, function (err, script) {
          if (err) { return asyncCallback(err); }
          interval.script = script.toObject();
          asyncCallback(null, interval);
        });
      }
      else {
        asyncCallback(null, interval)
      }
    }],
    function (error, results) {
      if (error) { return callback(error); }

      var newInterval = setInterval(
        RunScriptOnServer,
        results.duration,
        server,
        results);
      exports.runningScripts.push({
        action: newInterval,
        id: results._id
      });
      callback();
    });
}

function StopRunningScript (interval, callback) {
  var data = interval._id;
  if (data === undefined) {
    data = interval;
  }
  var scriptIndex = _.findIndex(exports.runningScripts, function (script) {
    return script.id.toString() === data.toString();
  });

  if (scriptIndex === -1) {
    callback('That interval ID is not running.');
  }
  else {
    clearInterval(exports.runningScripts[scriptIndex].action);
    exports.runningScripts.splice(scriptIndex, 1);
    callback();
  }
}

exports.start(null, {
  send: function (value, object) {
    if (value === 200) {
      console.log('Intervals Started');
    }
    else {
      console.error(object);
    }
  }
});
<|endoftext|>


<commit_before>#!env node
"use strict";

const COMMIT_ARTIFACTS = ['lib', 'lib-esm', 'release', 'package.json'];

let shx = require('shelljs');
let readlineSync = require('readline-sync');
let fs = require('fs');
let path = require('path');
let util = require('./util');
let _exec = util._exec;

let HYBRIDPKG = process.argv[2] || readlineSync.question(`Hybrid package name (e.g.: angular-hybrid or react-hybrid)`);

let pkg = require('../package.json');
let version = pkg.version;
let hybridVersion = require(`../../${HYBRIDPKG}/package.json`).version;

shx.cd(path.join(__dirname, '..'));

var widen = false;
var coreDep = pkg.dependencies['@uirouter/core'];
var isNarrow = /^[[=~]?(\d.*)/.exec(coreDep);
var widenedDep = isNarrow && '^' + isNarrow[1];

if (isNarrow && readlineSync.keyInYN('Widen @uirouter/core dependency from ' + coreDep + ' to ' + widenedDep + '?')) {
  widen = false;
}

const YYYYMMDD = (function() {
  var date = new Date();
  var year = date.getFullYear();

  var month = date.getMonth() + 1;
  month = (month < 10 ? "0" : "") + month;

  var day  = date.getDate();
  day = (day < 10 ? "0" : "") + day;

  return year + month + day;
})();

let tagname = `SNAPSHOT-${YYYYMMDD}`;
tagname += readlineSync.question(`Suffix for tag ${tagname} (optional)?`);

if (!readlineSync.keyInYN(`Ready to publish ${tagname} tag?`)) {
  process.exit(1);
}

util.ensureCleanMaster('master');

// then tag and push tag
_exec(`git checkout -b ${tagname}-prep`);

pkg.dependencies['@uirouter/core'] = widenedDep;
// pkg.version = tagname;

fs.writeFileSync("package.json", JSON.stringify(pkg, undefined, 2));
_exec('git commit -m "Widening @uirouter/core dependency range to ' + widenedDep + '" package.json');

_exec('npm run package');

_exec(`git add --force ${COMMIT_ARTIFACTS.join(' ')}`);
_exec(`git rm yarn.lock`);

_exec(`git commit -m 'chore(*): commiting build files'`);
_exec(`git tag ${tagname}`);
_exec(`git push -u origin ${tagname}`);
_exec(`git checkout master`);
_exec(`git branch -D ${tagname}-prep`);
<commit_msg>chore(artifacts): remove dependency on angular-hybrid package<commit_after>#!env node
"use strict";

const COMMIT_ARTIFACTS = ['lib', 'lib-esm', 'release', 'package.json'];

let shx = require('shelljs');
let readlineSync = require('readline-sync');
let fs = require('fs');
let path = require('path');
let util = require('./util');
let _exec = util._exec;

let pkg = require('../package.json');
let version = pkg.version;

shx.cd(path.join(__dirname, '..'));

var widen = false;
var coreDep = pkg.dependencies['@uirouter/core'];
var isNarrow = /^[[=~]?(\d.*)/.exec(coreDep);
var widenedDep = isNarrow && '^' + isNarrow[1];

if (isNarrow && readlineSync.keyInYN('Widen @uirouter/core dependency from ' + coreDep + ' to ' + widenedDep + '?')) {
  widen = false;
}

const YYYYMMDD = (function() {
  var date = new Date();
  var year = date.getFullYear();

  var month = date.getMonth() + 1;
  month = (month < 10 ? "0" : "") + month;

  var day  = date.getDate();
  day = (day < 10 ? "0" : "") + day;

  return year + month + day;
})();

let tagname = `SNAPSHOT-${YYYYMMDD}`;
tagname += readlineSync.question(`Suffix for tag ${tagname} (optional)?`);

if (!readlineSync.keyInYN(`Ready to publish ${tagname} tag?`)) {
  process.exit(1);
}

util.ensureCleanMaster('master');

// then tag and push tag
_exec(`git checkout -b ${tagname}-prep`);

pkg.dependencies['@uirouter/core'] = widenedDep;
// pkg.version = tagname;

fs.writeFileSync("package.json", JSON.stringify(pkg, undefined, 2));
_exec('git commit -m "Widening @uirouter/core dependency range to ' + widenedDep + '" package.json');

_exec('npm run package');

_exec(`git add --force ${COMMIT_ARTIFACTS.join(' ')}`);
_exec(`git rm yarn.lock`);

_exec(`git commit -m 'chore(*): commiting build files'`);
_exec(`git tag ${tagname}`);
_exec(`git push -u origin ${tagname}`);
_exec(`git checkout master`);
_exec(`git branch -D ${tagname}-prep`);
<|endoftext|>


<commit_before>define(['js/core/Bindable', 'js/core/Base'], function (Bindable, Base) {

    var defaultConditionFnc = function(){
        return true;
    };

    var Validator = Bindable.inherit('js.data.validator.Validator', {

        $validatorCache: {},

        defaults: {
            /***
             * the field of the entity to validate
             * @type String
             */
            field: null,
            /***
             * the error code for this validation error
             * @type String
             */
            errorCode: 'isInvalid',
            /***
             * the error message displayed for the user
             * @type String
             */
            errorMessage: null,
            /***
             * a compare function used for validation
             * @type Function
             */
            condition: null
        },

        ctor: function () {
            this.callBase();

            var cacheKey = this._generateCacheKey.apply(this, arguments);
            if (cacheKey && !this.$validatorCache[cacheKey]) {
                this.$validatorCache[cacheKey] = this;
            }

            return this.$validatorCache[cacheKey];
        },

        _generateCacheKey: function () {
            return null;
        },

        /***
         * validates entities
         * @param entity
         * @param callback
         */
        validate: function (entity, options, callback) {
            if (options instanceof Function) {
                callback = options;
                options = {};
            }

            options = options || {};

            var self = this,
                callbackInvoked = false,
                condition = this.$.condition || defaultConditionFnc;

            if (!this._validationRequired(entity)) {
                internalCallback(null);
                return;
            }

            try {
                // TOOD: make validate sync
                internalCallback(null, this._validate(entity));
            } catch(e) {
                internalCallback(e);
            }

            function internalCallback(err, result) {
                if (callbackInvoked) {
                    self.log('Validator returned twice. Ignore second return', Base.LOGLEVEL.WARN);
                    return;
                }

                callbackInvoked = true;
                // returns an array of errors
                callback(err, result);
            }
        },

        _validationRequired: function(entity) {

            return !(this.$.field && !entity.$[this.$.field] && !entity.schema[this.$.field].required);

        },

        /***
         * performs a synchronous validation
         * @param {js.data.Entity} entity
         * @abstract
         * @private
         */
        _validate: function (entity) {
            throw new Error("abstract method _validate from Validator");
        },

        _getErrorMessage: function () {
            if (this.$.field) {
                return  (this.$.errorMessage || "Field '%' is invalid").replace('%', this.$.field);
            } else {
                return this.$.errorMessage || "Entity is invalid";
            }
        },
        _createError: function(code, message, field){
            return new Validator.Error({
                code: code,
                message: message,
                field: field
            });
        },
        _createFieldError: function (field) {
            return this._createError(this.$.errorCode, this._getErrorMessage(), field || this.$.field);
        }

    });

    Validator.Error = Bindable.inherit({
    });

    return Validator;
})
;<commit_msg>added some documentation to Validator<commit_after>define(['js/core/Bindable', 'js/core/Base'], function (Bindable, Base) {

    var defaultConditionFnc = function(){
        return true;
    };

    var Validator = Bindable.inherit('js.data.validator.Validator', {

        $validatorCache: {},

        defaults: {
            /***
             * the field of the entity to validate
             * @type String
             */
            field: null,
            /***
             * the error code for this validation error
             * @type String
             */
            errorCode: 'isInvalid',
            /***
             * the error message displayed for the user
             * @type String
             */
            errorMessage: null,
            /***
             * a compare function used for validation
             * @type Function
             */
            condition: null
        },

        ctor: function () {
            this.callBase();

            var cacheKey = this._generateCacheKey.apply(this, arguments);
            if (cacheKey && !this.$validatorCache[cacheKey]) {
                this.$validatorCache[cacheKey] = this;
            }

            return this.$validatorCache[cacheKey];
        },

        _generateCacheKey: function () {
            return null;
        },

        /***
         * validates entities
         * @param {js.data.Entity} entity
         * @param {Object} [options]
         * @param {Function} callback
         */
        validate: function (entity, options, callback) {
            if (options instanceof Function) {
                callback = options;
                options = {};
            }

            options = options || {};

            var self = this,
                callbackInvoked = false,
                condition = this.$.condition || defaultConditionFnc;

            if (!this._validationRequired(entity)) {
                internalCallback(null);
                return;
            }

            try {
                // TOOD: make validate sync
                internalCallback(null, this._validate(entity));
            } catch(e) {
                internalCallback(e);
            }

            function internalCallback(err, result) {
                if (callbackInvoked) {
                    self.log('Validator returned twice. Ignore second return', Base.LOGLEVEL.WARN);
                    return;
                }

                callbackInvoked = true;
                // returns an array of errors
                callback(err, result);
            }
        },

        /***
         * Returns true if entity has the field set or the field is required
         * @param {js.data.Entity} entity
         * @returns {boolean}
         * @private
         */
        _validationRequired: function(entity) {
            return !(this.$.field && !entity.$[this.$.field] && !entity.schema[this.$.field].required);
        },

        /***
         * performs a synchronous validation
         * @param {js.data.Entity} entity
         * @abstract
         * @private
         */
        _validate: function (entity) {
            throw new Error("abstract method _validate from Validator");
        },

        _getErrorMessage: function () {
            if (this.$.field) {
                return  (this.$.errorMessage || "Field '%' is invalid").replace('%', this.$.field);
            } else {
                return this.$.errorMessage || "Entity is invalid";
            }
        },
        /***
         * Creates an Validation Error object with a code, message and a field
         * @param {String} code
         * @param {String} message
         * @param {String} field
         * @returns {js.data.validator.Validator.Error}
         * @private
         */
        _createError: function(code, message, field){
            return new Validator.Error({
                code: code,
                message: message,
                field: field
            });
        },
        /***
         * Create a field error
         *
         * @param {String} [field] - the field
         * @returns {js.data.validator.Validator.Error} an error instance
         * @private
         */
        _createFieldError: function (field) {
            return this._createError(this.$.errorCode, this._getErrorMessage(), field || this.$.field);
        }

    });

    Validator.Error = Bindable.inherit({
    });

    return Validator;
})
;<|endoftext|>


<commit_before>/**
 * @class Oskari.mapframework.bundle.PluginMapModuleBundleInstance
 *
 * This bundle instance starts the map view, but doesn't work anymore after the
 * new versioning scheme. See
 * Oskari.mapframework.bundle.mapfull.MapFullBundleInstance for current
 * implementation.
 *
 * @deprecated use mapfull bundle instead.
 */
Oskari.clazz.define("Oskari.mapframework.bundle.PluginMapModuleBundleInstance",

/**
 * @method create called automatically on construction
 * @static
 */
function() {
    this.name = 'mapmodule';
    this.mediator = null;
    this.sandbox = null;
    this.conf = null;
    this.impl = null;
    this.facade = null;
    this.ui = null;
}, {
    __name : "Oskari.mapframework.bundle.PluginMapModuleBundleInstance",
    /**
     * @method getName
     * @return {String} the name for the component
     */
    getName : function() {
        return this.__name;
    },

    /**
     * @method start
     * Implements BundleInstance protocol start method.
     * Creates the map view.
     */
    "start" : function() {

        if (this.mediator.getState() == "started")
            return;

        this.libs = {
            ext : Oskari.$("Ext")
        };

        var facade = Oskari.$('UI.facade');
        this.facade = facade;

        var sandbox = facade.getSandbox();
        this.sandbox = sandbox;

        var conf = Oskari.$("startup");

        this.conf = conf;

        var showIndexMap = conf.mapConfigurations.index_map;
        var showZoomBar = conf.mapConfigurations.zoom_bar;
        var showScaleBar = conf.mapConfigurations.scala_bar;
        var allowMapMovements = conf.mapConfigurations.pan;

        var impl = Oskari.clazz.create('Oskari.mapframework.ui.module.common.MapModule', "Main", showIndexMap, showZoomBar, showScaleBar, allowMapMovements);
        // impl.setOpt('createTilesGrid', false);
        this.impl = impl;

        var pnl = this._createMapPanel();
        this._panel = pnl;

        var def = this.facade.appendExtensionModule(this.impl, this.name, {}, this, 'Center', {
            'fi' : {
                title : ''
            },
            'sv' : {
                title : '?'
            },
            'en' : {
                title : ''
            }

        }, pnl);
        this.def = def;

        // plugins
        var plugins = [];
        plugins.push('Oskari.mapframework.bundle.mapmodule.plugin.LayersPlugin');
        plugins.push('Oskari.mapframework.mapmodule.WmsLayerPlugin');
        //plugins.push('Oskari.mapframework.mapmodule.SketchLayerPlugin');
        plugins.push('Oskari.mapframework.mapmodule.MarkersPlugin');
        plugins.push('Oskari.mapframework.mapmodule.VectorLayerPlugin');
        plugins.push('Oskari.mapframework.mapmodule.TilesGridPlugin');
        plugins.push('Oskari.mapframework.mapmodule.ControlsPlugin');
        plugins.push('Oskari.mapframework.mapmodule.WfsLayerPlugin');
        plugins.push('Oskari.mapframework.mapmodule.GetInfoPlugin');

        for (var i = 0; i < plugins.length; i++) {
            var plugin = Oskari.clazz.create(plugins[i]);
            impl.registerPlugin(plugin);
        }

        var mapster = this._createMapContainer(this.impl.getMap());
        this._mapster = mapster;
        pnl.add(mapster);

        facade.registerPart('Mapster', this._mapster);

        // call real modules start
        this.impl.start(sandbox);
        this.mediator.setState("started");
        return this;
    },
    /**
     * @method _createMapPanel
     * creates (Ext) map panel
     * @private
     */
    _createMapPanel : function() {
        var xt = this.libs.ext;
        var pnl = xt.create('Ext.Panel', {
            region : 'center',
            layout : 'fit',
            items : []
        });

        return pnl;

    },
    /**
     * @method _createMapContainer
     * creates (Ext) map panel with openlayers map
     * @param {OpenLayers.Map} map
     * @private
     */
    _createMapContainer : function(map) {
        var xt = this.libs.ext;
        var mapster = xt.createWidget('nlsfimappanel', {
            olmap : map,
            layout : 'absolute'
        });

        return mapster;
    },
    /**
     * @method update
     * implements BundleInstance protocol update method - does nothing atm
     */
    "update" : function(manager, b, bi, info) {
        manager.alert("RECEIVED update notification @BUNDLE_INSTANCE: " + info);
    },
    /**
     * @method stop
     * implements BundleInstance protocol stop method
     */
    "stop" : function() {

        this.impl.stop();

        this.facade.removeExtensionModule(this.impl, this.name, this.impl.eventHandlers, this, this.def);
        this.def = null;

        this.mediator.setState("stopped");

        return this;
    }
}, {
    /**
     * @property {String[]} protocol
     * @static
     */
    "protocol" : ["Oskari.bundle.BundleInstance", "Oskari.mapframework.bundle.extension.Extension"]
});
<commit_msg>[AL-985] rm instance.js<commit_after><|endoftext|>


<commit_before>
class Header extends Component {
  render() {
    return (

HEADER

    )
  }
}
<commit_msg>refeactor(components): header structure refactor<commit_after>
class Header extends Component {
  render() {
    return (

            Nav Link

              Login with Google

    )
  }
}
<|endoftext|>