<commit_before>Messenger.Models.Conversation = Marbles.Model.createClass({
	displayName: 'Messenger.Models.Conversation',

	mixins: [{
		ctor: {
			modelName: 'conversation',

			cidMappingScope: ['id', 'entity'],

			// toJSON() will only return these attrs
			JSONKeys: [
				'id',
				'type',
				'entity',
				'version',
				'mentions',
				'published_at'
			],

			findOrInit: function (attrs) {
				return this.find(attrs, {fetch:false}) || new this(attrs);
			},

			findOrFetch: function (attrs, options) {
				var _instance, _res, _xhr;
				_instance = this.find(attrs, {fetch:false});
				if (_instance && options && options.callback) {
					// defer callback until after fn return
					setTimeout(function () {
						var res = {
							post: c.toJSON()
						};
						var xhr = {
							status: 304
						};
						if (typeof options.callback === 'function') {
							options.callback(res, xhr);
						} else {
							if (typeof options.callback.success === 'function') {
								options.callback.success(res, xhr);
							}
							if (typeof options.callback.complete === 'function') {
								options.callback.complete(res, xhr);
							}
						}
					}, 0);
				} else if (!_instance) {
					_instance = this.fetch(attrs, options);
				}
				return _instance;
			},

			fetch: function (attrs, options) {
				var _instance = new this(attrs);
				_instance.fetch(options);
				return _instance;
			}
		}
	}],

	didInitialize: function () {
		this.set('type', this.type || Messenger.config.POST_TYPES.CONVERSATION);
		this.initNewMessage();
		this.initMessages();

		if (this.id === 'new') {
			this.once('change:id', this.initMessages, this);
		}

		this.once('detach', this.handleDetach, this);
	},

	handleDetach: function () {
		this.messages.detach();
		this.newMessage.detach();
	},

	initNewMessage: function (entity) {
		this.newMessage = Messenger.Models.Message.findOrInit({
			id: 'new',
			entity: this.entity,
			conversation_id: this.id
		});
		this.newMessage.initConversation(this);
	},

	initMessages: function () {
		if (this.messages) {
			this.messages.detach();
		}

		this.messages = Messenger.Collections.Messages.findOrInit({
			params: {
				types: [Messenger.config.POST_TYPES.MESSAGE],
				mentions: this.entity +' '+ this.id
			}
		});

		this.messages.on('change', this.__cacheLatestMessage, this);
	},

	setRecipients: function (entities) {
		var mentions = [];
		for (var i = 0, _len = entities.length; i < _len; i++) {
			mentions.push({
				entity: entities[i]
			});
		}
		this.set('mentions', mentions);
	},

	saveNewMessage: function (options) {
		if (this.shouldSaveNewMessage) {
			this.newMessage.save({
				success: function (res, xhr) {
					this.initNewMessage();
					options.success(res, xhr);
				}.bind(this),

				failure: function (res, xhr) {
					options.failure(res, xhr);
				},

				complete: function (res, xhr) {
					options.complete(res, xhr);
				}
			});
			return;
		} else {
			options.success();
			options.complete();
		}
	},

	save: function (options) {
		var err = this.validate();
		if (err) {
			var res = { error: err };
			var xhr = { status: 400 };
			if (typeof options.failure === 'function') {
				options.failure(res, xhr);
			}
			if (typeof options.complete === 'function') {
				options.complete(res, xhr);
			}
			return;
		}

		var data = this.toJSON();
		var callback = {
			success: function (res, xhr) {
				this.parseAttributes(res.post);
				this.saveNewMessage({
					success: function () {
						if (typeof options.success === 'function') {
							options.success(res, xhr);
						}
					},

					failure: function (res, xhr) {
						if (typeof options.failure === 'function') {
							options.failure(res, xhr);
						}
					},

					complete: function () {
						if (typeof options.complete === 'function') {
							options.complete(res, xhr);
						}
					}
				});
			}.bind(this),

			failure: function (res, xhr) {
				if (typeof options.failure === 'function') {
					options.failure(res, xhr);
				}
			},

			complete: function (res, xhr) {
				if (typeof options.complete === 'function') {
					options.complete(res, xhr);
				}
			}
		};
		if (this.id === 'new') {
			delete data.id;
			Messenger.client.createPost(data, {
				callback: callback
			});
		} else {
			data.version = {
				parents: [{
					version: data.version.id
				}]
			};
			Messenger.client.updatePost(data, {
				callback: callback
			});
		}
	},

	validate: function () {
		if (!this.mentions || this.mentions.length === 0) {
			return "Conversation must have participants.";
		}

		if (this.shouldSaveNewMessage) {
			return this.newMessage.validate();
		}

		return null;
	},

	performDelete: function (callback) {
		var performDeleteConversation = function () {
			Messenger.client.deletePost({
				params: [{
					entity: this.entity,
					post: this.id
				}],

				callback: {
					success: function (res, xhr) {
						this.detach();
						if (typeof callback.success === 'function') {
							callback.success();
						}
					}.bind(this),

					failure: callback.failure
				}
			});
		}.bind(this);

		this.__deleteMessages({
			success: performDeleteConversation,
			failure: callback.failure
		});
	},

	__deleteMessages: function (callback) {
		var fetchComplete = false;
		var numRemaining = 0;
		var numFailed = 0;

		var handleComplete = function () {
			if (fetchComplete && numRemaining === 0 && numFailed === 0) {
				callback.success();
			}
		};

		var handleDeleteSuccess = function () {
			numRemaining--;

			handleComplete();
		}.bind(this);

		var handleDeleteFailure = function (res, xhr) {
			numRemaining--;
			numFailed++;

			callback.failure(res, xhr);
			handleComplete();
		}.bind(this);

		var deleteMessage = function (message) {
			message.performDelete({
				success: handleDeleteSuccess,
				failure: handleDeleteFailure
			});
		};

		var handleFetchSuccess = function () {
				var models = this.messages.models();
				if (models.length === 0) {
					return handleFetchComplete();
				}

				var len = models.length;

				numRemaining += len;

				for (var i = 0; i < len; i++) {
					deleteMessage(models[i]);
				}

				fetchNextPage();
		}.bind(this);

		var handleFetchComplete = function () {
			fetchComplete = true;
			handleComplete();
		}.bind(this);

		var fetchNextPage = function () {
			var lastPage = !this.messages.fetchNext({
				callback: {
					success: handleFetchSuccess,
					failure: callback.failure
				}
			});

			if (lastPage) {
				handleFetchComplete();
			}
		}.bind(this);

		this.__fetchMessages({
			success: handleFetchSuccess,
			failure: callback.failure
		});
	},

	__fetchMessages: function (callback) {
		this.messages.fetch({
			callback: callback
		});
	},

	fetch: function (options) {
		var conversation = this;
		var opts = Marbles.Utils.extend({}, options || {}, {
			params: [{
				entity: this.entity,
				post: this.id
			}],
			callback: {
				success: function (res, xhr) {
					conversation.parseAttributes(res.post);

					if (options.callback) {
						if (typeof options.callback === 'function') {
							options.callback(res, xhr);
						} else if (typeof options.callback.success === 'function') {
							options.callback.success(res, xhr);
						}
					}
				},

				failure: function (res, xhr) {
					if (options.callback) {
						if (typeof options.callback === 'function') {
							options.callback(res, xhr);
						} else if (typeof options.callback.failure === 'function') {
							options.callback.failure(res, xhr);
						}
					}
				}
			}
		});
		Messenger.client.getPost(opts);
	},

	fetchLatestMessage: function () {
		var latestMessage = this.__getLatestCachedMessage();

		if (latestMessage) {
			this.messages.resetModels([latestMessage]);
		} else {
			this.messages.fetch({
				params: {
					limit: 1
				}
			});
		}
	},

	__getLatestCachedMessage: function () {
		var manifest = Messenger.LocalCache.getItem('manifest');
		if (!manifest || !manifest.latestConversationMessage) {
			return null;
		}

		var latestMessageMeta = manifest.latestConversationMessage[this.entity +':'+ this.id];
		if (!latestMessageMeta) {
			return null;
		}

		var latestMessageJSON = Messenger.LocalCache.getItem(latestMessageMeta.entity +':'+ latestMessageMeta.id);
		if (!latestMessageJSON) {
			return null;
		}

		return Messenger.Models.Message.findOrInit(latestMessageJSON);
	},

	__cacheLatestMessage: function () {
		var latestMessage = this.messages.first();
		if (!latestMessage) {
			return;
		}

		var latestMessageJSON = latestMessage.toJSON();
		var latestMessageMeta = {
			entity: latestMessage.entity,
			id: latestMessage.id
		};

		Messenger.LocalCache.setItem(latestMessage.entity +':'+ latestMessage.id, latestMessageJSON);

		var manifest = Messenger.LocalCache.getItem('manifest') || {};
		if (!manifest.latestConversationMessage) {
			manifest.latestConversationMessage = {};
		}

		var key = this.entity +':'+ this.id;

		var tmp = manifest.latestConversationMessage[key];
		if (tmp) {
			Messenger.LocalCache.removeItem(tmp.entity +':'+ tmp.id);
		}

		manifest.latestConversationMessage[key] = latestMessageMeta;
		Messenger.LocalCache.setItem('manifest', manifest);
	}
});
<commit_msg>Fetch latest message even when cached<commit_after>Messenger.Models.Conversation = Marbles.Model.createClass({
	displayName: 'Messenger.Models.Conversation',

	mixins: [{
		ctor: {
			modelName: 'conversation',

			cidMappingScope: ['id', 'entity'],

			// toJSON() will only return these attrs
			JSONKeys: [
				'id',
				'type',
				'entity',
				'version',
				'mentions',
				'published_at'
			],

			findOrInit: function (attrs) {
				return this.find(attrs, {fetch:false}) || new this(attrs);
			},

			findOrFetch: function (attrs, options) {
				var _instance, _res, _xhr;
				_instance = this.find(attrs, {fetch:false});
				if (_instance && options && options.callback) {
					// defer callback until after fn return
					setTimeout(function () {
						var res = {
							post: c.toJSON()
						};
						var xhr = {
							status: 304
						};
						if (typeof options.callback === 'function') {
							options.callback(res, xhr);
						} else {
							if (typeof options.callback.success === 'function') {
								options.callback.success(res, xhr);
							}
							if (typeof options.callback.complete === 'function') {
								options.callback.complete(res, xhr);
							}
						}
					}, 0);
				} else if (!_instance) {
					_instance = this.fetch(attrs, options);
				}
				return _instance;
			},

			fetch: function (attrs, options) {
				var _instance = new this(attrs);
				_instance.fetch(options);
				return _instance;
			}
		}
	}],

	didInitialize: function () {
		this.set('type', this.type || Messenger.config.POST_TYPES.CONVERSATION);
		this.initNewMessage();
		this.initMessages();

		if (this.id === 'new') {
			this.once('change:id', this.initMessages, this);
		}

		this.once('detach', this.handleDetach, this);
	},

	handleDetach: function () {
		this.messages.detach();
		this.newMessage.detach();
	},

	initNewMessage: function (entity) {
		this.newMessage = Messenger.Models.Message.findOrInit({
			id: 'new',
			entity: this.entity,
			conversation_id: this.id
		});
		this.newMessage.initConversation(this);
	},

	initMessages: function () {
		if (this.messages) {
			this.messages.detach();
		}

		this.messages = Messenger.Collections.Messages.findOrInit({
			params: {
				types: [Messenger.config.POST_TYPES.MESSAGE],
				mentions: this.entity +' '+ this.id
			}
		});

		this.messages.on('change', this.__cacheLatestMessage, this);
	},

	setRecipients: function (entities) {
		var mentions = [];
		for (var i = 0, _len = entities.length; i < _len; i++) {
			mentions.push({
				entity: entities[i]
			});
		}
		this.set('mentions', mentions);
	},

	saveNewMessage: function (options) {
		if (this.shouldSaveNewMessage) {
			this.newMessage.save({
				success: function (res, xhr) {
					this.initNewMessage();
					options.success(res, xhr);
				}.bind(this),

				failure: function (res, xhr) {
					options.failure(res, xhr);
				},

				complete: function (res, xhr) {
					options.complete(res, xhr);
				}
			});
			return;
		} else {
			options.success();
			options.complete();
		}
	},

	save: function (options) {
		var err = this.validate();
		if (err) {
			var res = { error: err };
			var xhr = { status: 400 };
			if (typeof options.failure === 'function') {
				options.failure(res, xhr);
			}
			if (typeof options.complete === 'function') {
				options.complete(res, xhr);
			}
			return;
		}

		var data = this.toJSON();
		var callback = {
			success: function (res, xhr) {
				this.parseAttributes(res.post);
				this.saveNewMessage({
					success: function () {
						if (typeof options.success === 'function') {
							options.success(res, xhr);
						}
					},

					failure: function (res, xhr) {
						if (typeof options.failure === 'function') {
							options.failure(res, xhr);
						}
					},

					complete: function () {
						if (typeof options.complete === 'function') {
							options.complete(res, xhr);
						}
					}
				});
			}.bind(this),

			failure: function (res, xhr) {
				if (typeof options.failure === 'function') {
					options.failure(res, xhr);
				}
			},

			complete: function (res, xhr) {
				if (typeof options.complete === 'function') {
					options.complete(res, xhr);
				}
			}
		};
		if (this.id === 'new') {
			delete data.id;
			Messenger.client.createPost(data, {
				callback: callback
			});
		} else {
			data.version = {
				parents: [{
					version: data.version.id
				}]
			};
			Messenger.client.updatePost(data, {
				callback: callback
			});
		}
	},

	validate: function () {
		if (!this.mentions || this.mentions.length === 0) {
			return "Conversation must have participants.";
		}

		if (this.shouldSaveNewMessage) {
			return this.newMessage.validate();
		}

		return null;
	},

	performDelete: function (callback) {
		var performDeleteConversation = function () {
			Messenger.client.deletePost({
				params: [{
					entity: this.entity,
					post: this.id
				}],

				callback: {
					success: function (res, xhr) {
						this.detach();
						if (typeof callback.success === 'function') {
							callback.success();
						}
					}.bind(this),

					failure: callback.failure
				}
			});
		}.bind(this);

		this.__deleteMessages({
			success: performDeleteConversation,
			failure: callback.failure
		});
	},

	__deleteMessages: function (callback) {
		var fetchComplete = false;
		var numRemaining = 0;
		var numFailed = 0;

		var handleComplete = function () {
			if (fetchComplete && numRemaining === 0 && numFailed === 0) {
				callback.success();
			}
		};

		var handleDeleteSuccess = function () {
			numRemaining--;

			handleComplete();
		}.bind(this);

		var handleDeleteFailure = function (res, xhr) {
			numRemaining--;
			numFailed++;

			callback.failure(res, xhr);
			handleComplete();
		}.bind(this);

		var deleteMessage = function (message) {
			message.performDelete({
				success: handleDeleteSuccess,
				failure: handleDeleteFailure
			});
		};

		var handleFetchSuccess = function () {
				var models = this.messages.models();
				if (models.length === 0) {
					return handleFetchComplete();
				}

				var len = models.length;

				numRemaining += len;

				for (var i = 0; i < len; i++) {
					deleteMessage(models[i]);
				}

				fetchNextPage();
		}.bind(this);

		var handleFetchComplete = function () {
			fetchComplete = true;
			handleComplete();
		}.bind(this);

		var fetchNextPage = function () {
			var lastPage = !this.messages.fetchNext({
				callback: {
					success: handleFetchSuccess,
					failure: callback.failure
				}
			});

			if (lastPage) {
				handleFetchComplete();
			}
		}.bind(this);

		this.__fetchMessages({
			success: handleFetchSuccess,
			failure: callback.failure
		});
	},

	__fetchMessages: function (callback) {
		this.messages.fetch({
			callback: callback
		});
	},

	fetch: function (options) {
		var conversation = this;
		var opts = Marbles.Utils.extend({}, options || {}, {
			params: [{
				entity: this.entity,
				post: this.id
			}],
			callback: {
				success: function (res, xhr) {
					conversation.parseAttributes(res.post);

					if (options.callback) {
						if (typeof options.callback === 'function') {
							options.callback(res, xhr);
						} else if (typeof options.callback.success === 'function') {
							options.callback.success(res, xhr);
						}
					}
				},

				failure: function (res, xhr) {
					if (options.callback) {
						if (typeof options.callback === 'function') {
							options.callback(res, xhr);
						} else if (typeof options.callback.failure === 'function') {
							options.callback.failure(res, xhr);
						}
					}
				}
			}
		});
		Messenger.client.getPost(opts);
	},

	fetchLatestMessage: function () {
		var latestMessage = this.__getLatestCachedMessage();

		if (latestMessage) {
			this.messages.resetModels([latestMessage]);
		}

		this.messages.fetch({
			params: {
				limit: 1
			}
		});
	},

	__getLatestCachedMessage: function () {
		var manifest = Messenger.LocalCache.getItem('manifest');
		if (!manifest || !manifest.latestConversationMessage) {
			return null;
		}

		var latestMessageMeta = manifest.latestConversationMessage[this.entity +':'+ this.id];
		if (!latestMessageMeta) {
			return null;
		}

		var latestMessageJSON = Messenger.LocalCache.getItem(latestMessageMeta.entity +':'+ latestMessageMeta.id);
		if (!latestMessageJSON) {
			return null;
		}

		return Messenger.Models.Message.findOrInit(latestMessageJSON);
	},

	__cacheLatestMessage: function () {
		var latestMessage = this.messages.first();
		if (!latestMessage) {
			return;
		}

		var latestMessageJSON = latestMessage.toJSON();
		var latestMessageMeta = {
			entity: latestMessage.entity,
			id: latestMessage.id
		};

		Messenger.LocalCache.setItem(latestMessage.entity +':'+ latestMessage.id, latestMessageJSON);

		var manifest = Messenger.LocalCache.getItem('manifest') || {};
		if (!manifest.latestConversationMessage) {
			manifest.latestConversationMessage = {};
		}

		var key = this.entity +':'+ this.id;

		var tmp = manifest.latestConversationMessage[key];
		if (tmp) {
			Messenger.LocalCache.removeItem(tmp.entity +':'+ tmp.id);
		}

		manifest.latestConversationMessage[key] = latestMessageMeta;
		Messenger.LocalCache.setItem('manifest', manifest);
	}
});
<|endoftext|>


