<commit_before>import React from "react";
import { bindActionCreators } from "redux";
import { connect } from "react-redux";
import injectSheet from "react-jss";
import { Link } from "react-router-dom";

import { Hamburger, Search } from "../icons";
import { openSidebar } from "../actions";
import MobileNavButton from "./MobileNavButton";
import { FeaturedSectionsBar } from "../../sections/components";

import { openSubscriptionModal } from "../../accounts/actions";

const styles = {
  MastheadBar: {
    backgroundColor: "#fff",
    boxShadow: "0 2px 4px 0 rgba(0,0,0,.2)",
    height: "73px",
    left: 0,
    position: "fixed",
    width: "100%",
    top: 0,
    zIndex: 1000,
    display: "flex",
    flexDirection: "column",
    alignItems: "center"
  },
  barContainer: {
    display: "flex",
    height: "37px",
    justifyContent: "space-between",
    alignItems: "center",
    margin: "0 auto",
    padding: "5px 30px 0px 30px",
    position: "relative",
    textAlign: "center",
    width: "100%",
  },
  sidebarToggle: {
    "& button": {
      position: "relative",
      left: "-10px",
      top: "2px",
    },
  },
  brandingLink: {
    bottom: "5px",
    color: "#000",
    fontFamily: "Mrs Eaves Small Caps",
    fontSize: "2.5rem",
    textDecoration: "none",
    "&:hover, &:active, &:focus": {
      color: "#000",
      textDecoration: "none",
    },
  },
  navButtons: {
    marginTop: "20px",
    fontFamily: "Circular Std",
    fontSize: "13px",
    fontWeight: 300,
    display: "flex",
    flexDirection: "column",
    "& button": {
      marginLeft: "24px",
    },
  },
  userTools: {
    marginBottom: "12px",
    "& > a, span": {
      color: "#888",
      "&:hover, &:active, &:focus": {
        color: "#888",
        cursor: "pointer",
        textDecoration: "underline",
      },
    },
  },
  subscriber: {
    borderLeft: "1px solid #888",
    marginLeft: "9px",
    paddingLeft: "8px",
  },
  searchLink: {
    alignSelf: "flex-end",
    color: "#000",
    "&:hover, &:active, &:focus": {
      color: "#000",
    },
    "& svg": {
      display: "inline",
      marginRight: "4px",
      transform: "translateY(-2px)",
    },
  },
  responsiveSectionNamesContainer: {
    display: "inline",
  },
  sectionsBarContainer: {
    display: "flex",
    justifyContent: "center",
  },
  "@media (max-width: 1100px)": {
    MastheadBar: {
      height: "52px",
      flexDirection: "row"
    },
    sectionsBarContainer: {
      display: "none",
    },
    navButtons: {
      display: "none",
    },
  },
  "@media (max-width: 375px)": {
    brandingLink: {
      lineHeight: "2rem",
      marginTop: "7.5px",
    },
  },
};

const MastheadBar = ({
  classes,
  openSidebar,
  openSubscriptionModal,
  session,
}) => {
  return (

          <MobileNavButton onClick={openSidebar}>
            <Hamburger color={"#000"} size={20} />
          </MobileNavButton>

        <Link className={classes.brandingLink} to={"/"}>
          The Spectator
        </Link>

            {session ? (
              <Link to="/myaccount/profile">Profile</Link>
            ) : (
              <Link to="/myaccount">Log In</Link>
            )}

              Subscribe

          <Link to="/search" className={classes.searchLink}>
            <Search color={"#000"} />
            Search
          </Link>

        <FeaturedSectionsBar omitSearch={true} />

  );
};

const mapStateToProps = state => ({
  session: state.accounts.session,
});

const mapDispatchToProps = dispatch => {
  return bindActionCreators({ openSidebar, openSubscriptionModal }, dispatch);
};

export default connect(mapStateToProps, mapDispatchToProps)(
  injectSheet(styles)(MastheadBar),
);
<commit_msg>Fixed mobile vertical centering.<commit_after>import React from "react";
import { bindActionCreators } from "redux";
import { connect } from "react-redux";
import injectSheet from "react-jss";
import { Link } from "react-router-dom";

import { Hamburger, Search } from "../icons";
import { openSidebar } from "../actions";
import MobileNavButton from "./MobileNavButton";
import { FeaturedSectionsBar } from "../../sections/components";

import { openSubscriptionModal } from "../../accounts/actions";

const styles = {
  MastheadBar: {
    backgroundColor: "#fff",
    boxShadow: "0 2px 4px 0 rgba(0,0,0,.2)",
    height: "73px",
    left: 0,
    position: "fixed",
    width: "100%",
    top: 0,
    zIndex: 1000,
    display: "flex",
    flexDirection: "column",
    alignItems: "center"
  },
  barContainer: {
    display: "flex",
    height: "37px",
    justifyContent: "space-between",
    alignItems: "center",
    margin: "0 auto",
    padding: "0px 30px 0px 30px",
    position: "relative",
    textAlign: "center",
    width: "100%",
  },
  sidebarToggle: {
    "& button": {
      position: "relative",
      left: "-10px",
    },
  },
  brandingLink: {
    bottom: "5px",
    color: "#000",
    fontFamily: "Mrs Eaves Small Caps",
    fontSize: "2.5rem",
    textDecoration: "none",
    "&:hover, &:active, &:focus": {
      color: "#000",
      textDecoration: "none",
    },
  },
  navButtons: {
    marginTop: "20px",
    fontFamily: "Circular Std",
    fontSize: "13px",
    fontWeight: 300,
    display: "flex",
    flexDirection: "column",
    "& button": {
      marginLeft: "24px",
    },
  },
  userTools: {
    marginBottom: "12px",
    "& > a, span": {
      color: "#888",
      "&:hover, &:active, &:focus": {
        color: "#888",
        cursor: "pointer",
        textDecoration: "underline",
      },
    },
  },
  subscriber: {
    borderLeft: "1px solid #888",
    marginLeft: "9px",
    paddingLeft: "8px",
  },
  searchLink: {
    alignSelf: "flex-end",
    color: "#000",
    "&:hover, &:active, &:focus": {
      color: "#000",
    },
    "& svg": {
      display: "inline",
      marginRight: "4px",
      transform: "translateY(-2px)",
    },
  },
  responsiveSectionNamesContainer: {
    display: "inline",
  },
  sectionsBarContainer: {
    display: "flex",
    justifyContent: "center",
  },
  "@media (max-width: 1100px)": {
    MastheadBar: {
      height: "52px",
      flexDirection: "row"
    },
    sectionsBarContainer: {
      display: "none",
    },
    navButtons: {
      display: "none",
    },
  },
  "@media (max-width: 375px)": {
    brandingLink: {
      lineHeight: "2rem",
    },
  },
};

const MastheadBar = ({
  classes,
  openSidebar,
  openSubscriptionModal,
  session,
}) => {
  return (

          <MobileNavButton onClick={openSidebar}>
            <Hamburger color={"#000"} size={20} />
          </MobileNavButton>

        <Link className={classes.brandingLink} to={"/"}>
          The Spectator
        </Link>

            {session ? (
              <Link to="/myaccount/profile">Profile</Link>
            ) : (
              <Link to="/myaccount">Log In</Link>
            )}

              Subscribe

          <Link to="/search" className={classes.searchLink}>
            <Search color={"#000"} />
            Search
          </Link>

        <FeaturedSectionsBar omitSearch={true} />

  );
};

const mapStateToProps = state => ({
  session: state.accounts.session,
});

const mapDispatchToProps = dispatch => {
  return bindActionCreators({ openSidebar, openSubscriptionModal }, dispatch);
};

export default connect(mapStateToProps, mapDispatchToProps)(
  injectSheet(styles)(MastheadBar),
);
<|endoftext|>


<commit_before>var Plurb = require('../db/dbconfig').Plurb;
var User = require('../db/dbconfig').User;
var Topic = require('../db/dbconfig').Topic;

