<commit_before>// Registration
$registrationSection = $('.registration-section'),
$confirmationSection = $('.confirmation-section'),
$registerForm = $('.form.registration'),
eventCode = $('#event-code').text().toLowerCase(),
eventTitle = $('#event-name').text(), // Stripe description
eventStartDate = $('#event-start').text(),
eventDates = $('#event-dates').text(),
eventVenue = $('#event-venue').text(),
eventDepositAmount = $('#event-deposit-amount').text(),
eventDepositDate = $('#event-deposit-date').text(),
eventLodgingOptions = $('#event-lodging-options').text(),
eventLodgingPrices = $('#event-lodging-prices').text(),
eventStripe = $('#event-stripe').text()

// Event initialization
const eventButton = '.button.pay',
eventFirstName = '#event-firstname',
eventLastName = '#event-lastname',
eventEmail = '#event-email',
eventMobile = '#event-mobile',
eventBirthdate = '#event-birthdate',
eventFemale = '#event-gender-female',
eventMale = '#event-gender-male',
eventOther = '#event-gender-other',
eventReferral = '#event-referral',
eventExperienceContainer = '.event-container.experience',
eventExperienceYes = '#event-experience-yes',
eventExperienceNo = '#event-experience-no',
eventExperienceDetails = '#event-experience-details',
eventDietContainer = '.event-container.diet',
eventDietYes = '#event-diet-yes',
eventDietNo = '#event-diet-no',
eventDietDetails = '#event-diet-details'
eventStatus = '#event-status',
eventPartnerContainer = '.event-container.partner',
eventPartnerName = '#event-partner-name'
eventPartnerFemale = '#event-partner-gender-female',
eventPartnerMale = '#event-partner-gender-male',
eventPartnerOther = '#event-partner-gender-other',
eventPayBoth = '#event-pay-both',
eventPayMe = '#event-pay-me',
eventLodging = '#event-lodging',
eventDepositContainer = '.event-container.deposit',
eventDepositText = '#event-deposit-text',
eventDepositFull = '#event-deposit-full',
eventDepositDeposit = '#event-deposit-deposit',
eventTerms = '#event-terms'

// SAVE FORM
function saveEvent() {
	var values = {};
	$('input, textarea, select').each(function() {
		if ($(this).is(':radio')) {
			if ($(this).is(':checked')) { values[$(this).attr('name')] = $(this).val() }
		}
		else {
			values[$(this).attr('name')] = $(this).val()
		}
	})
	localStorage.setItem('EcstaticLiving:Event', JSON.stringify(values))
}

// REPOPULATE SAVED FORM
function repopulateEvent() {
	if (localStorage.getItem('EcstaticLiving:Event')) {
		var values = JSON.parse(localStorage.getItem('EcstaticLiving:Event'))
		for (var item in values) {
			if ($('*[name=' + item + ']').is(':radio')) {
				$('input[name=' + item + '][value="' + values[item] + '"]').prop('checked', true)
			}
			else {
				$('*[name=' + item + ']').val(values[item])
			}
		}
		localStorage.removeItem('EcstaticLiving:Event')
	}
}

// PARTICIPANTS
function participants() {
	if (($(eventStatus).find('option:selected').val() === 'Couple') || ($(eventStatus).find('option:selected').val() === 'Two Singles (paired)')) {
		return 2
	} else if ($(eventStatus).find('option:selected').val() === 'Single') {
		return 1
	}
}

// FORM VALIDATION
function validationPersonal() {
	if ($(eventFirstName).val() !== '' && $(eventLastName).val() !== '' && $(eventEmail).val() !== '' && $(eventMobile).val() !== '' && $(eventBirthdate).val() !== '' &&
		($(eventFemale).is(':checked') || $(eventMale).is(':checked') || $(eventOther).is(':checked'))) {
		return true
	}
	return false
}
function validationDetails() {
	if ($(eventReferral).val() !== ''
		&& (($(eventExperienceYes).is(':checked') && $(eventExperienceDetails).val() !== '') || $(eventExperienceNo).is(':checked'))
		&& (($(eventDietYes).is(':checked') && $(eventDietDetails).val() !== '') || $(eventDietNo).is(':checked'))) {
		return true
	}
	return false
}
function validationStatus() {
	if (
		(participants() === 2
			&& $(eventPartnerName).val() !== ''
			&& ($(eventPartnerFemale).is(':checked') || $(eventPartnerMale).is(':checked') || $(eventPartnerOther).is(':checked'))
			&& ($(eventPayBoth).is(':checked') || $(eventPayMe).is(':checked')))
		|| participants() === 1
	) {
		return true
	}
	return false
}
function validationLodging() {
	if ($(eventLodging).val() !== '' && (
		$(eventDepositContainer).is(':visible') && ($(eventDepositFull).is(':checked') || $(eventDepositDeposit).is(':checked'))
	) || $(eventDepositContainer).is(':hidden')) {
		return true
	}
	return false
}
function eventValidation() {
	if (validationPersonal() && validationDetails() && validationStatus() && validationLodging() && $(eventTerms).is(':checked')) {
		console.log('*** VALID ***');
		document.getElementById('register-button').disabled = false
		document.getElementById('register-button').style.background = 'linear-gradient(bottom left, #800000, #b00000)'
		document.getElementById('register-button').style.color = '#333333'
	} else {
		console.log('invalid');
		document.getElementById('register-button').disabled = true
		document.getElementById('register-button').style.background = ''
		document.getElementById('register-button').style.color = '#ffffff'
	}
}
$(eventFirstName + ',' + eventLastName + ',' + eventEmail + ',' + eventMobile + ',' + eventBirthdate + ',' + eventFemale + ',' + eventMale + ',' + eventOther + ',' + eventReferral + ',' + eventExperienceDetails + ',' + eventDietDetails + ',' + eventStatus + ',' + eventPartnerName + ',' + eventPartnerFemale + ',' + eventPartnerMale + ',' + eventPartnerOther + ',' + eventLodging + ',' + eventTerms).on('change', function () {
	eventValidation()
})

// PARTNERSHIP
function showPartner() {
	$(eventPartnerContainer).show()
	$(eventPartnerContainer).animate({
		top: 0,
		opacity: 1
	}, 200)
	if ($(eventPayBoth).is(':checked')) {
		resetLodging('for both')
	} else {
		resetLodging('per person')
	}
}

function hidePartner() {
	$(eventPartnerName).val('')
	$(eventPartnerFemale + ',' + eventPartnerMale + ',' + eventPartnerOther + ',' + eventPayBoth + ',' + eventPayMe).prop('checked', false)
	$(eventPartnerContainer).animate({
		top: -40,
		opacity: 0
	}, 200)
	$(eventPartnerContainer).hide()
	resetLodging()
}

$(eventStatus).change(function() {
	participants() === 2 ? showPartner() : hidePartner()
})

$(eventPayBoth + ',' + eventPayMe).change(function() {
	if ($(eventPayBoth).is(':checked')) {
		resetLodging('for both')
	} else if (participants() === 2) {
		resetLodging('per person')
	} else {
		resetLodging('')
	}
})

// PREVIOUS EXPERIENCE
function showExperience() {
	$(eventExperienceContainer).show()
	$(eventExperienceContainer).animate({
		top: 40,
		opacity: 1
	}, 200)
}

function hideExperience() {
	$(eventExperienceDetails).val('')
	$(eventExperienceContainer).animate({
		top: 0,
		opacity: 0
	}, 200)
	$(eventExperienceContainer).hide()
}

$(eventExperienceNo + ',' + eventExperienceYes).change(function() {
	if ($(eventExperienceYes).is(':checked')) showExperience()
	if ($(eventExperienceNo).is(':checked')) hideExperience()
})

// DIETARY NEEDS
function showDiet() {
	$(eventDietContainer).show()
	$(eventDietContainer).animate({
		top: 0,
		opacity: 1
	}, 200)
}

function hideDiet() {
	$(eventDietDetails).val('')
	$(eventDietContainer).animate({
		top: -40,
		opacity: 0
	}, 200)
	$(eventDietContainer).hide()
}

$(eventDietNo + ',' + eventDietYes).change(function() {
	if ($(eventDietYes).is(':checked')) showDiet()
	if ($(eventDietNo).is(':checked')) hideDiet()
})

// LODGING
function resetLodging(paymentStatus) {
	//	Adds lodging options & prices based on CMS input
	var lodgingOptions = eventLodgingOptions.split(' | ')
	var lodgingPrices = eventLodgingPrices.split(' | ')
	$(eventLodging).empty()
	if (lodgingOptions.length > 0) {
		$(eventLodging).append($('<option>', {
			value: '',
			text: 'Event option...'
		}))
	}
	paymentStatus = paymentStatus ? paymentStatus : ''
	const paymentFactor = (paymentStatus === 'for both') ? 2 : 1
	const spacer = paymentStatus ? ' ' : ''
	const closer = (paymentStatus || paymentStatus === '') ? ')' : ''
	for (let i = 0; i < lodgingOptions.length; i++) {
		$(eventLodging).append($('<option>', {
			value: lodgingPrices[i] * paymentFactor,
			text: lodgingOptions[i] + ' ($' + lodgingPrices[i] * paymentFactor + spacer + paymentStatus + closer
		}))
	}
	eventPrice = parseInt(eventDepositAmount) * paymentFactor
	$(eventDepositText).text(`Pay deposit only ($${eventPrice}${spacer}${paymentStatus})`)
}

// SHOW REGISTRATION
function showRegistration() {
	$registrationSection.show()
	$confirmationSection.hide()
}

// SHOW CONFIRMATION
function showConfirmation() {
	$registrationSection.hide()
	$confirmationSection.show()
}

function resetEventForm() {
	showRegistration()
	$('.w-form-done').hide()
	$('.w-form-fail').hide()
	$registerForm[0].reset()
	repopulateEvent()
	resetLodging()
	if ($(eventExperienceDetails).val() === '') hideExperience()
	if ($(eventDietDetails).val() === '') hideDiet()
	if ($(eventPartnerName).val() === '') hidePartner()
	eventValidation()
	if (new Date() < new Date(eventDepositDate)) {
		$(eventDepositContainer).show()
		$(eventDepositFull).prop('checked', true)
	} else {
		$(eventDepositContainer).hide()
	}
	$registerForm.parsley()
	$registerForm.show()
	$(eventTerms).attr('checked', false)
	eventValidation()
}

// EVENT PAGE
if (window.location.href.indexOf('/events/') > -1) {
	resetEventForm()
}
<commit_msg>Integrating form into website.<commit_after>// Registration
$registrationSection = $('.registration-section'),
$confirmationSection = $('.confirmation-section'),
$registerForm = $('.form.registration'),
eventCode = $('#event-code').text().toLowerCase(),
eventTitle = $('#event-name').text(), // Stripe description
eventStartDate = $('#event-start').text(),
eventDates = $('#event-dates').text(),
eventVenue = $('#event-venue').text(),
eventDepositAmount = $('#event-deposit-amount').text(),
eventDepositDate = $('#event-deposit-date').text(),
eventLodgingOptions = $('#event-lodging-options').text(),
eventLodgingPrices = $('#event-lodging-prices').text(),
eventStripe = $('#event-stripe').text()