<commit_before>'use strict';

var h = require('react-hyperscript');
var React = require('react');
var Router = require('react-router');

// Flux
var ApplicationActions = require('../actions/application.actions');
var ApplicationStore = require('../stores/application.store');

// Components
var ApplicationTable = require('./application-table');

function _getApplications() {
  return ApplicationStore.getApplications();
}

var ApplicationIndex = React.createClass({

  displayName: 'ApplicationIndex',

  mixins: [Router.State, Router.Navigation],

  getInitialState: function getInitialState() {
    return {
      applicationStats: {},
      applications: [],
      sortedApplications: [],
      filterBy: null
    };
  },

  componentWillMount: function componentWillMount() {
    this._filterRowsBy(this.state.filterBy);
  },

  componentDidMount: function componentDidMount() {
    ApplicationActions.getApplications();
    ApplicationStore.addChangeListener(this._onChange);
  },

  componentWillUnmount: function componentWillUnmount() {
    ApplicationStore.removeChangeListener(this._onChange);
  },

  _onChange: function _onChange() {
    this.setState({
      applications: _getApplications()
    });
    this._filterRowsBy(this.state.filterBy);
  },

  _onClick: function _onClick(event) {
    if (event) {
      this.transitionTo('applicationPage', {id: event._id});
    }
  },

  _onFilterChange: function _onFilterChange(event) {
    this._filterRowsBy(event.target.value);
  },

  _filterRowsBy: function _filterRowsBy(filterBy) {
    var applications = this.state.applications.slice();
    var sortedApplications;

    if (filterBy) {
      sortedApplications = applications.filter(function filter(row) {
        return (row['name'].toLowerCase().indexOf(filterBy.toLowerCase()) >= 0);
      });
    } else {
      sortedApplications = applications;
    }

    this.setState({
      sortedApplications: sortedApplications,
      filterBy: filterBy
    });
  },

  render: function render() {
    return (
      h('div', {className: 'container'}, [
        h('div', {className: 'row'}, [
          h('section', {className: 'col-md-12'}, [
            h('div', {className: 'page__header'}, [
              h('h4', {className: 'page__title'}, 'Application index')
            ])
          ]),
          h('section', {className: 'col-md-12'}, [
            h('div', {className: 'page__body'}, [
              h(ApplicationTable, {
                applications: this.state.sortedApplications,
                initialLength: this.state.applications.length,
                filter: '',
                onClick: this._onClick
              })
            ])
          ])
        ])
      ])
    );
  }

});

module.exports = ApplicationIndex;
<commit_msg>Update index; just the table now<commit_after>'use strict';

var h = require('react-hyperscript');
var React = require('react');
var Router = require('react-router');

// Flux
var ApplicationActions = require('../actions/application.actions');
var ApplicationStore = require('../stores/application.store');
var SessionStore = require('../stores/session.store');

// Components
var ApplicationTable = require('./application-table');

function _getApplications() {
  return ApplicationStore.getApplications();
}

function _getCurrentHackathon() {
  var hackathon = SessionStore.getCurrentHackathon();

  return hackathon;
}

var ApplicationIndex = React.createClass({

  displayName: 'ApplicationIndex',

  mixins: [Router.State, Router.Navigation],

  getInitialState: function getInitialState() {
    return {
      applicationStats: {},
      applications: [],
      sortedApplications: [],
      filterBy: null
    };
  },

  componentWillMount: function componentWillMount() {
    var hackathon = _getCurrentHackathon();

    this.setState({
      currentHackathon: hackathon
    });

    this._filterRowsBy(this.state.filterBy);
  },

  componentDidMount: function componentDidMount() {
    ApplicationActions.getApplications();
    ApplicationStore.addChangeListener(this._onChange);
  },

  componentWillUnmount: function componentWillUnmount() {
    ApplicationStore.removeChangeListener(this._onChange);
  },

  _onClick: function _onClick(event) {
    if (event) {
      this.transitionTo('applicationPage', {id: event._id});
    }
  },

  _onFilterChange: function _onFilterChange(event) {
    this._filterRowsBy(event.target.value);
  },

  _filterRowsBy: function _filterRowsBy(filterBy) {
    var applications = this.state.applications.slice();
    var sortedApplications;

    if (filterBy) {
      sortedApplications = applications.filter(function filter(row) {
        return (row['name'].toLowerCase().indexOf(filterBy.toLowerCase()) >= 0);
      });
    } else {
      sortedApplications = applications;
    }

    this.setState({
      sortedApplications: sortedApplications,
      filterBy: filterBy
    });
  },

  _onChange: function _onChange() {
    var hackathon = _getCurrentHackathon();

    this.setState({
      applications: _getApplications(),
      currentHackathon: hackathon
    });

    this._filterRowsBy(this.state.filterBy);
  },

  render: function render() {
    return (
      h('div', {className: 'row'}, [
        h('section', {className: 'col-md-12'}, [
          h('div', {className: 'page__body'}, [
            h(ApplicationTable, {
              applications: this.state.sortedApplications,
              initialLength: this.state.applications.length,
              filter: '',
              onClick: this._onClick
            })
          ])
        ])
      ])
    );
  }

});

