<commit_before>App.info({
  id: 'br.com.app.sistemameionorte',
  name: 'Meio Norte',
  description: 'Aplicativo Interativo Sistema Meio Norte de Comunicação',
  version: '0.1.30'
});

App.icons({

  // iOS
  // 'iphone': 'public/icons/ios/Icon-60.png',
  // 'iphone_2x': 'public/icons/ios/AppIcon.appiconset/Icon-60@2x.png',
  // 'ipad': 'public/icons/ios/Icon-72.png',
  // 'ipad_2x': 'public/icons/ios/Icon-72@2x.png',

  // Android
  'android_ldpi': 'public/icons/android/drawable-ldpi/ic_launcher.png',
  'android_mdpi': 'public/icons/android/drawable-mdpi/ic_launcher.png',
  'android_hdpi': 'public/icons/android/drawable-hdpi/ic_launcher.png',
  'android_xhdpi': 'public/icons/android/drawable-xhdpi/ic_launcher.png'

});

App.launchScreens({

  // iOS
  // 'iphone': 'public/images/splash/splash-320x480.png',
  // 'iphone_2x': 'public/images/splash/splash-320x480@2x.png',
  // 'iphone5': 'public/images/splash/splash-320x568@2x.png',
  // 'ipad_portrait': 'public/images/splash/splash-768x1024.png',
  // 'ipad_portrait_2x': 'public/images/splash/splash-768x1024@2x.png',
  // 'ipad_landscape': 'public/images/splash/splash-1024x768.png',
  // 'ipad_landscape_2x': 'public/images/splash/splash-1024x768@2x.png',

  // Android
  'android_ldpi_portrait': 'public/splash/android/drawable-ldpi/screen.png',
  'android_ldpi_landscape': 'public/splash/android/drawable-land-ldpi/screen.png',
  'android_mdpi_portrait': 'public/splash/android/drawable-mdpi/screen.png',
  'android_mdpi_landscape': 'public/splash/android/drawable-land-mdpi/screen.png',
  'android_hdpi_portrait': 'public/splash/android/drawable-hdpi/screen.png',
  'android_hdpi_landscape': 'public/splash/android/drawable-land-hdpi/screen.png',
  'android_xhdpi_portrait': 'public/splash/android/drawable-xhdpi/screen.png',
  'android_xhdpi_landscape': 'public/splash/android/drawable-land-xhdpi/screen.png'
});

App.setPreference('BackgroundColor', '0xffffffff');
App.setPreference('HideKeyboardFormAccessoryBar', true);
App.setPreference('StatusBarOverlaysWebView', 'true');
App.setPreference('StatusBarStyle', 'lightcontent');
App.setPreference("SplashScreenDelay", 20000);

// cordova plugin facebook
App.configurePlugin('com.phonegap.plugins.facebookconnect', {
     APP_ID: '638977909535835',
     APP_NAME: 'vtv'
});

// // regras de acesso cross origen
App.accessRule("*");
App.accessRule("*://*.meteor.com");
// //App.accessRule("*://localhost:3010/*");
<commit_msg>versao<commit_after>App.info({
  id: 'br.com.app.sistemameionorte',
  name: 'Meio Norte',
  description: 'Aplicativo Interativo Sistema Meio Norte de Comunicação',
  version: '0.1.31'
});

App.icons({

  // iOS
  // 'iphone': 'public/icons/ios/Icon-60.png',
  // 'iphone_2x': 'public/icons/ios/AppIcon.appiconset/Icon-60@2x.png',
  // 'ipad': 'public/icons/ios/Icon-72.png',
  // 'ipad_2x': 'public/icons/ios/Icon-72@2x.png',

  // Android
  'android_ldpi': 'public/icons/android/drawable-ldpi/ic_launcher.png',
  'android_mdpi': 'public/icons/android/drawable-mdpi/ic_launcher.png',
  'android_hdpi': 'public/icons/android/drawable-hdpi/ic_launcher.png',
  'android_xhdpi': 'public/icons/android/drawable-xhdpi/ic_launcher.png'

});

App.launchScreens({

  // iOS
  // 'iphone': 'public/images/splash/splash-320x480.png',
  // 'iphone_2x': 'public/images/splash/splash-320x480@2x.png',
  // 'iphone5': 'public/images/splash/splash-320x568@2x.png',
  // 'ipad_portrait': 'public/images/splash/splash-768x1024.png',
  // 'ipad_portrait_2x': 'public/images/splash/splash-768x1024@2x.png',
  // 'ipad_landscape': 'public/images/splash/splash-1024x768.png',
  // 'ipad_landscape_2x': 'public/images/splash/splash-1024x768@2x.png',

  // Android
  'android_ldpi_portrait': 'public/splash/android/drawable-ldpi/screen.png',
  'android_ldpi_landscape': 'public/splash/android/drawable-land-ldpi/screen.png',
  'android_mdpi_portrait': 'public/splash/android/drawable-mdpi/screen.png',
  'android_mdpi_landscape': 'public/splash/android/drawable-land-mdpi/screen.png',
  'android_hdpi_portrait': 'public/splash/android/drawable-hdpi/screen.png',
  'android_hdpi_landscape': 'public/splash/android/drawable-land-hdpi/screen.png',
  'android_xhdpi_portrait': 'public/splash/android/drawable-xhdpi/screen.png',
  'android_xhdpi_landscape': 'public/splash/android/drawable-land-xhdpi/screen.png'
});

App.setPreference('BackgroundColor', '0xffffffff');
App.setPreference('HideKeyboardFormAccessoryBar', true);
App.setPreference('StatusBarOverlaysWebView', 'true');
App.setPreference('StatusBarStyle', 'lightcontent');
App.setPreference("SplashScreenDelay", 20000);

// cordova plugin facebook
App.configurePlugin('com.phonegap.plugins.facebookconnect', {
     APP_ID: '638977909535835',
     APP_NAME: 'vtv'
});

// // regras de acesso cross origen
App.accessRule("*");
App.accessRule("*://*.meteor.com");
// //App.accessRule("*://localhost:3010/*");
<|endoftext|>


<commit_before>class MediaInfo {
	constructor(device, platform) {
		this.device = undefined;
		this.platform = undefined;
		this.ip = undefined;
		this.product = undefined;
		this.title = undefined;
		this.state = undefined;

	}
}

module.exports = MediaInfo;<commit_msg>For some reason this was player info, but it is now been replaced with all the variables specific for mediaInfo<commit_after>class MediaInfo {
	constructor() {
		this.duration = undefined;
		this.height = undefined;
		this.width = undefined;
		this.bitrate = undefined;
		this.resolution = undefined;
		this.framerate = undefined;
		this.protocol = undefined;
		this.container = undefined;
		this.audioCodec = undefined;
	}
}

module.exports = MediaInfo;<|endoftext|>


<commit_before>const db = require('../../../database/schemas.js');

module.exports = {
  getOne: (req, res) => {
    db.Post.findOne({
      where: {
        id: req.params.listId,
      },
    })
    .then((listing) => {
      res.send(listing);
    });
  },

  getAll: (req, res) => {
    db.Post.findAll({})
    .then((listings) => {
      res.send(listings);
    });
  },

  createOne: (req, res) => {
    db.Post.create({
      body: req.body.body,
      tags: req.body.tags,
      user_id: req.params.id,
    })
    .then((listing) => {
      res.send(listing);
    });
  },

  patchOne: (req, res) => {
    db.Post.update(req.body, {
      where: {
        id: req.params.listId,
      },
    })
    .then((status) => {
      res.send(status);
    });
  },

  deleteOne: (req, res) => {
    db.Post.destroy({
      where: {
        id: req.params.listId,
      },
    })
    .then((status) => {
      if (status === 1) {
        res.send('listing deleted!');
      } else {
        res.send('listing wasn\'t found');
      }
    });
  },

  getAllPhotos: (req, res) => {
    db.Picture.findAll({
      where: {
        post_id: req.params.listId,
      },
    })
    .then((photos) => {
      res.send(photos);
    });
  },

  createOnePhoto: (req, res) => {
    db.Picture.create({
      img_name: req.body.img_name,
      img_path: req.body.img_path,
      post_id: req.params.listId,
    })
    .then((photoData) => {
      res.send(photoData);
    });
  },

  patchOnePhoto: (req, res) => {

  },

  deleteOnePhoto: (req, res) => {

  },
};
<commit_msg>Implement the patchOnePhoto callback for listingController. Close #55<commit_after>const db = require('../../../database/schemas.js');

module.exports = {
  getOne: (req, res) => {
    db.Post.findOne({
      where: {
        id: req.params.listId,
      },
    })
    .then((listing) => {
      res.send(listing);
    });
  },

  getAll: (req, res) => {
    db.Post.findAll({})
    .then((listings) => {
      res.send(listings);
    });
  },

  createOne: (req, res) => {
    db.Post.create({
      body: req.body.body,
      tags: req.body.tags,
      user_id: req.params.id,
    })
    .then((listing) => {
      res.send(listing);
    });
  },

  patchOne: (req, res) => {
    db.Post.update(req.body, {
      where: {
        id: req.params.listId,
      },
    })
    .then((status) => {
      res.send(status);
    });
  },

  deleteOne: (req, res) => {
    db.Post.destroy({
      where: {
        id: req.params.listId,
      },
    })
    .then((status) => {
      if (status === 1) {
        res.send('listing deleted!');
      } else {
        res.send('listing wasn\'t found');
      }
    });
  },

  getAllPhotos: (req, res) => {
    db.Picture.findAll({
      where: {
        post_id: req.params.listId,
      },
    })
    .then((photos) => {
      res.send(photos);
    });
  },

  createOnePhoto: (req, res) => {
    db.Picture.create({
      img_name: req.body.img_name,
      img_path: req.body.img_path,
      post_id: req.params.listId,
    })
    .then((photoData) => {
      res.send(photoData);
    });
  },

  patchOnePhoto: (req, res) => {
    db.Picture.update(
      {
        img_name: req.body.img_name,
        img_path: req.body.img_path,
      },
      {
        where: {
          id: req.params.id,
        },
      })
    .then((status) => {
      res.send(status);
    });
  },

  deleteOnePhoto: (req, res) => {

  },
};
<|endoftext|>


<commit_before>const PlotCard = require('../../../plotcard.js');

class AClashOfKings extends PlotCard {
    setupCardAbilities() {
        this.reaction({
            when: {
                afterChallenge: (e, challenge) => (
                    challenge.winner === this.controller &&
                    challenge.challengeType === 'power' &&
                    challenge.loser.power > 0
                )
            },
            handler: () => {
                var challenge = this.game.currentChallenge;
                this.game.addMessage('{0} uses {1} to move 1 power from {2}\'s faction card to their own', challenge.winner, this, challenge.loser);
                this.game.transferPower(challenge.winner, challenge.loser, 1);
            }
        });
    }
}

AClashOfKings.code = '01001';