module.exports = {

  createPlurb: function (req, res) {
    var googId = req.session.user;
    var topicId = req.body.topicId;
    //make a db call using the googid and returns user data
    User.find({where:
      {googid: googId}
    })
    .then(function (user) {
      //set the values for first and last names, picture
      //put all data into an objected used to create plurb
      var plurbData = {
        text: req.body.text,
        lat: req.body.lat,
        long: req.body.long,
        firstName: user.dataValues.firstName,
        lastName: user.dataValues.lastName,
        picture: user.dataValues.picture
      };
      Plurb.create(plurbData)
      .then(function (plurb) {
        //sets the foreign key of googId and topicId
        return plurb.setUser(googId);
      })
      .then(function(plurb) {
        return plurb.setTopic(topicId);
      })
      .then(function(plurb){
        res.status(201).json(plurb);
      })
      .catch(function (err) {
        console.error(err);
      });
    });
  },

  // // Is this handler ever used on FE?
  // getPlurb: function (req, res) {
  //   var plurbId = req.params.plurbId;
  //   Plurb.findById(plurbId)
  //   .then(function (plurb) {
  //     res.status(200).json(plurb);
  //   })
  //   .catch(function (err) {
  //     console.error(err);
  //   });
  // },

  deletePlurb: function (req, res) {
    var plurbId = req.params.plurbId;
    Plurb.destroy({where: {id: plurbId}})
    .then(function () {
      res.status(201);
    })
    .catch(function (err) {
      console.error(err);
    });
  },

  getPlurbsByLocation: function (req, res) {

    // OPTIONAL PARAMS
    // search terms
    var selectedUID = req.body.googId;
    var selectedTopicId = req.body.topicId;
    var clientUID = req.session.user;

    // REQUIRED PARAMS
    var minLat = req.body.mapBounds.minLat;
    var maxLat = req.body.mapBounds.maxLat;
    var minLng = req.body.mapBounds.minLng;
    var maxLng = req.body.mapBounds.maxLng;
    var filter = req.body.filter; // filter state of app

    var query = {};
    var promised = false;

    //////////////////////////// FILTER set to FRIENDS ///////////////////////
    if (filter === 'FRIENDS') {

      // if selectedUID is null
      if (selectedUID === null) {
        promised = true;

        // DEFAULT send plurbs of user's friends
        var friendsGoogIds = [];

        // Find user's friends' googIds
        User.find({where: {googid: clientUID}})
        .then(function(user) {
          // pull all friends
          user.getFriends()
          .then(function(friends){
            friendsGoogIds = friends.map(function(friend) {
              return Number(friend.dataValues.googid);
            });
            // final get all plurbs of user's friends query
            query = {
              include: [Topic],
              where: {
                lat: {$between: [minLat, maxLat]},
                long: {$between: [minLng, maxLng]},
                UserGoogid: {$in: friendsGoogIds}
              }
            };
            Plurb.findAll(query)
            .then(function(plurbs) {
              res.status(200).json(plurbs);
            });
          })
          .catch(function (err) {
            console.error (err);
          });
        })
        .catch(function(err) {
          console.error(err);
        });
      } else {
      // SEARCH plurbs of selectedUID
        query = {
          include: [Topic],
          where: {
            lat: {$between: [minLat, maxLat]},
            long: {$between: [minLng, maxLng]},
            UserGoogid: selectedUID,
          },
        };
      }
    }

    //////////////////////////// FILTER set to TOPICS ///////////////////////
    if (filter === 'TOPICS') {

      // if selectedTopicId is null
      if (selectedTopicId === null) {
        // DEFAULT send all plurbs
        query = {
          include: [Topic],
          where: {
            lat: {$between: [minLat, maxLat]},
            long: {$between: [minLng, maxLng]},
          }
        };

      } else {
        // SEARCH plurbs of selectedTopicId
        query = {
          include: [Topic],
          where: {
            lat: {$between: [minLat, maxLat]},
            long: {$between: [minLng, maxLng]},
            TopicId: selectedTopicId,
          }
        };
      }
    }

    // Use built query to find plurbs
    if (!promised) { // make sure res was not already sent
      Plurb.findAll(query)
      .then(function (plurbs) {
        res.status(200).json(plurbs);
      })
      .catch(function (err) {
        console.error (err);
      });
    }
  },
};
<commit_msg>(style) Add comment<commit_after>var Plurb = require('../db/dbconfig').Plurb;
var User = require('../db/dbconfig').User;
var Topic = require('../db/dbconfig').Topic;

module.exports = {

  createPlurb: function (req, res) {
    var googId = req.session.user;
    var topicId = req.body.topicId;
    //make a db call using the googid and returns user data
    User.find({where:
      {googid: googId}
    })
    .then(function (user) {
      //set the values for first and last names, picture
      //put all data into an objected used to create plurb
      var plurbData = {
        text: req.body.text,
        lat: req.body.lat,
        long: req.body.long,
        firstName: user.dataValues.firstName,
        lastName: user.dataValues.lastName,
        picture: user.dataValues.picture
      };
      Plurb.create(plurbData)
      .then(function (plurb) {
        //sets the foreign key of googId
        return plurb.setUser(googId);
      })
        // sets the foreign key of topicId
      .then(function(plurb) {
        return plurb.setTopic(topicId);
      })
      .then(function(plurb){
        res.status(201).json(plurb);
      })
      .catch(function (err) {
        console.error(err);
      });
    });
  },

  // // Is this handler ever used on FE?
  // getPlurb: function (req, res) {
  //   var plurbId = req.params.plurbId;
  //   Plurb.findById(plurbId)
  //   .then(function (plurb) {
  //     res.status(200).json(plurb);
  //   })
  //   .catch(function (err) {
  //     console.error(err);
  //   });
  // },

  deletePlurb: function (req, res) {
    var plurbId = req.params.plurbId;
    Plurb.destroy({where: {id: plurbId}})
    .then(function () {
      res.status(201);
    })
    .catch(function (err) {
      console.error(err);
    });
  },

  getPlurbsByLocation: function (req, res) {

    // OPTIONAL PARAMS
    // search terms
    var selectedUID = req.body.googId;
    var selectedTopicId = req.body.topicId;
    var clientUID = req.session.user;

    // REQUIRED PARAMS
    var minLat = req.body.mapBounds.minLat;
    var maxLat = req.body.mapBounds.maxLat;
    var minLng = req.body.mapBounds.minLng;
    var maxLng = req.body.mapBounds.maxLng;
    var filter = req.body.filter; // filter state of app

    var query = {};
    var promised = false;

    //////////////////////////// FILTER set to FRIENDS ///////////////////////
    if (filter === 'FRIENDS') {

      // if selectedUID is null
      if (selectedUID === null) {
        promised = true;

        // DEFAULT send plurbs of user's friends
        var friendsGoogIds = [];

        // Find user's friends' googIds
        User.find({where: {googid: clientUID}})
        .then(function(user) {
          // pull all friends
          user.getFriends()
          .then(function(friends){
            friendsGoogIds = friends.map(function(friend) {
              return Number(friend.dataValues.googid);
            });
            // final get all plurbs of user's friends query
            query = {
              include: [Topic],
              where: {
                lat: {$between: [minLat, maxLat]},
                long: {$between: [minLng, maxLng]},
                UserGoogid: {$in: friendsGoogIds}
              }
            };
            Plurb.findAll(query)
            .then(function(plurbs) {
              res.status(200).json(plurbs);
            });
          })
          .catch(function (err) {
            console.error (err);
          });
        })
        .catch(function(err) {
          console.error(err);
        });
      } else {
      // SEARCH plurbs of selectedUID
        query = {
          include: [Topic],
          where: {
            lat: {$between: [minLat, maxLat]},
            long: {$between: [minLng, maxLng]},
            UserGoogid: selectedUID,
          },
        };
      }
    }

    //////////////////////////// FILTER set to TOPICS ///////////////////////
    if (filter === 'TOPICS') {

      // if selectedTopicId is null
      if (selectedTopicId === null) {
        // DEFAULT send all plurbs
        query = {
          include: [Topic],
          where: {
            lat: {$between: [minLat, maxLat]},
            long: {$between: [minLng, maxLng]},
          }
        };

      } else {
        // SEARCH plurbs of selectedTopicId
        query = {
          include: [Topic],
          where: {
            lat: {$between: [minLat, maxLat]},
            long: {$between: [minLng, maxLng]},
            TopicId: selectedTopicId,
          }
        };
      }
    }

    // Use built query to find plurbs
    if (!promised) { // make sure res was not already sent
      Plurb.findAll(query)
      .then(function (plurbs) {
        res.status(200).json(plurbs);
      })
      .catch(function (err) {
        console.error (err);
      });
    }
  },
};
<|endoftext|>


<commit_before>exports.onRouteUpdate = () => {
  const scroller = document.getElementById('scroller');
  if (scroller != null) scroller.scrollTo(0, 0);
};
<commit_msg>fix(scroll): Fix scroll manager<commit_after>exports.onRouteUpdate = () => {
  const hash = window.location.hash;
  const targetId = hash.slice(1);

  if (targetId.length > 0) {
    const target = document.getElementById(target);

    if (target != null) target.scrollIntoView(true);
  } else {
    const scroller = document.getElementById('scroller');
    if (scroller != null) scroller.scrollTo(0, 0);
  }
};
<|endoftext|>


<commit_before>// from https://github.com/michalstocki/FlashWavRecorder/
// adapted for use in Baruch College's TfCS Wordpress website

jQuery(function () {

  var RECORDER_APP_ID = "recorderApp";
//  var $level = $('.level .progress');

  var appWidth = 24;
  var appHeight = 24;
  var flashvars = {'upload_image': 'http://michalstocki.github.io/FlashWavRecorder/html/images/upload.png'};
  var params = { allowScriptAccess: 'always', wmode: 'transparent'};
  var attributes = {'id': RECORDER_APP_ID, 'name': RECORDER_APP_ID};
  swfobject.embedSWF("../files/2016/06/recorder.jpg", "flashcontent", appWidth, appHeight, "11.0.0", "", flashvars, params, attributes);

  window.fwr_event_handler = function fwr_event_handler() {
    var name, $controls;
    switch (arguments[0]) {
      case "ready":
        FWRecorder.uploadFormId = "#uploadForm";
        FWRecorder.uploadFieldName = "upload_file[filename]";
        FWRecorder.connect(RECORDER_APP_ID, 0);
        FWRecorder.recorderOriginalWidth = appWidth;
        FWRecorder.recorderOriginalHeight = appHeight;
        break;

      case "microphone_user_request":
        FWRecorder.showPermissionWindow();
        break;

      case "permission_panel_closed":
        FWRecorder.defaultSize();
        break;

      case "recording":
        FWRecorder.hide();
        FWRecorder.resize(1, 1);
        FWRecorder.observeLevel();
        break;

      case "recording_stopped":
        // FWRecorder.show();
        window.duration = arguments[2].toFixed(2) * 1000;

        FWRecorder.stopObservingLevel();
        jQuery(".audiolevel").css({height: 0});
        break;

      case "microphone_level":
      	var curLevel = jQuery(".audiolevel").height();
        jQuery(".audiolevel").css({height: (arguments[1]*90 + curLevel*10/40) + '%'});
        break;

    }
  };

  function recorderEl() {
    return jQuery('#' + RECORDER_APP_ID);
  }
});

// fix flash object in a specific position on window.
// this way the flash object being resized will not mess with the page layout
jQuery(document).ready(function(){
    if (document.getElementById('recorderApp')) {
        var flashobject = document.getElementById('recorderApp');
        flashobject.style.position = "fixed";
    }
});

// pressing the record button first asks permission and triggers recording
jQuery(document).on('click', '.record', function () {
	if (!FWRecorder.isMicrophoneAccessible()) {
		FWRecorder.showPermissionWindow();
	} else {
	    jQuery(this).toggleClass('recording');
	}
    if (jQuery(this).hasClass('recording')) {
	    FWRecorder.configure(22, 80, 1, 0);
        FWRecorder.setUseEchoSuppression(true);
        jQuery(".progress").css({ width: '0%' });
    	setTimeout(function() { FWRecorder.record('audio', 'audio.wav'); }, 1);

    } else {
    	setTimeout(function() { FWRecorder.stopRecording('audio');}, 1);
    }
});