module.exports = ApplicationIndex;
<|endoftext|>


<commit_before>'use strict';

angular.module('copayApp.controllers').controller('advancedSettingsController', function($scope, $rootScope, $log, $window, lodash, configService, uxLanguage, platformInfo, pushNotificationsService, profileService, feeService) {

  var updateConfig = function() {

    var config = configService.getSync();

    $scope.spendUnconfirmed = {
      value: config.wallet.spendUnconfirmed
    };
    $scope.bitpayCardEnabled = {
      value: config.bitpayCard.enabled
    };
    $scope.amazonEnabled = {
      value: config.amazon.enabled
    };
    $scope.glideraEnabled = {
      value: config.glidera.enabled
    };
    $scope.coinbaseEnabled = {
      value: config.coinbase.enabled
    };
    $scope.recentTransactionsEnabled = {
      value: config.recentTransactions.enabled
    };
    $scope.frequentlyUsedEnabled = {
      value: config.frequentlyUsed.enabled
    };
  };

  $scope.spendUnconfirmedChange = function() {
    var opts = {
      wallet: {
        spendUnconfirmed: $scope.spendUnconfirmed.value
      }
    };
    configService.set(opts, function(err) {
      if (err) $log.debug(err);
    });
  };

  $scope.bitpayCardChange = function() {
    var opts = {
      bitpayCard: {
        enabled: $scope.bitpayCardEnabled.value
      }
    };
    configService.set(opts, function(err) {
      if (err) $log.debug(err);
    });
  };

  $scope.amazonChange = function() {
    var opts = {
      amazon: {
        enabled: $scope.amazonEnabled.value
      }
    };
    configService.set(opts, function(err) {
      if (err) $log.debug(err);
    });
  };

  $scope.glideraChange = function() {
    var opts = {
      glidera: {
        enabled: $scope.glideraEnabled.value
      }
    };
    configService.set(opts, function(err) {
      if (err) $log.debug(err);
    });
  };

  $scope.coinbaseChange = function() {
    var opts = {
      coinbase: {
        enabled: $scope.coinbaseEnabled.value
      }
    };
    configService.set(opts, function(err) {
      if (err) $log.debug(err);
    });
  };

  $scope.recentTransactionsChange = function() {
    var opts = {
      recentTransactions: {
        enabled: $scope.recentTransactionsEnabled.value
      }
    };
    configService.set(opts, function(err) {
      if (err) $log.debug(err);
    });
  };

  $scope.frequentlyUsedChange = function() {
    var opts = {
      frequentlyUsed: {
        enabled: $scope.frequentlyUsedEnabled.value
      }
    };
    configService.set(opts, function(err) {
      if (err) $log.debug(err);
    });
  };

  $scope.$on("$ionicView.enter", function(event, data) {
    updateConfig();
  });

});
<commit_msg>preload settings toggle values<commit_after>'use strict';

angular.module('copayApp.controllers').controller('advancedSettingsController', function($scope, $rootScope, $log, $window, lodash, configService, uxLanguage, platformInfo, pushNotificationsService, profileService, feeService) {

  var updateConfig = function() {

    var config = configService.getSync();

    $scope.spendUnconfirmed = {
      value: config.wallet.spendUnconfirmed
    };
    $scope.bitpayCardEnabled = {
      value: config.bitpayCard.enabled
    };
    $scope.amazonEnabled = {
      value: config.amazon.enabled
    };
    $scope.glideraEnabled = {
      value: config.glidera.enabled
    };
    $scope.coinbaseEnabled = {
      value: config.coinbase.enabled
    };
    $scope.recentTransactionsEnabled = {
      value: config.recentTransactions.enabled
    };
    $scope.frequentlyUsedEnabled = {
      value: config.frequentlyUsed.enabled
    };
  };

  $scope.spendUnconfirmedChange = function() {
    var opts = {
      wallet: {
        spendUnconfirmed: $scope.spendUnconfirmed.value
      }
    };
    configService.set(opts, function(err) {
      if (err) $log.debug(err);
    });
  };

  $scope.bitpayCardChange = function() {
    var opts = {
      bitpayCard: {
        enabled: $scope.bitpayCardEnabled.value
      }
    };
    configService.set(opts, function(err) {
      if (err) $log.debug(err);
    });
  };

  $scope.amazonChange = function() {
    var opts = {
      amazon: {
        enabled: $scope.amazonEnabled.value
      }
    };
    configService.set(opts, function(err) {
      if (err) $log.debug(err);
    });
  };

  $scope.glideraChange = function() {
    var opts = {
      glidera: {
        enabled: $scope.glideraEnabled.value
      }
    };
    configService.set(opts, function(err) {
      if (err) $log.debug(err);
    });
  };

  $scope.coinbaseChange = function() {
    var opts = {
      coinbase: {
        enabled: $scope.coinbaseEnabled.value
      }
    };
    configService.set(opts, function(err) {
      if (err) $log.debug(err);
    });
  };

  $scope.recentTransactionsChange = function() {
    var opts = {
      recentTransactions: {
        enabled: $scope.recentTransactionsEnabled.value
      }
    };
    configService.set(opts, function(err) {
      if (err) $log.debug(err);
    });
  };

  $scope.frequentlyUsedChange = function() {
    var opts = {
      frequentlyUsed: {
        enabled: $scope.frequentlyUsedEnabled.value
      }
    };
    configService.set(opts, function(err) {
      if (err) $log.debug(err);
    });
  };

  $scope.$on("$ionicView.beforeEnter", function(event, data) {
    updateConfig();
  });

});
<|endoftext|>


<commit_before>NumberButton.prototype = Object.create(GeneralButton.prototype);
NumberButton.prototype.constructor = NumberButton;

/**
 * A button with number representations on it.
 * If you supply more than one representation the button will stretch.
 * Publishes numberPress event on click.
 * NOTE: This button will not go to "up" state after click unless you set keepDown option to false.
 * @param {number} number - The number for the button.
 * @param {number|Array} representations - The representations of the button (see GLOBAL.NUMBER_REPRESENTATION).
 * @param {Object} options - A list of options (in addition to GeneralButton):
 *        {number} min: The minimum value of the button.
 *        {number} max: The maximum value of the button.
 *        {number} size: the small side of the button (the other depend on representation amount) (default 75).
 *        {boolean} vertical: stretch button vertically if many representations, otherwise horisontally (default true).
 *        {string} spriteKey: Used for object representation only. The key to the sprite.
 *        {string} spriteFrame: Used for object representation only. The framename in the sprite.
                                NOTE: Used like this: spriteFrame + this.number
 * @return {Object} Itself.
 */
function NumberButton (number, representations, options) {
	/* The order here is a bit weird because GeneralButton calls setSize, which this class overshadows. */
	if (typeof options.keepDown === 'undefined' || options.keepDown === null) {
		options.keepDown = true;
	}
	this.representations = representations;
	this.background = options.background;
	this.spriteKey = options.spriteKey;
	this.spriteFrame = options.spriteFrame;

	GeneralButton.call(this, options); // Parent constructor.

	this.vertical = options.vertical;
	if (typeof this.vertical === 'undefined' || this.vertical === null) {
		this.vertical = true;
	}
	this.setDirection(!this.vertical);

	this.min = options.min || null;
	this.max = options.max || null;
	this._number = 0;
	this.number = number;

	this._clicker = options.onClick;
	/* This will be called in the GeneralButton's onInputDown */
	this.onClick = function () {
		EventSystem.publish(GLOBAL.EVENT.numberPress, [this.number, this.representations]);
		if (this._clicker) {
			this._clicker(this.number);
		}
	};

	return this;
}

/**
 * @property {number|Array} representations - The representations on the button.
 */
Object.defineProperty(NumberButton.prototype, 'representations', {
	get: function () {
		return this._representations;
	},
	set: function (value) {
		this._representations = Array.isArray(value) ? value : [value];
		if (typeof this.number !== 'undefined' && this.number !== null) {
			this.updateGraphics();
		}
	}
});

/**
 * @property {number} number - The number on the button. Set according to representations.
 *                             NOTE: This can not be less or more than min or max.
 */
Object.defineProperty(NumberButton.prototype, 'number', {
	get: function () {
		return this._number;
	},
	set: function (value) {
		/* Chcek boundaries */
		if (this.min && value < this.min) { value = this.min; }
		if (this.max && value > this.max) { value = this.max; }
		if (value === this._number) { return; }

		this._number = value;

		this.updateGraphics();
	}
});

/**
 * Update the graphics of the button.
 */
NumberButton.prototype.updateGraphics = function () {
	/* Remove old graphics. */
	if (this.children.length > 1) {
		this.removeBetween(1, this.children.length-1, true);
	}

	if (typeof this.background === 'undefined' && this.representations[0] !== GLOBAL.NUMBER_REPRESENTATION.yesno) {
		// TODO: This color handling is due to a bug in Pixi, remove when bug is fixed.
		if (typeof this.originColor === 'undefined' || this.originColor === null) {
			this.originColor = this.color;
			this.originPressed = this.colorPressed;
			this.colorAdd = Phaser.Color.getBlue(this.color) > 3 ? -1 : 1;
		}
		if (this._number > 0) {
			this.bg.frameName = 'button_plus';
			this.color = this.originColor + 1*this.colorAdd;
			this.colorPressed = this.originPressed + 1*this.colorAdd;
		} else if (this._number < 0) {
			this.bg.frameName = 'button_minus';
			this.color = this.originColor + 2*this.colorAdd;
			this.colorPressed = this.originPressed + 2*this.colorAdd;
		} else {
			this.bg.frameName = 'button_zero';
			this.color = this.originColor + 3*this.colorAdd;
			this.colorPressed = this.originPressed + 3*this.colorAdd;
		}
		this.setSize();
		this.reset();
	}

	/* Add new graphics. */
	var x = 0;
	var y = 0;
	var offset = 0;
	var useNum = Math.abs(this._number);
	for (var i = 0; i < this.representations.length; i++) {
		if (this.vertical) {
			y = this.size * i;
		} else {
			x = this.size * i;
		}

		if (this.representations[i] === GLOBAL.NUMBER_REPRESENTATION.dots) {
			offset = this.calcOffset(16);
			this.add(new DotsRepresentation(useNum, x+offset.x, y+offset.y, this.size-offset.o, this.color));

		} else if (this.representations[i] === GLOBAL.NUMBER_REPRESENTATION.fingers) {
			offset = this.calcOffset(24);
			this.add(new FingerRepresentation(useNum, x+offset.x, y+offset.y, this.size-offset.o, this.color));

		} else if (this.representations[i] === GLOBAL.NUMBER_REPRESENTATION.strikes) {
			offset = this.calcOffset(12);
			this.add(new StrikeRepresentation(useNum, x+offset.x, y+offset.y, this.size-offset.o, this.color, this.max - this.min + 1));

		} else if (this.representations[i] === GLOBAL.NUMBER_REPRESENTATION.objects) {
			var s = this.create(x, y, this.spriteKey, (this.spriteFrame ? this.spriteFrame + Math.abs(this._number) : null));
			var scale = this.size/(s.width > s.height ? s.width : s.height)*0.8;
			s.scale.set(scale);
			s.x = (!this.direction ? (this._number > 0 ? this.size * 0.8 : this.size * 1.2) : this.size)/2 - s.width/2;
			s.y = (this.direction ? (this._number > 0 ? this.size * 1.2 : this.size * 0.8) : this.size)/2 - s.height/2;

		} else if (this.representations[i] === GLOBAL.NUMBER_REPRESENTATION.numbers) {
			this.add(new NumberRepresentation(this._number, x, y, this.size/2, this.color));

		} else if (this.representations[i] === GLOBAL.NUMBER_REPRESENTATION.dice) {
			offset = this.calcOffset(12);
			this.add(new DiceRepresentation(useNum, x+offset.x, y+offset.y, this.size-offset.o, this.color));

		} else if (this.representations[i] === GLOBAL.NUMBER_REPRESENTATION.yesno) {
			this._number = this._number % 2;
			this.add(new YesnoRepresentation(this._number, x, y, this.size/2, this.color));
		}
	}
};