// Event initialization
const eventButton = '.button.pay',
eventFirstName = '#event-firstname',
eventLastName = '#event-lastname',
eventEmail = '#event-email',
eventMobile = '#event-mobile',
eventBirthdate = '#event-birthdate',
eventFemale = '#event-gender-female',
eventMale = '#event-gender-male',
eventOther = '#event-gender-other',
eventReferral = '#event-referral',
eventExperienceContainer = '.event-container.experience',
eventExperienceYes = '#event-experience-yes',
eventExperienceNo = '#event-experience-no',
eventExperienceDetails = '#event-experience-details',
eventDietContainer = '.event-container.diet',
eventDietYes = '#event-diet-yes',
eventDietNo = '#event-diet-no',
eventDietDetails = '#event-diet-details'
eventStatus = '#event-status',
eventPartnerContainer = '.event-container.partner',
eventPartnerName = '#event-partner-name'
eventPartnerFemale = '#event-partner-gender-female',
eventPartnerMale = '#event-partner-gender-male',
eventPartnerOther = '#event-partner-gender-other',
eventPayBoth = '#event-pay-both',
eventPayMe = '#event-pay-me',
eventLodging = '#event-lodging',
eventDepositContainer = '.event-container.deposit',
eventDepositText = '#event-deposit-text',
eventDepositFull = '#event-deposit-full',
eventDepositDeposit = '#event-deposit-deposit',
eventTerms = '#event-terms'

// SAVE FORM
function saveEvent() {
	var values = {};
	$('input, textarea, select').each(function() {
		if ($(this).is(':radio')) {
			if ($(this).is(':checked')) { values[$(this).attr('name')] = $(this).val() }
		}
		else {
			values[$(this).attr('name')] = $(this).val()
		}
	})
	localStorage.setItem('EcstaticLiving:Event', JSON.stringify(values))
}

// REPOPULATE SAVED FORM
function repopulateEvent() {
	if (localStorage.getItem('EcstaticLiving:Event')) {
		var values = JSON.parse(localStorage.getItem('EcstaticLiving:Event'))
		for (var item in values) {
			if ($('*[name=' + item + ']').is(':radio')) {
				$('input[name=' + item + '][value="' + values[item] + '"]').prop('checked', true)
			}
			else {
				$('*[name=' + item + ']').val(values[item])
			}
		}
		localStorage.removeItem('EcstaticLiving:Event')
	}
}

// PARTICIPANTS
function participants() {
	if (($(eventStatus).find('option:selected').val() === 'Couple') || ($(eventStatus).find('option:selected').val() === 'Two Singles (paired)')) {
		return 2
	} else if ($(eventStatus).find('option:selected').val() === 'Single') {
		return 1
	}
}

// FORM VALIDATION
function validationPersonal() {
	if ($(eventFirstName).val() !== '' && $(eventLastName).val() !== '' && $(eventEmail).val() !== '' && $(eventMobile).val() !== '' && $(eventBirthdate).val() !== '' &&
		($(eventFemale).is(':checked') || $(eventMale).is(':checked') || $(eventOther).is(':checked'))) {
		return true
	}
	return false
}
function validationDetails() {
	if ($(eventReferral).val() !== ''
		&& (($(eventExperienceYes).is(':checked') && $(eventExperienceDetails).val() !== '') || $(eventExperienceNo).is(':checked'))
		&& (($(eventDietYes).is(':checked') && $(eventDietDetails).val() !== '') || $(eventDietNo).is(':checked'))) {
		return true
	}
	return false
}
function validationStatus() {
	if (
		(participants() === 2
			&& $(eventPartnerName).val() !== ''
			&& ($(eventPartnerFemale).is(':checked') || $(eventPartnerMale).is(':checked') || $(eventPartnerOther).is(':checked'))
			&& ($(eventPayBoth).is(':checked') || $(eventPayMe).is(':checked')))
		|| participants() === 1
	) {
		return true
	}
	return false
}
function validationLodging() {
	if ($(eventLodging).val() !== '' && (
		$(eventDepositContainer).is(':visible') && ($(eventDepositFull).is(':checked') || $(eventDepositDeposit).is(':checked'))
	) || $(eventDepositContainer).is(':hidden')) {
		return true
	}
	return false
}
function eventValidation() {
	if (validationPersonal() && validationDetails() && validationStatus() && validationLodging() && $(eventTerms).is(':checked')) {
		console.log('*** VALID ***');
		document.getElementById('register-button').disabled = false
		document.getElementById('register-button').style.background = 'linear-gradient(bottom left, #800000, #b00000)'
		document.getElementById('register-button').style.color = '#ffffff'
	} else {
		console.log('invalid');
		document.getElementById('register-button').disabled = true
		document.getElementById('register-button').style.background = ''
		document.getElementById('register-button').style.color = '#333333'
	}
}
$(eventFirstName + ',' + eventLastName + ',' + eventEmail + ',' + eventMobile + ',' + eventBirthdate + ',' + eventFemale + ',' + eventMale + ',' + eventOther + ',' + eventReferral + ',' + eventExperienceDetails + ',' + eventDietDetails + ',' + eventStatus + ',' + eventPartnerName + ',' + eventPartnerFemale + ',' + eventPartnerMale + ',' + eventPartnerOther + ',' + eventLodging + ',' + eventTerms).on('change', function () {
	eventValidation()
})

// PARTNERSHIP
function showPartner() {
	$(eventPartnerContainer).show()
	$(eventPartnerContainer).animate({
		top: 0,
		opacity: 1
	}, 200)
	if ($(eventPayBoth).is(':checked')) {
		resetLodging('for both')
	} else {
		resetLodging('per person')
	}
}

function hidePartner() {
	$(eventPartnerName).val('')
	$(eventPartnerFemale + ',' + eventPartnerMale + ',' + eventPartnerOther + ',' + eventPayBoth + ',' + eventPayMe).prop('checked', false)
	$(eventPartnerContainer).animate({
		top: -40,
		opacity: 0
	}, 200)
	$(eventPartnerContainer).hide()
	resetLodging()
}

$(eventStatus).change(function() {
	participants() === 2 ? showPartner() : hidePartner()
})

$(eventPayBoth + ',' + eventPayMe).change(function() {
	if ($(eventPayBoth).is(':checked')) {
		resetLodging('for both')
	} else if (participants() === 2) {
		resetLodging('per person')
	} else {
		resetLodging('')
	}
})

// PREVIOUS EXPERIENCE
function showExperience() {
	$(eventExperienceContainer).show()
	$(eventExperienceContainer).animate({
		top: 40,
		opacity: 1
	}, 200)
}

function hideExperience() {
	$(eventExperienceDetails).val('')
	$(eventExperienceContainer).animate({
		top: 0,
		opacity: 0
	}, 200)
	$(eventExperienceContainer).hide()
}

$(eventExperienceNo + ',' + eventExperienceYes).change(function() {
	if ($(eventExperienceYes).is(':checked')) showExperience()
	if ($(eventExperienceNo).is(':checked')) hideExperience()
})

// DIETARY NEEDS
function showDiet() {
	$(eventDietContainer).show()
	$(eventDietContainer).animate({
		top: 0,
		opacity: 1
	}, 200)
}

function hideDiet() {
	$(eventDietDetails).val('')
	$(eventDietContainer).animate({
		top: -40,
		opacity: 0
	}, 200)
	$(eventDietContainer).hide()
}

$(eventDietNo + ',' + eventDietYes).change(function() {
	if ($(eventDietYes).is(':checked')) showDiet()
	if ($(eventDietNo).is(':checked')) hideDiet()
})

// LODGING
function resetLodging(paymentStatus) {
	//	Adds lodging options & prices based on CMS input
	var lodgingOptions = eventLodgingOptions.split(' | ')
	var lodgingPrices = eventLodgingPrices.split(' | ')
	$(eventLodging).empty()
	if (lodgingOptions.length > 0) {
		$(eventLodging).append($('<option>', {
			value: '',
			text: 'Event option...'
		}))
	}
	paymentStatus = paymentStatus ? paymentStatus : ''
	const paymentFactor = (paymentStatus === 'for both') ? 2 : 1
	const spacer = paymentStatus ? ' ' : ''
	const closer = (paymentStatus || paymentStatus === '') ? ')' : ''
	for (let i = 0; i < lodgingOptions.length; i++) {
		$(eventLodging).append($('<option>', {
			value: lodgingPrices[i] * paymentFactor,
			text: lodgingOptions[i] + ' ($' + lodgingPrices[i] * paymentFactor + spacer + paymentStatus + closer
		}))
	}
	eventPrice = parseInt(eventDepositAmount) * paymentFactor
	$(eventDepositText).text(`Pay deposit only ($${eventPrice}${spacer}${paymentStatus})`)
}

// SHOW REGISTRATION
function showRegistration() {
	$registrationSection.show()
	$confirmationSection.hide()
}

// SHOW CONFIRMATION
function showConfirmation() {
	$registrationSection.hide()
	$confirmationSection.show()
}

function resetEventForm() {
	showRegistration()
	$('.w-form-done').hide()
	$('.w-form-fail').hide()
	$registerForm[0].reset()
	repopulateEvent()
	resetLodging()
	if ($(eventExperienceDetails).val() === '') hideExperience()
	if ($(eventDietDetails).val() === '') hideDiet()
	if ($(eventPartnerName).val() === '') hidePartner()
	eventValidation()
	if (new Date() < new Date(eventDepositDate)) {
		$(eventDepositContainer).show()
		$(eventDepositFull).prop('checked', true)
	} else {
		$(eventDepositContainer).hide()
	}
	$registerForm.parsley()
	$registerForm.show()
	$(eventTerms).attr('checked', false)
	eventValidation()
}

// EVENT PAGE
if (window.location.href.indexOf('/events/') > -1) {
	resetEventForm()
}
<|endoftext|>


<commit_before>export const LOG_EVENT = 'LOG_EVENT';

export const logEvent = (event) => {
    return ({
        type: LOG_EVENT,
        event
    });
}
<commit_msg>[actions] Add triggers and updaters<commit_after>export const UPDATE_TRIGGERS = 'UPDATE_TRIGGERS';
export const SWITCH_RELAY = 'SWITCH_RELAY';

export const updateTriggers = (timesheet, relayId) => {
    return ({
        type: UPDATE_TRIGGERS,
        timesheet,
        relayId
    });
}

export const switchRelay = (relayId, switched, manual = false) => {
    return ({
        type: SWITCH_RELAY,
        relayId,
        switched,
        manual
    });
}
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */

var Snap = require('Snap.js');
var bus = require('bus');
var o = require('query');

exports = module.exports = function refresh(ctx) {
  ctx = ctx || document;

  var snapper = new Snap({
    element: o('#snap-content'),
    disable: 'right',
    touchToDrag: false,
    hyperextensible: false
  });

  var myToggleButton = o('#toggleButton', ctx);

  myToggleButton && myToggleButton.addEventListener('click', function(e) {
    e.preventDefault();

    if("left" === snapper.state().state) {
      snapper.close();
    } else {
      snapper.open('left');
    }
  });

  bus.on('page:change', onPageChange);

  function onPageChange () {
    snapper.close();
  };

  exports.snapper = snapper;
  exports.close = snapper.close;
  exports.destroy = function () {
    bus.off('page:chanbge', onPageChange);
  };
}<commit_msg>[snapper] - Fix typo on destroy<commit_after>/**
 * Module dependencies.
 */

var Snap = require('Snap.js');
var bus = require('bus');
var o = require('query');

exports = module.exports = function refresh(ctx) {
  ctx = ctx || document;

  var snapper = new Snap({
    element: o('#snap-content'),
    disable: 'right',
    touchToDrag: false,
    hyperextensible: false
  });

  var myToggleButton = o('#toggleButton', ctx);

  myToggleButton && myToggleButton.addEventListener('click', function(e) {
    e.preventDefault();

    if("left" === snapper.state().state) {
      snapper.close();
    } else {
      snapper.open('left');
    }
  });

  bus.on('page:change', onPageChange);

  function onPageChange () {
    snapper.close();
  };

  exports.snapper = snapper;
  exports.close = snapper.close;
  exports.destroy = function () {
    bus.off('page:change', onPageChange);
  };
}<|endoftext|>