// animates play button
jQuery(document).on('click', '.playback', function () {
  if (jQuery(".record").hasClass('recording')) {
    FWRecorder.stopRecording();
    setTimeout(function() { jQuery(".record").removeClass('recording'); }, 5);
  }
	jQuery(".progress").css({ width: '0%' });
	setTimeout(function() { FWRecorder.playBack('audio'); }, 5);
	jQuery(".progress").animate({width: '100%'}, window.duration+10, function() {} );
  setTimeout(function() { jQuery(".progress").animate({width: '0%'}, 10, function() {} ); }, 5);
});

// toggles help pop-up text next to recorder buttons
jQuery(document).on('hover', '.help', function () {
  jQuery(".help-text").toggleClass('display-none');
});<commit_msg>help triggered by css not js<commit_after>// from https://github.com/michalstocki/FlashWavRecorder/
// adapted for use in Baruch College's TfCS Wordpress website

jQuery(function () {

  var RECORDER_APP_ID = "recorderApp";
//  var $level = $('.level .progress');

  var appWidth = 24;
  var appHeight = 24;
  var flashvars = {'upload_image': 'http://michalstocki.github.io/FlashWavRecorder/html/images/upload.png'};
  var params = { allowScriptAccess: 'always', wmode: 'transparent'};
  var attributes = {'id': RECORDER_APP_ID, 'name': RECORDER_APP_ID};
  swfobject.embedSWF("../files/2016/06/recorder.jpg", "flashcontent", appWidth, appHeight, "11.0.0", "", flashvars, params, attributes);

  window.fwr_event_handler = function fwr_event_handler() {
    var name, $controls;
    switch (arguments[0]) {
      case "ready":
        FWRecorder.uploadFormId = "#uploadForm";
        FWRecorder.uploadFieldName = "upload_file[filename]";
        FWRecorder.connect(RECORDER_APP_ID, 0);
        FWRecorder.recorderOriginalWidth = appWidth;
        FWRecorder.recorderOriginalHeight = appHeight;
        break;

      case "microphone_user_request":
        FWRecorder.showPermissionWindow();
        break;

      case "permission_panel_closed":
        FWRecorder.defaultSize();
        break;

      case "recording":
        FWRecorder.hide();
        FWRecorder.resize(1, 1);
        FWRecorder.observeLevel();
        break;

      case "recording_stopped":
        // FWRecorder.show();
        window.duration = arguments[2].toFixed(2) * 1000;

        FWRecorder.stopObservingLevel();
        jQuery(".audiolevel").css({height: 0});
        break;

      case "microphone_level":
      	var curLevel = jQuery(".audiolevel").height();
        jQuery(".audiolevel").css({height: (arguments[1]*90 + curLevel*10/40) + '%'});
        break;

    }
  };

  function recorderEl() {
    return jQuery('#' + RECORDER_APP_ID);
  }
});

// fix flash object in a specific position on window.
// this way the flash object being resized will not mess with the page layout
jQuery(document).ready(function(){
    if (document.getElementById('recorderApp')) {
        var flashobject = document.getElementById('recorderApp');
        flashobject.style.position = "fixed";
    }
});

// pressing the record button first asks permission and triggers recording
jQuery(document).on('click', '.record', function () {
	if (!FWRecorder.isMicrophoneAccessible()) {
		FWRecorder.showPermissionWindow();
	} else {
	    jQuery(this).toggleClass('recording');
	}
    if (jQuery(this).hasClass('recording')) {
	    FWRecorder.configure(22, 80, 1, 0);
        FWRecorder.setUseEchoSuppression(true);
        jQuery(".progress").css({ width: '0%' });
    	setTimeout(function() { FWRecorder.record('audio', 'audio.wav'); }, 1);

    } else {
    	setTimeout(function() { FWRecorder.stopRecording('audio');}, 1);
    }
});

// animates play button
jQuery(document).on('click', '.playback', function () {
  if (jQuery(".record").hasClass('recording')) {
    FWRecorder.stopRecording();
    setTimeout(function() { jQuery(".record").removeClass('recording'); }, 5);
  }
	jQuery(".progress").css({ width: '0%' });
	setTimeout(function() { FWRecorder.playBack('audio'); }, 5);
	jQuery(".progress").animate({width: '100%'}, window.duration+10, function() {} );
  setTimeout(function() { jQuery(".progress").animate({width: '0%'}, 10, function() {} ); }, 5);
});

// toggles help pop-up text next to recorder buttons
// jQuery(document).on('hover', '.help', function () {
//   jQuery(".help-text").toggleClass('display-none');
// });<|endoftext|>


<commit_before>/*jslint node: true */
'use strict';

angular.module('myApp.controllers', [])
    .controller('LakeListTabCtrl', [
        '$scope', 'UserLocationService', 'LakeDataProviderService', 'LatLngDistanceService',
        function($scope, UserLocationService, LakeDataProviderService, LatLngDistanceService) {
            /* Controller for the lake list */
            var lakeList = LakeDataProviderService.getListOfLakesWithDescription();

            /* jshint unused:false */
            var userLocation = UserLocationService.getUserLocation()
                .then(function success(res) {
                    var lakeListWithDistance = lakeList.map(function(lake) {
                        // distance calculated by long/lat in meters
                        var distance = LatLngDistanceService.distanceTo(res, lake.location);

                        return {
                            'name': lake.name,
                            'description': lake.description,
                            'attributes': lake.attributes,
                            'distance': distance / 1000
                        };
                    });

                    lakeListWithDistance.sort(function compare(a, b) {
                        return a.distance - b.distance;
                    });

                    $scope.lakeList = lakeListWithDistance;
                }, function error() {
                    $scope.lakeList = lakeList; // no distance nor locations
                });
        }
    ])
    .controller('MapTabCtrl', ['$scope', '$modal', 'leafletData', 'leafletEvents', 'LakeDataProviderService', 'UserLocationService', 'mapCenter',
        function($scope, $modal, leafletData, leafletEvents, LakeDataProviderService, UserLocationService, mapCenter) {
            /* Controller for the lake map providing an overview */
            angular.extend($scope, {
                center: mapCenter,
                defaults: {
                    tileLayer: 'https://{s}.tiles.mapbox.com/v3/foobar123.j5b19dpp/{z}/{x}/{y}.png',
                    tileLayerOptions: {
                        attribution: '© Mapbox © OpenStreetMap contributors',
                        detectRetina: true,
                        reuseTiles: true,
                    }
                }
            });

            $scope.markers = LakeDataProviderService.getLakeLocationMarkers();

            var userLocationMarkerIcon = {
                'iconUrl': 'public/img/marker-red.png',
                'shadowUrl': 'public/img/marker-shadow.png',
                'iconSize': [25, 41],
                'shadowSize': [41, 41],
                'popupAnchor': [0, -39]
            };

            /* jshint unused:false */
            var userLocation = UserLocationService.getUserLocation()
                .then(function success(res) {
                    $scope.markers.userLocationMarker = {
                        'lat': res.lat,
                        'lng': res.lng,
                        'icon': userLocationMarkerIcon,
                        'message': 'Aktueller Standpunkt'
                    };
                });

            $scope.$on('leafletDirectiveMarker.click', function(event, leafletEvent) {
                if (leafletEvent.markerName !== 'userLocationMarker') {
                    /* jshint unused:false */
                    var modalInstance = $modal.open({
                        'controller': 'ModalInstanceCtrl',
                        'templateUrl': 'public/partials/lakeDescriptionModal.html',
                        'resolve': {
                            'data': function() {
                                return $scope.markers[leafletEvent.markerName].data;
                            }
                        }
                    });
                }
            });
        }
    ])
    .controller('MainCtrl', ['$scope', '$window', '$modal', 'appTitle', 'footNotice', 'contributors', 'labInfo',
        function($scope, $window, $modal, appTitle, footNotice, contributors, labInfo) {
            var footCols = 0;
            $window.document.title = appTitle; // set page title

            $scope.title = appTitle; // sets h1

            // build footer and increment column count for bootstrap grid cols
            $scope.footNotice = footNotice;
            footCols++;

            $scope.contributors = contributors;
            footCols++;

            // logo and link with title
            $scope.labInfo = labInfo;
            footCols++;

            if (footCols > 0) {
                $scope.footerColumns = (12 / footCols); // FIXME: what about 5, 7 and so on?
            } else {
                $scope.footerCloumns = 1;
            }

            // show help modal
            $scope.showHelpModal = function() {
                /* jshint unused:false */
                var modalInstance = $modal.open({
                    'controller': 'ModalInstanceCtrl',
                    'templateUrl': 'public/partials/faq.html',
                    'resolve': {
                        'data': function() {
                            return null;
                        }
                    }
                });
            };
        }
    ])
    .controller('ModalInstanceCtrl', ['$scope', '$modalInstance', 'data',
        function($scope, $modalInstance, data) {
            $scope.data = data;
            $scope.dismiss = function() {
                $modalInstance.dismiss();
            };
        }
    ]);
<commit_msg>improved optional footer element processing and html class computation<commit_after>/*jslint node: true */
'use strict';