/**
 * Calculate the different offsets for the button (needed due to arrow in button).
 * @param {Number} offset - Offset from button edge (used like: this.size/offset).
 */
NumberButton.prototype.calcOffset = function (offset) {
	var t = {};
	t.o = this.size/offset;
	if (this.direction) { /* Up/Down */
		t.x = t.o*1.8;
		t.y = t.o*(this._number >= 0 ? 3.3 : 1);
	} else { /* Left/Right */
		t.x = t.o*(this._number >= 0 ? 1 : 3.3);
		t.y = t.o*2;
	}
	t.o *= 4;
	return t;
};

/**
 * Set the size of this button.
 * @param {Number} The new size.
 */
NumberButton.prototype.setSize = function (size) {
	GeneralButton.prototype.setSize.call(this, size || this.size);

	// If the button should expand horizontally it will be rotated.
	// So we always want to change height, not width.
	this.bg.height *= this.representations.length;

	return this;
};

/**
 * Set the direction of the background button.
 * @param {Boolean} val - True = up/down, false = left/right.
 */
NumberButton.prototype.setDirection = function (val) {
	this.direction = val;
	if (val) {
		this.bg.rotation = -Math.PI/2;
		this.bg.y += this.bg.width;
		this.bg.adjusted = this.bg.width;
	} else {
		this.bg.rotation = 0;
		this.bg.y -= this.bg.adjusted || 0;
	}

	if (this.number) {
		this.updateGraphics();
	}

	return this;
};<commit_msg>NumberButton: Bugfix for tint<commit_after>NumberButton.prototype = Object.create(GeneralButton.prototype);
NumberButton.prototype.constructor = NumberButton;

/**
 * A button with number representations on it.
 * If you supply more than one representation the button will stretch.
 * Publishes numberPress event on click.
 * NOTE: This button will not go to "up" state after click unless you set keepDown option to false.
 * @param {number} number - The number for the button.
 * @param {number|Array} representations - The representations of the button (see GLOBAL.NUMBER_REPRESENTATION).
 * @param {Object} options - A list of options (in addition to GeneralButton):
 *        {number} min: The minimum value of the button.
 *        {number} max: The maximum value of the button.
 *        {number} size: the small side of the button (the other depend on representation amount) (default 75).
 *        {boolean} vertical: stretch button vertically if many representations, otherwise horisontally (default true).
 *        {string} spriteKey: Used for object representation only. The key to the sprite.
 *        {string} spriteFrame: Used for object representation only. The framename in the sprite.
                                NOTE: Used like this: spriteFrame + this.number
 * @return {Object} Itself.
 */
function NumberButton (number, representations, options) {
	/* The order here is a bit weird because GeneralButton calls setSize, which this class overshadows. */
	if (typeof options.keepDown === 'undefined' || options.keepDown === null) {
		options.keepDown = true;
	}
	this.representations = representations;
	this.background = options.background;
	this.spriteKey = options.spriteKey;
	this.spriteFrame = options.spriteFrame;

	GeneralButton.call(this, options); // Parent constructor.

	this.vertical = options.vertical;
	if (typeof this.vertical === 'undefined' || this.vertical === null) {
		this.vertical = true;
	}
	this.setDirection(!this.vertical);

	this.min = options.min || null;
	this.max = options.max || null;
	this._number = 0;
	this.number = number;

	this._clicker = options.onClick;
	/* This will be called in the GeneralButton's onInputDown */
	this.onClick = function () {
		EventSystem.publish(GLOBAL.EVENT.numberPress, [this.number, this.representations]);
		if (this._clicker) {
			this._clicker(this.number);
		}
	};

	return this;
}

/**
 * @property {number|Array} representations - The representations on the button.
 */
Object.defineProperty(NumberButton.prototype, 'representations', {
	get: function () {
		return this._representations;
	},
	set: function (value) {
		this._representations = Array.isArray(value) ? value : [value];
		if (typeof this.number !== 'undefined' && this.number !== null) {
			this.updateGraphics();
		}
	}
});

/**
 * @property {number} number - The number on the button. Set according to representations.
 *                             NOTE: This can not be less or more than min or max.
 */
Object.defineProperty(NumberButton.prototype, 'number', {
	get: function () {
		return this._number;
	},
	set: function (value) {
		/* Chcek boundaries */
		if (this.min && value < this.min) { value = this.min; }
		if (this.max && value > this.max) { value = this.max; }
		if (value === this._number) { return; }

		this._number = value;

		this.updateGraphics();
	}
});

/**
 * Update the graphics of the button.
 */
NumberButton.prototype.updateGraphics = function () {
	/* Remove old graphics. */
	if (this.children.length > 1) {
		this.removeBetween(1, this.children.length-1, true);
	}

	if (typeof this.background === 'undefined' && this.representations[0] !== GLOBAL.NUMBER_REPRESENTATION.yesno) {
		// TODO: This color handling is due to a bug in Pixi, remove when bug is fixed.
		if (typeof this.originColor === 'undefined' || this.originColor === null) {
			this.originColor = this.color;
			this.originPressed = this.colorPressed;
			this.colorAdd = Phaser.Color.getBlue(this.color) > 3 ? -1 : 1;
		}
		if (this._number > 0) {
			this.bg.frameName = 'button_plus';
			this.color = this.originColor + 1*this.colorAdd;
			this.colorPressed = this.originPressed + 1;
		} else if (this._number < 0) {
			this.bg.frameName = 'button_minus';
			this.color = this.originColor + 2*this.colorAdd;
			this.colorPressed = this.originPressed + 2;
		} else {
			this.bg.frameName = 'button_zero';
			this.color = this.originColor + 3*this.colorAdd;
			this.colorPressed = this.originPressed + 3;
		}
		this.setSize();
		this.reset();
	}

	/* Add new graphics. */
	var x = 0;
	var y = 0;
	var offset = 0;
	var useNum = Math.abs(this._number);
	for (var i = 0; i < this.representations.length; i++) {
		if (this.vertical) {
			y = this.size * i;
		} else {
			x = this.size * i;
		}

		if (this.representations[i] === GLOBAL.NUMBER_REPRESENTATION.dots) {
			offset = this.calcOffset(16);
			this.add(new DotsRepresentation(useNum, x+offset.x, y+offset.y, this.size-offset.o, this.color));

		} else if (this.representations[i] === GLOBAL.NUMBER_REPRESENTATION.fingers) {
			offset = this.calcOffset(24);
			this.add(new FingerRepresentation(useNum, x+offset.x, y+offset.y, this.size-offset.o, this.color));

		} else if (this.representations[i] === GLOBAL.NUMBER_REPRESENTATION.strikes) {
			offset = this.calcOffset(12);
			this.add(new StrikeRepresentation(useNum, x+offset.x, y+offset.y, this.size-offset.o, this.color, this.max - this.min + 1));

		} else if (this.representations[i] === GLOBAL.NUMBER_REPRESENTATION.objects) {
			var s = this.create(x, y, this.spriteKey, (this.spriteFrame ? this.spriteFrame + Math.abs(this._number) : null));
			var scale = this.size/(s.width > s.height ? s.width : s.height)*0.8;
			s.scale.set(scale);
			s.x = (!this.direction ? (this._number > 0 ? this.size * 0.8 : this.size * 1.2) : this.size)/2 - s.width/2;
			s.y = (this.direction ? (this._number > 0 ? this.size * 1.2 : this.size * 0.8) : this.size)/2 - s.height/2;

		} else if (this.representations[i] === GLOBAL.NUMBER_REPRESENTATION.numbers) {
			this.add(new NumberRepresentation(this._number, x, y, this.size/2, this.color));

		} else if (this.representations[i] === GLOBAL.NUMBER_REPRESENTATION.dice) {
			offset = this.calcOffset(12);
			this.add(new DiceRepresentation(useNum, x+offset.x, y+offset.y, this.size-offset.o, this.color));

		} else if (this.representations[i] === GLOBAL.NUMBER_REPRESENTATION.yesno) {
			this._number = this._number % 2;
			offset = this.size*0.1;
			this.add(new YesnoRepresentation(this._number, x + offset, y + offset, this.size - offset*2));
		}
	}
};

/**
 * Calculate the different offsets for the button (needed due to arrow in button).
 * @param {Number} offset - Offset from button edge (used like: this.size/offset).
 */
NumberButton.prototype.calcOffset = function (offset) {
	var t = {};
	t.o = this.size/offset;
	if (this.direction) { /* Up/Down */
		t.x = t.o*1.8;
		t.y = t.o*(this._number >= 0 ? 3.3 : 1);
	} else { /* Left/Right */
		t.x = t.o*(this._number >= 0 ? 1 : 3.3);
		t.y = t.o*2;
	}
	t.o *= 4;
	return t;
};

/**
 * Set the size of this button.
 * @param {Number} The new size.
 */
NumberButton.prototype.setSize = function (size) {
	GeneralButton.prototype.setSize.call(this, size || this.size);

	// If the button should expand horizontally it will be rotated.
	// So we always want to change height, not width.
	this.bg.height *= this.representations.length;

	return this;
};

/**
 * Set the direction of the background button.
 * @param {Boolean} val - True = up/down, false = left/right.
 */
NumberButton.prototype.setDirection = function (val) {
	this.direction = val;
	if (val) {
		this.bg.rotation = -Math.PI/2;
		this.bg.y += this.bg.width;
		this.bg.adjusted = this.bg.width;
	} else {
		this.bg.rotation = 0;
		this.bg.y -= this.bg.adjusted || 0;
	}

	if (this.number) {
		this.updateGraphics();
	}

	return this;
};<|endoftext|>