<commit_before>// Actions will go here
import axios from 'axios';
import { browserHistory } from 'react-router';
import * as TYPES from '../constants/actions';

const API_URL = 'http://localhost:8080';

export const authError = (error) => ({
	type: TYPES.AUTHORIZE_ERROR,
	payload: error,
});

export const signinUser = ({ email, password }) => (
	(dispatch) => {
		axios.post(`${API_URL}/user/signin`, { email, password })
			.then(response => {
				console.log('response inside signinUser : ', response);
				dispatch({ type: TYPES.AUTHORIZE_USER });
				dispatch({ type: TYPES.GET_USER_INFO, payload: response.data });
				dispatch({ type: TYPES.POPULATE_ICEBOX, payload: response.data.contents });
				localStorage.setItem('token', response.data.token);
				browserHistory.push('/icebox');
			})
			.catch(response => {
				dispatch(authError(response));
			});
	}
);

export const signupUser = ({ email, name, password }) => (
	(dispatch) => {
		axios.post(`${API_URL}/user/signup`, { email, name, password })
			.then(response => {
				console.log('Response from signup', response);
				dispatch({ type: TYPES.AUTHORIZE_USER });
				dispatch({ type: TYPES.GET_USER_INFO, payload: response.data });
				localStorage.setItem('token', response.data.token);
				browserHistory.push('/icebox');
			})
			.catch(response => {
				// console.log('error in signup user, response of : ',response);
				dispatch(authError(response.data.error));
			});
	}
);

export const signoutUser = () => {
	localStorage.removeItem('token');
	localStorage.removeItem('state');
	browserHistory.push('/');
	return dispatch => {
		dispatch({ type: TYPES.DEAUTHORIZE_USER });
		// dispatch({ type: TYPES.CLEAR_USER_INFO });
		// dispatch({ type: TYPES.CLEAR_ICEBOX });
	};
};

export const getUserProfile = () => (
	(dispatch) => {
		axios.get(`${API_URL}/api/profile`, {
			headers: { authorization: localStorage.getItem('token') },
		})
			.then(response => {
				console.log('Successful', response);
				dispatch({ type: TYPES.GET_USER_PROFILE, payload: response.data });
			})
			.catch(response => (
				response
				// console.log('error in getUserProfile, response of : ', response);
			));
	}
);

export const addUserToIcebox = ({ email }) => (
	(dispatch) => {
		console.log('Inside of addUser in actions', email);
		axios.post(`${API_URL}/api/profile/add`, { email }, {
			headers: { authorization: localStorage.getItem('token') },
		})
		.then(response => {
			console.log('Successfully added user', response);
			dispatch({ type: TYPES.ADD_USER_ICEBOX, payload: response.data });
		})
		.catch(response => (
			response
		));
	}
);

export const removeUserFromIcebox = ({ user }) => (
	(dispatch) => {
		console.log('Inside of removeUser in actions', user);
		axios.post(`${API_URL}/api/profile/remove`, { user }, {
			headers: { authorization: localStorage.getItem('token') },
		})
		.then(response => {
			console.log('Successfully removed user', response);
			dispatch({ type: TYPES.REMOVE_USER_ICEBOX, payload: response.data });
		})
		.catch(response => (
			response
		));
	}
);

export const updateUserStaples = (staples) => (
	(dispatch) => {
		console.log('Inside of updateUserStaples in actions', staples);
		axios.post(`${API_URL}/api/profile/staples`, staples, {
			headers: { authorization: localStorage.getItem('token') },
		})
		.then(response => {
			console.log('Successfully added user', response);
			dispatch({ type: TYPES.UPDATE_USER_STAPLES, payload: response.data });
		})
		.catch(response => (
			response
		));
	}
);

export const acceptInvite = (details) => (
	(dispatch) => {
		console.log('Inside of acceptInvitation in actions', details);
		axios.post(`${API_URL}/api/profile/accept`, details, {
			headers: { authorization: localStorage.getItem('token') },
		})
		.then(response => {
			console.log('Successfully accepted invite', response);
			dispatch({ type: TYPES.UPDATE_USER_INFO, payload: response.data });
			dispatch({ type: TYPES.POPULATE_ICEBOX, payload: response.data.contents });
		})
		.catch(response => (
			response
		));
	}
);

export const setSortBy = (sort) => ({
	type: TYPES.SET_SORT,
	sort,
});

export const setSortOrder = (order) => ({
	type: TYPES.SET_SORT_ORDER,
	order,
});

export const setIceboxSearch = (searchTerm) => ({
	type: TYPES.SET_ICEBOX_SEARCH,
	searchTerm,
});

export const clearIceboxSearch = () => ({
	type: TYPES.CLEAR_ICEBOX_SEARCH,
});

export const addIceboxItems = ({ foodItems }) => (
	(dispatch) => {
		dispatch({ type: TYPES.START_LOADING });
		console.log('foodItems in addIceboxItems is : ', foodItems);
		axios.post(`${API_URL}/api/icebox/add`, { foodItems }, {
			headers: { authorization: localStorage.getItem('token') },
		})
			.then(response => {
				console.log('good response from addIceboxItems is : ', response);
				dispatch({ type: TYPES.ADD_ITEMS, payload: response.data.recognizedItems });
				dispatch({
					type: TYPES.CLARIFY_ITEMS,
					noExpirationItems: response.data.noExpirationItems,
					unrecognizedItems: response.data.unrecognizedItems,
				});
				dispatch({ type: TYPES.END_LOADING });
			})
			.catch(response => {
				console.log('bad response from addIceboxItems is : ', response);
				dispatch({ type: TYPES.END_LOADING });
				// dispatch({ type: TYPES.ICEBOX_ERROR, payload: response.data });
			});
	}
);

export const resolveIceboxItems = ({ foodItems }) => (
	(dispatch) => {
		dispatch({ type: TYPES.START_LOADING });
		console.log('foodItems in resolveIceboxItems is : ', foodItems);
		axios.post(`${API_URL}/api/icebox/resolve`, { foodItems }, {
			headers: { authorization: localStorage.getItem('token') },
		})
			.then(response => {
				console.log('good response from resolveIceboxItems is : ', response);
				dispatch({ type: TYPES.END_LOADING });
				dispatch({ type: TYPES.ADD_ITEMS, payload: response.data.addedItems });
				dispatch({ type: TYPES.CLEAR_CLARIFYING_ITEMS });
			})
			.catch(response => {
				console.log('bad response from resolveIceboxItems is : ', response);
				dispatch({ type: TYPES.END_LOADING });
				// dispatch({ type: TYPES.ICEBOX_ERROR, payload: response.data });
			});
	}
);

export const removeIceboxItems = ({ items }) => (
	dispatch => {
		dispatch({ type: TYPES.START_LOADING });
		console.log('items passed in are : ', items);
		const itemIDs = {};
		items.forEach(item => {
			itemIDs[item.itemID] = true;
		});
		axios.post(`${API_URL}/api/icebox/remove`, { items }, {
			headers: { authorization: localStorage.getItem('token') },
		})
			.then(() => {
				dispatch({ type: TYPES.END_LOADING });
				dispatch({ type: TYPES.REMOVE_ITEMS, payload: itemIDs });
			})
			.catch(response => {
				dispatch({ type: TYPES.END_LOADING });
				console.log('error in removeIceboxItems, response of : ', response);
			});
	}
);

export const addToTrash = ({ id }) => {
	console.log('addToTrash called, with id of : ', id);
	return {
		type: TYPES.ADD_TO_TRASH,
		payload: id,
	};
};

export const removeFromTrash = ({ id }) => ({
	type: TYPES.REMOVE_FROM_TRASH,
	payload: id,
});

export const getRecipes = () => (
	(dispatch) => {
		dispatch({ type: TYPES.START_LOADING });
		axios.get(`${API_URL}/api/icebox/pastRecipes`, {
			headers: { authorization: localStorage.getItem('token') },
		})
			.then(response => {
				dispatch({ type: TYPES.END_LOADING });
				dispatch({ type: TYPES.GET_RECIPES, payload: response.data });
			})
			.catch(response => {
				dispatch({ type: TYPES.END_LOADING });
				console.log('error in getRecipes, response of : ', response);
			});
	}
);

export const getRecipeSuggestions = () => (
	(dispatch) => {
		dispatch({ type: TYPES.START_LOADING });
		axios.get(`${API_URL}/api/icebox/recipes`, {
			headers: { authorization: localStorage.getItem('token') },
		})
			.then(response => {
				// console.log('response from getRecipeSuggestions is : ', response);
				dispatch({ type: TYPES.END_LOADING });
				dispatch({ type: TYPES.GET_RECIPE_SUGGESTIONS, payload: response.data });
			})
			.catch(response => {
				dispatch({ type: TYPES.END_LOADING });
				console.log('error in getRecipeSuggestions, response of : ', response);
			});
	}
);

export const chooseRecipe = ({ recipe }) => (
	(dispatch) => {
		axios.post(`${API_URL}/api/icebox/recipes`, { recipe }, {
			headers: { authorization: localStorage.getItem('token') },
		})
			.then(response => {
				dispatch({ type: TYPES.SET_CHOSEN_RECIPE, payload: response.data });
			})
			.catch(response => (
				response
				// console.log('error in chooseRecipe, response of : ',response);
			));
	}
);

export const showRecipeDetails = (recipeId) => (

	(dispatch) => {
		console.log('actions, showRecDetail params: ', recipeId);
		axios.get(`${API_URL}/api/icebox/recipe_details`, {
			headers: { authorization: localStorage.getItem('token'), getId: recipeId },
		})
			.then(response => {
				console.log('Actions, showRecipeDetails resp', response);
				dispatch({ type: TYPES.GET_RECIPE_DETAIL, payload: response.data });
			})
				.catch(response => (
					response
				));
	}
);

export const clearRecipe = () => ({
	type: TYPES.CLEAR_CHOSEN_RECIPE,
});
<commit_msg>[fix] corrects signoutUser action to clear icebox contents, user info, and authentication status as well as localstorage<commit_after>// Actions will go here
import axios from 'axios';
import { browserHistory } from 'react-router';
import * as TYPES from '../constants/actions';

const API_URL = 'http://localhost:8080';

export const authError = (error) => ({
	type: TYPES.AUTHORIZE_ERROR,
	payload: error,
});

export const signinUser = ({ email, password }) => (
	(dispatch) => {
		axios.post(`${API_URL}/user/signin`, { email, password })
			.then(response => {
				console.log('response inside signinUser : ', response);
				dispatch({ type: TYPES.AUTHORIZE_USER });
				dispatch({ type: TYPES.GET_USER_INFO, payload: response.data });
				dispatch({ type: TYPES.POPULATE_ICEBOX, payload: response.data.contents });
				localStorage.setItem('token', response.data.token);
				browserHistory.push('/icebox');
			})
			.catch(response => {
				dispatch(authError(response));
			});
	}
);

export const signupUser = ({ email, name, password }) => (
	(dispatch) => {
		axios.post(`${API_URL}/user/signup`, { email, name, password })
			.then(response => {
				console.log('Response from signup', response);
				dispatch({ type: TYPES.AUTHORIZE_USER });
				dispatch({ type: TYPES.GET_USER_INFO, payload: response.data });
				localStorage.setItem('token', response.data.token);
				browserHistory.push('/icebox');
			})
			.catch(response => {
				// console.log('error in signup user, response of : ',response);
				dispatch(authError(response.data.error));
			});
	}
);