angular.module('myApp.controllers', [])
    .controller('LakeListTabCtrl', [
        '$scope', 'UserLocationService', 'LakeDataProviderService', 'LatLngDistanceService',
        function($scope, UserLocationService, LakeDataProviderService, LatLngDistanceService) {
            /* Controller for the lake list */
            var lakeList = LakeDataProviderService.getListOfLakesWithDescription();

            /* jshint unused:false */
            var userLocation = UserLocationService.getUserLocation()
                .then(function success(res) {
                    var lakeListWithDistance = lakeList.map(function(lake) {
                        // distance calculated by long/lat in meters
                        var distance = LatLngDistanceService.distanceTo(res, lake.location);

                        return {
                            'name': lake.name,
                            'description': lake.description,
                            'attributes': lake.attributes,
                            'distance': distance / 1000
                        };
                    });

                    lakeListWithDistance.sort(function compare(a, b) {
                        return a.distance - b.distance;
                    });

                    $scope.lakeList = lakeListWithDistance;
                }, function error() {
                    $scope.lakeList = lakeList; // no distance nor locations
                });
        }
    ])
    .controller('MapTabCtrl', ['$scope', '$modal', 'leafletData', 'leafletEvents', 'LakeDataProviderService', 'UserLocationService', 'mapCenter',
        function($scope, $modal, leafletData, leafletEvents, LakeDataProviderService, UserLocationService, mapCenter) {
            /* Controller for the lake map providing an overview */
            angular.extend($scope, {
                center: mapCenter,
                defaults: {
                    tileLayer: 'https://{s}.tiles.mapbox.com/v3/foobar123.j5b19dpp/{z}/{x}/{y}.png',
                    tileLayerOptions: {
                        attribution: '© Mapbox © OpenStreetMap contributors',
                        detectRetina: true,
                        reuseTiles: true,
                    }
                }
            });

            $scope.markers = LakeDataProviderService.getLakeLocationMarkers();

            var userLocationMarkerIcon = {
                'iconUrl': 'public/img/marker-red.png',
                'shadowUrl': 'public/img/marker-shadow.png',
                'iconSize': [25, 41],
                'shadowSize': [41, 41],
                'popupAnchor': [0, -39]
            };

            /* jshint unused:false */
            var userLocation = UserLocationService.getUserLocation()
                .then(function success(res) {
                    $scope.markers.userLocationMarker = {
                        'lat': res.lat,
                        'lng': res.lng,
                        'icon': userLocationMarkerIcon,
                        'message': 'Aktueller Standpunkt'
                    };
                });

            $scope.$on('leafletDirectiveMarker.click', function(event, leafletEvent) {
                if (leafletEvent.markerName !== 'userLocationMarker') {
                    /* jshint unused:false */
                    var modalInstance = $modal.open({
                        'controller': 'ModalInstanceCtrl',
                        'templateUrl': 'public/partials/lakeDescriptionModal.html',
                        'resolve': {
                            'data': function() {
                                return $scope.markers[leafletEvent.markerName].data;
                            }
                        }
                    });
                }
            });
        }
    ])
    .controller('MainCtrl', ['$scope', '$window', '$modal', 'appTitle', 'footNotice', 'contributors', 'labInfo',
        function($scope, $window, $modal, appTitle, footNotice, contributors, labInfo) {
            var footCols = 0;
            $window.document.title = appTitle; // set page title

            $scope.title = appTitle; // sets h1

            // build footer and increment column count for bootstrap grid cols
            if (footNotice) {
                $scope.footNotice = footNotice;
                footCols++;
            }

            if (contributors) {
                $scope.contributors = contributors;
                footCols++;
            }

            // logo and link with title
            if (labInfo) {
                $scope.labInfo = labInfo;
                footCols++;
            }

            if (footCols > 0) {
                $scope.footerColumns = (12 / footCols); // FIXME: what about 5, 7 and so on?
            } else {
                $scope.footerCloumns = 1;
            }

            // show help modal
            $scope.showHelpModal = function() {
                /* jshint unused:false */
                var modalInstance = $modal.open({
                    'controller': 'ModalInstanceCtrl',
                    'templateUrl': 'public/partials/faq.html',
                    'resolve': {
                        'data': function() {
                            return null;
                        }
                    }
                });
            };
        }
    ])
    .controller('ModalInstanceCtrl', ['$scope', '$modalInstance', 'data',
        function($scope, $modalInstance, data) {
            $scope.data = data;
            $scope.dismiss = function() {
                $modalInstance.dismiss();
            };
        }
    ]);
<|endoftext|>


<commit_before>import Ember from 'ember';
import { addQueryParam, addQueryParams } from 'ui/utils/util';
import C from 'ui/utils/constants';

const MIN_VERSION = 'minimumRancherVersion_lte';
const MAX_VERSION = 'maximumRancherVersion_gte';

export default Ember.Service.extend({
  settings: Ember.inject.service(),
  store: Ember.inject.service('store'),
  userStore: Ember.inject.service('user-store'),
  projects : Ember.inject.service(),

  cache            : null,
  catalogs         : null,

  templateBase: Ember.computed('projects.current.orchestration', function() {
    return this.get('projects.current.orchestration') || 'cattle';
  }),

  refresh() {
    const store = this.get('store');

    return store.request({
      url: `${this.get('app.catalogEndpoint')}/templates?refresh&action=refresh`,
      method: 'POST',
      timeout: null, // I'm willing to wait...
    });
  },

  fetchCatalogs() {
    return this.get('store').request({url: `${this.get('app.catalogEndpoint')}/catalogs`});
  },

  fetchTemplate(id, upgrade=false) {
    let type = 'templates';
    if ( upgrade === true ) {
      type = 'templateversions';
    }

    let url = this._addLimits(`${this.get('app.catalogEndpoint')}/${type}/${id}`);
    return this.get('store').request({url: url});
  },

  fetchTemplates(params) {
    let cache        = this.get('cache');
    let templateBase = params.templateBase || this.get('templateBase');
    let catalogId    = params.catalogId;
    let plusInfra    = (params.plusInfra || false);

    let qp           = {
      'category_ne': 'system',
    };

    if (catalogId && catalogId !== 'all') {
      qp['catalogId'] = catalogId;
    }

    // If the catalogIds dont match we need to go get the other catalog from the store since we do not cache all catalogs
    if ( cache && cache.catalogId === catalogId)
    {
      return Ember.RSVP.resolve(this.filter(cache, params.category, templateBase, plusInfra));
    }

    let url = this._addLimits(`${this.get('app.catalogEndpoint')}/templates`, qp);
    return this.get('store').request({url: url}).then((res) => {
      res.catalogId = catalogId;
      this.set('cache', res);
      return this.filter(res, params.category, templateBase, plusInfra);
    });
  },

  filter(data, category, templateBase, plusInfra) {
    let bases = [];

    category = category.toLowerCase();

    if ( templateBase === 'cattle' ) {
      bases.push('');
    } else {
      bases.push(templateBase);
    }

    if ( plusInfra ) {
      bases.push(C.EXTERNAL_ID.KIND_INFRA);
    }

    data = data.filter((tpl) => {
      if ( category !== 'all' && (tpl.get('category')||'').toLowerCase() !== category ) {
        return false;
      }

      if ( !bases.includes(tpl.get('templateBase')||'') ) {
        return false;
      }

      // While we're looping through them all..
      if (tpl.catalogId === C.CATALOG.LIBRARY_KEY) {
        Ember.set(tpl, 'official', true);
      }

      return true;
    });

    data = data.sortBy('name');

    return Ember.Object.create({
      categories: this._uniqKeys(data, 'category'),
      catalog: data,
      templateBase: templateBase,
    });
  },

  _addLimits(url, qp) {
    let version = this.get('settings.rancherVersion');
    qp = qp || {};

    if (version) {
      qp[MIN_VERSION] = version;
      qp[MAX_VERSION] = version;
    }

    url = addQueryParams(url, qp);

    return url;
  },

  _uniqKeys(data, name) {
    let out = data.map((item) => item[name]);
    out = out.uniq().sort((a,b) => a.localeCompare(b, 'en', {sensitivity: 'base'}));
    out.unshift('all');
    return out;
  },
});
<commit_msg>jshint<commit_after>import Ember from 'ember';
import { addQueryParams } from 'ui/utils/util';
import C from 'ui/utils/constants';

const MIN_VERSION = 'minimumRancherVersion_lte';
const MAX_VERSION = 'maximumRancherVersion_gte';

export default Ember.Service.extend({
  settings: Ember.inject.service(),
  store: Ember.inject.service('store'),
  userStore: Ember.inject.service('user-store'),
  projects : Ember.inject.service(),

  cache            : null,
  catalogs         : null,

  templateBase: Ember.computed('projects.current.orchestration', function() {
    return this.get('projects.current.orchestration') || 'cattle';
  }),

  refresh() {
    const store = this.get('store');

    return store.request({
      url: `${this.get('app.catalogEndpoint')}/templates?refresh&action=refresh`,
      method: 'POST',
      timeout: null, // I'm willing to wait...
    });
  },

  fetchCatalogs() {
    return this.get('store').request({url: `${this.get('app.catalogEndpoint')}/catalogs`});
  },

  fetchTemplate(id, upgrade=false) {
    let type = 'templates';
    if ( upgrade === true ) {
      type = 'templateversions';
    }

    let url = this._addLimits(`${this.get('app.catalogEndpoint')}/${type}/${id}`);
    return this.get('store').request({url: url});
  },

  fetchTemplates(params) {
    let cache        = this.get('cache');
    let templateBase = params.templateBase || this.get('templateBase');
    let catalogId    = params.catalogId;
    let plusInfra    = (params.plusInfra || false);

    let qp           = {
      'category_ne': 'system',
    };

    if (catalogId && catalogId !== 'all') {
      qp['catalogId'] = catalogId;
    }

    // If the catalogIds dont match we need to go get the other catalog from the store since we do not cache all catalogs
    if ( cache && cache.catalogId === catalogId)
    {
      return Ember.RSVP.resolve(this.filter(cache, params.category, templateBase, plusInfra));
    }

    let url = this._addLimits(`${this.get('app.catalogEndpoint')}/templates`, qp);
    return this.get('store').request({url: url}).then((res) => {
      res.catalogId = catalogId;
      this.set('cache', res);
      return this.filter(res, params.category, templateBase, plusInfra);
    });
  },

  filter(data, category, templateBase, plusInfra) {
    let bases = [];

    category = category.toLowerCase();

    if ( templateBase === 'cattle' ) {
      bases.push('');
    } else {
      bases.push(templateBase);
    }

    if ( plusInfra ) {
      bases.push(C.EXTERNAL_ID.KIND_INFRA);
    }

    data = data.filter((tpl) => {
      if ( category !== 'all' && (tpl.get('category')||'').toLowerCase() !== category ) {
        return false;
      }

      if ( !bases.includes(tpl.get('templateBase')||'') ) {
        return false;
      }

      // While we're looping through them all..
      if (tpl.catalogId === C.CATALOG.LIBRARY_KEY) {
        Ember.set(tpl, 'official', true);
      }

      return true;
    });

    data = data.sortBy('name');

    return Ember.Object.create({
      categories: this._uniqKeys(data, 'category'),
      catalog: data,
      templateBase: templateBase,
    });
  },

  _addLimits(url, qp) {
    let version = this.get('settings.rancherVersion');
    qp = qp || {};

    if (version) {
      qp[MIN_VERSION] = version;
      qp[MAX_VERSION] = version;
    }

    url = addQueryParams(url, qp);

    return url;
  },

  _uniqKeys(data, name) {
    let out = data.map((item) => item[name]);
    out = out.uniq().sort((a,b) => a.localeCompare(b, 'en', {sensitivity: 'base'}));
    out.unshift('all');
    return out;
  },
});
<|endoftext|>