<commit_before>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300
//Added a comment that achieves no real goal.
if ( process.argv[ 2 ] && process.argv<commit_msg>Update character<commit_after>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300
//Added a comment that achieves no real goal.
if ( process.argv[ 2 ] && process.argv[<|endoftext|>


<commit_before>'use strict';

var Promise = require('es6-promise').Promise;

var Command = require('../../cli/command');

var services = require('../../services');

module.exports = new Command(
  'services',
  'list services for your org',
  function(ctx) {
    return new Promise(function(resolve) {
      resolve();
    });
  }
);
<commit_msg>Fix lint errors in 'ag services' base<commit_after>'use strict';

var Promise = require('es6-promise').Promise;

var Command = require('../../cli/command');

module.exports = new Command(
  'services',
  'list services for your org',
  function(/*ctx*/) {
    return new Promise(function(resolve) {
      resolve();
    });
  }
);
<|endoftext|>


<commit_before>'use strict';

var repl            =  require('repl')
  , path            =  require('path')
  , cardinal        =  require('cardinal')
  , util            =  require('util')
  , state           =  require('./lib/state')
  , config          =  require('./config/current')
  , initConfig      =  require('./config/init')
  , managePlugins   =  require('./lib/manage-plugins')
  , initWatcher     =  require('./lib/watcher-init')
  , feedEdits       =  require('./lib/feedEdits')
  , core            =  require('./lib/dox/core')
  , log             =  require('./lib/log')
  , instructions    =  require('./lib/instructions')
  , initBuiltins    =  require('./lib/builtins/init')
  , findexquire     =  require('./lib/findexquire')
  , stdin           =  process.stdin
  , stdout          =  process.stdout
  ;
function createRepl(stdin) {
  var r = repl.start({
        prompt          :  config.prompt || 'pad > '
      , input           :  stdin
      , output          :  stdout
      , ignoreUndefined :  true
      , useColors       :  true
      , useGlobal       :  true
      });
  log.repl = r;

  r.state = state;
  r.config = config;

  global.$repl = r;
  global.require = findexquire(path.join(process.cwd(), 'repl.js'), true);

  r.writer = function (s) {
    // i.e. Function.src returns the higlighted string at __replpad_print_raw__ which we just want to print as is
    var printRaw = s && s.__replpad_print_raw__;
    return printRaw || util.inspect(s, config.inspect.showHidden, config.inspect.depth, true);
  };

  return r;
}

function boot(stdin) {
  instructions();

  var repl = createRepl(stdin);
  state.__defineGetter__('repl', function () { return repl; });

  managePlugins();
  initBuiltins();

  // this step needs to happen last otherwise the `dox` getters are invoked prematurely and all core functions output
  core(repl);
}

module.exports = function repreprep(root) {

  initConfig();

  if (!root) {
    log.print('Watching no files since no path was specified.');
    return boot(stdin);
  }

  var watcher = initWatcher(root);
  watcher.on('initialized', function () {
    boot(stdin);
    var feedEdit = feedEdits(stdin, stdout);
    watcher.on('file-changed', feedEdit);

  });
};
<commit_msg>removing obsolete comment<commit_after>'use strict';

var repl            =  require('repl')
  , path            =  require('path')
  , cardinal        =  require('cardinal')
  , util            =  require('util')
  , state           =  require('./lib/state')
  , config          =  require('./config/current')
  , initConfig      =  require('./config/init')
  , managePlugins   =  require('./lib/manage-plugins')
  , initWatcher     =  require('./lib/watcher-init')
  , feedEdits       =  require('./lib/feedEdits')
  , core            =  require('./lib/dox/core')
  , log             =  require('./lib/log')
  , instructions    =  require('./lib/instructions')
  , initBuiltins    =  require('./lib/builtins/init')
  , findexquire     =  require('./lib/findexquire')
  , stdin           =  process.stdin
  , stdout          =  process.stdout
  ;
function createRepl(stdin) {
  var r = repl.start({
        prompt          :  config.prompt || 'pad > '
      , input           :  stdin
      , output          :  stdout
      , ignoreUndefined :  true
      , useColors       :  true
      , useGlobal       :  true
      });
  log.repl = r;

  r.state = state;
  r.config = config;

  global.$repl = r;
  global.require = findexquire(path.join(process.cwd(), 'repl.js'), true);

  r.writer = function (s) {
    // i.e. Function.src returns the higlighted string at __replpad_print_raw__ which we just want to print as is
    var printRaw = s && s.__replpad_print_raw__;
    return printRaw || util.inspect(s, config.inspect.showHidden, config.inspect.depth, true);
  };

  return r;
}

function boot(stdin) {
  instructions();

  var repl = createRepl(stdin);
  state.__defineGetter__('repl', function () { return repl; });

  managePlugins();
  initBuiltins();

  core(repl);
}

module.exports = function repreprep(root) {

  initConfig();

  if (!root) {
    log.print('Watching no files since no path was specified.');
    return boot(stdin);
  }

  var watcher = initWatcher(root);
  watcher.on('initialized', function () {
    boot(stdin);
    var feedEdit = feedEdits(stdin, stdout);
    watcher.on('file-changed', feedEdit);

  });
};
<|endoftext|>


<commit_before>var fs = require('fs');
var child_process = requir<commit_msg>Update character<commit_after>var fs = require('fs');
var child_process = require<|endoftext|>


<commit_before>var fs = require('fs');
var child_process = require(<commit_msg>Update character<commit_after>var fs = require('fs');
var child_process = require('<|endoftext|>


<commit_before>var mongoose = require('mongoose');
var Course = mongoose.model('Course');
var Event = mongoose.model('Event');
var Post = mongoose.model('Post');
var User = mongoose.model('User');
var Assignment = mongoose.model('Assignment');

var CourseCtrl = {
  init: function(app) {
    // ******** Course **********
    // GET list of courses
    app.get('/courses', function(req, res, next) {
      var filter = {};
      Course.find({}, filter)
        .exec(function(err, courses) {
          if (err) return next(err);
          return res.json(courses);
      });
    });

    // Create new course
    app.post('/courses', function(req, res, next) {
      var newCourse = new Course({
        name: req.body.name
      });
      newCourse.save(function(err) {
        if (err) return next(err);
        return res.json(201, newCourse);
      });
    });

    // Get course by id
    app.get('/courses/:courseId', function(req, res, next) {
      var query = {
        _id: req.params.courseId
      };
      Course.findOne(query)
        .exec(function(err, course) {
          if (err) return next(err);
          if (!course) return res.end(404);
          return res.json(course);
        });
    });

    // Register a User to a Course (add user to 'students' set)
    app.post('/courses/:courseId/register', function(req, res, next) {
      var student = {
        userId: req.body.studentId
      };
      var update = { $addToSet: { students: student } };
      var query = { _id: req.params.courseId };
      Course.findOneAndUpdate(query, update)
        .exec(function(err, course) {
          if (err) return next(err);
          if (!course) return next(null, false);
          res.status(200);
          return res.end();
        });
    });

    // ******** Course Timeline Posts **********
    // Create new post
    app.post('/courses/:courseId/posts', function(req, res, next) {
      var newPost = new Post({
        date: (new Date()).getTime(),
        text: req.body.text
      });
      var query = { _id: req.params.courseId };
      var update = { $push: { posts: newPost } };
      var options = { "new": true };
      Course.findOneAndUpdate(query, update, options)
        .exec(function(err, course) {
          if (err) return next(err);
          return res.json(201, newPost);
        });
    });

    // Get posts by course ID
    // @TODO pagination
    app.get('/courses/:courseId/posts', function(req, res, next) {
      var filter = { posts: true };
      var startDate = req.body.startDate || (new Date()).getTime();
      var query = { _id: req.params.courseId };
      Course.findOne(query, filter)
        .exec(function(err, course) {
          if (err) return next(err);
          if (!course) return res.end(404);
          return res.json(course.posts || []);
        });
    });

    // ******** Course Events **********
    // Create new event
    app.post('/courses/:courseId/events', function(req, res, next) {
      var newEvent = new Event({
        startDate: req.body.startDate,
        endDate: req.body.endDate,
        description: req.body.description,
        title: req.body.title
      });
      var update = { $push: { events: newEvent } };
      var options = { "new": true };
      var query = { _id: req.params.courseId };
      Course.findOneAndUpdate(query, update, options)
        .exec(function(err, course) {
          if (err) return next(err);
          return res.json(201, newEvent);
        });
    });

    // Get events by course ID
    // @TODO pagination
    // @TODO query by dates
    app.get('/courses/:courseId/events', function(req, res, next) {
      var filter = { events: true };
      var query = { _id: req.params.courseId };
      Course.findOne(query, filter)
        .exec(function(err, course) {
          if (err) return next(err);
          if (!course) return res.end(404);
          return res.json(course.events || []);
        });
    });

    // ******** Course Assignments **********
    // Get assignments by course ID
    // @TODO pagination
    app.get('/courses/:courseId/assignments', function(req, res, next) {
      var filter = { assignment: true };
      var startDate = req.body.startDate || (new Date()).getTime();
      var query = { _id: req.params.courseId };
      Course.findOne(query, filter)
        .exec(function(err, course) {
          if (err) return next(err);
          if (!course) return res.end(404);
          return res.json(course.assignments || []);
        });
    });

    app.post('/courses/:courseId/assignments', function(req, res, next) {
      var newAssignment = new Assignment({
        due: req.body.due,
        description: req.body.description,
        posted: (new Date()).getTime()
      });
      var query = { _id: req.params.courseId };
      var update = { $push: { assignments: newAssignment } };
      Course.findOneAndUpdate(query, update)
        .exec(function(err, course) {
          if (err) return next(err);
          if (!course) return res.end(404);
          return res.json(newAssignment);
        });
    });

    // Get exams by course ID
    // @TODO pagination
    app.get('/courses/:courseId/exams', function(req, res, next) {
      var filter = { exams: true };
      var startDate = req.body.startDate || (new Date()).getTime();
      var query = { _id: req.params.courseId };
      Course.findOne(query, filter)
        .exec(function(err, course) {
          if (err) return next(err);
          if (!course) return res.end(404);
          return res.json(course.exams || []);
        });
    });

    // Get notes by course ID
    // @TODO pagination
    app.get('/courses/:courseId/notes', function(req, res, next) {
      var filter = { notes: true };
      var startDate = req.body.startDate || (new Date()).getTime();
      var query = { _id: req.params.courseId };
      Course.findOne(query, filter)
        .exec(function(err, course) {
          if (err) return next(err);
          if (!course) return res.end(404);
          return res.json(course.notes || []);
        });
    });

    // Get quizzes by course ID
    // @TODO pagination
    app.get('/courses/:courseId/quizzes', function(req, res, next) {
      var filter = { quizzes: true };
      var startDate = req.body.startDate || (new Date()).getTime();
      var query = { _id: req.params.courseId };
      Course.findOne(query, filter)
        .exec(function(err, course) {
          if (err) return next(err);
          if (!course) return res.end(404);
          return res.json(course.quizzes || []);
        });
    });
  }
};

module.exports = CourseCtrl;
<commit_msg>Add GET request for assignments  by courseId<commit_after>var mongoose = require('mongoose');
var Course = mongoose.model('Course');
var Event = mongoose.model('Event');
var Post = mongoose.model('Post');
var User = mongoose.model('User');
var Assignment = mongoose.model('Assignment');

var CourseCtrl = {
  init: function(app) {
    // ******** Course **********
    // GET list of courses
    app.get('/courses', function(req, res, next) {
      var filter = {};
      Course.find({}, filter)
        .exec(function(err, courses) {
          if (err) return next(err);
          return res.json(courses);
      });
    });

    // Create new course
    app.post('/courses', function(req, res, next) {
      var newCourse = new Course({
        name: req.body.name
      });
      newCourse.save(function(err) {
        if (err) return next(err);
        return res.json(201, newCourse);
      });
    });

    // Get course by id
    app.get('/courses/:courseId', function(req, res, next) {
      var query = {
        _id: req.params.courseId
      };
      Course.findOne(query)
        .exec(function(err, course) {
          if (err) return next(err);
          if (!course) return res.end(404);
          return res.json(course);
        });
    });

    // Register a User to a Course (add user to 'students' set)
    app.post('/courses/:courseId/register', function(req, res, next) {
      var student = {
        userId: req.body.studentId
      };
      var update = { $addToSet: { students: student } };
      var query = { _id: req.params.courseId };
      Course.findOneAndUpdate(query, update)
        .exec(function(err, course) {
          if (err) return next(err);
          if (!course) return next(null, false);
          res.status(200);
          return res.end();
        });
    });

    // ******** Course Timeline Posts **********
    // Create new post
    app.post('/courses/:courseId/posts', function(req, res, next) {
      var newPost = new Post({
        date: (new Date()).getTime(),
        text: req.body.text
      });
      var query = { _id: req.params.courseId };
      var update = { $push: { posts: newPost } };
      var options = { "new": true };
      Course.findOneAndUpdate(query, update, options)
        .exec(function(err, course) {
          if (err) return next(err);
          return res.json(201, newPost);
        });
    });

    // Get posts by course ID
    // @TODO pagination
    app.get('/courses/:courseId/posts', function(req, res, next) {
      var filter = { posts: true };
      var startDate = req.body.startDate || (new Date()).getTime();
      var query = { _id: req.params.courseId };
      Course.findOne(query, filter)
        .exec(function(err, course) {
          if (err) return next(err);
          if (!course) return res.end(404);
          return res.json(course.posts || []);
        });
    });

    // ******** Course Events **********
    // Create new event
    app.post('/courses/:courseId/events', function(req, res, next) {
      var newEvent = new Event({
        startDate: req.body.startDate,
        endDate: req.body.endDate,
        description: req.body.description,
        title: req.body.title
      });
      var update = { $push: { events: newEvent } };
      var options = { "new": true };
      var query = { _id: req.params.courseId };
      Course.findOneAndUpdate(query, update, options)
        .exec(function(err, course) {
          if (err) return next(err);
          return res.json(201, newEvent);
        });
    });

    // Get events by course ID
    // @TODO pagination
    // @TODO query by dates
    app.get('/courses/:courseId/events', function(req, res, next) {
      var filter = { events: true };
      var query = { _id: req.params.courseId };
      Course.findOne(query, filter)
        .exec(function(err, course) {
          if (err) return next(err);
          if (!course) return res.end(404);
          return res.json(course.events || []);
        });
    });

    // ******** Course Assignments **********
    // Get assignments by course ID
    // @TODO pagination
    app.get('/courses/:courseId/assignments', function(req, res, next) {
      var filter = { assignments: true };
      var query = { _id: req.params.courseId };
      Course.findOne(query, filter)
        .exec(function(err, course) {
          if (err) return next(err);
          if (!course) return res.end(404);
          return res.json(course.assignments || []);
        });
    });

    app.post('/courses/:courseId/assignments', function(req, res, next) {
      var newAssignment = new Assignment({
        due: req.body.due,
        description: req.body.description,
        posted: (new Date()).getTime()
      });
      var query = { _id: req.params.courseId };
      var update = { $push: { assignments: newAssignment } };
      Course.findOneAndUpdate(query, update)
        .exec(function(err, course) {
          if (err) return next(err);
          if (!course) return res.end(404);
          return res.json(newAssignment);
        });
    });

    // Get exams by course ID
    // @TODO pagination
    app.get('/courses/:courseId/exams', function(req, res, next) {
      var filter = { exams: true };
      var startDate = req.body.startDate || (new Date()).getTime();
      var query = { _id: req.params.courseId };
      Course.findOne(query, filter)
        .exec(function(err, course) {
          if (err) return next(err);
          if (!course) return res.end(404);
          return res.json(course.exams || []);
        });
    });

    // Get notes by course ID
    // @TODO pagination
    app.get('/courses/:courseId/notes', function(req, res, next) {
      var filter = { notes: true };
      var startDate = req.body.startDate || (new Date()).getTime();
      var query = { _id: req.params.courseId };
      Course.findOne(query, filter)
        .exec(function(err, course) {
          if (err) return next(err);
          if (!course) return res.end(404);
          return res.json(course.notes || []);
        });
    });

    // Get quizzes by course ID
    // @TODO pagination
    app.get('/courses/:courseId/quizzes', function(req, res, next) {
      var filter = { quizzes: true };
      var startDate = req.body.startDate || (new Date()).getTime();
      var query = { _id: req.params.courseId };
      Course.findOne(query, filter)
        .exec(function(err, course) {
          if (err) return next(err);
          if (!course) return res.end(404);
          return res.json(course.quizzes || []);
        });
    });
  }
};

module.exports = CourseCtrl;
<|endoftext|>


<commit_before>import AuthenticatedRoute from 'ghost-admin/routes/authenticated';
import classic from 'ember-classic-decorator';
import {action} from '@ember/object';
import {inject as service} from '@ember/service';

@classic
export default class MembersRoute extends AuthenticatedRoute {
    @service router;

    _requiresBackgroundRefresh = true;

    init() {
        super.init(...arguments);
        this.router.on('routeWillChange', (transition) => {
            this.showUnsavedChangesModal(transition);
        });
    }

    beforeModel() {
        super.beforeModel(...arguments);
        if (!this.session.user.isAdmin) {
            return this.transitionTo('home');
        }
    }

    model(params) {
        this._requiresBackgroundRefresh = false;

        if (params.member_id) {
            return this.store.queryRecord('member', {id: params.member_id, include: 'email_recipients,products'});
        } else {
            return this.store.createRecord('member');
        }
    }

    setupController(controller, member) {
        super.setupController(...arguments);
        if (this._requiresBackgroundRefresh) {
            controller.fetchMemberTask.perform(member.get('id'));
        }
    }

    deactivate() {
        super.deactivate(...arguments);
        // clean up newly created records and revert unsaved changes to existing
        this.controller.member.rollbackAttributes();
        this._requiresBackgroundRefresh = true;
    }

    @action
    save() {
        this.controller.save();
    }

    titleToken() {
        return this.controller.member.name;
    }

    showUnsavedChangesModal(transition) {
        if (transition.from && transition.from.name === this.routeName && transition.targetName) {
            let {controller} = this;

            // member.changedAttributes is always true for new members but number of changed attrs is reliable
            let isChanged = Object.keys(controller.member.changedAttributes()).length > 0;

            if (!controller.member.isDeleted && isChanged) {
                transition.abort();
                controller.toggleUnsavedChangesModal(transition);
                return;
            }
        }
    }
}
<commit_msg>Removed `@classic` decorator from `member` route<commit_after>import AuthenticatedRoute from 'ghost-admin/routes/authenticated';
import {action} from '@ember/object';
import {inject as service} from '@ember/service';

export default class MembersRoute extends AuthenticatedRoute {
    @service router;

    _requiresBackgroundRefresh = true;

    constructor() {
        super(...arguments);
        this.router.on('routeWillChange', (transition) => {
            this.showUnsavedChangesModal(transition);
        });
    }

    beforeModel() {
        super.beforeModel(...arguments);
        if (!this.session.user.isAdmin) {
            return this.transitionTo('home');
        }
    }

    model(params) {
        this._requiresBackgroundRefresh = false;

        if (params.member_id) {
            return this.store.queryRecord('member', {id: params.member_id, include: 'email_recipients,products'});
        } else {
            return this.store.createRecord('member');
        }
    }

    setupController(controller, member) {
        super.setupController(...arguments);
        if (this._requiresBackgroundRefresh) {
            // `member` is passed directly in `<LinkTo>` so it can be a proxy
            // object used by the sparse list requiring the use of .get()
            controller.fetchMemberTask.perform(member.get('id'));
        }
    }

    deactivate() {
        super.deactivate(...arguments);
        // clean up newly created records and revert unsaved changes to existing
        this.controller.member.rollbackAttributes();
        this._requiresBackgroundRefresh = true;
    }

    @action
    save() {
        this.controller.save();
    }

    titleToken() {
        return this.controller.member.name;
    }

    showUnsavedChangesModal(transition) {
        if (transition.from && transition.from.name === this.routeName && transition.targetName) {
            let {controller} = this;

            // member.changedAttributes is always true for new members but number of changed attrs is reliable
            let isChanged = Object.keys(controller.member.changedAttributes()).length > 0;

            if (!controller.member.isDeleted && isChanged) {
                transition.abort();
                controller.toggleUnsavedChangesModal(transition);
                return;
            }
        }
    }
}
<|endoftext|>


<commit_before>! function(t) {
  function i(i, a) {
    this.settings = t.extend(!0, e, a), this.$context = i, this.domAudio = this.$context.find("audio")[0], this.$domPlaylist = this.$context.find(".jAudio--playlist"), this.$domControls = this.$context.find(".jAudio--controls"), this.$domVolumeBar = this.$context.find(".jAudio--volume"), this.$domDetails = this.$context.find(".jAudio--details"), this.$domStatusBar = this.$context.find(".jAudio--status-bar"), this.$domProgressBar = this.$context.find(".jAudio--progress-bar-wrapper"), this.$domTime = this.$context.find(".jAudio--time"), this.$domElapsedTime = this.$context.find(".jAudio--time-elapsed"), this.$domTotalTime = this.$context.find(".jAudio--time-total"), this.$domThumb = this.$context.find(".jAudio--thumb"), this.currentState = "pause", this.currentTrack = this.settings.defaultTrack, this.currentElapsedTime = void 0, this.timer = void 0, this.init()
  }
  var a = "jAudio",
    e = {
      playlist: [],
      defaultAlbum: void 0,
      defaultArtist: void 0,
      defaultTrack: 0,
      autoPlay: !1,
      debug: !1
    };
  i.prototype = {
    init: function() {
      var t = this;
      t.renderPlaylist(), t.preLoadTrack(), t.highlightTrack(), t.updateTotalTime(), t.events(), t.debug(), t.domAudio.volume = .05
    },
    play: function(t) {
      var i = this;
      i.domAudio.play(), "play" !== i.currentState && (clearInterval(i.timer), i.timer = setInterval(i.run.bind(i), 50), i.currentState = "play", t.data("action", "pause"), t.removeClass("jAudio--control-play"), t.addClass("jAudio--control-pause"), t.toggleClass("active"))
    },
    pause: function(t) {
      var i = this;
      i.domAudio.pause(), clearInterval(i.timer), i.currentState = "pause", t.data("action", "play"), t.removeClass("jAudio--control-pause"), t.addClass("jAudio--control-play"), t.toggleClass("active")
    },
    stop: function() {
      var t = this;
      t.domAudio.pause(), t.domAudio.currentTime = 0, t.animateProgressBarPosition(), clearInterval(t.timer), t.updateElapsedTime(), t.currentState = "stop"
    },
    prev: function() {
      var t, i = this;
      t = 0 === i.currentTrack ? i.settings.playlist.length - 1 : i.currentTrack - 1, i.changeTrack(t)
    },
    next: function() {
      var t, i = this;

      var isLast = i.settings.playlist.length - 1;
      if (isLast === 0) {
        console.log('you just hit next on the last item');
      }

      console.log(isLast);
      t = i.currentTrack === i.settings.playlist.length - 1 ? 0 : i.currentTrack + 1, i.changeTrack(t)
    },
    preLoadTrack: function() {
      var t = this,
        i = t.settings.defaultTrack;
      t.changeTrack(i), t.stop()
    },
    changeTrack: function(t) {
      var i = this;
      i.currentTrack = t, i.domAudio.src = i.settings.playlist[t].file, ("play" === i.currentState || i.settings.autoPlay) && i.play(), i.highlightTrack(), i.updateThumb(), i.renderDetails()
    },
    events: function() {
      var i = this;
      i.$domControls.on("click", ".jAudio--control", function() {
        var a = t(this),
          e = a.data("action");
        switch (e) {
          case "prev":
            i.prev.call(i, a);
            break;
          case "next":
            i.next.call(i, a);
            break;
          case "pause":
            i.pause.call(i, a);
            break;
          case "stop":
            i.stop.call(i, a);
            break;
          case "play":
            i.play.call(i, a)
        }
      }), i.$domPlaylist.on("click", ".jAudio--playlist-item", function() {
        var a = t(this),
          e = (a.data("track"), a.index());
        i.currentTrack !== e && i.changeTrack(e)
      }), i.$domProgressBar.on("click", function(t) {
        i.updateProgressBar(t), i.updateElapsedTime()
      }), t(i.domAudio).on("loadedmetadata", function() {
        i.animateProgressBarPosition.call(i), i.updateElapsedTime.call(i), i.updateTotalTime.call(i)
      })
    },
    getAudioSeconds: function(t) {
      var i = this,
        t = t % 60;
      return t = i.addZero(Math.floor(t), 2), t = 60 > t ? t : "00"
    },
    getAudioMinutes: function(t) {
      var i = this,
        t = t / 60;
      return t = i.addZero(Math.floor(t), 2), t = 60 > t ? t : "00"
    },
    addZero: function(t, i) {
      for (var t = String(t); t.length  a && "0" === t[0];) t = t.substr(1, t.length), a++;
      return t
    },
    highlightTrack: function() {
      var t = this,
        i = t.$domPlaylist.children(),
        a = "active";
      i.removeClass(a), i.eq(t.currentTrack).addClass(a)
    },
    renderDetails: function() {
      var t = this,
        i = t.settings.playlist[t.currentTrack],
        a = (i.file, i.thumb, i.trackName),
        e = i.trackArtist,
        r = (i.trackAlbum, "");
      r += "
", r += "" + a + "", r += "" + e + "", r += "
", t.$domDetails.html(r)
    },
    renderPlaylist: function() {
      var i = this,
        a = "";
      t.each(i.settings.playlist, function(t, i) {
        {
          var e = i.file,
            r = i.category_thumb,
            o = i.trackName,
            s = i.trackArtist;
          i.trackAlbum
        }
        trackDuration = "00:00", a += "
", a += "
<object type='image/svg+xml' data='" + r + "'></object>
", a += "
", a += "
" + o + "
", a += "
" + s + "
", a += "
", a += "
"
      }), i.$domPlaylist.html(a)
    },
    run: function() {
      var t = this;
      t.animateProgressBarPosition(), t.updateElapsedTime(), t.domAudio.ended && t.next()
    },
    animateProgressBarPosition: function() {
      var t = this,
        i = 100 * t.domAudio.currentTime / t.domAudio.duration + "%",
        a = {
          width: i
        };
      t.$domProgressBar.children().eq(0).css(a)
    },
    updateProgressBar: function(t) {
      var i, a, e, r = this;
      t.offsetX && (i = t.offsetX), void 0 === i && t.layerX && (i = t.layerX), a = i / r.$domProgressBar.width(), e = r.domAudio.duration * a, r.domAudio.currentTime = e, r.animateProgressBarPosition()
    },
    updateElapsedTime: function() {
      var t = this,
        i = t.domAudio.currentTime,
        a = t.getAudioMinutes(i),
        e = t.getAudioSeconds(i),
        r = a + ":" + e;
      t.$domElapsedTime.text(r)
    },
    updateTotalTime: function() {
      var t = this,
        i = t.domAudio.duration,
        a = t.getAudioMinutes(i),
        e = t.getAudioSeconds(i),
        r = a + ":" + e;
      t.$domTotalTime.text(r)
    },
    updateThumb: function() {
      var t = this,
        i = t.settings.playlist[t.currentTrack].thumb,
        a = {
          "background": "linear-gradient(rgba(0,0,0,.3), rgba(0,0,0,.3)), url(" + i + ")",
          "background-repeat": "no-repeat",
          "background-size": "cover",
          "background-position": "center center"
        };
      t.$domThumb.css(a)
    },
    debug: function() {
      var t = this;
      t.settings.debug && console.log(t.settings)
    }
  }, t.fn[a] = function(a) {
    var e = function() {
      return new i(t(this), a)
    };
    t(this).each(e)
  }
}(jQuery);
<commit_msg>WIP last audio podcast listening<commit_after>! function(t) {
  function i(i, a) {
    this.settings = t.extend(!0, e, a), this.$context = i, this.domAudio = this.$context.find("audio")[0], this.$domPlaylist = this.$context.find(".jAudio--playlist"), this.$domControls = this.$context.find(".jAudio--controls"), this.$domVolumeBar = this.$context.find(".jAudio--volume"), this.$domDetails = this.$context.find(".jAudio--details"), this.$domStatusBar = this.$context.find(".jAudio--status-bar"), this.$domProgressBar = this.$context.find(".jAudio--progress-bar-wrapper"), this.$domTime = this.$context.find(".jAudio--time"), this.$domElapsedTime = this.$context.find(".jAudio--time-elapsed"), this.$domTotalTime = this.$context.find(".jAudio--time-total"), this.$domThumb = this.$context.find(".jAudio--thumb"), this.currentState = "pause", this.currentTrack = this.settings.defaultTrack, this.currentElapsedTime = void 0, this.timer = void 0, this.init()
  }
  var a = "jAudio",
    e = {
      playlist: [],
      defaultAlbum: void 0,
      defaultArtist: void 0,
      defaultTrack: 0,
      autoPlay: !1,
      debug: !1
    };
  i.prototype = {
    init: function() {
      var t = this;
      t.renderPlaylist(), t.preLoadTrack(), t.highlightTrack(), t.updateTotalTime(), t.events(), t.debug(), t.domAudio.volume = .05
    },
    play: function(t) {
      var i = this;
      i.domAudio.play(), "play" !== i.currentState && (clearInterval(i.timer), i.timer = setInterval(i.run.bind(i), 50), i.currentState = "play", t.data("action", "pause"), t.removeClass("jAudio--control-play"), t.addClass("jAudio--control-pause"), t.toggleClass("active"))
    },
    pause: function(t) {
      var i = this;
      i.domAudio.pause(), clearInterval(i.timer), i.currentState = "pause", t.data("action", "play"), t.removeClass("jAudio--control-pause"), t.addClass("jAudio--control-play"), t.toggleClass("active")
    },
    stop: function() {
      var t = this;
      t.domAudio.pause(), t.domAudio.currentTime = 0, t.animateProgressBarPosition(), clearInterval(t.timer), t.updateElapsedTime(), t.currentState = "stop"
    },
    prev: function() {
      var t, i = this;
      t = 0 === i.currentTrack ? i.settings.playlist.length - 1 : i.currentTrack - 1, i.changeTrack(t)
    },
    next: function() {
      var t, i = this;

      console.log('asdf');
      console.log(i.currentTrack)
      var isLast = i.settings.playlist.length - 1;
      if (isLast === 0) {
        console.log('you just hit next on the last item');
      }
      console.log(isLast);
      t = i.currentTrack === i.settings.playlist.length - 1 ? 0 : i.currentTrack + 1, i.changeTrack(t)
    },
    preLoadTrack: function() {
      var t = this,
        i = t.settings.defaultTrack;
      t.changeTrack(i), t.stop()
    },
    changeTrack: function(t) {
      var i = this;
      i.currentTrack = t, i.domAudio.src = i.settings.playlist[t].file, ("play" === i.currentState || i.settings.autoPlay) && i.play(), i.highlightTrack(), i.updateThumb(), i.renderDetails()
    },
    events: function() {
      var i = this;
      i.$domControls.on("click", ".jAudio--control", function() {
        var a = t(this),
          e = a.data("action");
        switch (e) {
          case "prev":
            i.prev.call(i, a);
            break;
          case "next":
            i.next.call(i, a);
            break;
          case "pause":
            i.pause.call(i, a);
            break;
          case "stop":
            i.stop.call(i, a);
            break;
          case "play":
            i.play.call(i, a)
        }
      }), i.$domPlaylist.on("click", ".jAudio--playlist-item", function() {
        var a = t(this),
          e = (a.data("track"), a.index());
        i.currentTrack !== e && i.changeTrack(e)
      }), i.$domProgressBar.on("click", function(t) {
        i.updateProgressBar(t), i.updateElapsedTime()
      }), t(i.domAudio).on("loadedmetadata", function() {
        i.animateProgressBarPosition.call(i), i.updateElapsedTime.call(i), i.updateTotalTime.call(i)
      })
    },
    getAudioSeconds: function(t) {
      var i = this,
        t = t % 60;
      return t = i.addZero(Math.floor(t), 2), t = 60 > t ? t : "00"
    },
    getAudioMinutes: function(t) {
      var i = this,
        t = t / 60;
      return t = i.addZero(Math.floor(t), 2), t = 60 > t ? t : "00"
    },
    addZero: function(t, i) {
      for (var t = String(t); t.length  a && "0" === t[0];) t = t.substr(1, t.length), a++;
      return t
    },
    highlightTrack: function() {
      var t = this,
        i = t.$domPlaylist.children(),
        a = "active";
      i.removeClass(a), i.eq(t.currentTrack).addClass(a)
    },
    renderDetails: function() {
      var t = this,
        i = t.settings.playlist[t.currentTrack],
        a = (i.file, i.thumb, i.trackName),
        e = i.trackArtist,
        r = (i.trackAlbum, "");
      r += "
", r += "" + a + "", r += "" + e + "", r += "
", t.$domDetails.html(r)
    },
    renderPlaylist: function() {
      var i = this,
        a = "";
      t.each(i.settings.playlist, function(t, i) {
        {
          var e = i.file,
            r = i.category_thumb,
            o = i.trackName,
            s = i.trackArtist;
          i.trackAlbum
        }
        trackDuration = "00:00", a += "
", a += "
<object type='image/svg+xml' data='" + r + "'></object>
", a += "
", a += "
" + o + "
", a += "
" + s + "
", a += "
", a += "
"
      }), i.$domPlaylist.html(a)
    },
    run: function() {
      var t = this;
      t.animateProgressBarPosition(), t.updateElapsedTime(), t.domAudio.ended && t.next()
    },
    animateProgressBarPosition: function() {
      var t = this,
        i = 100 * t.domAudio.currentTime / t.domAudio.duration + "%",
        a = {
          width: i
        };
      t.$domProgressBar.children().eq(0).css(a)
    },
    updateProgressBar: function(t) {
      var i, a, e, r = this;
      t.offsetX && (i = t.offsetX), void 0 === i && t.layerX && (i = t.layerX), a = i / r.$domProgressBar.width(), e = r.domAudio.duration * a, r.domAudio.currentTime = e, r.animateProgressBarPosition()
    },
    updateElapsedTime: function() {
      var t = this,
        i = t.domAudio.currentTime,
        a = t.getAudioMinutes(i),
        e = t.getAudioSeconds(i),
        r = a + ":" + e;
      t.$domElapsedTime.text(r)
    },
    updateTotalTime: function() {
      var t = this,
        i = t.domAudio.duration,
        a = t.getAudioMinutes(i),
        e = t.getAudioSeconds(i),
        r = a + ":" + e;
      t.$domTotalTime.text(r)
    },
    updateThumb: function() {
      var t = this,
        i = t.settings.playlist[t.currentTrack].thumb,
        a = {
          "background": "linear-gradient(rgba(0,0,0,.3), rgba(0,0,0,.3)), url(" + i + ")",
          "background-repeat": "no-repeat",
          "background-size": "cover",
          "background-position": "center center"
        };
      t.$domThumb.css(a)
    },
    debug: function() {
      var t = this;
      t.settings.debug && console.log(t.settings)
    }
  }, t.fn[a] = function(a) {
    var e = function() {
      return new i(t(this), a)
    };
    t(this).each(e)
  }
}(jQuery);
<|endoftext|>


<commit_before>require('dotenv').config();
const express = require('express');
const router = express.Router();
const fetch = require('node-fetch');
const hbs = require('hbs');
const co = require('co');

const Airtable = require('airtable');
Airtable.configure({
  endpointUrl: 'https://api.airtable.com',
  apiKey: process.env.AIRTABLE_API_KEY
});
const base = Airtable.base(process.env.AIRTABLE_APP_ID);

hbs.registerHelper('concat', (...args) => args.slice(0, -1).join(''));
hbs.registerHelper("inc", value => parseInt(value) + 1);

function *getWotDDefinition(wotd) {
  const b = yield fetch('https://od-api.oxforddictionaries.com/api/v1/entries/en/' + wotd, {
      headers: {
        app_id: process.env.OED_APP_ID,
        app_key: process.env.OED_APP_KEY
      }
    });

  const j = yield b.json();

  return j.results[0];
}

router.get('/wotd', function (req, res, next) {
  co(function*() {
    try {
      let defn = yield getWotDDefinition('ace');
      res.send(defn);
    } catch (err) {
      console.error (err);
    }
  });
});

async function getWotDDefinition2(wotd) {
  const b = await fetch('https://od-api.oxforddictionaries.com/api/v1/entries/en/' + wotd, {
      headers: {
        app_id: process.env.OED_APP_ID,
        app_key: process.env.OED_APP_KEY
      }
    });

  const j = await b.json();

  return j.results[0];
}

router.get('/wotd2', function (req, res, next) {
  (async function() {
    const r = await getWotDDefinition2('ace')
    res.send(r);
  })();

});

router.get('/', function (req, res, next) {
  const meetingDetails = {};

  const p1 = base('Meetings').select({ view: 'Grid view' }).all().then(meetingRecords => {
    const meeting = meetingRecords[0];
    const word = meeting.get('Word of the Day');
    const location = meeting.get('Location');
    const date = new Date(meeting.get('Date and Time')).toLocaleDateString();
    const topic = meeting.get('Topic');

    meetingDetails.wotd = word;
    meetingDetails.location = location;
    meetingDetails.date = date;
    meetingDetails.topic = topic;

    const wotdP = fetch('https://od-api.oxforddictionaries.com/api/v1/entries/en/' + word, {
      headers: {
        app_id: process.env.OED_APP_ID,
        app_key: process.env.OED_APP_KEY
      }
    });

    // Get the basic functionaries
    const tmP = base('Members').find(meeting.get('Toastmaster'));
    const topicmP = base('Members').find(meeting.get('TopicsMaster'));
    const geP = base('Members').find(meeting.get('General Evaluator'));
    const timerP = base('Members').find(meeting.get('Timer'));
    const ahP = base('Members').find(meeting.get('Ah-counter'));

    // Now to get the speeches. These are a little tricker because (a) it's an array, and (b) there's more nested data to be fetched within these.
    const speechPs = meeting.get('Speeches').map(speechID => base('Speeches').find(speechID));

    return Promise.all([wotdP, tmP, topicmP, geP, timerP, ahP, ...speechPs]);

  }).then(([wotdBody, toastmaster, topicsmaster, genevalEval, timer, ahCounter, ...speeches]) => {

    // These details are available now, so stash them in shared state.
    meetingDetails.toastmaster = toastmaster.get('Name');
    meetingDetails.topicsmaster = topicsmaster.get('Name');
    meetingDetails.generalEvaluator = genevalEval.get('Name');
    meetingDetails.timer = timer.get('Name');
    meetingDetails.ahCounter = ahCounter.get('Name');
    meetingDetails.speeches = [];

    // Some more things require more fetching, so Promisify these now. E.g., the WOTD response which is just a body just now.
    const promises = [wotdBody.json()];

    speeches.forEach(speech => {
      const speechDetails = {};

      speechDetails.title = speech.get('Title');

      promises.push(base('Members').find(speech.get('Speaker')));
      promises.push(base('Members').find(speech.get('Evaluator')));
      promises.push(base('Projects').find(speech.get('Project')));

      meetingDetails.speeches.push(speechDetails);
    });

    return Promise.all(promises);

  }).then(([wotdDefn, ...speechDeets]) => {
    // Now we have everything we need to fill in the meeting details.
    meetingDetails.wotdDefinition = wotdDefn.results[0];

    // FIXME speechDeets has an implicit ordering of (speaker, evaluator). There's doubtless a better way.
    // UGH recursion can't be the best way of doing this. This is like C :(
    const projectPs = [];

    const t = function (sePair, i) {
      if (sePair.length == 0) return;

      let [s, e, p, ...rest] = sePair;
      meetingDetails.speeches[i].speaker = s.get('Name');
      meetingDetails.speeches[i].evaluator = e.get('Name');
      meetingDetails.speeches[i].project = p.get('Project ID');
      meetingDetails.speeches[i].time = p.get('Time');

      t(rest, i+1);
    }

    t(speechDeets, 0);

    res.render('agenda', {
      title: 'Dolby Speakers Meeting',
      meeting: meetingDetails
    });
  }).catch(err => {
    // throw new Error(err);
  });
});

module.exports = router;<commit_msg>Starting to get the hang of asyncs.<commit_after>require('dotenv').config();
const express = require('express');
const router = express.Router();
const fetch = require('node-fetch');
const hbs = require('hbs');
const co = require('co');

const Airtable = require('airtable');
Airtable.configure({
  endpointUrl: 'https://api.airtable.com',
  apiKey: process.env.AIRTABLE_API_KEY
});
const base = Airtable.base(process.env.AIRTABLE_APP_ID);

hbs.registerHelper('concat', (...args) => args.slice(0, -1).join(''));
hbs.registerHelper("inc", value => parseInt(value) + 1);

async function getWotDDefinition(wotd) {
  const b = await fetch('https://od-api.oxforddictionaries.com/api/v1/entries/en/' + wotd, {
      headers: {
        app_id: process.env.OED_APP_ID,
        app_key: process.env.OED_APP_KEY
      }
    });

  const j = await b.json();

  return j.results[0];
}

router.get('/wotd', function (req, res, next) {
  (async () => {
    try {
      const r = await getWotDDefinition('ace')
      res.send(r);
    } catch (err) {
      console.log(err);
    }
  })();
});

router.get('/', function (req, res, next) {
  const meetingDetails = {};

  const p1 = base('Meetings').select({ view: 'Grid view' }).all().then(meetingRecords => {
    const meeting = meetingRecords[0];
    const word = meeting.get('Word of the Day');
    const location = meeting.get('Location');
    const date = new Date(meeting.get('Date and Time')).toLocaleDateString();
    const topic = meeting.get('Topic');

    meetingDetails.wotd = word;
    meetingDetails.location = location;
    meetingDetails.date = date;
    meetingDetails.topic = topic;

    const wotdP = fetch('https://od-api.oxforddictionaries.com/api/v1/entries/en/' + word, {
      headers: {
        app_id: process.env.OED_APP_ID,
        app_key: process.env.OED_APP_KEY
      }
    });

    // Get the basic functionaries
    const tmP = base('Members').find(meeting.get('Toastmaster'));
    const topicmP = base('Members').find(meeting.get('TopicsMaster'));
    const geP = base('Members').find(meeting.get('General Evaluator'));
    const timerP = base('Members').find(meeting.get('Timer'));
    const ahP = base('Members').find(meeting.get('Ah-counter'));

    // Now to get the speeches. These are a little tricker because (a) it's an array, and (b) there's more nested data to be fetched within these.
    const speechPs = meeting.get('Speeches').map(speechID => base('Speeches').find(speechID));

    return Promise.all([wotdP, tmP, topicmP, geP, timerP, ahP, ...speechPs]);

  }).then(([wotdBody, toastmaster, topicsmaster, genevalEval, timer, ahCounter, ...speeches]) => {

    // These details are available now, so stash them in shared state.
    meetingDetails.toastmaster = toastmaster.get('Name');
    meetingDetails.topicsmaster = topicsmaster.get('Name');
    meetingDetails.generalEvaluator = genevalEval.get('Name');
    meetingDetails.timer = timer.get('Name');
    meetingDetails.ahCounter = ahCounter.get('Name');
    meetingDetails.speeches = [];

    // Some more things require more fetching, so Promisify these now. E.g., the WOTD response which is just a body just now.
    const promises = [wotdBody.json()];

    speeches.forEach(speech => {
      const speechDetails = {};

      speechDetails.title = speech.get('Title');

      promises.push(base('Members').find(speech.get('Speaker')));
      promises.push(base('Members').find(speech.get('Evaluator')));
      promises.push(base('Projects').find(speech.get('Project')));

      meetingDetails.speeches.push(speechDetails);
    });

    return Promise.all(promises);

  }).then(([wotdDefn, ...speechDeets]) => {
    // Now we have everything we need to fill in the meeting details.
    meetingDetails.wotdDefinition = wotdDefn.results[0];

    // FIXME speechDeets has an implicit ordering of (speaker, evaluator). There's doubtless a better way.
    // UGH recursion can't be the best way of doing this. This is like C :(
    const projectPs = [];

    const t = function (sePair, i) {
      if (sePair.length == 0) return;

      let [s, e, p, ...rest] = sePair;
      meetingDetails.speeches[i].speaker = s.get('Name');
      meetingDetails.speeches[i].evaluator = e.get('Name');
      meetingDetails.speeches[i].project = p.get('Project ID');
      meetingDetails.speeches[i].time = p.get('Time');

      t(rest, i+1);
    }

    t(speechDeets, 0);

    res.render('agenda', {
      title: 'Dolby Speakers Meeting',
      meeting: meetingDetails
    });
  }).catch(err => {
    // throw new Error(err);
  });
});

module.exports = router;<|endoftext|>


<commit_before>/*
 * Module dependencies.
 */

var template = require('./forgot-form');
var t = require('t');
var FormView = require('form-view');
var page = require('page');

/**
 * Expose ForgotView.
 */

module.exports = ForgotView;

/**
 * Forgot password view
 *
 * @return {ForgotView} `ForgotView` instance.
 * @api public
 */

function ForgotView() {
  if (!(this instanceof ForgotView)) {
    return new ForgotView();
  };

  FormView.call(this, template);
}

/**
 * Extend from `FormView`
 */

FormView(ForgotView);

ForgotView.prototype.switchOn = function() {
  this.on('success', this.bound('onsuccess'));
  this.on('error', this.bound('onerror'));
};

ForgotView.prototype.switchoff = function() {
  this.off('success', this.bound('onsuccess'));
  this.off('error', this.bound('onerror'));
};

/**
 * Show success message
 */

ForgotView.prototype.onsuccess = function() {
  var form = this.find('form');
  var explanation = this.find('p.explanation-message');
  var success = this.find('p.success-message');

  form.addClass('hide');
  explanation.addClass('hide');
  success.removeClass('hide');
}

/**
 * Handle errors
 */

 ForgotView.prototype.onerror = function(error) {
    if ('notvalidated' === error.status) page('/signup/resend-validation-email');
 };<commit_msg>Remove unneeded switchOff function from forgot view<commit_after>/*
 * Module dependencies.
 */

var template = require('./forgot-form');
var t = require('t');
var FormView = require('form-view');
var page = require('page');

/**
 * Expose ForgotView.
 */

module.exports = ForgotView;

/**
 * Forgot password view
 *
 * @return {ForgotView} `ForgotView` instance.
 * @api public
 */

function ForgotView() {
  if (!(this instanceof ForgotView)) {
    return new ForgotView();
  };

  FormView.call(this, template);
}

/**
 * Extend from `FormView`
 */

FormView(ForgotView);

ForgotView.prototype.switchOn = function() {
  this.on('success', this.bound('onsuccess'));
  this.on('error', this.bound('onerror'));
};

/**
 * Show success message
 */

ForgotView.prototype.onsuccess = function() {
  var form = this.find('form');
  var explanation = this.find('p.explanation-message');
  var success = this.find('p.success-message');

  form.addClass('hide');
  explanation.addClass('hide');
  success.removeClass('hide');
}

/**
 * Handle errors
 */

 ForgotView.prototype.onerror = function(error) {
    if ('notvalidated' === error.status) page('/signup/resend-validation-email');
 };<|endoftext|>