export const signoutUser = () => (
	dispatch => {
		dispatch({ type: TYPES.DEAUTHORIZE_USER });
		dispatch({ type: TYPES.CLEAR_USER_INFO });
		dispatch({ type: TYPES.CLEAR_ICEBOX });
		localStorage.clear();
		browserHistory.push('/');
	}
);

export const getUserProfile = () => (
	(dispatch) => {
		axios.get(`${API_URL}/api/profile`, {
			headers: { authorization: localStorage.getItem('token') },
		})
			.then(response => {
				console.log('Successful', response);
				dispatch({ type: TYPES.GET_USER_PROFILE, payload: response.data });
			})
			.catch(response => (
				response
				// console.log('error in getUserProfile, response of : ', response);
			));
	}
);

export const addUserToIcebox = ({ email }) => (
	(dispatch) => {
		console.log('Inside of addUser in actions', email);
		axios.post(`${API_URL}/api/profile/add`, { email }, {
			headers: { authorization: localStorage.getItem('token') },
		})
		.then(response => {
			console.log('Successfully added user', response);
			dispatch({ type: TYPES.ADD_USER_ICEBOX, payload: response.data });
		})
		.catch(response => (
			response
		));
	}
);

export const removeUserFromIcebox = ({ user }) => (
	(dispatch) => {
		console.log('Inside of removeUser in actions', user);
		axios.post(`${API_URL}/api/profile/remove`, { user }, {
			headers: { authorization: localStorage.getItem('token') },
		})
		.then(response => {
			console.log('Successfully removed user', response);
			dispatch({ type: TYPES.REMOVE_USER_ICEBOX, payload: response.data });
		})
		.catch(response => (
			response
		));
	}
);

export const updateUserStaples = (staples) => (
	(dispatch) => {
		console.log('Inside of updateUserStaples in actions', staples);
		axios.post(`${API_URL}/api/profile/staples`, staples, {
			headers: { authorization: localStorage.getItem('token') },
		})
		.then(response => {
			console.log('Successfully added user', response);
			dispatch({ type: TYPES.UPDATE_USER_STAPLES, payload: response.data });
		})
		.catch(response => (
			response
		));
	}
);

export const acceptInvite = (details) => (
	(dispatch) => {
		console.log('Inside of acceptInvitation in actions', details);
		axios.post(`${API_URL}/api/profile/accept`, details, {
			headers: { authorization: localStorage.getItem('token') },
		})
		.then(response => {
			console.log('Successfully accepted invite', response);
			dispatch({ type: TYPES.UPDATE_USER_INFO, payload: response.data });
			dispatch({ type: TYPES.POPULATE_ICEBOX, payload: response.data.contents });
		})
		.catch(response => (
			response
		));
	}
);

export const setSortBy = (sort) => ({
	type: TYPES.SET_SORT,
	sort,
});

export const setSortOrder = (order) => ({
	type: TYPES.SET_SORT_ORDER,
	order,
});

export const setIceboxSearch = (searchTerm) => ({
	type: TYPES.SET_ICEBOX_SEARCH,
	searchTerm,
});

export const clearIceboxSearch = () => ({
	type: TYPES.CLEAR_ICEBOX_SEARCH,
});

export const addIceboxItems = ({ foodItems }) => (
	(dispatch) => {
		dispatch({ type: TYPES.START_LOADING });
		console.log('foodItems in addIceboxItems is : ', foodItems);
		axios.post(`${API_URL}/api/icebox/add`, { foodItems }, {
			headers: { authorization: localStorage.getItem('token') },
		})
			.then(response => {
				console.log('good response from addIceboxItems is : ', response);
				dispatch({ type: TYPES.ADD_ITEMS, payload: response.data.recognizedItems });
				dispatch({
					type: TYPES.CLARIFY_ITEMS,
					noExpirationItems: response.data.noExpirationItems,
					unrecognizedItems: response.data.unrecognizedItems,
				});
				dispatch({ type: TYPES.END_LOADING });
			})
			.catch(response => {
				console.log('bad response from addIceboxItems is : ', response);
				dispatch({ type: TYPES.END_LOADING });
				// dispatch({ type: TYPES.ICEBOX_ERROR, payload: response.data });
			});
	}
);

export const resolveIceboxItems = ({ foodItems }) => (
	(dispatch) => {
		dispatch({ type: TYPES.START_LOADING });
		console.log('foodItems in resolveIceboxItems is : ', foodItems);
		axios.post(`${API_URL}/api/icebox/resolve`, { foodItems }, {
			headers: { authorization: localStorage.getItem('token') },
		})
			.then(response => {
				console.log('good response from resolveIceboxItems is : ', response);
				dispatch({ type: TYPES.END_LOADING });
				dispatch({ type: TYPES.ADD_ITEMS, payload: response.data.addedItems });
				dispatch({ type: TYPES.CLEAR_CLARIFYING_ITEMS });
			})
			.catch(response => {
				console.log('bad response from resolveIceboxItems is : ', response);
				dispatch({ type: TYPES.END_LOADING });
				// dispatch({ type: TYPES.ICEBOX_ERROR, payload: response.data });
			});
	}
);

export const removeIceboxItems = ({ items }) => (
	dispatch => {
		dispatch({ type: TYPES.START_LOADING });
		console.log('items passed in are : ', items);
		const itemIDs = {};
		items.forEach(item => {
			itemIDs[item.itemID] = true;
		});
		axios.post(`${API_URL}/api/icebox/remove`, { items }, {
			headers: { authorization: localStorage.getItem('token') },
		})
			.then(() => {
				dispatch({ type: TYPES.END_LOADING });
				dispatch({ type: TYPES.REMOVE_ITEMS, payload: itemIDs });
			})
			.catch(response => {
				dispatch({ type: TYPES.END_LOADING });
				console.log('error in removeIceboxItems, response of : ', response);
			});
	}
);

export const addToTrash = ({ id }) => {
	console.log('addToTrash called, with id of : ', id);
	return {
		type: TYPES.ADD_TO_TRASH,
		payload: id,
	};
};

export const removeFromTrash = ({ id }) => ({
	type: TYPES.REMOVE_FROM_TRASH,
	payload: id,
});

export const getRecipes = () => (
	(dispatch) => {
		dispatch({ type: TYPES.START_LOADING });
		axios.get(`${API_URL}/api/icebox/pastRecipes`, {
			headers: { authorization: localStorage.getItem('token') },
		})
			.then(response => {
				dispatch({ type: TYPES.END_LOADING });
				dispatch({ type: TYPES.GET_RECIPES, payload: response.data });
			})
			.catch(response => {
				dispatch({ type: TYPES.END_LOADING });
				console.log('error in getRecipes, response of : ', response);
			});
	}
);

export const getRecipeSuggestions = () => (
	(dispatch) => {
		dispatch({ type: TYPES.START_LOADING });
		axios.get(`${API_URL}/api/icebox/recipes`, {
			headers: { authorization: localStorage.getItem('token') },
		})
			.then(response => {
				// console.log('response from getRecipeSuggestions is : ', response);
				dispatch({ type: TYPES.END_LOADING });
				dispatch({ type: TYPES.GET_RECIPE_SUGGESTIONS, payload: response.data });
			})
			.catch(response => {
				dispatch({ type: TYPES.END_LOADING });
				console.log('error in getRecipeSuggestions, response of : ', response);
			});
	}
);

export const chooseRecipe = ({ recipe }) => (
	(dispatch) => {
		axios.post(`${API_URL}/api/icebox/recipes`, { recipe }, {
			headers: { authorization: localStorage.getItem('token') },
		})
			.then(response => {
				dispatch({ type: TYPES.SET_CHOSEN_RECIPE, payload: response.data });
			})
			.catch(response => (
				response
				// console.log('error in chooseRecipe, response of : ',response);
			));
	}
);

export const showRecipeDetails = (recipeId) => (

	(dispatch) => {
		console.log('actions, showRecDetail params: ', recipeId);
		axios.get(`${API_URL}/api/icebox/recipe_details`, {
			headers: { authorization: localStorage.getItem('token'), getId: recipeId },
		})
			.then(response => {
				console.log('Actions, showRecipeDetails resp', response);
				dispatch({ type: TYPES.GET_RECIPE_DETAIL, payload: response.data });
			})
				.catch(response => (
					response
				));
	}
);

export const clearRecipe = () => ({
	type: TYPES.CLEAR_CHOSEN_RECIPE,
});
<|endoftext|>


<commit_before>
// using Thunk as middleware - all actions will return a function
// Thunk gets appllied in the main index.js file
import axios from "axios";
import { hashHistory } from 'react-router';
import {
  FETCH_TRINOMIAL,
  CHECK_TRINOMIAL,
  FETCH_REPORT,
  AUTH_USER,
  UNAUTH_USER,
  AUTH_ERROR
} from './types';

// const ROOT_URL = "http://localhost:3000";
const ROOT_URL = "https://factoring-api.herokuapp.com";

export function fetchTrinomial(pattern) {
  return function(dispatch) {
    // console.log("fetching a new trinomial");
    axios.get(`${ROOT_URL}/trinomial/${pattern}`, {
      headers: { authorization: localStorage.getItem('token') }
    })
      .then( ({data}) => { dispatch( { type: FETCH_TRINOMIAL, payload: data } )
      }).catch(
        () => {}
      );
  }
}

export function checkTrinomial(values, pattern) {
  return function(dispatch) {
    axios.post(`${ROOT_URL}/trinomial/check`, values, {
      headers: { authorization: localStorage.getItem('token') }
    })
      .then(
        response => {
          dispatch( {type: CHECK_TRINOMIAL} );
          dispatch( fetchTrinomial(pattern) );
      }).catch(
        () => {}
      );
  }
}

export function fetchReport() {
  return function(dispatch) {
    axios.get(`${ROOT_URL}/user/report`, {
      headers: { authorization: localStorage.getItem('token') }
    })
      .then( ({data}) => {
        dispatch({ type: FETCH_REPORT, payload: data })
      })
      .catch(
        () => {}
      );
  }
}

export function signupUser( {username, password, password_confirmation} ) {
  return function(dispatch) {
    axios.post(`${ROOT_URL}/user/signup`, { username, password, password_confirmation })
      .then(
        response => { hashHistory.push("/signin"); }
      ).catch(
        error => {
          const errors = error.response.data;
          dispatch( authError(errors) );
        }
      );
  }
}

export function signinUser({username, password}) {
  return function(dispatch) {
    // console.log("made it to singinUser");
    axios.post(`${ROOT_URL}/user/singin`, { username, password })
      .then( response => {
        // if good
        // update state to indicate user is authenticated
        dispatch({ type: AUTH_USER });
        // save JWT token in the local storage - managed by user's browser
        localStorage.setItem('token', response.data.auth_token);
        // redirect to route '/report'
        hashHistory.push("/report");
      }).catch(
        () => { dispatch( authError("Invalid username and/or password") )}
      );
  }
}

export function signoutUser() {
  return function(dispatch) {
    localStorage.removeItem('token');
    dispatch({ type: UNAUTH_USER });
  }
}

export function authError(error) {
  return {
    type: AUTH_ERROR,
    payload: error
  };
}
<commit_msg>fixed typo with api post<commit_after>
// using Thunk as middleware - all actions will return a function
// Thunk gets appllied in the main index.js file
import axios from "axios";
import { hashHistory } from 'react-router';
import {
  FETCH_TRINOMIAL,
  CHECK_TRINOMIAL,
  FETCH_REPORT,
  AUTH_USER,
  UNAUTH_USER,
  AUTH_ERROR
} from './types';

// const ROOT_URL = "http://localhost:3000";
const ROOT_URL = "https://factoring-api.herokuapp.com";