module.exports = AClashOfKings;
<commit_msg>Fix a clash of kings (#273)<commit_after>const PlotCard = require('../../../plotcard.js');

class AClashOfKings extends PlotCard {
    setupCardAbilities() {
        this.reaction({
            when: {
                afterChallenge: (e, challenge) => (
                    challenge.winner === this.controller &&
                    challenge.challengeType === 'power' &&
                    challenge.loser.faction.power > 0
                )
            },
            handler: () => {
                var challenge = this.game.currentChallenge;
                this.game.addMessage('{0} uses {1} to move 1 power from {2}\'s faction card to their own', challenge.winner, this, challenge.loser);
                this.game.transferPower(challenge.winner, challenge.loser, 1);
            }
        });
    }
}

AClashOfKings.code = '01001';

module.exports = AClashOfKings;
<|endoftext|>


<commit_before>
var Plugin = require('nokomis/plugin')
var Negotiator = require('negotiator')

var ContentNegotiator = module.exports = Plugin.extend({

  run: function(instance, callback) {
    instance._neg = new Negotiator(instance.req)
    callback()
  },

  preferredMediaType: function() {
    return this._neg.preferredMediaType.apply(this._neg, arguments)
  },

  preferredMediaTypes: function() {
    return this._neg.preferredMediaTypes.apply(this._neg, arguments)
  },

  preferredLanguage: function() {
    return this._neg.preferredLanguage.apply(this._neg, arguments)
  },

  preferredLanguages: function() {
    return this._neg.preferredLanguages.apply(this._neg, arguments)
  },

  preferredEncoding: function() {
    return this._neg.preferredEncoding.apply(this._neg, arguments)
  },

  preferredEncodings: function() {
    return this._neg.preferredEncodings.apply(this._neg, arguments)
  },

  mediaType: function() {
    var type = this.preferredMediaType(this.availableMediaTypes)
    return type || this._defaultMediaType
  }

})
<commit_msg>content negotiation happens based on format param now<commit_after>
var Plugin = require('nokomis/plugin')
var Negotiator = require('negotiator')
var Url = require('url')

var formatMap = {
  'html': 'text/html',
  'json': 'application/json',
  'xml': 'application/xml'
}

var ContentNegotiator = module.exports = Plugin.extend({

  run: function(instance, callback) {
    instance._neg = new Negotiator(instance.req)
    callback()
  },

  preferredMediaType: function() {
    return this._neg.preferredMediaType.apply(this._neg, arguments)
  },

  preferredMediaTypes: function() {
    return this._neg.preferredMediaTypes.apply(this._neg, arguments)
  },

  preferredLanguage: function() {
    return this._neg.preferredLanguage.apply(this._neg, arguments)
  },

  preferredLanguages: function() {
    return this._neg.preferredLanguages.apply(this._neg, arguments)
  },

  preferredEncoding: function() {
    return this._neg.preferredEncoding.apply(this._neg, arguments)
  },

  preferredEncodings: function() {
    return this._neg.preferredEncodings.apply(this._neg, arguments)
  },

  mediaType: function() {
    var availableTypes = this.availableMediaTypes

    var fmt = this.route.params.format
    if (fmt && fmt in formatMap) {
      fmt = formatMap[fmt]
      if (~availableTypes.indexOf(fmt)) {
        availableTypes = [fmt]
      }
    }

    var type = this.preferredMediaType(availableTypes)
    return type || this._defaultMediaType
  }

})
<|endoftext|>


<commit_before>'use strict';

const db = require('./../../../database/dbHelpers.js');
const _id = '_id';
const all = '*';

function combineTagsAndCards(cards, tags) {
  return cards.map(card => {
    const newCard = card;
    newCard.tags_ids = newCard.tags_ids.map(tagID => {
      const newTag = tags[tagID];
      return newTag;
    });
    return newCard;
  });
}

const savePin = function* () {
  let imageData;
  const fields = this.request.body.fields;
  yield db.cloudinaryUpload(this.request.body.files.file.path, data => (imageData = data));
  fields.image_url = imageData.url;
  yield db.queryDB(db.insertQueryBuilder(db.TAGS, fields.tags));
  fields.tags = yield db.queryDB(
    db.selectQueryBuilder(db.TAGS, { column: _id, params: fields.tags.split(' ') })
  );
  const result = yield db.queryDB(db.insertQueryBuilder(db.CARDS, fields));
  if (result.command === 'INSERT' && result.rowCount === 1) {
    this.response.status = 200;
  }
};

const getPins = function* () {
  const tags = this.request.query.tags.split(',');
  const tagQuery = yield db.queryDB(
    db.selectQueryBuilder(db.TAGS, { column: all, params: tags })
  );

  const tagsAndIDs = tagQuery.rows.reduce((tagsObject, tag) => {
    const tagsObj = tagsObject;
    tagsObj[tag._id] = tag.tag;
    return tagsObj;
  }, {});

  const cardsQuery = yield db.queryDB(
    db.selectQueryBuilder(db.CARDS, {
      column: [all],
      params: tagQuery.rows
    })
  );
  this.status = 200;
  this.body = combineTagsAndCards(cardsQuery.rows, tagsAndIDs);
};

module.exports = {
  savePin,
  getPins
};
<commit_msg>[fix] on pin save only saves unique tags<commit_after>'use strict';

const db = require('./../../../database/dbHelpers.js');
const _id = '_id';
const all = '*';

function combineTagsAndCards(cards, tags) {
  return cards.map(card => {
    const newCard = card;
    newCard.tags_ids = newCard.tags_ids.map(tagID => {
      const newTag = tags[tagID];
      return newTag;
    });
    return newCard;
  });
}

const savePin = function* () {
  let imageData;
  const fields = this.request.body.fields;
  const tags = fields.tags.split(' ');
  const availableTags = yield db.queryDB(
    db.selectQueryBuilder(db.TAGS, { column: all, params: tags })
  );
  const extractedTags = availableTags.rows.map(tagRow => tagRow.tag);
  const tagsToSave = tags.filter(tag => extractedTags.indexOf(tag) === -1).join(' ');
  yield db.cloudinaryUpload(this.request.body.files.file.path, data => (imageData = data));
  fields.image_url = imageData.url;
  yield db.queryDB(db.insertQueryBuilder(db.TAGS, tagsToSave));
  fields.tags = yield db.queryDB(
    db.selectQueryBuilder(db.TAGS, { column: _id, params: fields.tags.split(' ') })
  );
  const result = yield db.queryDB(db.insertQueryBuilder(db.CARDS, fields));
  if (result.command === 'INSERT' && result.rowCount === 1) {
    this.response.status = 200;
  }
};

const getPins = function* () {
  const tags = this.request.query.tags.split(',');
  const tagQuery = yield db.queryDB(
    db.selectQueryBuilder(db.TAGS, { column: all, params: tags })
  );

  const tagsAndIDs = tagQuery.rows.reduce((tagsObject, tag) => {
    const tagsObj = tagsObject;
    tagsObj[tag._id] = tag.tag;
    return tagsObj;
  }, {});

  const cardsQuery = yield db.queryDB(
    db.selectQueryBuilder(db.CARDS, {
      column: [all],
      params: tagQuery.rows
    })
  );
  this.status = 200;
  this.body = combineTagsAndCards(cardsQuery.rows, tagsAndIDs);
};

module.exports = {
  savePin,
  getPins
};
<|endoftext|>


<commit_before>var keystone = require('keystone'),
	Types = keystone.Field.Types;

// Create model. Additional options allow menu name to be used what auto-generating URLs
var Agency = new keystone.List('Agency', {
	track: true,
	autokey: { path: 'key', from: 'code', unique: true },
	map: { name: 'code' }
});

// Create fields
Agency.add({
	code: { type: Types.Text, label: 'agency code', required: true, initial: true },
	name: { type: Types.Text, label: 'agency name', required: true, initial: true },

	phone: { type: Types.Text, label: 'phone number', initial: true },
	fax: { type: Types.Text, label: 'fax number', initial: true },

	address: {
		street1: { type: Types.Text, label: 'street 1', initial: true },
		street2: { type: Types.Text, label: 'street 2', initial: true },
		city: { type: Types.Text, label: 'city', initial: true },
		state: { type: Types.Relationship, label: 'state', ref: 'State', initial: true },
		zipCode: { type: Types.Text, label: 'zip code', initial: true },
		region: { type: Types.Relationship, label: 'region', ref: 'Region', initial: true }
	},

	url: { type: Types.Text, label: 'agency url', initial: true },
	generalInquiryContact: { type: Types.Email, label: 'general inquiry contact', initial: true }

/* Container for data migration fields ( these should be kept until after phase 2 and the old system is phased out completely ) */
}, {
	// system field to store an appropriate file prefix
	oldId: { type: Types.Text, hidden: true }

});

// Set up relationship values to show up at the bottom of the model if any exist
Agency.relationship({ ref: 'Social Worker', refPath: 'agency', path: 'agency', label: 'agency contacts' });
Agency.relationship({ ref: 'Inquiry', refPath: 'agency', path: 'agency', label: 'inquries' });
Agency.relationship({ ref: 'Inquiry', refPath: 'agencyReferral', path: 'agencyReferral', label: 'agency referral inquiries' });

// Define default columns in the admin interface and register the model
Agency.defaultColumns = 'code, name, phone';
Agency.register();<commit_msg>#23 | note relationship display behavior in Agency for future implementation<commit_after>var keystone = require('keystone'),
	Types = keystone.Field.Types;

// Create model. Additional options allow menu name to be used what auto-generating URLs
var Agency = new keystone.List('Agency', {
	track: true,
	autokey: { path: 'key', from: 'code', unique: true },
	map: { name: 'code' }
});

// Create fields
Agency.add({
	code: { type: Types.Text, label: 'agency code', required: true, initial: true },
	name: { type: Types.Text, label: 'agency name', required: true, initial: true },

	phone: { type: Types.Text, label: 'phone number', initial: true },
	fax: { type: Types.Text, label: 'fax number', initial: true },

	address: {
		street1: { type: Types.Text, label: 'street 1', initial: true },
		street2: { type: Types.Text, label: 'street 2', initial: true },
		city: { type: Types.Text, label: 'city', initial: true },
		state: { type: Types.Relationship, label: 'state', ref: 'State', initial: true },
		zipCode: { type: Types.Text, label: 'zip code', initial: true },
		region: { type: Types.Relationship, label: 'region', ref: 'Region', initial: true }
	},

	url: { type: Types.Text, label: 'agency url', initial: true },
	generalInquiryContact: { type: Types.Email, label: 'general inquiry contact', initial: true }

/* Container for data migration fields ( these should be kept until after phase 2 and the old system is phased out completely ) */
}, {
	// system field to store an appropriate file prefix
	oldId: { type: Types.Text, hidden: true }

});

// Set up relationship values to show up at the bottom of the model if any exist
// TODO: set up a relationship for Social Workers as agency contacts.  This doesn't seem to work as Social Worker extends User
Agency.relationship({ ref: 'Inquiry', refPath: 'agency', path: 'agency', label: 'inquries' });
Agency.relationship({ ref: 'Inquiry', refPath: 'agencyReferral', path: 'agencyReferral', label: 'agency referral inquiries' });

// Define default columns in the admin interface and register the model
Agency.defaultColumns = 'code, name, phone';
Agency.register();<|endoftext|>


<commit_before>const rp = require('request-promise');
const logger = require('./Logger');
	class Deezer {

		constructor() {
		}

		search(q) {
			return rp(`https://api.deezer.com/search/playlist?q=${q}`);
		}

		getPlaylist(q) {
			//let weather = ['clear sky', 'broken clouds'];
			/*
			if (/(clear sky)|(few|scattered) clouds/.test(q)) {
				q = ['clear sky', 'sun shining', 'sunny', 'sunshine'];
			} else if (/(broken|overcast) clouds/.test(q)) {
				q = ['clouds'];
			}
			*/
			return this.search(q).then((res) => {
				let plNames = JSON.parse(res).data.map(pl => pl.title);
				logger.cacheSet('matchingPlaylists', plNames);
				return this.getTracks(JSON.parse(res))
			});
		}

		getTracks(res) {
			const limit = res.total >= 25 ? 24 : res.total - 1;
			const idx = Math.floor(Math.random() * (limit + 1));
			//console.log('\n-----------\nDEEZER RESPONSE:', res.total);
			//console.log(`INDEX  --> ${idx}`);
			const playlistData = res.data[idx];
			logger.cacheSet('playlistData', playlistData);

			const playlistTracksUrl = playlistData['tracklist'];

			//console.log('DATA', res.data[idx]);

			return rp(playlistTracksUrl).then((res) => {
				return this.processPlaylistTracks(playlistData, JSON.parse(res))
			});

		}

		processPlaylistTracks(plData, res) {

				const tracks = res.data.map((el) => {
				return {
					title: el.title,
					duration: el.duration,
					source: el.preview,
					artist: el.artist.name,
					cover: el.album.cover_small
				}
			});

			plData = {
				title: plData.title,
				link: plData.link,
				cover: plData.picture,
				author: plData.user.name
			};

			plData.tracks = tracks;
			return plData;
		}

	}

module.exports = Deezer;<commit_msg>reduce unneeded methods<commit_after>const rp = require('request-promise');
const logger = require('./Logger');
class Deezer {

	constructor() {
	}

	search(q) {
		return rp(`https://api.deezer.com/search/playlist?q=${q}`);
	}

	getPlaylist(q) {
		// get daytime && season also ?
		var t_q;
		if (/(clear sky)|(few|scattered) clouds/.test(q)) {
			t_q = ['clear sky', 'sun shining', 'sunny', 'sunshine'];
		} else if (/(broken|overcast) clouds/.test(q)) {
			t_q = ['clouds'];
		} else if (/drizzle|rain/.test(q)) {
			t_q = ['rainy']
		}

		return Promise.all(
			t_q.map((el) => this.search(el))
		).then((res) => {
			let plNames = res
				.map((el) => {
					return JSON.parse(el).data.map((elInner) => {
						return {
							title: elInner.title,
							url: elInner.tracklist,
							cover: elInner.picture,
							author: elInner.user.name
						}
					});
				})
				.reduce((a, b) => {
					return a.concat(b);
				});

			const limit = plNames.length >= 25 ? 24 : plNames.length - 1;
			const idx = Math.floor(Math.random() * (limit + 1));

			logger.cacheSet('playlists', plNames[idx]);
			logger.cacheSet('playlists', plNames.map(el => el.title));

			var pl = plNames[idx];
			const url = plNames[idx].url;

			return rp(url).then((res) => (Object.assign(pl, JSON.parse(res))));
		});
	}
}

module.exports = Deezer;<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

function propertyInstall(proto) {
  proto[constantize(this.name)] = this;

  var name            = this.name;
  var slotName        = name + '$';
  var adapt           = this.adapt
  var preSet          = this.preSet;
  var postSet         = this.postSet;
  var getter          = this.getter;
  var setter          = this.setter;
  var factory         = this.factory;
  var hasDefaultValue = this.hasOwnProperty('defaultValue');
  var defaultValue    = this.defaultValue;

  /* Future
     Object.defineProperty(proto, slotName, {
     get: function propSlotGetter() {
     return this.getSlot(name);
     },
     set: function propSlotSetter(value) {
     value.link.link(this.getSlot(name));
     },
     configurable: true
     });
  */

  console.log('Defining Property ', proto.model_.name, name);
  Object.defineProperty(proto, name, {
    get: function propGetter() {
      if ( getter ) return getter.call(this);

      if ( ( hasDefaultValue || factory ) &&
           ! this.instance_.hasOwnProperty(name) )
      {
        if ( hasDefaultValue ) return defaultValue;

        var value = factory.call(this);
        this.instance_[name] = value;
        return value;
      }

      return this.instance_[name];
    },
    set: function propSetter(newValue) {
      if ( setter ) {
        setter.call(this, newValue);
        return;
      }

      // TODO: add logic to not trigger factory
      var oldValue = this[name];

      if ( adapt )  newValue = adapt.call(this, oldValue, newValue);

      if ( preSet ) newValue = preSet.call(this, oldValue, newValue);

      this.instance_[name] = newValue;

      // TODO: fire property change event

      // TODO: call global setter

      if ( postSet ) postSet.call(this, oldValue, newValue);
    },
    configurable: true
  });
}

var FProto = {
  create: function(args) {
    var obj = Object.create(this);
    obj.instance_ = {};

    // TODO: lookup if valid method names
    for ( var key in args ) obj[key] = args[key];

    return obj;
  }
};

var models = [];
function MODEL(m) {
console.log('PASS 0', m.name);
  var proto = Object.create(FProto);
  global[m.name] = proto;
  proto.model_ = m;
  models.push(m);
}

MODEL({
  name: 'FObject',
  extends: null,

  properties: [
  ],

  methods: [
    {
      name: 'toString',
      code: function() {
        // Distinguish between prototypes and instances.
        return (this.instance_ ? 'FProto' : '') + this.model_.name;
      }
    }
  ],

  axioms: [
  ]
});

MODEL({
  name: 'Model',

  properties: [
    {
      name: 'name'
    },
    {
      name: 'extends',
      defaultValue: 'FObject'
    },
    {
      type: 'Array',
      subType: 'Property',
      name: 'properties'/*,
      adapt: function(_, ps) {

      }*/
    },
    {
      type: 'Array',
      subType: 'Method',
      name: 'methods',
      adaptElement: function(e) {
        if ( typeof e === 'function' ) {
          console.assert(e.name, 'Method must be named');
          return Method.create({name: e.name, code: e});
        }
        return e;
      }
    },
    {
      name: 'proto',
      factory: function() {
        var proto = this.extends ? Object.create(global[this.extends]) : {};

        proto.model_ = this;

        if ( m.axioms ) {
          for ( var i = 0 ; j < m.axioms.length ; j++ ) {
            var a = m.axioms[j];
            a.install.call(a, proto);
          }
        }

        if ( m.methods ) {
          for ( var j = 0 ; i < m.methods.length ; j++ ) {
            var meth = m.methods[j];
            proto[meth.name] = meth.code;
          }
        }

        if ( m.properties ) {
          for ( var j = 0 ; j < m.properties.length ; j++ ) {
            var p = m.properties[j];
            propertyInstall.call(p, proto);
          }
        }

        return proto;
      }
    }
  ],

  methods: [
  ]
});

MODEL({
  name: 'Property',

  properties: [
    {
      name: 'type'
    },
    {
      name: 'name'
    },
    {
      name: 'defaultValue'
    },
    {
      name: 'factory'
    },
    {
      name: 'preSet'
    }
  ],

  methods: [
    {
      name: 'install',
      code: propertyInstall
    }
  ]
});

MODEL({
  name: 'Method',

  properties: [
    {
      name: 'name'
    },
    {
      name: 'code'
    }
  ],

  methods: [
    {
      name: 'install',
      code: function(proto) {
        proto[this.name] = this.code;
      }
    }
  ]
});

MODEL({
  name: 'Constant',

  properties: [
    {
      name: 'name'
    },
    {
      name: 'value'
    }
  ],

  methods: [
    {
      name: 'install',
      code: function(proto) {
        proto[constantize(this.name)] = this.value;
      }
    }
  ]
});

MODEL({
  name: 'StringProperty',
  extends: 'Property',

  properties: [
    {
      name: 'defaultValue',
      defaultValue: ''
    },
    {
      name: 'preSet',
      defaultValue: function(_, a) {
        return a ? a.toString() : '';
      }
    }
  ]
});

MODEL({
  name: 'ArrayProperty',
  extends: 'Property',

  properties: [
    {
      name: 'factory',
      defaultValue: function() { return []; }
    },
    {
      name: 'subType'
    },
    {
      name: 'preSet',
      defaultValue: function(_, a) {
        // TODO: loop for performance
        return a.map(function() { return global[this.subType].create(a); });
      }
    },
    {
      name: 'adaptElement'
    },
    {
      name: 'adapt',
      defaultValue: function(a) {
        if ( ! a ) return [];
        return a.map(this.adaptElement);
      }
    }
  ]
});

/*
  create: create object then update
  remote create from regular objects or remove from prototypes
  acreate or afromJSON

  TODO:
  - property overriding

*/

for ( var i = 0 ; i < models.length ; i++ ) {
  var m = models[i];
  var proto = global[m.name];

console.log('PASS 1', i, m.name);

  if ( m.axioms ) {
    for ( var i = 0 ; j < m.axioms.length ; j++ ) {
      var a = m.axioms[j];
      a.install.call(a, proto);
    }
  }
}

for ( var i = 0 ; i < models.length.length ; i++ ) {
  var m = models[i];
  var proto = global[m.name];

console.log('PASS 2', i, m.name);

  if ( m.methods ) {
    for ( var j = 0 ; i < m.methods ; j++ ) {
      var meth = m.methods[j];
      proto[meth.name] = meth.code;
    }
  }
}

for ( var i = 0 ; i < models.length ; i++ ) {
  var m = models[i];
  var proto = global[m.name];

console.log('PASS 3', i, m.name);

  if ( m.properties ) {
    for ( var j = 0 ; j < m.properties.length ; j++ ) {
      var p = m.properties[j];
      propertyInstall.call(p, proto);
    }
  }
}

MODEL = function(m) {
  var model = Model.create(m);
  var proto = model.proto;
  global[m.name] = proto;
  return proto;
}

MODEL({
  name: 'Person',

  properties: [
    {
      name: 'name'
    },
    {
      name: 'age'
    }
  ],

  methods: [
    {
      name: 'sayHello',
      code: function() { console.log('Hello World!'); }
    }
  ]
});

var p = Person.create({name: 'Adam', age: 0});
console.log(p);
<commit_msg>FO3 work.<commit_after>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

function propertyInstall(proto) {
  proto[constantize(this.name)] = this;

  var name            = this.name;
  var slotName        = name + '$';
  var adapt           = this.adapt
  var preSet          = this.preSet;
  var postSet         = this.postSet;
  var getter          = this.getter;
  var setter          = this.setter;
  var factory         = this.factory;
  var hasDefaultValue = this.hasOwnProperty('defaultValue');
  var defaultValue    = this.defaultValue;

  /* Future
     Object.defineProperty(proto, slotName, {
     get: function propSlotGetter() {
     return this.getSlot(name);
     },
     set: function propSlotSetter(value) {
     value.link.link(this.getSlot(name));
     },
     configurable: true
     });
  */

  console.log('Defining Property ', proto.model_.name, name);
  Object.defineProperty(proto, name, {
    get: function propGetter() {
      if ( getter ) return getter.call(this);

      if ( ( hasDefaultValue || factory ) &&
           ! this.instance_.hasOwnProperty(name) )
      {
        if ( hasDefaultValue ) return defaultValue;

        var value = factory.call(this);
        this.instance_[name] = value;
        return value;
      }

      return this.instance_[name];
    },
    set: function propSetter(newValue) {
      if ( setter ) {
        setter.call(this, newValue);
        return;
      }

      // TODO: add logic to not trigger factory
      var oldValue = this[name];

      if ( adapt )  newValue = adapt.call(this, oldValue, newValue);

      if ( preSet ) newValue = preSet.call(this, oldValue, newValue);

      this.instance_[name] = newValue;

      // TODO: fire property change event

      // TODO: call global setter

      if ( postSet ) postSet.call(this, oldValue, newValue);
    },
    configurable: true
  });
}

var FProto = {
  create: function(args) {
    var obj = Object.create(this);
    obj.instance_ = {};

    // TODO: lookup if valid method names
    for ( var key in args ) obj[key] = args[key];

    return obj;
  }
};

var models = [];
function MODEL(m) {
console.log('PASS 0', m.name);
  var proto = Object.create(FProto);
  global[m.name] = proto;
  proto.model_ = m;
  models.push(m);
}

MODEL({
  name: 'FObject',
  extends: null,

  properties: [
  ],

  methods: [
    {
      name: 'toString',
      code: function() {
        // Distinguish between prototypes and instances.
        return (this.instance_ ? 'FProto' : '') + this.model_.name;
      }
    }
  ],

  axioms: [
  ]
});

MODEL({
  name: 'Model',

  properties: [
    {
      name: 'name'
    },
    {
      name: 'extends',
      defaultValue: 'FObject'
    },
    {
      type: 'Array',
      subType: 'Property',
      name: 'properties'/*,
      adapt: function(_, ps) {

      }*/
    },
    {
      type: 'Array',
      subType: 'Method',
      name: 'methods',
      adaptElement: function(e) {
        if ( typeof e === 'function' ) {
          console.assert(e.name, 'Method must be named');
          return Method.create({name: e.name, code: e});
        }
        return e;
      }
    },
    {
      name: 'proto',
      factory: function() {
        var proto = this.extends ? Object.create(global[this.extends]) : {};
        var m     = this;

        proto.model_ = this;

        if ( m.axioms ) {
          for ( var j = 0 ; j < m.axioms.length ; j++ ) {
            var a = m.axioms[j];
            a.install.call(a, proto);
          }
        }

console.log('*** ', m.name);
debugger;
        if ( m.methods ) {
          for ( var j = 0 ; j < m.methods.length ; j++ ) {
            var meth = m.methods[j];
            console.log('*********************** Adding Method: ', meth.name);
            proto[meth.name] = meth.code;
          }
        }

        if ( m.properties ) {
          for ( var j = 0 ; j < m.properties.length ; j++ ) {
            var p = m.properties[j];
            propertyInstall.call(p, proto);
          }
        }

        return proto;
      }
    }
  ]
});

MODEL({
  name: 'Property',

  properties: [
    {
      name: 'type'
    },
    {
      name: 'name'
    },
    {
      name: 'defaultValue'
    },
    {
      name: 'factory'
    },
    {
      name: 'preSet'
    }
  ],

  methods: [
    {
      name: 'install',
      code: propertyInstall
    }
  ]
});

MODEL({
  name: 'Method',

  properties: [
    {
      name: 'name'
    },
    {
      name: 'code'
    }
  ],

  methods: [
    {
      name: 'install',
      code: function(proto) {
        proto[this.name] = this.code;
      }
    }
  ]
});

MODEL({
  name: 'Constant',

  properties: [
    {
      name: 'name'
    },
    {
      name: 'value'
    }
  ],

  methods: [
    {
      name: 'install',
      code: function(proto) {
        proto[constantize(this.name)] = this.value;
      }
    }
  ]
});

MODEL({
  name: 'StringProperty',
  extends: 'Property',

  properties: [
    {
      name: 'defaultValue',
      defaultValue: ''
    },
    {
      name: 'preSet',
      defaultValue: function(_, a) {
        return a ? a.toString() : '';
      }
    }
  ]
});

MODEL({
  name: 'ArrayProperty',
  extends: 'Property',

  properties: [
    {
      name: 'factory',
      defaultValue: function() { return []; }
    },
    {
      name: 'subType'
    },
    {
      name: 'preSet',
      defaultValue: function(_, a) {
        // TODO: loop for performance
        return a.map(function() { return global[this.subType].create(a); });
      }
    },
    {
      name: 'adaptElement'
    },
    {
      name: 'adapt',
      defaultValue: function(a) {
        if ( ! a ) return [];
        return a.map(this.adaptElement);
      }
    }
  ]
});

/*
  create: create object then update
  remote create from regular objects or remove from prototypes
  acreate or afromJSON

  TODO:
  - property overriding

*/

for ( var i = 0 ; i < models.length ; i++ ) {
  var m = models[i];
  var proto = global[m.name];

console.log('PASS 1', i, m.name);

  if ( m.axioms ) {
    for ( var i = 0 ; j < m.axioms.length ; j++ ) {
      var a = m.axioms[j];
      a.install.call(a, proto);
    }
  }
}

for ( var i = 0 ; i < models.length.length ; i++ ) {
  var m = models[i];
  var proto = global[m.name];

console.log('PASS 2', i, m.name);

  if ( m.methods ) {
    for ( var j = 0 ; i < m.methods ; j++ ) {
      var meth = m.methods[j];
      proto[meth.name] = meth.code;
    }
  }
}

for ( var i = 0 ; i < models.length ; i++ ) {
  var m = models[i];
  var proto = global[m.name];

console.log('PASS 3', i, m.name);

  if ( m.properties ) {
    for ( var j = 0 ; j < m.properties.length ; j++ ) {
      var p = m.properties[j];
      propertyInstall.call(p, proto);
    }
  }
}

MODEL = function(m) {
  var model = Model.create(m);
  var proto = model.proto;
  global[m.name] = proto;
  return proto;
}

MODEL({
  name: 'Person',

  properties: [
    {
      name: 'name'
    },
    {
      name: 'age'
    }
  ],

  methods: [
    {
      name: 'sayHello',
      code: function() { console.log('Hello World!'); }
    }
  ]
});

var p = Person.create({name: 'Adam', age: 0});
console.log(p);
<|endoftext|>


<commit_before>/*
 MIT License http://www.opensource.org/licenses/mit-license.php
 Author Tobias Koppers @sokra
 */

"use strict";

const { ConcatSource } = require("webpack-sources");
const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
const Template = require("./Template");

const validateOptions = require("schema-utils");
const schema = require("../schemas/plugins/BannerPlugin.json");

/** @typedef {import("../declarations/plugins/BannerPlugin").BannerPluginArgument} BannerPluginArgument */
/** @typedef {import("../declarations/plugins/BannerPlugin").BannerPluginOptions} BannerPluginOptions */

const wrapComment = str => {
	if (!str.includes("\n")) {
		return Template.toComment(str);
	}
	return `/*!\n * ${str
		.replace(/\*\//g, "* /")
		.split("\n")
		.join("\n * ")}\n */`;
};

class BannerPlugin {
	/**
	 * @param {BannerPluginArgument} options options object
	 */
	constructor(options) {
		if (arguments.length > 1) {
			throw new Error(
				"BannerPlugin only takes one argument (pass an options object)"
			);
		}

		validateOptions(schema, options, "Banner Plugin");

		if (["string", "function"].indexOf(typeof options) !== -1) {
			options = {
				banner: options
			};
		}

		/** @type {BannerPluginOptions} */
		this.options = options;

		const bannerOption = options.banner;
		if (typeof bannerOption === "function") {
			const getBanner = bannerOption;
			this.banner = this.options.raw
				? getBanner
				: data => wrapComment(getBanner(data));
		} else {
			const banner = this.options.raw
				? bannerOption
				: wrapComment(bannerOption);
			this.banner = () => banner;
		}
	}

	apply(compiler) {
		const options = this.options;
		const banner = this.banner;
		const matchObject = ModuleFilenameHelpers.matchObject.bind(
			undefined,
			options
		);

		compiler.hooks.compilation.tap("BannerPlugin", compilation => {
			compilation.hooks.optimizeChunkAssets.tap("BannerPlugin", chunks => {
				for (const chunk of chunks) {
					if (options.entryOnly && !chunk.canBeInitial()) {
						continue;
					}

					for (const file of chunk.files) {
						if (!matchObject(file)) {
							continue;
						}

						let query = "";
						let filename = file;
						const hash = compilation.hash;
						const querySplit = filename.indexOf("?");

						if (querySplit >= 0) {
							query = filename.substr(querySplit);
							filename = filename.substr(0, querySplit);
						}

						const lastSlashIndex = filename.lastIndexOf("/");

						const basename =
							lastSlashIndex === -1
								? filename
								: filename.substr(lastSlashIndex + 1);

						const data = {
							hash,
							chunk,
							filename,
							basename,
							query
						};

						const comment = compilation.getPath(banner(data), data);

						compilation.assets[file] = new ConcatSource(
							comment,
							"\n",
							compilation.assets[file]
						);
					}
				}
			});
		});
	}
}

module.exports = BannerPlugin;
<commit_msg>fix: revert<commit_after>/*
 MIT License http://www.opensource.org/licenses/mit-license.php
 Author Tobias Koppers @sokra
 */

"use strict";

const { ConcatSource } = require("webpack-sources");
const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
const Template = require("./Template");

const validateOptions = require("schema-utils");
const schema = require("../schemas/plugins/BannerPlugin.json");

/** @typedef {import("../declarations/plugins/BannerPlugin").BannerPluginArgument} BannerPluginArgument */
/** @typedef {import("../declarations/plugins/BannerPlugin").BannerPluginOptions} BannerPluginOptions */

const wrapComment = str => {
	if (!str.includes("\n")) {
		return Template.toComment(str);
	}
	return `/*!\n * ${str
		.replace(/\*\//g, "* /")
		.split("\n")
		.join("\n * ")}\n */`;
};

class BannerPlugin {
	/**
	 * @param {BannerPluginArgument} options options object
	 */
	constructor(options) {
		if (arguments.length > 1) {
			throw new Error(
				"BannerPlugin only takes one argument (pass an options object)"
			);
		}

		validateOptions(schema, options, "Banner Plugin");

		if (typeof options === "string" || typeof options === "function") {
			options = {
				banner: options
			};
		}

		/** @type {BannerPluginOptions} */
		this.options = options;

		const bannerOption = options.banner;
		if (typeof bannerOption === "function") {
			const getBanner = bannerOption;
			this.banner = this.options.raw
				? getBanner
				: data => wrapComment(getBanner(data));
		} else {
			const banner = this.options.raw
				? bannerOption
				: wrapComment(bannerOption);
			this.banner = () => banner;
		}
	}

	apply(compiler) {
		const options = this.options;
		const banner = this.banner;
		const matchObject = ModuleFilenameHelpers.matchObject.bind(
			undefined,
			options
		);

		compiler.hooks.compilation.tap("BannerPlugin", compilation => {
			compilation.hooks.optimizeChunkAssets.tap("BannerPlugin", chunks => {
				for (const chunk of chunks) {
					if (options.entryOnly && !chunk.canBeInitial()) {
						continue;
					}

					for (const file of chunk.files) {
						if (!matchObject(file)) {
							continue;
						}

						let query = "";
						let filename = file;
						const hash = compilation.hash;
						const querySplit = filename.indexOf("?");

						if (querySplit >= 0) {
							query = filename.substr(querySplit);
							filename = filename.substr(0, querySplit);
						}

						const lastSlashIndex = filename.lastIndexOf("/");

						const basename =
							lastSlashIndex === -1
								? filename
								: filename.substr(lastSlashIndex + 1);

						const data = {
							hash,
							chunk,
							filename,
							basename,
							query
						};

						const comment = compilation.getPath(banner(data), data);

						compilation.assets[file] = new ConcatSource(
							comment,
							"\n",
							compilation.assets[file]
						);
					}
				}
			});
		});
	}
}

module.exports = BannerPlugin;
<|endoftext|>


<commit_before>// ==UserScript==
// @id             iitc-plugin-update-check@jonatkins
// @name           IITC plugin: Check for updates
// @category       Tweaks
// @version        0.1.0.@@DATETIMEVERSION@@
// @namespace      https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL      @@UPDATEURL@@
// @downloadURL    @@DOWNLOADURL@@
// @description    [@@BUILDNAME@@-@@BUILDDATE@@] Check for updates for IITC and plugins against http://iitc.jonatkins.com/. Can also report status messages for known IITC issues.
// @include        https://www.ingress.com/intel*
// @include        http://www.ingress.com/intel*
// @match          https://www.ingress.com/intel*
// @match          http://www.ingress.com/intel*
// @grant          none
// ==/UserScript==

@@PLUGINSTART@@

// PLUGIN START ////////////////////////////////////////////////////////

// use own namespace for plugin
window.plugin.updateCheck = function() {};

window.plugin.updateCheck.url = 'http://iitc.jonatkins.com/versioncheck.php?build=@@BUILDNAME@@';
window.plugin.updateCheck.versionDataLoading = false;

window.plugin.updateCheck.versionCompare = function(a,b) {
  a = a.split('.');
  b = b.split('.');

  // adding dummy -1 entries to both split arrays simplifies comparisons
  a.push(-1);
  b.push(-1);

  var minlen = Math.min(a.length, b.length);

  for (var i=0; i<minlen; i++) {
    var anum = parseInt(a[i]);
    var bnum = parseInt(b[i]);
    if (anum != bnum) {
      return bnum-anum;
    }
  }

  return 0;
}

window.plugin.updateCheck.loadVersionData = function() {
  if (!window.plugin.updateCheck.versionDataLoading) {
    window.plugin.updateCheck.versionDataLoading = true;

    var s = document.createElement('script');
    s.setAttribute('type','text/javascript');
    s.setAttribute('src', window.plugin.updateCheck.url+'&callback=window.plugin.updateCheck.versionDataCallback');
    s.setAttribute('id','update-check-script-tag');
    document.getElementsByTagName("head")[0].appendChild(s);

  } else {
    // else we're already loading the script and it hasn't completed - do nothing
    console.warn('update-check: already loading data - cannot load again');
  }
}

window.plugin.updateCheck.versionDataCallback = function(data) {
  // data loaded - flag it's not loading any more and remove the script tag
  window.plugin.updateCheck.versionDataLoading = false;
  var s = document.getElementById('update-check-script-tag');
  if (s) {
    s.parentNode.removeChild(s);
  }

  dialog({
    text: JSON.stringify(data,null,2),
    title: 'debug version check',
    width: 700
  });

  window.plugin.updateCheck.showReport(data);
}

window.plugin.updateCheck.compareDetails = function(web_version, script_version) {
  // compare the local script version data with the website version data
  // and return an object with the results
  var result = {};

  result.webUrl = web_version.pageUrl;
  result.downloadUrl = web_version.downloadUrl;
  result.webVersion = web_version.version;

  result.localVersion = script_version.script && script_version.script.version;

  if (result.localVersion && result.webVersion) {
    result.comp = window.plugin.updateCheck.versionCompare (result.localVersion, result.webVersion);

    result.outOfDate = result.comp>0;
    result.upToDate = result.comp==0;
    result.localNewer = result.comp<0;

  }

  if (!result.localVersion) {

  } else if (!result.webVersion) {
  }

  return result;
}

window.plugin.updateCheck.showReport = function(data) {
  var result = 'WORK IN PROGRESS - NOT YET FUNCTIONAL';

  if (data.error) {
    result += '
Error checking for updates
'+data.error+'
';
  } else {
    if (data.name) {
      result += '
IITC update check: '+data.name+'
';
    }

    if (data.iitc && window.script_info) {

      var compare = window.plugin.updateCheck.compareDetails(data.iitc, window.script_info);

      result += '
IITC Main script: '+JSON.stringify(compare)+'
';

    } else {
      if (!data.iitc) {
        result += '
Warning: no version information for main IITC script found in response
';
      }
      if (!window.script_info) {
        result += '
Warning: your IITC script does not contain version data
';
      }
    }

  }

  dialog({
    width: 500,
    title: 'Update check',
    html: result
  });
}

window.plugin.updateCheck.open = function() {

  // TODO? open a dialog/show a message indicating that the update check is in progress, before the data is loaded?
  // TODO? prevent loading the version data every time - cache it, with a user option to force fresh data

  window.plugin.updateCheck.loadVersionData();
}

window.plugin.updateCheck.setup  = function() {
  $('#toolbox').append(' Update check');
};

var setup =  window.plugin.updateCheck.setup;

// PLUGIN END //////////////////////////////////////////////////////////

@@PLUGINEND@@
<commit_msg>update check plugin - basic functionality now done<commit_after>// ==UserScript==
// @id             iitc-plugin-update-check@jonatkins
// @name           IITC plugin: Check for updates
// @category       Tweaks
// @version        0.1.0.@@DATETIMEVERSION@@
// @namespace      https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL      @@UPDATEURL@@
// @downloadURL    @@DOWNLOADURL@@
// @description    [@@BUILDNAME@@-@@BUILDDATE@@] Check for updates for IITC and plugins against http://iitc.jonatkins.com/. Can also report status messages for known IITC issues.
// @include        https://www.ingress.com/intel*
// @include        http://www.ingress.com/intel*
// @match          https://www.ingress.com/intel*
// @match          http://www.ingress.com/intel*
// @grant          none
// ==/UserScript==

@@PLUGINSTART@@

// PLUGIN START ////////////////////////////////////////////////////////

// use own namespace for plugin
window.plugin.updateCheck = function() {};

window.plugin.updateCheck.url = 'http://iitc.jonatkins.com/versioncheck.php?build=@@BUILDNAME@@';
window.plugin.updateCheck.versionDataLoading = false;

window.plugin.updateCheck.versionCompare = function(a,b) {
  a = a.split('.');
  b = b.split('.');

  // adding dummy -1 entries to both split arrays simplifies comparisons
  a.push(-1);
  b.push(-1);

  var minlen = Math.min(a.length, b.length);

  for (var i=0; i<minlen; i++) {
    var anum = parseInt(a[i]);
    var bnum = parseInt(b[i]);
    if (anum != bnum) {
      return bnum-anum;
    }
  }

  return 0;
}

window.plugin.updateCheck.loadVersionData = function() {
  if (!window.plugin.updateCheck.versionDataLoading) {
    window.plugin.updateCheck.versionDataLoading = true;

    var s = document.createElement('script');
    s.setAttribute('type','text/javascript');
    s.setAttribute('src', window.plugin.updateCheck.url+'&callback=window.plugin.updateCheck.versionDataCallback');
    s.setAttribute('id','update-check-script-tag');
    document.getElementsByTagName("head")[0].appendChild(s);

  } else {
    // else we're already loading the script and it hasn't completed - do nothing
    console.warn('update-check: already loading data - cannot load again');
  }
}

window.plugin.updateCheck.versionDataCallback = function(data) {
  // data loaded - flag it's not loading any more and remove the script tag
  window.plugin.updateCheck.versionDataLoading = false;
  var s = document.getElementById('update-check-script-tag');
  if (s) {
    s.parentNode.removeChild(s);
  }

  window.plugin.updateCheck.showReport(data);
}

window.plugin.updateCheck.versionHTML = function(ver) {
  var re = new RegExp ('^([0-9]+\\.[0-9]+\\.[0-9]+)(\\.2[0-9][0-9][0-9][01][0-9][0123][0-9]\\.[0-9]+)$');
  var match = ver.match(re);
  if (match) {
    return match[1]+''+match[2]+'';
  } else {
    return ver;
  }
}

window.plugin.updateCheck.compareDetails = function(web_version, script_version) {
  // compare the local script version data with the website version data
  // and return an object with the results
  var result = {};

  result.webUrl = web_version.pageUrl;
  result.downloadUrl = web_version.downloadUrl;
  result.webVersion = web_version.version;

  result.localVersion = script_version.script && script_version.script.version;

  if (result.localVersion && result.webVersion) {
    result.comp = window.plugin.updateCheck.versionCompare (result.localVersion, result.webVersion);

    result.outOfDate = result.comp>0;
    result.upToDate = result.comp==0;
    result.localNewer = result.comp<0;

  }

  var webVerHTML = result.webVersion && window.plugin.updateCheck.versionHTML(result.webVersion);
  var localVerHTML = result.localVersion && window.plugin.updateCheck.versionHTML(result.localVersion);
  var webLinkInstallHTML = '';
  if (result.downloadUrl && result.webUrl) {
    webLinkInstallHTML = 'web '
                       + 'install';
  }

  if (!result.localVersion) {
    result.html = 'version check failed '+webLinkInstallHTML;
  } else if (!result.webVersion) {
    result.html = 'version check failed';
  } else if (result.upToDate) {
    result.html = 'up to date';
  } else if (result.outOfDate) {
    result.html = 'out of date '+webLinkInstallHTML;
  } else if (result.localNewer) {
    result.html = localVerHTML+' is newer than '+webVerHTML+'(?!)';
  } else {
    console.warn ('Unknown case of version combinations!');
    result.html = 'version check failed(!?)';
  }

  return result;
}

window.plugin.updateCheck.showReport = function(data) {
  var result = 'WORK IN PROGRESS';

  if (data.error) {
    result += '
Error checking for updates
'+data.error+'
';
  } else {
    if (data.name) {
      result += '
IITC update check: '+data.name+'
';
    }

    if (data.iitc && window.script_info) {
      var compare = window.plugin.updateCheck.compareDetails(data.iitc, window.script_info);
      result += '
IITC Main script: '+compare.html+'
';

    } else {
      if (!data.iitc) {
        result += '
Warning: no version information for main IITC script found in response
';
      }
      if (!window.script_info) {
        result += '
Warning: your IITC script does not contain version data
';
      }
    }

    if (data.plugins && window.bootPlugins) {
      result += '
Plugins:
';

      if (window.bootPlugins.length == 0) {
        result += '
No plugins installed
';
      } else {
        for (var i=0; i<window.bootPlugins.length; i++) {
          var info = window.bootPlugins[i].info;
          var name = info.script && info.script.name || info.pluginId || ('(unknown plugin index '+i+')');
          name = name.replace ( /^IITC plugin: /i, '' );
          if (info && info.pluginId) {

            var webinfo = data.plugins[info.pluginId];
            if (webinfo) {
              var compare = window.plugin.updateCheck.compareDetails(webinfo,info);
              result += '
'+name+': '+compare.html+'
';
            } else {
              result += '
'+name+': no version data on server(!?)
';
            }
          } else {
            result += '
'+name+': non-standard plugin - cannot check version
';
          }
        }
      }

      result += '

';
    }

  }

  dialog({
    width: 700,
    title: 'Update check',
    html: result
  });
}

window.plugin.updateCheck.open = function() {

  // TODO? open a dialog/show a message indicating that the update check is in progress, before the data is loaded?
  // TODO? prevent loading the version data every time - cache it, with a user option to force fresh data

  window.plugin.updateCheck.loadVersionData();
}

window.plugin.updateCheck.setup  = function() {
  $('#toolbox').append(' Update check');
};

var setup =  window.plugin.updateCheck.setup;

// PLUGIN END //////////////////////////////////////////////////////////

@@PLUGINEND@@
<|endoftext|>


<commit_before>/**
 * CKEditor plugin: Dragable image resizing for Webkit
 * - Shows semi-transparent overlay while resizing
 * - Enforces Aspect Ratio (unless holding shift)
 * - Snap to size of other images in editor
 * - Escape while dragging cancels resize
 *
 */
(function() {
  "use strict";

  var PLUGIN_NAME = 'webkitdrag';

  var IMAGE_SNAP_TO_SIZE = 7;

  /**
   * Initializes the plugin
   */
  CKEDITOR.plugins.add(PLUGIN_NAME, {
    onLoad: function() {
      // This plugin only applies to Webkit.
      if (!CKEDITOR.env.webkit) {
        return;
      }

      // CSS is added in a compressed form
      CKEDITOR.addCss('img::selection{color:rgba(0,0,0,0)}img.cke-resize {outline: 1px dashed #000}#ckimgrsz{position:absolute;width:0;height:0;cursor:default}#ckimgrsz .preview{position:absolute;top:0;left:0;width:0;height:0;background-size:100% 100%;opacity:.65;outline:1px dashed #000}#ckimgrsz span{position:absolute;width:5px;height:5px;background:#fff;border:1px solid #000}#ckimgrsz span:hover,#ckimgrsz span.active{background:#000}#ckimgrsz span.tl,#ckimgrsz span.br{cursor:nwse-resize}#ckimgrsz span.tm,#ckimgrsz span.bm{cursor:ns-resize}#ckimgrsz span.tr,#ckimgrsz span.bl{cursor:nesw-resize}#ckimgrsz span.lm,#ckimgrsz span.rm{cursor:ew-resize}body.dragging-tl,body.dragging-tl *,body.dragging-br,body.dragging-br *{cursor:nwse-resize!important}body.dragging-tm,body.dragging-tm *,body.dragging-bm,body.dragging-bm *{cursor:ns-resize!important}body.dragging-tr,body.dragging-tr *,body.dragging-bl,body.dragging-bl *{cursor:nesw-resize!important}body.dragging-lm,body.dragging-lm *,body.dragging-rm,body.dragging-rm *{cursor:ew-resize!important}');
    },
    init: function(editor) {
      // This plugin only applies to Webkit
      if (!CKEDITOR.env.webkit) {
        return;
      }
      //onDomReady handler
      editor.on('contentDom', function(evt) {
        init(editor);
      });
    }
  });

  function init(editor) {
    var window = editor.window.$, document = editor.document.$, body = document.body;
    var snapToSize = (typeof IMAGE_SNAP_TO_SIZE == 'undefined') ? null : IMAGE_SNAP_TO_SIZE;

    function DragEvent() {
      this.events = {
        mousemove: bind(this.mousemove, this),
        keydown: bind(this.keydown, this),
        mouseup: bind(this.mouseup, this)
      };
    }

    DragEvent.prototype = {
      start: function(e) {
        if (e.button !== 0) {
          //right-click or middle-click
          return;
        }
        e.preventDefault();
        e.stopPropagation();
        this.target = e.target;
        this.attr = e.target.className;
        this.startPos = {x: e.clientX, y: e.clientY};
        this.update(e);
        var events = this.events;
        document.addEventListener('mousemove', events.mousemove, false);
        document.addEventListener('keydown', events.keydown, false);
        document.addEventListener('mouseup', events.mouseup, false);
        body.className += ' dragging-' + this.attr;
        this.onStart && this.onStart();
      },
      update: function(e) {
        this.currentPos = {x: e.clientX, y: e.clientY};
        this.delta = {x: e.clientX - this.startPos.x, y: e.clientY - this.startPos.y};
        this.keys = {shift: e.shiftKey, ctrl: e.ctrlKey, alt: e.altKey};
      },
      mousemove: function(e) {
        this.update(e);
        this.onDrag && this.onDrag();
        if (e.which === 0) {
          //mouse button released outside window; mouseup wasn't fired (Chrome)
          this.mouseup(e);
        }
      },
      keydown: function(e) {
        //escape key cancels dragging
        if (e.keyCode == 27) {
          this.release();
        }
      },
      mouseup: function(e) {
        this.update(e);
        this.release();
        this.onComplete && this.onComplete();
      },
      release: function() {
        body.className = body.className.replace('dragging-' + this.attr, '');
        var events = this.events;
        document.removeEventListener('mousemove', events.mousemove, false);
        document.removeEventListener('keydown', events.keydown, false);
        document.removeEventListener('mouseup', events.mouseup, false);
        this.onRelease && this.onRelease();
      }
    };

    function Resizer(element) {
      this.el = element;
      this.events = {
        initDrag: bind(this.initDrag, this)
      };
      this.init();
      this.show();
    }

    Resizer.prototype = {
      init: function() {
        var old = Resizer.instance;
        Resizer.instance = this;
        if (old) {
          //reuse existing dom elements
          old.hide();
          this.container = old.container;
          this.preview = old.preview;
          this.handles = old.handles;
          return;
        }
        var container = this.container = document.createElement('div');
        container.id = 'ckimgrsz';
        var preview = this.preview = document.createElement('div');
        preview.className = 'preview';
        container.appendChild(preview);
        var handles = this.handles = {};
        handles.tl = document.createElement('span');
        handles.tl.className = 'tl';
        handles.tm = document.createElement('span');
        handles.tm.className = 'tm';
        handles.tr = document.createElement('span');
        handles.tr.className = 'tr';
        handles.lm = document.createElement('span');
        handles.lm.className = 'lm';
        handles.rm = document.createElement('span');
        handles.rm.className = 'rm';
        handles.bl = document.createElement('span');
        handles.bl.className = 'bl';
        handles.bm = document.createElement('span');
        handles.bm.className = 'bm';
        handles.br = document.createElement('span');
        handles.br.className = 'br';
        for (var n in handles) {
          container.appendChild(handles[n]);
        }
      },
      show: function() {
        if (snapToSize) {
          this.otherImages = toArray(document.getElementsByTagName('img'));
          this.otherImages.splice(this.otherImages.indexOf(this.el), 1);
        }
        var box = this.box = getBoundingBox(window, this.el);
        this.container.style.left = box.left + 'px';
        this.container.style.top = box.top + 'px';
        body.appendChild(this.container);
        this.showHandles();
      },
      hide: function() {
        if (this.container.parentNode) {
          this.hideHandles();
          this.container.parentNode.removeChild(this.container);
        }
      },
      initDrag: function(e) {
        var resizer = this;
        var drag = new DragEvent();
        drag.onStart = function() {
          resizer.showPreview();
          resizer.isDragging = true;
          editor.getSelection().lock();
        };
        drag.onDrag = function() {
          resizer.calculateSize(this);
          resizer.updatePreview();
          resizer.updateHandles(resizer.previewBox);
        };
        drag.onRelease = function() {
          resizer.isDragging = false;
          resizer.hidePreview();
          resizer.hide();

          editor.getSelection().unlock();

          // Save an undo snapshot before the image is permanently changed.
          editor.fire('saveSnapshot');
        };
        drag.onComplete = function() {
          resizer.resizeComplete();

          // Save another snapshot after the image is changed.
          editor.fire('saveSnapshot');
        };
        drag.start(e);
      },
      updateHandles: function(box) {
        var handles = this.handles;
        handles.tl.style.left = '-3px';
        handles.tl.style.top = '-3px';
        handles.tm.style.left = (Math.round(box.width / 2) - 3) + 'px';
        handles.tm.style.top = '-3px';
        handles.tr.style.left = (box.width - 4) + 'px';
        handles.tr.style.top = '-3px';
        handles.lm.style.left = '-3px';
        handles.lm.style.top = (Math.round(box.height / 2) - 3) + 'px';
        handles.rm.style.left = (box.width - 4) + 'px';
        handles.rm.style.top = (Math.round(box.height / 2) - 3) + 'px';
        handles.bl.style.left = '-3px';
        handles.bl.style.top = (box.height - 4) + 'px';
        handles.bm.style.left = (Math.round(box.width / 2) - 3) + 'px';
        handles.bm.style.top = (box.height - 4) + 'px';
        handles.br.style.left = (box.width - 4) + 'px';
        handles.br.style.top = (box.height - 4) + 'px';
      },
      showHandles: function() {
        var handles = this.handles;
        this.updateHandles(this.box);
        for (var n in handles) {
          handles[n].style.display = 'block';
          handles[n].addEventListener('mousedown', this.events.initDrag, false);
        }
        this.el.className += ' cke-resize';
      },
      hideHandles: function() {
        var handles = this.handles;
        for (var n in handles) {
          handles[n].removeEventListener('mousedown', this.events.initDrag, false);
          handles[n].style.display = 'none';
        }
        this.el.className = this.el.className.replace(' cke-resize', '');
        console.log(this.el.className);
      },
      showPreview: function() {
        this.preview.style.backgroundImage = 'url("' + this.el.src + '")';
        this.preview.style.display = 'block';
        // Move handles to the preview so they resize with it.
        for (var n in this.handles) {
          this.preview.appendChild(this.handles[n]);
        }
        this.calculateSize();
        this.updatePreview();
        this.preview.style.display = 'block';
      },
      updatePreview: function() {
        var box = this.previewBox;
        this.preview.style.top = box.top + 'px';
        this.preview.style.left = box.left + 'px';
        this.preview.style.width = box.width + 'px';
        this.preview.style.height = box.height + 'px';
      },
      hidePreview: function() {
        var box = getBoundingBox(window, this.preview);
        this.result = {width: box.width, height: box.height};
        // Move handles back to the wrapping container.
        for (var n in this.handles) {
          this.container.appendChild(this.handles[n]);
        }
        this.preview.style.display = 'none';
      },
      calculateSize: function(data) {
        var box = this.previewBox = {top: 0, left: 0, width: this.box.width, height: this.box.height};
        if (!data) return;
        var attr = data.target.className;
        if (~attr.indexOf('r')) {
          box.width = Math.max(32, this.box.width + data.delta.x);
        }
        if (~attr.indexOf('b')) {
          box.height = Math.max(32, this.box.height + data.delta.y);
        }
        if (~attr.indexOf('l')) {
          box.width = Math.max(32, this.box.width - data.delta.x);
        }
        if (~attr.indexOf('t')) {
          box.height = Math.max(32, this.box.height - data.delta.y);
        }
        //if dragging corner, enforce aspect ratio (unless shift key is being held)
        if (attr.indexOf('m') < 0 && !data.keys.shift) {
          var ratio = this.box.width / this.box.height;
          if (box.width / box.height > ratio) {
            box.height = Math.round(box.width / ratio);
          } else {
            box.width = Math.round(box.height * ratio);
          }
        }
        if (snapToSize) {
          var others = this.otherImages;
          for (var i = 0; i < others.length; i++) {
            var other = getBoundingBox(window, others[i]);
            if (Math.abs(box.width - other.width) <= snapToSize && Math.abs(box.height - other.height) <= snapToSize) {
              box.width = other.width;
              box.height = other.height;
              break;
            }
          }
        }
        //recalculate left or top position
        if (~attr.indexOf('l')) {
          box.left = this.box.width - box.width;
        }
        if (~attr.indexOf('t')) {
          box.top = this.box.height - box.height;
        }
      },
      resizeComplete: function() {
        this.el.style.width = this.result.width + 'px';
        this.el.style.height = this.result.height + 'px';
      }
    };
    Resizer.hide = function() {
      this.instance && this.instance.hide();
    };

    editor.on('selectionChange', function(evt) {
      var data = evt.data;

      // If an element is selected and that element is an IMG.
      if (data.selection.getType() != CKEDITOR.SELECTION_NONE && data.selection.getStartElement().is('img')) {
        // And we're not right or middle clicking on the image.
        if (!window.event || !window.event.button || window.event.button === 0) {
          new Resizer(data.selection.getStartElement().$);
        }
      } else {
        Resizer.hide();
      }
    });
    editor.on('beforeUndoImage', function() {
      // Remove the handles before undo images are saved.
      Resizer.hide();
    });
    editor.on('afterUndoImage', function() {
      // Restore the handles after undo images are saved.
      editor.forceNextSelectionCheck();
      editor.selectionChange();
    });
    editor.on('beforeModeUnload', function self() {
      editor.removeListener('beforeModeUnload', self);
      Resizer.hide();
    });

    // Check resizes to the window and update the selection.
    var resizeTimeout;
    editor.window.on('resize', function() {
      // Cancel any resize waiting to happen
      clearTimeout(resizeTimeout);
      // Delay resize for 10ms
      resizeTimeout = setTimeout(resizeHandler, 10);
    });
    function resizeHandler() {
      editor.forceNextSelectionCheck();
      editor.selectionChange();
    }
  }

  //helper functions
  function toArray(obj) {
    var len = obj.length, arr = new Array(len);
    for (var i = 0; i < len; i++) {
      arr[i] = obj[i];
    }
    return arr;
  }

  function bind(fn, ctx) {
    if (fn.bind) {
      return fn.bind(ctx);
    }
    return function() {
      fn.apply(ctx, arguments);
    };
  }

  function getBoundingBox(window, el) {
    var rect = el.getBoundingClientRect();
    return {
      left: rect.left + window.pageXOffset,
      top: rect.top + window.pageYOffset,
      width: rect.width,
      height: rect.height
    };
  }
})();
<commit_msg>update browser detection to include opera<commit_after>/**
 * CKEditor plugin: Dragable image resizing for Webkit
 * - Shows semi-transparent overlay while resizing
 * - Enforces Aspect Ratio (unless holding shift)
 * - Snap to size of other images in editor
 * - Escape while dragging cancels resize
 *
 */
(function() {
  "use strict";

  var PLUGIN_NAME = 'webkitdrag';

  var IMAGE_SNAP_TO_SIZE = 7;

  /**
   * Initializes the plugin
   */
  CKEDITOR.plugins.add(PLUGIN_NAME, {
    onLoad: function() {
      // This plugin only applies to Webkit.
      if (!CKEDITOR.env.webkit) {
        return;
      }

      // CSS is added in a compressed form
      CKEDITOR.addCss('img::selection{color:rgba(0,0,0,0)}img.cke-resize {outline: 1px dashed #000}#ckimgrsz{position:absolute;width:0;height:0;cursor:default}#ckimgrsz .preview{position:absolute;top:0;left:0;width:0;height:0;background-size:100% 100%;opacity:.65;outline:1px dashed #000}#ckimgrsz span{position:absolute;width:5px;height:5px;background:#fff;border:1px solid #000}#ckimgrsz span:hover,#ckimgrsz span.active{background:#000}#ckimgrsz span.tl,#ckimgrsz span.br{cursor:nwse-resize}#ckimgrsz span.tm,#ckimgrsz span.bm{cursor:ns-resize}#ckimgrsz span.tr,#ckimgrsz span.bl{cursor:nesw-resize}#ckimgrsz span.lm,#ckimgrsz span.rm{cursor:ew-resize}body.dragging-tl,body.dragging-tl *,body.dragging-br,body.dragging-br *{cursor:nwse-resize!important}body.dragging-tm,body.dragging-tm *,body.dragging-bm,body.dragging-bm *{cursor:ns-resize!important}body.dragging-tr,body.dragging-tr *,body.dragging-bl,body.dragging-bl *{cursor:nesw-resize!important}body.dragging-lm,body.dragging-lm *,body.dragging-rm,body.dragging-rm *{cursor:ew-resize!important}');
    },
    init: function(editor) {
      // This plugin only applies to Webkit and Opera
      if (!CKEDITOR.env.webkit && !CKEDITOR.env.opera) {
        return;
      }
      //onDomReady handler
      editor.on('contentDom', function(evt) {
        init(editor);
      });
    }
  });

  function init(editor) {
    var window = editor.window.$, document = editor.document.$, body = document.body;
    var snapToSize = (typeof IMAGE_SNAP_TO_SIZE == 'undefined') ? null : IMAGE_SNAP_TO_SIZE;

    function DragEvent() {
      this.events = {
        mousemove: bind(this.mousemove, this),
        keydown: bind(this.keydown, this),
        mouseup: bind(this.mouseup, this)
      };
    }

    DragEvent.prototype = {
      start: function(e) {
        if (e.button !== 0) {
          //right-click or middle-click
          return;
        }
        e.preventDefault();
        e.stopPropagation();
        this.target = e.target;
        this.attr = e.target.className;
        this.startPos = {x: e.clientX, y: e.clientY};
        this.update(e);
        var events = this.events;
        document.addEventListener('mousemove', events.mousemove, false);
        document.addEventListener('keydown', events.keydown, false);
        document.addEventListener('mouseup', events.mouseup, false);
        body.className += ' dragging-' + this.attr;
        this.onStart && this.onStart();
      },
      update: function(e) {
        this.currentPos = {x: e.clientX, y: e.clientY};
        this.delta = {x: e.clientX - this.startPos.x, y: e.clientY - this.startPos.y};
        this.keys = {shift: e.shiftKey, ctrl: e.ctrlKey, alt: e.altKey};
      },
      mousemove: function(e) {
        this.update(e);
        this.onDrag && this.onDrag();
        if (e.which === 0) {
          //mouse button released outside window; mouseup wasn't fired (Chrome)
          this.mouseup(e);
        }
      },
      keydown: function(e) {
        //escape key cancels dragging
        if (e.keyCode == 27) {
          this.release();
        }
      },
      mouseup: function(e) {
        this.update(e);
        this.release();
        this.onComplete && this.onComplete();
      },
      release: function() {
        body.className = body.className.replace('dragging-' + this.attr, '');
        var events = this.events;
        document.removeEventListener('mousemove', events.mousemove, false);
        document.removeEventListener('keydown', events.keydown, false);
        document.removeEventListener('mouseup', events.mouseup, false);
        this.onRelease && this.onRelease();
      }
    };

    function Resizer(element) {
      this.el = element;
      this.events = {
        initDrag: bind(this.initDrag, this)
      };
      this.init();
      this.show();
    }

    Resizer.prototype = {
      init: function() {
        var old = Resizer.instance;
        Resizer.instance = this;
        if (old) {
          //reuse existing dom elements
          old.hide();
          this.container = old.container;
          this.preview = old.preview;
          this.handles = old.handles;
          return;
        }
        var container = this.container = document.createElement('div');
        container.id = 'ckimgrsz';
        var preview = this.preview = document.createElement('div');
        preview.className = 'preview';
        container.appendChild(preview);
        var handles = this.handles = {};
        handles.tl = document.createElement('span');
        handles.tl.className = 'tl';
        handles.tm = document.createElement('span');
        handles.tm.className = 'tm';
        handles.tr = document.createElement('span');
        handles.tr.className = 'tr';
        handles.lm = document.createElement('span');
        handles.lm.className = 'lm';
        handles.rm = document.createElement('span');
        handles.rm.className = 'rm';
        handles.bl = document.createElement('span');
        handles.bl.className = 'bl';
        handles.bm = document.createElement('span');
        handles.bm.className = 'bm';
        handles.br = document.createElement('span');
        handles.br.className = 'br';
        for (var n in handles) {
          container.appendChild(handles[n]);
        }
      },
      show: function() {
        if (snapToSize) {
          this.otherImages = toArray(document.getElementsByTagName('img'));
          this.otherImages.splice(this.otherImages.indexOf(this.el), 1);
        }
        var box = this.box = getBoundingBox(window, this.el);
        this.container.style.left = box.left + 'px';
        this.container.style.top = box.top + 'px';
        body.appendChild(this.container);
        this.showHandles();
      },
      hide: function() {
        if (this.container.parentNode) {
          this.hideHandles();
          this.container.parentNode.removeChild(this.container);
        }
      },
      initDrag: function(e) {
        var resizer = this;
        var drag = new DragEvent();
        drag.onStart = function() {
          resizer.showPreview();
          resizer.isDragging = true;
          editor.getSelection().lock();
        };
        drag.onDrag = function() {
          resizer.calculateSize(this);
          resizer.updatePreview();
          resizer.updateHandles(resizer.previewBox);
        };
        drag.onRelease = function() {
          resizer.isDragging = false;
          resizer.hidePreview();
          resizer.hide();

          editor.getSelection().unlock();

          // Save an undo snapshot before the image is permanently changed.
          editor.fire('saveSnapshot');
        };
        drag.onComplete = function() {
          resizer.resizeComplete();

          // Save another snapshot after the image is changed.
          editor.fire('saveSnapshot');
        };
        drag.start(e);
      },
      updateHandles: function(box) {
        var handles = this.handles;
        handles.tl.style.left = '-3px';
        handles.tl.style.top = '-3px';
        handles.tm.style.left = (Math.round(box.width / 2) - 3) + 'px';
        handles.tm.style.top = '-3px';
        handles.tr.style.left = (box.width - 4) + 'px';
        handles.tr.style.top = '-3px';
        handles.lm.style.left = '-3px';
        handles.lm.style.top = (Math.round(box.height / 2) - 3) + 'px';
        handles.rm.style.left = (box.width - 4) + 'px';
        handles.rm.style.top = (Math.round(box.height / 2) - 3) + 'px';
        handles.bl.style.left = '-3px';
        handles.bl.style.top = (box.height - 4) + 'px';
        handles.bm.style.left = (Math.round(box.width / 2) - 3) + 'px';
        handles.bm.style.top = (box.height - 4) + 'px';
        handles.br.style.left = (box.width - 4) + 'px';
        handles.br.style.top = (box.height - 4) + 'px';
      },
      showHandles: function() {
        var handles = this.handles;
        this.updateHandles(this.box);
        for (var n in handles) {
          handles[n].style.display = 'block';
          handles[n].addEventListener('mousedown', this.events.initDrag, false);
        }
        this.el.className += ' cke-resize';
      },
      hideHandles: function() {
        var handles = this.handles;
        for (var n in handles) {
          handles[n].removeEventListener('mousedown', this.events.initDrag, false);
          handles[n].style.display = 'none';
        }
        this.el.className = this.el.className.replace(' cke-resize', '');
        console.log(this.el.className);
      },
      showPreview: function() {
        this.preview.style.backgroundImage = 'url("' + this.el.src + '")';
        this.preview.style.display = 'block';
        // Move handles to the preview so they resize with it.
        for (var n in this.handles) {
          this.preview.appendChild(this.handles[n]);
        }
        this.calculateSize();
        this.updatePreview();
        this.preview.style.display = 'block';
      },
      updatePreview: function() {
        var box = this.previewBox;
        this.preview.style.top = box.top + 'px';
        this.preview.style.left = box.left + 'px';
        this.preview.style.width = box.width + 'px';
        this.preview.style.height = box.height + 'px';
      },
      hidePreview: function() {
        var box = getBoundingBox(window, this.preview);
        this.result = {width: box.width, height: box.height};
        // Move handles back to the wrapping container.
        for (var n in this.handles) {
          this.container.appendChild(this.handles[n]);
        }
        this.preview.style.display = 'none';
      },
      calculateSize: function(data) {
        var box = this.previewBox = {top: 0, left: 0, width: this.box.width, height: this.box.height};
        if (!data) return;
        var attr = data.target.className;
        if (~attr.indexOf('r')) {
          box.width = Math.max(32, this.box.width + data.delta.x);
        }
        if (~attr.indexOf('b')) {
          box.height = Math.max(32, this.box.height + data.delta.y);
        }
        if (~attr.indexOf('l')) {
          box.width = Math.max(32, this.box.width - data.delta.x);
        }
        if (~attr.indexOf('t')) {
          box.height = Math.max(32, this.box.height - data.delta.y);
        }
        //if dragging corner, enforce aspect ratio (unless shift key is being held)
        if (attr.indexOf('m') < 0 && !data.keys.shift) {
          var ratio = this.box.width / this.box.height;
          if (box.width / box.height > ratio) {
            box.height = Math.round(box.width / ratio);
          } else {
            box.width = Math.round(box.height * ratio);
          }
        }
        if (snapToSize) {
          var others = this.otherImages;
          for (var i = 0; i < others.length; i++) {
            var other = getBoundingBox(window, others[i]);
            if (Math.abs(box.width - other.width) <= snapToSize && Math.abs(box.height - other.height) <= snapToSize) {
              box.width = other.width;
              box.height = other.height;
              break;
            }
          }
        }
        //recalculate left or top position
        if (~attr.indexOf('l')) {
          box.left = this.box.width - box.width;
        }
        if (~attr.indexOf('t')) {
          box.top = this.box.height - box.height;
        }
      },
      resizeComplete: function() {
        this.el.style.width = this.result.width + 'px';
        this.el.style.height = this.result.height + 'px';
      }
    };
    Resizer.hide = function() {
      this.instance && this.instance.hide();
    };

    editor.on('selectionChange', function(evt) {
      var data = evt.data;

      // If an element is selected and that element is an IMG.
      if (data.selection.getType() != CKEDITOR.SELECTION_NONE && data.selection.getStartElement().is('img')) {
        // And we're not right or middle clicking on the image.
        if (!window.event || !window.event.button || window.event.button === 0) {
          new Resizer(data.selection.getStartElement().$);
        }
      } else {
        Resizer.hide();
      }
    });
    editor.on('beforeUndoImage', function() {
      // Remove the handles before undo images are saved.
      Resizer.hide();
    });
    editor.on('afterUndoImage', function() {
      // Restore the handles after undo images are saved.
      editor.forceNextSelectionCheck();
      editor.selectionChange();
    });
    editor.on('beforeModeUnload', function self() {
      editor.removeListener('beforeModeUnload', self);
      Resizer.hide();
    });

    // Check resizes to the window and update the selection.
    var resizeTimeout;
    editor.window.on('resize', function() {
      // Cancel any resize waiting to happen
      clearTimeout(resizeTimeout);
      // Delay resize for 10ms
      resizeTimeout = setTimeout(resizeHandler, 10);
    });
    function resizeHandler() {
      editor.forceNextSelectionCheck();
      editor.selectionChange();
    }
  }

  //helper functions
  function toArray(obj) {
    var len = obj.length, arr = new Array(len);
    for (var i = 0; i < len; i++) {
      arr[i] = obj[i];
    }
    return arr;
  }

  function bind(fn, ctx) {
    if (fn.bind) {
      return fn.bind(ctx);
    }
    return function() {
      fn.apply(ctx, arguments);
    };
  }

  function getBoundingBox(window, el) {
    var rect = el.getBoundingClientRect();
    return {
      left: rect.left + window.pageXOffset,
      top: rect.top + window.pageYOffset,
      width: rect.width,
      height: rect.height
    };
  }
})();
<|endoftext|>


<commit_before>'use strict';

(function() {

  var module = angular.module('pnc.record', [
    'ui.router',
    'pnc.remote.restClient',
    'pnc.util.header'
  ]);

  module.config([
    '$stateProvider',
    '$urlRouterProvider',
    function($stateProvider, $urlRouterProvider) {

    $stateProvider.state('record', {
      abstract: true,
      url: '/record',
      views: {
        'content@': {
          templateUrl: 'common/templates/single-col-center.tmpl.html'
        }
      }
    });

    $urlRouterProvider.when('/record/:recordId', '/record/:recordId/info');

    $stateProvider.state('record.detail', {
      url: '/{recordId:int}',
      templateUrl: 'record/views/record.detail.html',
      controller: 'RecordDetailController',
      controllerAs: 'recordCtrl',
      resolve: {
        restClient: 'PncRestClient',
        recordDetail: function(restClient, $stateParams) {
          return restClient.Record.get({
            recordId: $stateParams.recordId }).$promise;
        },
        configurationDetail: function(restClient, recordDetail) {
          return restClient.Configuration.get({
            configurationId: recordDetail.buildConfigurationId }).$promise;
        },
        projectDetail: function(restClient, configurationDetail) {
          return restClient.Project.get({
            projectId: configurationDetail.projectId }).$promise;
        }
      },
    });

    $stateProvider.state('record.detail.info', {
      url: '/info',
      templateUrl: 'record/views/record.detail.info.html',
      controller: 'RecordInfoController',
      controllerAs: 'infoCtrl',
    });

    $stateProvider.state('record.detail.result', {
      url: '/result',
      controller: 'RecordResultController',
      controllerAs: 'resultCtrl',
      templateUrl: 'record/views/record.detail.result.html',
      resolve: {
        restClient: 'PncRestClient',
        buildLog: function(restClient, recordDetail) {
          return restClient.Record.getLog({
            recordId: recordDetail.id}).$promise;
        }
      }
    });

    $stateProvider.state('record.detail.output', {
      url: '/output',
      controller: 'RecordOutputController',
      controllerAs: 'outputCtrl',
      templateUrl: 'record/views/record.detail.output.html'
    });

  }]);

})();
<commit_msg>Fixed visualization of breadcrumbs and layout of build records<commit_after>'use strict';

(function() {

  var module = angular.module('pnc.record', [
    'ui.router',
    'pnc.remote.restClient',
    'pnc.util.header',
    'angularUtils.directives.uiBreadcrumbs'
  ]);

  module.config([
    '$stateProvider',
    '$urlRouterProvider',
    function($stateProvider, $urlRouterProvider) {

    $stateProvider.state('record', {
      abstract: true,
      url: '/record',
      views: {
        'content@': {
          templateUrl: 'common/templates/single-col.tmpl.html'
          //templateUrl: 'common/templates/single-col-center.tmpl.html'
        }
      },
      data: {
        proxy: 'record.detail',
      }
    });

    $urlRouterProvider.when('/record/:recordId', '/record/:recordId/info');

    $stateProvider.state('record.detail', {
      url: '/{recordId:int}',
      templateUrl: 'record/views/record.detail.html',
      data: {
         displayName: '{{ recordDetail.name }}',
      },
      controller: 'RecordDetailController',
      controllerAs: 'recordCtrl',
      resolve: {
        restClient: 'PncRestClient',
        recordDetail: function(restClient, $stateParams) {
          return restClient.Record.get({
            recordId: $stateParams.recordId }).$promise;
        },
        configurationDetail: function(restClient, recordDetail) {
          return restClient.Configuration.get({
            configurationId: recordDetail.buildConfigurationId }).$promise;
        },
        projectDetail: function(restClient, configurationDetail) {
          return restClient.Project.get({
            projectId: configurationDetail.projectId }).$promise;
        }
      },
    });

    $stateProvider.state('record.detail.info', {
      url: '/info',
      templateUrl: 'record/views/record.detail.info.html',
      data: {
         displayName: '{{ recordDetail.id }}',
      },
      controller: 'RecordInfoController',
      controllerAs: 'infoCtrl',
    });

    $stateProvider.state('record.detail.result', {
      url: '/result',
      controller: 'RecordResultController',
      controllerAs: 'resultCtrl',
      templateUrl: 'record/views/record.detail.result.html',
      resolve: {
        restClient: 'PncRestClient',
        buildLog: function(restClient, recordDetail) {
          return restClient.Record.getLog({
            recordId: recordDetail.id}).$promise;
        }
      }
    });

    $stateProvider.state('record.detail.output', {
      url: '/output',
      controller: 'RecordOutputController',
      controllerAs: 'outputCtrl',
      templateUrl: 'record/views/record.detail.output.html'
    });

  }]);

})();
<|endoftext|>