<commit_before>// Draw parameters
var pc_SIZE = 16;

// Legend:
//  #: wall
//   : no cheese
//  .: cheese
//  o: big cheese
//  s: starting point
//  g: ghost starting point
//  _: forbidden for player
var pc_grid_template = [
	"############################",
	"#............##............#",
	"#.####.#####.##.#####.####.#",
	"#o####.#####.##.#####.####o#",
	"#.####.#####.##.#####.####.#",
	"#..........................#",
	"#.####.##.########.##.####.#",
	"#.####.##.########.##.####.#",
	"#......##....##....##......#",
	"######.#####.##.#####.######",
	"######.#####.##.#####.######",
	"######.##..........##.######",
	"######.##.###__###.##.######",
	"######.##.#gggggg#.##.######",
	"      ....#gggggg#....      ",
	"######.##.#gggggg#.##.######",
	"######.##.########.##.######",
	"######.##..........##.######",
	"######.##.########.##.######",
	"######.##.########.##.######",
	"#............##............#",
	"#.####.#####.##.#####.####.#",
	"#o####.#####.##.#####.####o#",
	"#...##.......s........##...#",
	"###.##.##.########.##.##.###",
	"###.##.##.########.##.##.###",
	"#......##....##....##......#",
	"#.##########.##.##########.#",
	"#.##########.##.##########.#",
	"#..........................#",
	"############################",
];
var pc_grid = [];

var pc_LEFT = 0;
var pc_TOP = 1;
var pc_RIGHT = 2;
var pc_BOTTOM = 3;
var pc_FPS = 10;
var pc_FRAMES_PER_CELL = 5;

/**
 * User position
 */

var pc_pacman_x = -1;
var pc_pacman_y = -1;
var pc_pacman_direction = pc_LEFT;

/**
 * Initialize the game
 */

function initGame() {
	// Already launched?
	if (pc_pacman_x != -1 || pc_pacman_y != -1)
		return;

	// Copy the grid into local grid
	pc_grid = pc_grid_template.slice();

	// Find the starting point
	var height = pc_grid.length;
	var width = pc_grid[0].length;
	for (i=0 ; i!=width ; i++) {
		for (j=0 ; j!=height ; j++) {
			if (pc_grid[j][i] == 's') {
				pc_pacman_x = i * pc_FRAMES_PER_CELL;
				pc_pacman_y = j * pc_FRAMES_PER_CELL;
			}
		}
	}

	// Resize canvas
	var canvas = document.getElementById('myCanvas');
	if (! canvas.getContext)
		return;
	var ctx = canvas.getContext('2d');
	var height = pc_grid.length;
	var width = pc_grid[0].length;
	canvas.width = width*pc_SIZE +10;
	canvas.height = height*pc_SIZE +10;

	// Launch the game
	iterateGame();
}

/**
 * Iterate inside the game
 */

function iterateGame() {
	var canvas = document.getElementById('myCanvas');
	if (! canvas.getContext)
		return;
	var ctx = canvas.getContext('2d');

	// Draw game
	drawEmptyGameBoard(canvas, ctx);
	drawPacMan(canvas, ctx);

	setTimeout(iterateGame, 1000/pc_FPS);
}

/**
 * Draw an empty game board
 */

function drawEmptyGameBoard(canvas, ctx) {
	/**
	 * Draw the Game Board based on pc_grid
	 */

	// Retrieve grid dimensions
	var height = pc_grid.length;
	var width = pc_grid[0].length;

	// Draw Game Board
	ctx.beginPath();
	ctx.fillStyle = "white";
	ctx.fillRect(0, 0, width*pc_SIZE +10, height*pc_SIZE +10);
	ctx.fill();

	ctx.beginPath();
	ctx.lineWidth = 3;
	ctx.strokeStyle = "black";
	ctx.moveTo(2, 2);
	ctx.lineTo(2, height*pc_SIZE +8);
	ctx.lineTo(width*pc_SIZE +8, height*pc_SIZE +8);
	ctx.lineTo(width*pc_SIZE +8, 2);
	ctx.closePath();
	ctx.stroke();

	for (i=0 ; i!=width ; i++) {
		for (j=0 ; j!=height ; j++) {
			if (pc_grid[j][i] == '#') {
				ctx.fillStyle = "#777777";
				ctx.fillRect(i*pc_SIZE +5, j*pc_SIZE +5, pc_SIZE, pc_SIZE);
			} else if (pc_grid[j][i] == '.') {
				ctx.beginPath();
				ctx.fillStyle = "#aaaa00";
				ctx.arc((i+.5)*pc_SIZE +5, (j+.5)*pc_SIZE +5, .2*pc_SIZE, 0, 2*Math.PI, false);
				ctx.fill();
			} else if (pc_grid[j][i] == 'o') {
				ctx.beginPath();
				ctx.fillStyle = "#aaaa00";
				ctx.arc((i+.5)*pc_SIZE +5, (j+.5)*pc_SIZE +5, .4*pc_SIZE, 0, 2*Math.PI, false);
				ctx.fill();
			}
		}
	}
}

/**
 * Draw the PacMan
 */

function drawPacMan(canvas, ctx) {
	var pacman_px_x = (1.*pc_pacman_x/pc_FRAMES_PER_CELL +.5)*pc_SIZE +5;
	var pacman_px_y = (1.*pc_pacman_y/pc_FRAMES_PER_CELL +.5)*pc_SIZE +5;

	ctx.beginPath();
	ctx.fillStyle = "#777700";
	if (pc_pacman_direction == pc_LEFT)
		ctx.arc(pacman_px_x, pacman_px_y, .45*pc_SIZE, Math.PI+Math.PI/7, Math.PI-Math.PI/7,false);
	else if (pc_pacman_direction == pc_TOP)
		ctx.arc(pacman_px_x, pacman_px_y, .45*pc_SIZE, -Math.PI/2+Math.PI/7, -Math.PI/2-Math.PI/7,false);
	else if (pc_pacman_direction == pc_RIGHT)
		ctx.arc(pacman_px_x, pacman_px_y, .45*pc_SIZE, Math.PI/7, -Math.PI/7,false);
	else
		ctx.arc(pacman_px_x, pacman_px_y, .45*pc_SIZE, Math.PI/2+Math.PI/7, Math.PI/2+-Math.PI/7,false);
	ctx.lineTo(pacman_px_x, pacman_px_y);
	ctx.fill();
}
<commit_msg>Left = initial direction for PacMan<commit_after>// Draw parameters
var pc_SIZE = 16;

// Legend:
//  #: wall
//   : no cheese
//  .: cheese
//  o: big cheese
//  s: starting point
//  g: ghost starting point
//  _: forbidden for player
var pc_grid_template = [
	"############################",
	"#............##............#",
	"#.####.#####.##.#####.####.#",
	"#o####.#####.##.#####.####o#",
	"#.####.#####.##.#####.####.#",
	"#..........................#",
	"#.####.##.########.##.####.#",
	"#.####.##.########.##.####.#",
	"#......##....##....##......#",
	"######.#####.##.#####.######",
	"######.#####.##.#####.######",
	"######.##..........##.######",
	"######.##.###__###.##.######",
	"######.##.#gggggg#.##.######",
	"      ....#gggggg#....      ",
	"######.##.#gggggg#.##.######",
	"######.##.########.##.######",
	"######.##..........##.######",
	"######.##.########.##.######",
	"######.##.########.##.######",
	"#............##............#",
	"#.####.#####.##.#####.####.#",
	"#o####.#####.##.#####.####o#",
	"#...##.......s........##...#",
	"###.##.##.########.##.##.###",
	"###.##.##.########.##.##.###",
	"#......##....##....##......#",
	"#.##########.##.##########.#",
	"#.##########.##.##########.#",
	"#..........................#",
	"############################",
];
var pc_grid = [];

var pc_LEFT = 0;
var pc_TOP = 1;
var pc_RIGHT = 2;
var pc_BOTTOM = 3;
var pc_FPS = 10;
var pc_FRAMES_PER_CELL = 5;

/**
 * User position
 */

var pc_pacman_x = -1;
var pc_pacman_y = -1;
var pc_pacman_direction = pc_LEFT;

/**
 * Initialize the game
 */