export function fetchTrinomial(pattern) {
  return function(dispatch) {
    // console.log("fetching a new trinomial");
    axios.get(`${ROOT_URL}/trinomial/${pattern}`, {
      headers: { authorization: localStorage.getItem('token') }
    })
      .then( ({data}) => { dispatch( { type: FETCH_TRINOMIAL, payload: data } )
      }).catch(
        () => {}
      );
  }
}

export function checkTrinomial(values, pattern) {
  return function(dispatch) {
    axios.post(`${ROOT_URL}/trinomial/check`, values, {
      headers: { authorization: localStorage.getItem('token') }
    })
      .then(
        response => {
          dispatch( {type: CHECK_TRINOMIAL} );
          dispatch( fetchTrinomial(pattern) );
      }).catch(
        () => {}
      );
  }
}

export function fetchReport() {
  return function(dispatch) {
    axios.get(`${ROOT_URL}/user/report`, {
      headers: { authorization: localStorage.getItem('token') }
    })
      .then( ({data}) => {
        dispatch({ type: FETCH_REPORT, payload: data })
      })
      .catch(
        () => {}
      );
  }
}

export function signupUser( {username, password, password_confirmation} ) {
  return function(dispatch) {
    axios.post(`${ROOT_URL}/user/signup`, { username, password, password_confirmation })
      .then(
        response => { hashHistory.push("/signin"); }
      ).catch(
        error => {
          const errors = error.response.data;
          dispatch( authError(errors) );
        }
      );
  }
}

export function signinUser({username, password}) {
  return function(dispatch) {
    // console.log("made it to singinUser");
    axios.post(`${ROOT_URL}/user/signin`, { username, password })
      .then( response => {
        // if good
        // update state to indicate user is authenticated
        dispatch({ type: AUTH_USER });
        // save JWT token in the local storage - managed by user's browser
        localStorage.setItem('token', response.data.auth_token);
        // redirect to route '/report'
        hashHistory.push("/report");
      }).catch(
        () => { dispatch( authError("Invalid username and/or password") )}
      );
  }
}

export function signoutUser() {
  return function(dispatch) {
    localStorage.removeItem('token');
    dispatch({ type: UNAUTH_USER });
  }
}

export function authError(error) {
  return {
    type: AUTH_ERROR,
    payload: error
  };
}
<|endoftext|>


<commit_before>/* global Log, Config */
'use strict';

const Crypto = require('crypto');
const Aws = require('aws-sdk');

const Source = require('./common');
const Parser = require('./metadata/parser');
const Util = require('./metadata/util');

/**
 * Metadata Source
 *
 * Expose EC2 metadata to the property-set
 *
 * @class Source.Metadata
 * @extends Source.Polling
 *
 * @param {Parser} parser
 */
class Metadata extends Source.Polling(Parser) { // eslint-disable-line new-cap
  /**
   * Constructor
   * @param {Object} opts
   *      - {Number} interval Polling interval. Default 30s.
   */
  constructor(opts) {
    // Inject defaults into options
    const options = Object.assign({
      timeout: Metadata.DEFAULT_TIMEOUT,
      host: Metadata.DEFAULT_HOST
    }, opts);

    super('ec2-metadata', options);

    /**
     * Initialize the metadata-service client
     */
    this.service = new Aws.MetadataService({
      httpOptions: {
        timeout: options.timeout
      },
      host: options.host
    });
  }

  /**
   * Metadata version
   *
   * Used to prepend paths for calls to the EC2 Metadata Service,
   * e.g. /<version>/meta-data/ami-id
   *
   * @returns {string}
   */
  get version() {
    return this.constructor.version;
  }

  /**
   *
   * Fetch implementation for EC2 Metadata
   * @param {Function} callback
   * @private
   */
  _fetch(callback) {
    Util.traverse(this.version, Parser.paths,

      // Call `Metadata.request` for each path
      (path, cb) => this.service.request(path, (err, value) => {
        if (err) {
          /*
           * AWS-SDK > 2.6.0 now raises an error with a null message when the underlying http
           * request returns a non-2xx status code. We don't want to abort the rest of the traversal
           * for this. Instead, log the error and swallow it.
           */
          Log.log('ERROR', 'Aws-sdk returned the following error during the metadata service request ' +
              `to ${path}: %j`, err);

          return cb(null, undefined);
        }
        cb(err, value);
      }),

      // Handle results of metadata tree traversal
      (err, data) => {
        if (err) {
          return callback(err);
        }

        let p = Promise.resolve(data);

        // Grab the ASG from the instance-id
        const instanceId = data['meta-data/instance-id'];
        const az = data['meta-data/placement/availability-zone'];

        if (instanceId && az) {
          const region = az.slice(0, -1);

          p = new Promise((resolve, reject) => {
            (new Aws.AutoScaling({region})).describeAutoScalingInstances({InstanceIds: [instanceId]}, (err, d) => {
              if (err) {
                return reject(err);
              }
              resolve(d);
            });
          }).then((d) => {
            const asg = d.AutoScalingInstances.map((instance) => instance.AutoScalingGroupName);

            // No reason it should be longer than 1 but worth a check
            if (asg.length > 1) {
              Log.log('WARN', `Instance id ${instanceId} is in multiple auto-scaling groups`, asg);
            }

            // Check to see if an instance is actually part of an ASG
            if (asg.length !== 0) {
              data['auto-scaling-group'] = asg[0];
            }

            return data;
          }).catch(() => data);
        }

        p.then((data) => {
          // Detect change by hashing the fetched data
          const hash = Crypto.createHash('sha1');
          const paths = Object.keys(data);

          Log.log('DEBUG', `Source/Metadata: Fetched ${paths.length} paths from the ec2-metadata service`, this.status());

          paths.sort().forEach((key) => {
            hash.update(`${key}:${data[key]}`);
          });

          const signature = hash.digest('base64');

          if (this._state === signature) {
            return callback(null, Source.NO_UPDATE);
          }

          this._state = signature;
          callback(null, data);
        });
      }
    );
  }
}

Metadata.version = 'latest';
Metadata.DEFAULT_TIMEOUT = 500; // eslint-disable-line rapid7/static-magic-numbers
Metadata.DEFAULT_HOST = '169.254.169.254:80';

/* Export */
module.exports = Metadata;
<commit_msg>Added logging if the call to describeAutoScalingInstances produces an error.<commit_after>/* global Log, Config */
'use strict';

const Crypto = require('crypto');
const Aws = require('aws-sdk');

const Source = require('./common');
const Parser = require('./metadata/parser');
const Util = require('./metadata/util');

/**
 * Metadata Source
 *
 * Expose EC2 metadata to the property-set
 *
 * @class Source.Metadata
 * @extends Source.Polling
 *
 * @param {Parser} parser
 */
class Metadata extends Source.Polling(Parser) { // eslint-disable-line new-cap
  /**
   * Constructor
   * @param {Object} opts
   *      - {Number} interval Polling interval. Default 30s.
   */
  constructor(opts) {
    // Inject defaults into options
    const options = Object.assign({
      timeout: Metadata.DEFAULT_TIMEOUT,
      host: Metadata.DEFAULT_HOST
    }, opts);

    super('ec2-metadata', options);

    /**
     * Initialize the metadata-service client
     */
    this.service = new Aws.MetadataService({
      httpOptions: {
        timeout: options.timeout
      },
      host: options.host
    });
  }

  /**
   * Metadata version
   *
   * Used to prepend paths for calls to the EC2 Metadata Service,
   * e.g. /<version>/meta-data/ami-id
   *
   * @returns {string}
   */
  get version() {
    return this.constructor.version;
  }

  /**
   *
   * Fetch implementation for EC2 Metadata
   * @param {Function} callback
   * @private
   */
  _fetch(callback) {
    Util.traverse(this.version, Parser.paths,

      // Call `Metadata.request` for each path
      (path, cb) => this.service.request(path, (err, value) => {
        if (err) {
          /*
           * AWS-SDK > 2.6.0 now raises an error with a null message when the underlying http
           * request returns a non-2xx status code. We don't want to abort the rest of the traversal
           * for this. Instead, log the error and swallow it.
           */
          Log.log('ERROR', 'Aws-sdk returned the following error during the metadata service request ' +
              `to ${path}: %j`, err);

          return cb(null, undefined);
        }
        cb(err, value);
      }),

      // Handle results of metadata tree traversal
      (err, data) => {
        if (err) {
          return callback(err);
        }

        let p = Promise.resolve(data);

        // Grab the ASG from the instance-id
        const instanceId = data['meta-data/instance-id'];
        const az = data['meta-data/placement/availability-zone'];

        if (instanceId && az) {
          const region = az.slice(0, -1);

          p = new Promise((resolve, reject) => {
            (new Aws.AutoScaling({region})).describeAutoScalingInstances({InstanceIds: [instanceId]}, (err, d) => {
              if (err) {
                Log.log('ERROR', err);

                return reject(err);
              }
              resolve(d);
            });
          }).then((d) => {
            const asg = d.AutoScalingInstances.map((instance) => instance.AutoScalingGroupName);

            // No reason it should be longer than 1 but worth a check
            if (asg.length > 1) {
              Log.log('WARN', `Instance id ${instanceId} is in multiple auto-scaling groups`, asg);
            }

            // Check to see if an instance is actually part of an ASG
            if (asg.length !== 0) {
              data['auto-scaling-group'] = asg[0];
            }

            return data;
          }).catch(() => data);
        }

        p.then((data) => {
          // Detect change by hashing the fetched data
          const hash = Crypto.createHash('sha1');
          const paths = Object.keys(data);

          Log.log('DEBUG', `Source/Metadata: Fetched ${paths.length} paths from the ec2-metadata service`, this.status());

          paths.sort().forEach((key) => {
            hash.update(`${key}:${data[key]}`);
          });

          const signature = hash.digest('base64');

          if (this._state === signature) {
            return callback(null, Source.NO_UPDATE);
          }

          this._state = signature;
          callback(null, data);
        });
      }
    );
  }
}

Metadata.version = 'latest';
Metadata.DEFAULT_TIMEOUT = 500; // eslint-disable-line rapid7/static-magic-numbers
Metadata.DEFAULT_HOST = '169.254.169.254:80';

/* Export */
module.exports = Metadata;
<|endoftext|>


<commit_before>/**
 * Sources
 * ======
 */
var inherit = require('inherit');

/**
 * Sources — класс для работы со списком уровней переопределения.
 * @name Sources
 */
module.exports = inherit({
    /**
     * Конструктор.
     * @param {SourceRoot[]} items
     */
    __constructor: function (items) {
        this._items = items;
    },

    /**
     * Возвращает объектные представления блоков по имени.
     * @param {String} blockName
     * @returns {Object[]}
     */
    getBlocks: function (blockName) {
        var block;
        var blocks = [];
        for (var i = 0, l = this._items.length; i < l; i++) {
            block = this._items[i].getBlocks()[blockName];
            if (block) {
                blocks.push(block);
            }
        }
        return blocks;
    },

    /**
     * Возвращает объектные представления элементов по имени.
     * @param {String} blockName
     * @param {String} elemName
     * @returns {Object[]}
     */
    getElems: function (blockName, elemName) {
        var block;
        var elements = [];
        for (var i = 0, l = this._items.length; i < l; i++) {
            block = this._items[i].getBlocks()[blockName];
            if (block && block.elements[elemName]) {
                elements.push(block.elements[elemName]);
            }
        }
        return elements;
    },

    /**
     * Возвращает файлы и директории по декларации блока.
     * @param {String} blockName
     * @param {String} modName
     * @param {String} modValue
     * @returns {{files: Array, dirs: Array}}
     */
    getBlockEntities: function (blockName, modName, modValue) {
        var block;
        var files = [];
        var dirs = [];
        var blocks = this.getBlocks(blockName);
        for (var i = 0, l = blocks.length; i < l; i++) {
            block = blocks[i];
            if (modName) {
                if (block.mods[modName] && block.mods[modName][modValue || '']) {
                    files = files.concat(block.mods[modName][modValue || ''].files);
                    dirs = dirs.concat(block.mods[modName][modValue || ''].dirs);
                }
            } else {
                files = files.concat(block.files);
                dirs = dirs.concat(block.dirs);
            }
        }
        return {files: files, dirs: dirs};
    },

    /**
     * Возвращает файлы и директории по декларации элемента.
     * @param {String} blockName
     * @param {String} elemName
     * @param {String} modName
     * @param {String} modValue
     * @returns {{files: Array, dirs: Array}}
     */
    getElemEntities: function (blockName, elemName, modName, modValue) {
        var elem;
        var files = [];
        var dirs = [];
        var elems = this.getElems(blockName, elemName);
        for (var i = 0, l = elems.length; i < l; i++) {
            elem = elems[i];
            if (modName) {
                if (elem.mods[modName] && elem.mods[modName][modValue || '']) {
                    files = files.concat(elem.mods[modName][modValue || ''].files);
                    dirs = dirs.concat(elem.mods[modName][modValue || ''].dirs);
                }
            } else {
                files = files.concat(elem.files);
                dirs = dirs.concat(elem.dirs);
            }
        }
        return {files: files, dirs: dirs};
    },

    /**
     * Возвращает файлы по декларации блока.
     * Каждый файл описывается в виде:
     * { fullname: <абсолютный путь к файлу>, name: <имя файла>, suffix: <суффикс>, mtime: <время изменения> }
     * @param {String} blockName
     * @param {String} modName
     * @param {String} modValue
     * @returns {Object[]}
     */
    getBlockFiles: function (blockName, modName, modValue) {
        return this.getBlockEntities(blockName, modName, modValue).files;
    },

    /**
     * Возвращает файлы по декларации элемента.
     * Каждый файл описывается в виде:
     * { fullname: <абсолютный путь к файлу>, name: <имя файла>, suffix: <суффикс>, mtime: <время изменения> }
     * @param {String} blockName
     * @param {String} elemName
     * @param {String} modName
     * @param {String} modValue
     * @returns {Object[]}
     */
    getElemFiles: function (blockName, elemName, modName, modValue) {
        return this.getElemEntities(blockName, elemName, modName, modValue).files;
    },

    /**
     * Возвращает файлы на основе декларации.
     * Каждый файл описывается в виде:
     * { fullname: <абсолютный путь к файлу>, name: <имя файла>, suffix: <суффикс>, mtime: <время изменения> }
     * @param {String} blockName
     * @param {String} elemName
     * @param {String} modName
     * @param {String} modValue
     * @returns {Object[]}
     */
    getFilesByDecl: function (blockName, elemName, modName, modValue) {
        if (elemName) {
            return this.getElemFiles(blockName, elemName, modName, modValue);
        } else {
            return this.getBlockFiles(blockName, modName, modValue);
        }
    },

    /**
     * Возвращает файлы на основе суффикса.
     * @param {String} suffix
     * @returns {Object[]}
     */
    getFilesBySuffix: function (suffix) {
        var files = [];
        this._items.forEach(function (sourceRoot) {
            var blocks = sourceRoot.getBlocks();
            Object.keys(blocks).forEach(function (blockName) {
                files = files.concat(getFilesInElementBySuffix(blocks[blockName], suffix));
            });
        });
        return files;
    },

    /**
     * Возвращает значения модификатора для блока.
     *
     * @param {String} blockName
     * @param {String} modName
     * @returns {String[]}
     */
    getModValues: function (blockName, modName) {
        var modVals = [];
        this._items.forEach(function (sourceRoot) {
            var blockInfo = sourceRoot.getBlocks()[blockName];
            if (blockInfo && blockInfo.mods && blockInfo.mods[modName]) {
                modVals = modVals.concat(Object.keys(blockInfo.mods[modName]));
            }
        });
        return modVals;
    }
});

function getFilesInElementBySuffix(element, suffix) {
    var files = element.files.filter(function (f) { return f.suffix === suffix; });
    var mods = element.mods;
    var elements = element.elements;
    Object.keys(mods).forEach(function (modName) {
        var mod = mods[modName];
        Object.keys(mod).forEach(function (modValue) {
            files = files.concat(mod[modValue].files.filter(function (f) { return f.suffix === suffix; }));
        });
    });
    if (elements) {
        Object.keys(elements).forEach(function (elemName) {
            files = files.concat(getFilesInElementBySuffix(elements[elemName], suffix));
        });
    }
    return files;
}
<commit_msg>source map modules: some-dir/../module to module<commit_after>/**
 * Sources
 * ======
 */
var inherit = require('inherit');

/**
 * Sources — класс для работы со списком уровней переопределения.
 * @name Sources
 */
module.exports = inherit({
    /**
     * Конструктор.
     * @param {SourceRoot[]} items
     */
    __constructor: function (items) {
        this._items = items;
    },

    /**
     * Возвращает объектные представления блоков по имени.
     * @param {String} blockName
     * @returns {Object[]}
     */
    getBlocks: function (blockName) {
        var block;
        var blocks = [];
        for (var i = 0, l = this._items.length; i < l; i++) {
            block = this._items[i].getBlocks()[blockName.split('/').pop()];
            if (block) {
                blocks.push(block);
            }
        }
        return blocks;
    },

    /**
     * Возвращает объектные представления элементов по имени.
     * @param {String} blockName
     * @param {String} elemName
     * @returns {Object[]}
     */
    getElems: function (blockName, elemName) {
        var block;
        var elements = [];
        for (var i = 0, l = this._items.length; i < l; i++) {
            block = this._items[i].getBlocks()[blockName.split('/').pop()];
            if (block && block.elements[elemName]) {
                elements.push(block.elements[elemName]);
            }
        }
        return elements;
    },

    /**
     * Возвращает файлы и директории по декларации блока.
     * @param {String} blockName
     * @param {String} modName
     * @param {String} modValue
     * @returns {{files: Array, dirs: Array}}
     */
    getBlockEntities: function (blockName, modName, modValue) {
        var block;
        var files = [];
        var dirs = [];
        var blocks = this.getBlocks(blockName);
        for (var i = 0, l = blocks.length; i < l; i++) {
            block = blocks[i];
            if (modName) {
                if (block.mods[modName] && block.mods[modName][modValue || '']) {
                    files = files.concat(block.mods[modName][modValue || ''].files);
                    dirs = dirs.concat(block.mods[modName][modValue || ''].dirs);
                }
            } else {
                files = files.concat(block.files);
                dirs = dirs.concat(block.dirs);
            }
        }
        return {files: files, dirs: dirs};
    },

    /**
     * Возвращает файлы и директории по декларации элемента.
     * @param {String} blockName
     * @param {String} elemName
     * @param {String} modName
     * @param {String} modValue
     * @returns {{files: Array, dirs: Array}}
     */
    getElemEntities: function (blockName, elemName, modName, modValue) {
        var elem;
        var files = [];
        var dirs = [];
        var elems = this.getElems(blockName, elemName);
        for (var i = 0, l = elems.length; i < l; i++) {
            elem = elems[i];
            if (modName) {
                if (elem.mods[modName] && elem.mods[modName][modValue || '']) {
                    files = files.concat(elem.mods[modName][modValue || ''].files);
                    dirs = dirs.concat(elem.mods[modName][modValue || ''].dirs);
                }
            } else {
                files = files.concat(elem.files);
                dirs = dirs.concat(elem.dirs);
            }
        }
        return {files: files, dirs: dirs};
    },

    /**
     * Возвращает файлы по декларации блока.
     * Каждый файл описывается в виде:
     * { fullname: <абсолютный путь к файлу>, name: <имя файла>, suffix: <суффикс>, mtime: <время изменения> }
     * @param {String} blockName
     * @param {String} modName
     * @param {String} modValue
     * @returns {Object[]}
     */
    getBlockFiles: function (blockName, modName, modValue) {
        return this.getBlockEntities(blockName, modName, modValue).files;
    },

    /**
     * Возвращает файлы по декларации элемента.
     * Каждый файл описывается в виде:
     * { fullname: <абсолютный путь к файлу>, name: <имя файла>, suffix: <суффикс>, mtime: <время изменения> }
     * @param {String} blockName
     * @param {String} elemName
     * @param {String} modName
     * @param {String} modValue
     * @returns {Object[]}
     */
    getElemFiles: function (blockName, elemName, modName, modValue) {
        return this.getElemEntities(blockName, elemName, modName, modValue).files;
    },

    /**
     * Возвращает файлы на основе декларации.
     * Каждый файл описывается в виде:
     * { fullname: <абсолютный путь к файлу>, name: <имя файла>, suffix: <суффикс>, mtime: <время изменения> }
     * @param {String} blockName
     * @param {String} elemName
     * @param {String} modName
     * @param {String} modValue
     * @returns {Object[]}
     */
    getFilesByDecl: function (blockName, elemName, modName, modValue) {
        if (elemName) {
            return this.getElemFiles(blockName, elemName, modName, modValue);
        } else {
            return this.getBlockFiles(blockName, modName, modValue);
        }
    },

    /**
     * Возвращает файлы на основе суффикса.
     * @param {String} suffix
     * @returns {Object[]}
     */
    getFilesBySuffix: function (suffix) {
        var files = [];
        this._items.forEach(function (sourceRoot) {
            var blocks = sourceRoot.getBlocks();
            Object.keys(blocks).forEach(function (blockName) {
                files = files.concat(getFilesInElementBySuffix(blocks[blockName.split('/').pop()], suffix));
            });
        });
        return files;
    },

    /**
     * Возвращает значения модификатора для блока.
     *
     * @param {String} blockName
     * @param {String} modName
     * @returns {String[]}
     */
    getModValues: function (blockName, modName) {
        var modVals = [];
        this._items.forEach(function (sourceRoot) {
            var blockInfo = sourceRoot.getBlocks()[blockName.split('/').pop()];
            if (blockInfo && blockInfo.mods && blockInfo.mods[modName]) {
                modVals = modVals.concat(Object.keys(blockInfo.mods[modName]));
            }
        });
        return modVals;
    }
});

function getFilesInElementBySuffix(element, suffix) {
    var files = element.files.filter(function (f) { return f.suffix === suffix; });
    var mods = element.mods;
    var elements = element.elements;
    Object.keys(mods).forEach(function (modName) {
        var mod = mods[modName];
        Object.keys(mod).forEach(function (modValue) {
            files = files.concat(mod[modValue].files.filter(function (f) { return f.suffix === suffix; }));
        });
    });
    if (elements) {
        Object.keys(elements).forEach(function (elemName) {
            files = files.concat(getFilesInElementBySuffix(elements[elemName], suffix));
        });
    }
    return files;
}
<|endoftext|>


<commit_before>/* See license.txt for terms of usage */

// ************************************************************************************************
// Constants

const CLASS_ID = Components.ID("{9589DC0D-9709-4578-883E-D393452B3611}");
const CLASS_NAME = "Firebug Annotation Service";
const CONTRACT_ID = "@joehewitt.com/firebug-annotation-service;1";

var EXPORTED_SYMBOLS = ["annotationService"];

const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;

const dirService = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);

// ************************************************************************************************
// Annotation service implementation

var FBTrace = null;

/**
 * @class Represents an internal Firebug annotation service. This service is used to
 * annotate sites with an info whether Firebug should be activated for them or not.
 */