function initGame() {
	// Already launched?
	if (pc_pacman_x != -1 || pc_pacman_y != -1)
		return;
	pc_pacman_direction = pc_LEFT;

	// Copy the grid into local grid
	pc_grid = pc_grid_template.slice();

	// Find the starting point
	var height = pc_grid.length;
	var width = pc_grid[0].length;
	for (i=0 ; i!=width ; i++) {
		for (j=0 ; j!=height ; j++) {
			if (pc_grid[j][i] == 's') {
				pc_pacman_x = i * pc_FRAMES_PER_CELL;
				pc_pacman_y = j * pc_FRAMES_PER_CELL;
			}
		}
	}

	// Resize canvas
	var canvas = document.getElementById('myCanvas');
	if (! canvas.getContext)
		return;
	var ctx = canvas.getContext('2d');
	var height = pc_grid.length;
	var width = pc_grid[0].length;
	canvas.width = width*pc_SIZE +10;
	canvas.height = height*pc_SIZE +10;

	// Launch the game
	iterateGame();
}

/**
 * Iterate inside the game
 */

function iterateGame() {
	var canvas = document.getElementById('myCanvas');
	if (! canvas.getContext)
		return;
	var ctx = canvas.getContext('2d');

	// Draw game
	drawEmptyGameBoard(canvas, ctx);
	drawPacMan(canvas, ctx);

	setTimeout(iterateGame, 1000/pc_FPS);
}

/**
 * Draw an empty game board
 */

function drawEmptyGameBoard(canvas, ctx) {
	/**
	 * Draw the Game Board based on pc_grid
	 */

	// Retrieve grid dimensions
	var height = pc_grid.length;
	var width = pc_grid[0].length;

	// Draw Game Board
	ctx.beginPath();
	ctx.fillStyle = "white";
	ctx.fillRect(0, 0, width*pc_SIZE +10, height*pc_SIZE +10);
	ctx.fill();

	ctx.beginPath();
	ctx.lineWidth = 3;
	ctx.strokeStyle = "black";
	ctx.moveTo(2, 2);
	ctx.lineTo(2, height*pc_SIZE +8);
	ctx.lineTo(width*pc_SIZE +8, height*pc_SIZE +8);
	ctx.lineTo(width*pc_SIZE +8, 2);
	ctx.closePath();
	ctx.stroke();

	for (i=0 ; i!=width ; i++) {
		for (j=0 ; j!=height ; j++) {
			if (pc_grid[j][i] == '#') {
				ctx.fillStyle = "#777777";
				ctx.fillRect(i*pc_SIZE +5, j*pc_SIZE +5, pc_SIZE, pc_SIZE);
			} else if (pc_grid[j][i] == '.') {
				ctx.beginPath();
				ctx.fillStyle = "#aaaa00";
				ctx.arc((i+.5)*pc_SIZE +5, (j+.5)*pc_SIZE +5, .2*pc_SIZE, 0, 2*Math.PI, false);
				ctx.fill();
			} else if (pc_grid[j][i] == 'o') {
				ctx.beginPath();
				ctx.fillStyle = "#aaaa00";
				ctx.arc((i+.5)*pc_SIZE +5, (j+.5)*pc_SIZE +5, .4*pc_SIZE, 0, 2*Math.PI, false);
				ctx.fill();
			}
		}
	}
}

/**
 * Draw the PacMan
 */

function drawPacMan(canvas, ctx) {
	var pacman_px_x = (1.*pc_pacman_x/pc_FRAMES_PER_CELL +.5)*pc_SIZE +5;
	var pacman_px_y = (1.*pc_pacman_y/pc_FRAMES_PER_CELL +.5)*pc_SIZE +5;

	ctx.beginPath();
	ctx.fillStyle = "#777700";
	if (pc_pacman_direction == pc_LEFT)
		ctx.arc(pacman_px_x, pacman_px_y, .45*pc_SIZE, Math.PI+Math.PI/7, Math.PI-Math.PI/7,false);
	else if (pc_pacman_direction == pc_TOP)
		ctx.arc(pacman_px_x, pacman_px_y, .45*pc_SIZE, -Math.PI/2+Math.PI/7, -Math.PI/2-Math.PI/7,false);
	else if (pc_pacman_direction == pc_RIGHT)
		ctx.arc(pacman_px_x, pacman_px_y, .45*pc_SIZE, Math.PI/7, -Math.PI/7,false);
	else
		ctx.arc(pacman_px_x, pacman_px_y, .45*pc_SIZE, Math.PI/2+Math.PI/7, Math.PI/2+-Math.PI/7,false);
	ctx.lineTo(pacman_px_x, pacman_px_y);
	ctx.fill();
}
<|endoftext|>


<commit_before>/**
 * Analyzes events bound to DOM elements
 */
/* global Document: true, Element: true, window: true */
'use strict';

exports.version = '0.1';

exports.module = function(phantomas) {
        phantomas.setMetric('eventsBound'); // @desc number of EventTarget.addEventListener calls

	// spy calls to EventTarget.addEventListener
	// @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget.addEventListener
	phantomas.once('init', function() {
		phantomas.evaluate(function() {
			(function(phantomas) {
				function eventSpy(eventType) {
					/* jshint validthis: true */
					phantomas.log('DOM event: "' + eventType + '" bound to "' + phantomas.getDOMPath(this) + '"');
					phantomas.incr('eventsBound');
				}

				phantomas.spy(Element.prototype, 'addEventListener', eventSpy);
				phantomas.spy(Document.prototype, 'addEventListener', eventSpy);
			})(window.__phantomas);
		});
	});

	phantomas.on('report', function() {
		phantomas.setMetricFromScope('eventsBound');
	});
};
<commit_msg>eventListeners: phantomas.incr() -> phantomas.incrMetric()<commit_after>/**
 * Analyzes events bound to DOM elements
 */
/* global Document: true, Element: true, window: true */
'use strict';

exports.version = '0.1';

exports.module = function(phantomas) {
        phantomas.setMetric('eventsBound'); // @desc number of EventTarget.addEventListener calls

	// spy calls to EventTarget.addEventListener
	// @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget.addEventListener
	phantomas.once('init', function() {
		phantomas.evaluate(function() {
			(function(phantomas) {
				function eventSpy(eventType) {
					/* jshint validthis: true */
					phantomas.log('DOM event: "' + eventType + '" bound to "' + phantomas.getDOMPath(this) + '"');
					phantomas.incrMetric('eventsBound');
				}

				phantomas.spy(Element.prototype, 'addEventListener', eventSpy);
				phantomas.spy(Document.prototype, 'addEventListener', eventSpy);
			})(window.__phantomas);
		});
	});
};
<|endoftext|>


<commit_before>'use strict';
var gulp = require('gulp');
var gutil = require('gulp-util');
var ts = require('gulp-typescript');
var sourcemaps = require('gulp-sourcemaps');
var merge = require('merge2');
var tslint = require('gulp-tslint');
var del = require('del');
var replace = require('gulp-token-replace');
var path = require('path');

const outDir = 'out';
var tsProject = ts.createProject('tsconfig.json', { declarationFiles: true });

gulp.task('tsc', function() {
    var tsResult = gulp.src(['*.ts', 'ts/**/*.ts', 'typings/**/*.ts'])
        .pipe(tslint())
        .pipe(sourcemaps.init())
        .pipe(ts(tsProject));

    var replacements = {
        'version': {
            'lkg': '1.4.41'
        }
    };
    return merge([
        tsResult.dts.pipe(gulp.dest(outDir)),
        tsResult.js
            .pipe(sourcemaps.write('.'))
            .pipe(replace({
                tokens: replacements,
                preserveUnknownTokens: true // we'll set the remaining ones later.
            }))
            .pipe(gulp.dest(outDir))
    ]);
});

gulp.task('copyPackageContents', ['tsc'], function() {
    return gulp
        .src([
            'package.json',
            '../../LICENSE.txt'
        ])
        .pipe(gulp.dest(outDir));
});

gulp.task('setPackageVersion', ['copyPackageContents'], function() {
    var nbgv = require(`./${outDir}`);
    return nbgv.setPackageVersion(outDir, '.');
});

gulp.task('setPackageVersionToken', ['copyPackageContents'], function() {
    var nbgv = require(`./${outDir}`);
    return nbgv.getGitVersion()
        .then(function(v) {
            var replacements = {
                version: { current: v.semVer1 }
            };
            return gulp.src([`${outDir}/*.js`])
                .pipe(replace({ tokens: replacements }))
                .pipe(gulp.dest(outDir));
        });
});

gulp.task('package', ['setPackageVersion','setPackageVersionToken'], function() {
    var afs = require('./out/asyncio');
    var binDir =  '../../bin/js';
    return afs.mkdirIfNotExistAsync(binDir)
        .then(function() {
            var ap = require('./out/asyncprocess');
            return ap.execAsync(`npm pack "${path.join(__dirname, outDir)}"`, { cwd: binDir });
        });
});

gulp.task('clean', function() {
    return del([
        outDir
    ])
});

gulp.task('default', ['package'], function() {
});

gulp.task('watch', ['tsc'], function() {
    return gulp.watch('**/*.ts', ['tsc']);
});
<commit_msg>Include README in npm package<commit_after>'use strict';
var gulp = require('gulp');
var gutil = require('gulp-util');
var ts = require('gulp-typescript');
var sourcemaps = require('gulp-sourcemaps');
var merge = require('merge2');
var tslint = require('gulp-tslint');
var del = require('del');
var replace = require('gulp-token-replace');
var path = require('path');

const outDir = 'out';
var tsProject = ts.createProject('tsconfig.json', { declarationFiles: true });

gulp.task('tsc', function() {
    var tsResult = gulp.src(['*.ts', 'ts/**/*.ts', 'typings/**/*.ts'])
        .pipe(tslint())
        .pipe(sourcemaps.init())
        .pipe(ts(tsProject));

    var replacements = {
        'version': {
            'lkg': '1.4.41'
        }
    };
    return merge([
        tsResult.dts.pipe(gulp.dest(outDir)),
        tsResult.js
            .pipe(sourcemaps.write('.'))
            .pipe(replace({
                tokens: replacements,
                preserveUnknownTokens: true // we'll set the remaining ones later.
            }))
            .pipe(gulp.dest(outDir))
    ]);
});

gulp.task('copyPackageContents', ['tsc'], function() {
    return gulp
        .src([
            'package.json',
            'README.md',
            '../../LICENSE.txt'
        ])
        .pipe(gulp.dest(outDir));
});