var annotationService =
{
    annotations: [],

    setPageAnnotation: function(uri, value)
    {
        if (FBTrace.DBG_ANNOTATIONS)
            FBTrace.sysout("AnnotationService.setPageAnnotation; " + value + ", " + uri.spec);

        this.annotations[uri.spec] = value;
    },

    getPageAnnotation: function(uri)
    {
        return this.annotations[uri.spec];
    },

    pageHasAnnotation: function(uri)
    {
        return this.annotations[uri.spec] ? true : false;
    },

    removePageAnnotation: function(uri)
    {
        if (FBTrace.DBG_ANNOTATIONS)
            FBTrace.sysout("AnnotationService.removePageAnnotation; " + uri.spec);

        delete this.annotations[uri.spec];
    },

    getAnnotations: function()
    {
        return this.annotations;
    },

    clear: function()
    {
        this.annotations = [];
    },

    initialize: function()
    {
        Components.utils.import("resource://firebug/firebug-trace-service.js");
        FBTrace = traceConsoleService.getTracer("extensions.firebug");

        // Get annotation file stored within the profile directory.
        this.file = dirService.get("ProfD", Ci.nsIFile);
        this.file.append("firebug");
        this.file.append("annotations.json");

        // Load annotations.
        this.loadAnnotations();
    },

    // Persistence
    loadAnnotations: function()
    {
        try
        {
            this.clear();

            if (!this.file.exists())
            {
                this.file.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
                if (FBTrace.DBG_ANNOTATIONS)
                    FBTrace.sysout("AnnotationService.loadAnnotations; Annotations file created " +
                        this.file.path);
                return;
            }

            var inputStream = Cc["@mozilla.org/network/file-input-stream;1"]
                .createInstance(Ci.nsIFileInputStream);
            var cstream = Cc["@mozilla.org/intl/converter-input-stream;1"]
                .createInstance(Ci.nsIConverterInputStream);

            // loadAnnotations input stream.
            inputStream.init(this.file, 0x01 | 0x08, 0666, 0); // read, create
            cstream.init(inputStream, "UTF-8", 0, 0);

            // Load annotations.
            var data = {};
            cstream.readString(-1, data);
            if (!data.value.length)
                return;

            var nativeJSON = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
            var arr = nativeJSON.decode(data.value);
            if (!arr)
                return;

            // Convert to map for faster lookup.
            for (var i=0; i<arr.length; i++)
                this.annotations[arr[i].uri] = arr[i].value;

            if (FBTrace.DBG_ANNOTATIONS)
                FBTrace.sysout("AnnotationService.loadAnnotations; Annotations loaded from " +
                    this.file.path, arr);
        }
        catch (err)
        {
            if (FBTrace.DBG_ERRORS || FBTrace.DBG_ANNOTATIONS)
                FBTrace.sysout("AnnotationService.loadAnnotations; EXCEPTION", err);
        }
    },

    flush: function()
    {
        try
        {
            // Initialize output stream.
            var outputStream = Cc["@mozilla.org/network/file-output-stream;1"]
                .createInstance(Ci.nsIFileOutputStream);
            outputStream.init(this.file, 0x02 | 0x08 | 0x20, 0666, 0); // write, create, truncate

            // Convert data to JSON.
            var arr = [];
            for (var uri in this.annotations)
                arr.push({
                    uri: uri,
                    value: this.annotations[uri]
                });

            var nativeJSON = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
            var jsonString = nativeJSON.encode(arr);

            // Store annotations.
            outputStream.write(jsonString, jsonString.length);
            outputStream.close();

            if (FBTrace.DBG_ANNOTATIONS)
                FBTrace.sysout("AnnotationService.loadAnnotations; Annotations stored to " +
                    this.file.path, jsonString);
        }
        catch (err)
        {
            if (FBTrace.DBG_ERRORS || FBTrace.DBG_ANNOTATIONS)
                FBTrace.sysout("AnnotationService.flush; EXCEPTION", err);
        }
    },

    /* nsISupports */
    QueryInterface: function(iid)
    {
        if (iid.equals(Ci.nsISupports))
            return this;

        throw Cr.NS_ERROR_NO_INTERFACE;
    }
};

annotationService.initialize();<commit_msg>[&1.6] Issue 3625: Annotation service fails for long files<commit_after>/* See license.txt for terms of usage */

// ************************************************************************************************
// Constants

const CLASS_ID = Components.ID("{9589DC0D-9709-4578-883E-D393452B3611}");
const CLASS_NAME = "Firebug Annotation Service";
const CONTRACT_ID = "@joehewitt.com/firebug-annotation-service;1";

var EXPORTED_SYMBOLS = ["annotationService"];

const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;

const dirService = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);

// ************************************************************************************************
// Annotation service implementation

var FBTrace = null;

/**
 * @class Represents an internal Firebug annotation service. This service is used to
 * annotate sites with an info whether Firebug should be activated for them or not.
 */

var annotationService =
{
    annotations: [],

    setPageAnnotation: function(uri, value)
    {
        if (FBTrace.DBG_ANNOTATIONS)
            FBTrace.sysout("AnnotationService.setPageAnnotation; " + value + ", " + uri.spec);

        this.annotations[uri.spec] = value;
    },

    getPageAnnotation: function(uri)
    {
        return this.annotations[uri.spec];
    },

    pageHasAnnotation: function(uri)
    {
        return this.annotations[uri.spec] ? true : false;
    },

    removePageAnnotation: function(uri)
    {
        if (FBTrace.DBG_ANNOTATIONS)
            FBTrace.sysout("AnnotationService.removePageAnnotation; " + uri.spec);

        delete this.annotations[uri.spec];
    },

    getAnnotations: function()
    {
        return this.annotations;
    },

    clear: function()
    {
        this.annotations = [];
    },

    initialize: function()
    {
        Components.utils.import("resource://firebug/firebug-trace-service.js");
        FBTrace = traceConsoleService.getTracer("extensions.firebug");

        // Get annotation file stored within the profile directory.
        this.file = dirService.get("ProfD", Ci.nsIFile);
        this.file.append("firebug");
        this.file.append("annotations.json");

        // Load annotations.
        this.loadAnnotations();
    },

    // Persistence
    loadAnnotations: function()
    {
        try
        {
            this.clear();

            if (!this.file.exists())
            {
                this.file.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
                if (FBTrace.DBG_ANNOTATIONS)
                    FBTrace.sysout("AnnotationService.loadAnnotations; Annotations file created " +
                        this.file.path);
                return;
            }

            var inputStream = Cc["@mozilla.org/network/file-input-stream;1"]
                .createInstance(Ci.nsIFileInputStream);
            var cstream = Cc["@mozilla.org/intl/converter-input-stream;1"]
                .createInstance(Ci.nsIConverterInputStream);

            // loadAnnotations input stream.
            inputStream.init(this.file, 0x01 | 0x08, 0666, 0); // read, create
            cstream.init(inputStream, "UTF-8", 0, 0);

            // Load annotations.
            var json = "";
            var data = {};
            while (cstream.readString(-1, data) != 0)
                json += data.value;

            if (!json.length)
                return;

            var nativeJSON = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
            var arr = nativeJSON.decode(json);
            if (!arr)
                return;

            // Convert to map for faster lookup.
            for (var i=0; i<arr.length; i++)
                this.annotations[arr[i].uri] = arr[i].value;

            if (FBTrace.DBG_ANNOTATIONS)
                FBTrace.sysout("AnnotationService.loadAnnotations; Annotations loaded from " +
                    this.file.path, arr);
        }
        catch (err)
        {
            if (FBTrace.DBG_ERRORS || FBTrace.DBG_ANNOTATIONS)
                FBTrace.sysout("AnnotationService.loadAnnotations; EXCEPTION", err);
        }
    },

    flush: function()
    {
        try
        {
            // Initialize output stream.
            var outputStream = Cc["@mozilla.org/network/file-output-stream;1"]
                .createInstance(Ci.nsIFileOutputStream);
            outputStream.init(this.file, 0x02 | 0x08 | 0x20, 0666, 0); // write, create, truncate

            // Convert data to JSON.
            var arr = [];
            for (var uri in this.annotations)
                arr.push({
                    uri: uri,
                    value: this.annotations[uri]
                });

            var nativeJSON = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
            var jsonString = nativeJSON.encode(arr);

            // Store annotations.
            outputStream.write(jsonString, jsonString.length);
            outputStream.close();

            if (FBTrace.DBG_ANNOTATIONS)
                FBTrace.sysout("AnnotationService.loadAnnotations; Annotations stored to " +
                    this.file.path, jsonString);
        }
        catch (err)
        {
            if (FBTrace.DBG_ERRORS || FBTrace.DBG_ANNOTATIONS)
                FBTrace.sysout("AnnotationService.flush; EXCEPTION", err);
        }
    },

    /* nsISupports */
    QueryInterface: function(iid)
    {
        if (iid.equals(Ci.nsISupports))
            return this;

        throw Cr.NS_ERROR_NO_INTERFACE;
    }
};

annotationService.initialize();<|endoftext|>


<commit_before>/* This file is part of Indico.
 * Copyright (C) 2002 - 2016 European Organization for Nuclear Research (CERN).
 *
 * Indico is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * Indico is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Indico; if not, see <http://www.gnu.org/licenses/>.
 */

(function($) {

    $.widget('ui.dropdown', {
        options: {
            selector: '.i-button',
            effect_on: 'slideDown',
            effect_off: 'fadeOut',
            time_on: 200,
            time_off: 200,
            positioning: {},
            relative_to: undefined,
            always_listen: false // if set to true, will trigger 'menu_select' event even when there is a valid href
        },

        _close: function(elem, effect) {
            var ul = elem.next('ul');

            elem.removeClass('open');

            this._effect('off', ul, effect);
            ul.find('ul').hide();
            elem.data('on', false);
            elem.parent().removeClass('selected');
            elem.siblings('ul').find('a').data('on', false);
        },

        _close_all: function(effect) {
            var self = this;

            this.element.find('a, button').each(function() {
                self._close($(this), effect);
            });
        },

        _open: function(elem) {
            var self = this;
            var sibl = elem.next('ul.dropdown');
            var positionReference = this.options.relative_to || elem;

            elem.addClass('open');

            this._effect('on', sibl);
            elem.data('on', true);
            elem.parent().addClass('selected');
            sibl.position($.extend({of: positionReference}, this.options.positioning[sibl.data('level')] ||
                                   {my: 'left top', at: 'left bottom', offset: '0px 0px'}));
            this.element.find('a').each(function() {
                if (this != elem.get(0)) {
                    self._close($(this));
                }
            });
        },

        _menuize: function(elem, selector) {
            var self = this;

            elem.find(this.options.selector).each(function() {
                var $this = $(this);
                if (!$this.attr('href') || $this.attr('href') == "#" || $this.data('ignore-href') !== undefined ||
                        self.options.always_listen) {
                    $this.click(function(e) {
                        if ($this.data('toggle') == 'dropdown') {
                            if ($this.data('on')) {
                                self._close($this);
                            } else if (!$this.hasClass('disabled')) {
                                self._open($this);
                            }
                            e.preventDefault();
                        } else {
                            var result = $this.triggerHandler('menu_select', self.element);
                            if (!result) {
                                self._close_all();
                            }
                            e.preventDefault();
                        }
                    });
                }
            });

            elem.find('ul.dropdown > li > a').each(function() {
                var $this = $(this);
                if (!$this.attr('href') || $this.attr('href') == "#" || $this.data('ignore-href') !== undefined ||
                        self.options.always_listen) {
                    $this.click(function(e) {
                        var result = $this.triggerHandler('menu_select', self.element);
                        if(!result) {
                            self._close_all();
                        }
                        e.preventDefault();
                    });
                }
            });

            elem.find('ul.dropdown > li.toggle').each(function() {
                var li = $(this);
                var link = $('<a>', {
                    'href': '#',
                    'text': li.text(),
                    'class': 'icon-checkmark ' + (li.data('state') ? '' : 'inactive'),
                    'click': function(e) {
                        e.preventDefault();
                        var $this = $(this);
                        var newState = !li.data('state');
                        $this.toggleClass('inactive', !newState);
                        li.data('state', newState);
                        li.triggerHandler('menu_toggle', [newState]);
                    }
                });
                li.html(link);
            });
        },

        _create: function() {
            var self = this;
            this._menuize(this.element);
            $(document).on('click', function(e){
                // click outside? close menus.
                if ($(self.element).has(e.target).length == 0) {
                    self._close_all();
                }
            });
        },

        _effect: function(st, elem, effect) {
            var func = effect === undefined ? this.options['effect_' + st] : effect;

            if (func === null) {
                // no pretty effects
                elem.hide();
            }
            else if (typeof func == 'function') {
                func.call(elem, this);
            }
            else {
                elem[func].call(elem, this.options['time_' + st]);
            }
        },

        close: function() {
            this._close_all(null);
        }
    });
})(jQuery);
<commit_msg>Code style fixes<commit_after>/* This file is part of Indico.
 * Copyright (C) 2002 - 2016 European Organization for Nuclear Research (CERN).
 *
 * Indico is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * Indico is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Indico; if not, see <http://www.gnu.org/licenses/>.
 */

(function($) {
    'use strict';

    $.widget('ui.dropdown', {
        options: {
            selector: '.i-button',
            effect_on: 'slideDown',
            effect_off: 'fadeOut',
            time_on: 200,
            time_off: 200,
            positioning: {},
            relative_to: undefined,
            always_listen: false // if set to true, will trigger 'menu_select' event even when there is a valid href
        },

        _close: function(elem, effect) {
            var ul = elem.next('ul');

            elem.removeClass('open');

            this._effect('off', ul, effect);
            ul.find('ul').hide();
            elem.data('on', false);
            elem.parent().removeClass('selected');
            elem.siblings('ul').find('a').data('on', false);
        },

        _close_all: function(effect) {
            var self = this;

            this.element.find('a, button').each(function() {
                self._close($(this), effect);
            });
        },

        _open: function(elem) {
            var self = this;
            var sibl = elem.next('ul.dropdown');
            var positionReference = this.options.relative_to || elem;

            elem.addClass('open');

            this._effect('on', sibl);
            elem.data('on', true);
            elem.parent().addClass('selected');
            sibl.position($.extend({of: positionReference}, this.options.positioning[sibl.data('level')] ||
                                   {my: 'left top', at: 'left bottom', offset: '0px 0px'}));
            this.element.find('a').each(function() {
                if (this !== elem.get(0)) {
                    self._close($(this));
                }
            });
        },

        _menuize: function(elem) {
            var self = this;

            elem.find(this.options.selector).each(function() {
                var $this = $(this);
                if (!$this.attr('href') || $this.attr('href') === "#" || $this.data('ignore-href') !== undefined ||
                        self.options.always_listen) {
                    $this.click(function(e) {
                        if ($this.data('toggle') === 'dropdown') {
                            if ($this.data('on')) {
                                self._close($this);
                            } else if (!$this.hasClass('disabled')) {
                                self._open($this);
                            }
                            e.preventDefault();
                        } else {
                            var result = $this.triggerHandler('menu_select', self.element);
                            if (!result) {
                                self._close_all();
                            }
                            e.preventDefault();
                        }
                    });
                }
            });

            elem.find('ul.dropdown > li > a').each(function() {
                var $this = $(this);
                if (!$this.attr('href') || $this.attr('href') === "#" || $this.data('ignore-href') !== undefined ||
                        self.options.always_listen) {
                    $this.click(function(e) {
                        var result = $this.triggerHandler('menu_select', self.element);
                        if (!result) {
                            self._close_all();
                        }
                        e.preventDefault();
                    });
                }
            });

            elem.find('ul.dropdown > li.toggle').each(function() {
                var li = $(this);
                var link = $('<a>', {
                    href: '#',
                    text: li.text(),
                    class: 'icon-checkmark ' + (li.data('state') ? '' : 'inactive'),
                    click: function(e) {
                        e.preventDefault();
                        var $this = $(this);
                        var newState = !li.data('state');
                        $this.toggleClass('inactive', !newState);
                        li.data('state', newState);
                        li.triggerHandler('menu_toggle', [newState]);
                    }
                });
                li.html(link);
            });
        },

        _create: function() {
            var self = this;
            this._menuize(this.element);
            $(document).on('click', function(e) {
                // click outside? close menus.
                if ($(self.element).has(e.target).length === 0) {
                    self._close_all();
                }
            });
        },

        _effect: function(st, elem, effect) {
            var func = effect === undefined ? this.options['effect_' + st] : effect;

            if (func === null) {
                // no pretty effects
                elem.hide();
            } else if (typeof func == 'function') {
                func.call(elem, this);
            } else {
                elem[func].call(elem, this.options['time_' + st]);
            }
        },

        close: function() {
            this._close_all(null);
        }
    });
})(jQuery);
<|endoftext|>


<commit_before>import * as ScriptLoader from "../util/ScriptLoader.js";
import * as ValueMax from "../util/ValueMax.js";
import * as PartTime from "../util/PartTime.js";
import * as Pool from "../util/Pool.js";
import * as Base64ToUint8Array_tester from "./Base64ToUint8Array_tester.js";
import * as GSheets_tester from "./GSheets_tester.js";
import * as AsyncWorker_tester from "./AsyncWorker_tester.js";
import * as jsPerf_NeuralWorker from "../jsPerf/jsPerf_NeuralWorker.js";

window.addEventListener( "load", event => {
  ScriptLoader
    .createPromise(
      "https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@3.19.0/dist/tf.min.js" )
    .then( test );
});

function test() {
  console.log("util testing...");
  let delayMilliseconds = 100;

  let pool_all_issuedCount_before = Pool.All.issuedCount;

  // Aggregate all progress about util_tester.
  let progress = ValueMax.Percentage.Aggregate.Pool.get_or_create_by();

  let progress_Base64ToUint8Array_tester = progress.child_add(
    ValueMax.Percentage.Aggregate.Pool.get_or_create_by() );

  let progress_GSheets_tester = progress.child_add(
    ValueMax.Percentage.Aggregate.Pool.get_or_create_by() );

  let progress_AsyncWorker_tester = progress.child_add(
    ValueMax.Percentage.Aggregate.Pool.get_or_create_by() );

  let progress_jsPerf_NeuralWorker_cpu = progress.child_add(
    ValueMax.Percentage.Aggregate.Pool.get_or_create_by() );

  let progress_jsPerf_NeuralWorker_webgl = progress.child_add(
    ValueMax.Percentage.Aggregate.Pool.get_or_create_by() );

  let progressReceiver
    = new ValueMax.Receiver.HTMLProgress.createByTitle_or_getDummy( "TestProgressBar" );

  async function* testerAll() {
    yield* jsPerf_NeuralWorker.tester( progress_jsPerf_NeuralWorker_cpu, "cpu" );
    yield* jsPerf_NeuralWorker.tester( progress_jsPerf_NeuralWorker_webgl, "webgl" );
    yield* AsyncWorker_tester.tester( progress_AsyncWorker_tester );
    yield* Base64ToUint8Array_tester.tester( progress_Base64ToUint8Array_tester );
    yield* GSheets_tester.tester( progress_GSheets_tester );
  }

  let tester = testerAll();

  let testPromise = PartTime.forOf(
    tester,
    ( progressRoot ) => {
      progressReceiver.setValueMax( // Report progress to UI.
        progressRoot.valuePercentage, progressRoot.maxPercentage );
    },
    () => { // Release resource.

      if ( 100 != progress.valuePercentage )
        throw Error( `util_tester.test(): `
          + `Progress (${progress.valuePercentage}) should be 100 `
          + `after testing done.`);

      progress.disposeResources_and_recycleToPool();
      progress = null;

      Pool.Asserter.assert_Pool_issuedCount( "util_tester.test()", pool_all_issuedCount_before );
    },
    delayMilliseconds
  ).then(r => {
  });

//   progressReceiver.informDone(r); // Inform UI progress done.

  testPromise.then(values => {
    console.log( "util testing... Done." );
  });

//!!! ...unfinished... test case by multipler web worker?
}
<commit_msg>try await import() in WorkerBodyStub.<commit_after>import * as ScriptLoader from "../util/ScriptLoader.js";
import * as ValueMax from "../util/ValueMax.js";
import * as PartTime from "../util/PartTime.js";
import * as Pool from "../util/Pool.js";
import * as Base64ToUint8Array_tester from "./Base64ToUint8Array_tester.js";
import * as GSheets_tester from "./GSheets_tester.js";
import * as AsyncWorker_tester from "./AsyncWorker_tester.js";
import * as jsPerf_NeuralWorker from "../jsPerf/jsPerf_NeuralWorker.js";

window.addEventListener( "load", event => {
  ScriptLoader
    .createPromise(
      "https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@3.19.0/dist/tf.min.js" )
    .then( test );
});

function test() {
  console.log("util testing...");
  let delayMilliseconds = 100;

  let pool_all_issuedCount_before = Pool.All.issuedCount;

  // Aggregate all progress about util_tester.
  let progress = ValueMax.Percentage.Aggregate.Pool.get_or_create_by();

  let progress_Base64ToUint8Array_tester = progress.child_add(
    ValueMax.Percentage.Aggregate.Pool.get_or_create_by() );

  let progress_GSheets_tester = progress.child_add(
    ValueMax.Percentage.Aggregate.Pool.get_or_create_by() );

  let progress_AsyncWorker_tester = progress.child_add(
    ValueMax.Percentage.Aggregate.Pool.get_or_create_by() );

  let progress_jsPerf_NeuralWorker_cpu = progress.child_add(
    ValueMax.Percentage.Aggregate.Pool.get_or_create_by() );

  let progress_jsPerf_NeuralWorker_webgl = progress.child_add(
    ValueMax.Percentage.Aggregate.Pool.get_or_create_by() );

  let progressReceiver
    = new ValueMax.Receiver.HTMLProgress.createByTitle_or_getDummy( "TestProgressBar" );

  async function* testerAll() {
    yield* AsyncWorker_tester.tester( progress_AsyncWorker_tester );
    yield* jsPerf_NeuralWorker.tester( progress_jsPerf_NeuralWorker_cpu, "cpu" );
    yield* jsPerf_NeuralWorker.tester( progress_jsPerf_NeuralWorker_webgl, "webgl" );
    yield* Base64ToUint8Array_tester.tester( progress_Base64ToUint8Array_tester );
    yield* GSheets_tester.tester( progress_GSheets_tester );
  }

  let tester = testerAll();

  let testPromise = PartTime.forOf(
    tester,
    ( progressRoot ) => {
      progressReceiver.setValueMax( // Report progress to UI.
        progressRoot.valuePercentage, progressRoot.maxPercentage );
    },
    () => { // Release resource.

      if ( 100 != progress.valuePercentage )
        throw Error( `util_tester.test(): `
          + `Progress (${progress.valuePercentage}) should be 100 `
          + `after testing done.`);

      progress.disposeResources_and_recycleToPool();
      progress = null;

      Pool.Asserter.assert_Pool_issuedCount( "util_tester.test()", pool_all_issuedCount_before );
    },
    delayMilliseconds
  ).then(r => {
  });

//   progressReceiver.informDone(r); // Inform UI progress done.

  testPromise.then(values => {
    console.log( "util testing... Done." );
  });

//!!! ...unfinished... test case by multipler web worker?
}
<|endoftext|>