gulp.task('setPackageVersion', ['copyPackageContents'], function() {
    var nbgv = require(`./${outDir}`);
    return nbgv.setPackageVersion(outDir, '.');
});

gulp.task('setPackageVersionToken', ['copyPackageContents'], function() {
    var nbgv = require(`./${outDir}`);
    return nbgv.getGitVersion()
        .then(function(v) {
            var replacements = {
                version: { current: v.semVer1 }
            };
            return gulp.src([`${outDir}/*.js`])
                .pipe(replace({ tokens: replacements }))
                .pipe(gulp.dest(outDir));
        });
});

gulp.task('package', ['setPackageVersion','setPackageVersionToken'], function() {
    var afs = require('./out/asyncio');
    var binDir =  '../../bin/js';
    return afs.mkdirIfNotExistAsync(binDir)
        .then(function() {
            var ap = require('./out/asyncprocess');
            return ap.execAsync(`npm pack "${path.join(__dirname, outDir)}"`, { cwd: binDir });
        });
});

gulp.task('clean', function() {
    return del([
        outDir
    ])
});

gulp.task('default', ['package'], function() {
});

gulp.task('watch', ['tsc'], function() {
    return gulp.watch('**/*.ts', ['tsc']);
});
<|endoftext|>


<commit_before>// LICENSE : MIT
"use strict";
import { AsocialBookmark, AsocialBookmarkOptions } from "asocial-bookmark";

const moment = require("moment");
export default class Client {
    /**
     * @param {import("asocial-bookmark").AsocialBookmarkOptions}serviceOptions
     */
    constructor(serviceOptions) {
        this.serviceOptions = serviceOptions;
    }

    isLogin() {
        return true;
    }

    loginAsync(callback) {
        return setTimeout(() => callback(), 0);
    }

    getContent(url) {
        const asocialBookmark = new AsocialBookmark(this.serviceOptions);
        return asocialBookmark
            .getBookmark({
                url,
                date: new Date()
            })
            .then((result) => {
                return {
                    title: result.title,
                    url: result.url,
                    comment: result.content,
                    tags: result.tags,
                    relatedItems: result.relatedItems
                        ? result.relatedItems.map((item) => {
                              return {
                                  title: item.title,
                                  URL: item.URL
                              };
                          })
                        : []
                };
            })
            .catch((error) => {
                // https://github.com/webpack/webpack/releases/tag/v5.64.2
                const match = url.match(
                    /^https:\/\/github\.com\/(?<owner>[^/])+\/(?<repo>[^/])+\/releases\/tag\/(?<version>[^/]+)/
                );
                const version = (match && match.groups.version) || undefined;
                // default
                return fetch(`https://jser-product-name.deno.dev/?url=${url}`)
                    .then((res) => res.json())
                    .then((json) => {
                        // { name, url }
                        if (json && json.releaseNoteProbability > 0.5) {
                            const comment = version ? `${json.name} ${version}リリース。` : `${json.name}`;
                            return {
                                comment
                            };
                        }
                    });
            });
    }

    getTags() {
        const asocialBookmark = new AsocialBookmark(this.serviceOptions);
        return asocialBookmark.getTags();
    }

    /**
     *
     * @param options
     * @returns {*}
     * {
            url,
            comment,
            tags = []
        }
     */
    postLink(options = {}) {
        const { title, url, viaURL, comment, tags, relatedItems } = options;
        const asocialBookmark = new AsocialBookmark(this.serviceOptions);
        const date = new Date();
        const isoDate = moment().utc().toDate();
        return asocialBookmark.updateBookmark({
            title,
            url,
            tags,
            viaURL,
            relatedItems,
            content: comment,
            date: isoDate
        });
    }
}
<commit_msg>use json.releaseNoteVersion<commit_after>// LICENSE : MIT
"use strict";
import { AsocialBookmark, AsocialBookmarkOptions } from "asocial-bookmark";

const moment = require("moment");
export default class Client {
    /**
     * @param {import("asocial-bookmark").AsocialBookmarkOptions}serviceOptions
     */
    constructor(serviceOptions) {
        this.serviceOptions = serviceOptions;
    }

    isLogin() {
        return true;
    }

    loginAsync(callback) {
        return setTimeout(() => callback(), 0);
    }

    getContent(url) {
        const asocialBookmark = new AsocialBookmark(this.serviceOptions);
        return asocialBookmark
            .getBookmark({
                url,
                date: new Date()
            })
            .then((result) => {
                return {
                    title: result.title,
                    url: result.url,
                    comment: result.content,
                    tags: result.tags,
                    relatedItems: result.relatedItems
                        ? result.relatedItems.map((item) => {
                              return {
                                  title: item.title,
                                  URL: item.URL
                              };
                          })
                        : []
                };
            })
            .catch((error) => {
                return fetch(`https://jser-product-name.deno.dev/?url=${url}`)
                    .then((res) => res.json())
                    .then((json) => {
                        // { name, url }
                        if (json && json.releaseNoteProbability > 0.5) {
                            const comment =
                                json.releaseNoteVersion !== undefined
                                    ? `${json.name} ${json.releaseNoteVersion}リリース。`
                                    : `${json.name}`;
                            return {
                                comment
                            };
                        }
                    });
            });
    }

    getTags() {
        const asocialBookmark = new AsocialBookmark(this.serviceOptions);
        return asocialBookmark.getTags();
    }

    /**
     *
     * @param options
     * @returns {*}
     * {
            url,
            comment,
            tags = []
        }
     */
    postLink(options = {}) {
        const { title, url, viaURL, comment, tags, relatedItems } = options;
        const asocialBookmark = new AsocialBookmark(this.serviceOptions);
        const date = new Date();
        const isoDate = moment().utc().toDate();
        return asocialBookmark.updateBookmark({
            title,
            url,
            tags,
            viaURL,
            relatedItems,
            content: comment,
            date: isoDate
        });
    }
}
<|endoftext|>


<commit_before>const DBH_CONSTANTS = require('./dbh-constants');
const fs = require('fs');
const jhipsterCore = require('jhipster-core');
const pluralize = require('pluralize');

/** a promise returning the current JHipster app config as a JSON object */
const getAppConfig = directory => new Promise((resolve, reject) => {
    // path to '.yo-rc.json'
    const path = directory + DBH_CONSTANTS.appConfigFile;

    // if file exists, return it as a JSON object
    if (fs.existsSync(path)) {
        fs.readFile(path, 'utf8', (err, data) => {
            if (err) {
                reject(new Error(err));
            }
            const appConfigToJson = JSON.parse(data);

            // handle undefined object
            if (appConfigToJson) {
                resolve(appConfigToJson);
            } else {
                reject(new Error(`getAppConfig: no output. Type: ${typeof appConfigToJson}, value: ${appConfigToJson}`));
            }
        });
    } else {
        reject(new Error(`getAppConfig: file ${path} not found`));
    }
});

/** assert parameter is a non-empty string */
const isTrueString = x => typeof x === 'string' && x !== '';

/** Validate user input when asking for a SQL column name */
const validateColumnName = (input, dbType) => {
    if (!/^([a-zA-Z0-9_]*)$/.test(input)) {
        return 'Your column name cannot contain special characters';
    } else if (input === '') {
        return 'Your column name cannot be empty';
    } else if (dbType === 'oracle' && input.length > 26) {
        return 'Your column name is too long for Oracle, try a shorter name';
    }
    return true;
};

/**
 * Validate user input when asking for a SQL table name
 * This function closely follows JHipster's own validateTableName function
 * (in generator-jhipster/generators/entity/index.js)
 **/
const validateTableName = (input, dbType) => {
    if (!/^([a-zA-Z0-9_]*)$/.test(input)) {
        return 'The table name cannot contain special characters';
    } else if (input === '') {
        return 'The table name cannot be empty';
    } else if (dbType === 'oracle' && input.length > 26) {
        return 'The table name is too long for Oracle, try a shorter name';
    } else if (dbType === 'oracle' && input.length > 14) {
        return 'The table name is long for Oracle, long table names can cause issues when used to create constraint names and join table names';
    } else if (jhipsterCore.isReservedTableName(input, dbType)) {
        return `'${input}' is a ${dbType} reserved keyword.`;
    }
    return true;
};

/**
 * get hibernate SnakeCase in JHipster preferred style.
 *
 * @param {string} value - table column name or table name string
 * @see org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy
 */
const hibernateSnakeCase = (value) => {
    let res = '';
    if (value) {
        value = value.replace('.', '_');
        res = value[0];
        for (let i = 1, len = value.length - 1; i < len; i++) {
            if (value[i - 1] !== value[i - 1].toUpperCase() &&
                value[i] !== value[i].toLowerCase() &&
                value[i + 1] !== value[i + 1].toUpperCase()
            ) {
                res += `_${value[i]}`;
            } else {
                res += value[i];
            }
        }
        res += value[value.length - 1];
        res = res.toLowerCase();
    }
    return res;
};

const getColumnIdName = (name) => hibernateSnakeCase(name) + '_id';

const getPluralColumnIdName = (name) => getColumnIdName(pluralize(name));

/**
 * Check if these relationships add constraints.
 * Typically, an one-to-many relationship doesn't add a constraint to the entity on the one side.
 *
 * @param relationships an array of relationship to check
 * @returns {boolean}
 */
const hasConstraints = (relationships) => {
    for(let idx = 0; idx < relationships.length; idx++) {
        if(relationships[idx].relationshipType === 'many-to-one' || (relationships[idx].relationshipType === 'one-to-one' && relationships[idx].ownerSide)) {
            return true;
        }
        if(relationships[idx].relationshipType === 'many-to-many' && relationships[idx].ownerSide) {
            return true;
        }
    }

    return false;
};

module.exports = {
    getAppConfig,
    isTrueString,
    validateColumnName,
    validateTableName,
    getColumnIdName,
    getPluralColumnIdName,
    hasConstraints
};
<commit_msg>lint dbh.js<commit_after>const DBH_CONSTANTS = require('./dbh-constants');
const fs = require('fs');
const jhipsterCore = require('jhipster-core');
const pluralize = require('pluralize');

/** a promise returning the current JHipster app config as a JSON object */
const getAppConfig = directory => new Promise((resolve, reject) => {
    // path to '.yo-rc.json'
    const path = directory + DBH_CONSTANTS.appConfigFile;

    // if file exists, return it as a JSON object
    if (fs.existsSync(path)) {
        fs.readFile(path, 'utf8', (err, data) => {
            if (err) {
                reject(new Error(err));
            }
            const appConfigToJson = JSON.parse(data);

            // handle undefined object
            if (appConfigToJson) {
                resolve(appConfigToJson);
            } else {
                reject(new Error(`getAppConfig: no output. Type: ${typeof appConfigToJson}, value: ${appConfigToJson}`));
            }
        });
    } else {
        reject(new Error(`getAppConfig: file ${path} not found`));
    }
});

/** assert parameter is a non-empty string */
const isTrueString = x => typeof x === 'string' && x !== '';

/** Validate user input when asking for a SQL column name */
const validateColumnName = (input, dbType) => {
    if (!/^([a-zA-Z0-9_]*)$/.test(input)) {
        return 'Your column name cannot contain special characters';
    } else if (input === '') {
        return 'Your column name cannot be empty';
    } else if (dbType === 'oracle' && input.length > 26) {
        return 'Your column name is too long for Oracle, try a shorter name';
    }
    return true;
};

/**
 * Validate user input when asking for a SQL table name
 * This function closely follows JHipster's own validateTableName function
 * (in generator-jhipster/generators/entity/index.js)
 **/
const validateTableName = (input, dbType) => {
    if (!/^([a-zA-Z0-9_]*)$/.test(input)) {
        return 'The table name cannot contain special characters';
    } else if (input === '') {
        return 'The table name cannot be empty';
    } else if (dbType === 'oracle' && input.length > 26) {
        return 'The table name is too long for Oracle, try a shorter name';
    } else if (dbType === 'oracle' && input.length > 14) {
        return 'The table name is long for Oracle, long table names can cause issues when used to create constraint names and join table names';
    } else if (jhipsterCore.isReservedTableName(input, dbType)) {
        return `'${input}' is a ${dbType} reserved keyword.`;
    }
    return true;
};

/**
 * get hibernate SnakeCase in JHipster preferred style.
 *
 * @param {string} value - table column name or table name string
 * @see org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy
 */
const hibernateSnakeCase = (value) => {
    let res = '';
    if (value) {
        value = value.replace('.', '_');
        res = value[0];
        for (let i = 1, len = value.length - 1; i < len; i++) {
            if (value[i - 1] !== value[i - 1].toUpperCase() &&
                value[i] !== value[i].toLowerCase() &&
                value[i + 1] !== value[i + 1].toUpperCase()
            ) {
                res += `_${value[i]}`;
            } else {
                res += value[i];
            }
        }
        res += value[value.length - 1];
        res = res.toLowerCase();
    }
    return res;
};

const getColumnIdName = name => `${hibernateSnakeCase(name)}_id`;

const getPluralColumnIdName = name => getColumnIdName(pluralize(name));

/**
 * Check if these relationships add constraints.
 * Typically, an one-to-many relationship doesn't add a constraint to the entity on the one side.
 *
 * @param relationships an array of relationship to check
 * @returns {boolean}
 */
const hasConstraints = (relationships) => {
    for (let idx = 0; idx < relationships.length; idx++) {
        if (relationships[idx].relationshipType === 'many-to-one' || (relationships[idx].relationshipType === 'one-to-one' && relationships[idx].ownerSide)) {
            return true;
        }
        if (relationships[idx].relationshipType === 'many-to-many' && relationships[idx].ownerSide) {
            return true;
        }
    }

    return false;
};

module.exports = {
    getAppConfig,
    isTrueString,
    validateColumnName,
    validateTableName,
    getColumnIdName,
    getPluralColumnIdName,
    hasConstraints
};
<|endoftext|>


<commit_before>'use strict';

/* Controllers */

function HangDownListCntr($scope) {
  $scope.apiLive = false;

  $scope.items = [];

  $scope.activeItem = 0;
  $scope.currentUser = null;

  $scope.regressTopic = function(){
    // If the API is not up yet, bail.
    if (!$scope.apiLive) return;

    if ($scope.activeItem > 0) {
      $scope.activeItem--;

      // Submit changes to Google.
      gapi.hangout.data.submitDelta( { activeItem: $scope.activeItem.toString() } );
    }
  };

  $scope.advanceTopic = function(){
    // If the API is not up yet, bail.
    if (!$scope.apiLive) return;

    if ($scope.activeItem < $scope.items.length - 1) {
      $scope.activeItem++;

      // Submit changes to Google.
      gapi.hangout.data.submitDelta( { activeItem: $scope.activeItem.toString() } );
    }
  };

  $scope.newTopicBuffer = '';
  $scope.addNewTopic = function(){
    // If the gapi hasn't be initialized, bail.
    if (!$scope.apiLive) return;

    // If there is no topic set, bail.
    if (!$scope.newTopicBuffer.length) return;

    // Otherwise, add the topic and reset the buffer.
    $scope.items.push({ label: $scope.newTopicBuffer, creator: $scope.currentUser.person.displayName });
    $scope.newTopicBuffer = '';

    // Submit changes to Google.
    // TODO: Come up with a better way to do this.
    gapi.hangout.data.submitDelta( { topics: JSON.stringify($scope.items) } );
  };

  var updateSharedState = function(StateChangedEvent){
    console.log(StateChangedEvent);

    $scope.items = JSON.parse(StateChangedEvent.state.topics);
    $scope.activeItem = parseInt(StateChangedEvent.state.activeItem);

    $scope.$apply();  // Have to do this to force the view to update.
  };

  var initGapiModel = function(){
    // Create expected values in the shared model.
    gapi.hangout.data.setValue('activeItem', '0');
    gapi.hangout.data.setValue('topics', JSON.stringify([]));
  };

  // Add a callback to initialize gAPI elements.
  gapi.hangout.onApiReady.add(function(eventObj){
    // Fetch the current state and make sure that the model is initialized.
    var initialState = gapi.hangout.data.getState();
    if (initialState.activeItem == undefined) initGapiModel();

    // TODO: If data already exists, make sure to init with that data.

    // Set up internal model to work with gapi.
    $scope.apiLive = true;
    $scope.currentUser = gapi.hangout.getLocalParticipant();

    // Install the event handler for a change in model state.
    gapi.hangout.data.onStateChanged.add(updateSharedState);
  });
}

//HangDownListCntr.$inject = ['$scope'];
<commit_msg>Start refactoring and testing sorting functionality.<commit_after>'use strict';

/* Controllers */

function HangDownListCntr($scope) {
  $scope.apiLive = false;

  $scope.items = [];

  $scope.activeItem = 0;
  $scope.currentUser = null;

  $scope.itemSortConfig = {
    update: function(e, ui){
      // TODO: Figure out the new index of the currently selected item.
      console.log($scope.items);
    }
  };

  var resetActiveIndex = function(){

  };

  $scope.regressTopic = function(){
    // If the API is not up yet, bail.
    if (!$scope.apiLive) return;

    if ($scope.activeItem > 0) {
      $scope.activeItem--;

      // Submit changes to Google.
      gapi.hangout.data.submitDelta( { activeItem: $scope.activeItem.toString() } );
    }
  };

  $scope.advanceTopic = function(){
    // If the API is not up yet, bail.
    if (!$scope.apiLive) return;

    if ($scope.activeItem < $scope.items.length - 1) {
      $scope.activeItem++;

      // Submit changes to Google.
      gapi.hangout.data.submitDelta( { activeItem: $scope.activeItem.toString() } );
    }
  };

  $scope.deleteTopic = function(topicId){
    // TODO: If selected topic doesn't exist, bail.
    // TODO: If the topic is currently selected, increment the selection to the next topic.
    // TODO: Delete selected topic.
    // TODO: Refresh selected index.
    // TODO: Push state.
  };

  $scope.newTopicBuffer = '';
  $scope.addNewTopic = function(){
    // If the gapi hasn't be initialized, bail.
    if (!$scope.apiLive) return;

    // If there is no topic set, bail.
    if (!$scope.newTopicBuffer.length) return;

    // Otherwise, add the topic and reset the buffer.
    $scope.items.push({
      id: new Date().getTime(),
      label: $scope.newTopicBuffer,
      creator: $scope.currentUser.person.displayName
    });
    $scope.newTopicBuffer = '';

    // Submit changes to Google.
    // TODO: Come up with a better way to do this.
    gapi.hangout.data.submitDelta( { topics: JSON.stringify($scope.items) } );
  };

  var applySharedState = function(StateChangedEvent){
    $scope.items = JSON.parse(StateChangedEvent.state.topics);
    $scope.activeItem = parseInt(StateChangedEvent.state.activeItem);

    $scope.$apply();  // Have to do this to force the view to update.
  };

  var initGapiModel = function(){
    // Create expected values in the shared model.
    gapi.hangout.data.setValue('activeItem', '0');
    gapi.hangout.data.setValue('topics', JSON.stringify([]));
  };

  // Add a callback to initialize gAPI elements.
  gapi.hangout.onApiReady.add(function(eventObj){
    // Fetch the current state and make sure that the model is initialized.
    var initialState = gapi.hangout.data.getState();
    if (initialState.activeItem == undefined) initGapiModel();

    // TODO: If data already exists, make sure to init with that data.

    // Set up internal model to work with gapi.
    $scope.apiLive = true;
    $scope.currentUser = gapi.hangout.getLocalParticipant();

    // Install the event handler for a change in model state.
    gapi.hangout.data.onStateChanged.add(applySharedState);
  });
}

//HangDownListCntr.$inject = ['$scope'];
<|endoftext|>