<commit_before>"use strict"

class RootView {
  constructor() {
    this.loadView()
    this.emitter = {}
    this.trackId = 0
    this.quantizer = new Quantizer(TIME_BASE)
    riot.observable(this.emitter)
  }

  setSong(song) {
    this.song = song
    this.toolbar.update({song: song})
    this.trackList.update({song: song})
    this.pianoRoll.track = song.getTrack(0)
  }

  loadView() {
    riot.compile(() => {
      this.trackInfoPane = riot.mount("track-info")[0]
      this.propertyPane = riot.mount("property-pane")[0]
      this.toolbar = riot.mount("toolbar")[0]
      this.eventList = riot.mount("event-list")[0]
      this.trackList = riot.mount("track-list")[0]
      this.pianoRoll = new PianoRollController(document.querySelector("#piano-roll"))

      this.viewDidLoad()
    })
  }

  changeTrack(trackId) {
    this.trackId = trackId
    const track = this.song.getTrack(trackId)
    this.pianoRoll.track = track
    this.trackInfoPane.update({track: track})
    this.trackList.update({selectedTrackId: trackId})
    this.eventList.update({track: track})
  }

  viewDidLoad() {
    this.toolbar.update({
      onChangeFile: e => {
        const file = e.target.files[0]
        if (file.type != "audio/mid" && file.type != "audio/midi") {
          return
        }
        this.emitter.trigger("change-file", file)
      },

      onClickPencil: e => {
        this.pianoRoll.mouseMode = 0
      },

      onClickSelection: e => {
        this.pianoRoll.mouseMode = 1
      },

      onClickScaleUp: e => {
        this.pianoRoll.noteScale = {
          x: this.pianoRoll.noteScale.x + 0.1,
          y: this.pianoRoll.noteScale.y,
        }
      },

      onClickScaleDown: e => {
        this.pianoRoll.noteScale = {
          x: Math.max(0.05, this.pianoRoll.noteScale.x - 0.1),
          y: this.pianoRoll.noteScale.y,
        }
      },

      onSelectTrack: e => {
        this.changeTrack(e.value)
      },

      onSelectQuantize: e => {
        SharedService.quantizer.denominator = e.value
      },

      onClickPlay: e => {
        SharedService.player.prepare(this.song)
        SharedService.player.play()
      },

      onClickStop: e => {
        if (SharedService.player.isPlaying) {
          SharedService.player.stop()
        } else {
          SharedService.player.stop()
          SharedService.player.position = 0
        }
      },

      onClickBackward: e => {
        SharedService.player.position -= TIME_BASE * 4
      },

      onClickForward: e => {
        SharedService.player.position += TIME_BASE * 4
      }
    })

    this.pianoRoll.emitter.on("select-notes", events => {
      this.propertyPane.update({notes: events})
    })

    this.pianoRoll.emitter.on("move-cursor", tick => {
        const t = SharedService.quantizer.round(tick)
        SharedService.player.seek(t)
    })

    this.propertyPane.emitter.on("update-note", e => {
      this.song.getTrack(this.trackId).updateEvent(e.id, e)
    })

    this.propertyPane.emitter.on("update-notes", changes => {
      this.song.getTrack(this.trackId).transaction(it => {
        changes.forEach(c => it.updateEvent(c.id, c))
      })
    })

    this.trackList.emitter.on("select-track", trackId => {
      this.changeTrack(trackId)
    })

    this.trackList.emitter.on("add-track", () => {
      this.song.addTrack(new Track)
    })

    this.trackInfoPane.update({
      onChangeName: e => {
        const track = this.song.getTrack(this.trackId)
        track.setName(e.target.value)
      },
      onChangeVolume: e => {
        const track = this.song.getTrack(this.trackId)
        const events = track.findVolumeEvents()
        if (events.length == 0) {
          return
        }
        track.updateEvent(events[0].id, {
          value: e.target.value
        })
      },
      onChangePan: e => {
        const track = this.song.getTrack(this.trackId)
        const events = track.findPanEvents()
        if (events.length == 0) {
          return
        }
        track.updateEvent(events[0].id, {
          value: e.target.value
        })
      },
      onClickInstrument: e => {
        const popup = new PopupComponent()
        const track = this.song.getTrack(this.trackId)
        const events = track.findProgramChangeEvents()
        if (events.length == 0) {
          return
        }

        const programNumber = events[0].value
        const ids = getGMMapIndexes(programNumber)
        riot.mount(popup.getContentElement(), "instrument-browser", {
          selectedCategoryId: ids[0],
          selectedInstrumentId: ids[1],
          onClickCancel: () => {
            popup.close()
          },
          onClickOK: e => {
            const programNumber = getGMMapProgramNumber(e.categoryId, e.instrumentId)
            track.updateEvent(events[0].id, {
              value: programNumber
            })
            popup.close()
          }
        })[0]
        popup.show()
      }
    })

    this.emitter.trigger("view-did-load")
  }
}
<commit_msg>remove unsed variable<commit_after>"use strict"

class RootView {
  constructor() {
    this.loadView()
    this.emitter = {}
    this.trackId = 0
    riot.observable(this.emitter)
  }

  setSong(song) {
    this.song = song
    this.toolbar.update({song: song})
    this.trackList.update({song: song})
    this.pianoRoll.track = song.getTrack(0)
  }

  loadView() {
    riot.compile(() => {
      this.trackInfoPane = riot.mount("track-info")[0]
      this.propertyPane = riot.mount("property-pane")[0]
      this.toolbar = riot.mount("toolbar")[0]
      this.eventList = riot.mount("event-list")[0]
      this.trackList = riot.mount("track-list")[0]
      this.pianoRoll = new PianoRollController(document.querySelector("#piano-roll"))

      this.viewDidLoad()
    })
  }

  changeTrack(trackId) {
    this.trackId = trackId
    const track = this.song.getTrack(trackId)
    this.pianoRoll.track = track
    this.trackInfoPane.update({track: track})
    this.trackList.update({selectedTrackId: trackId})
    this.eventList.update({track: track})
  }

  viewDidLoad() {
    this.toolbar.update({
      onChangeFile: e => {
        const file = e.target.files[0]
        if (file.type != "audio/mid" && file.type != "audio/midi") {
          return
        }
        this.emitter.trigger("change-file", file)
      },

      onClickPencil: e => {
        this.pianoRoll.mouseMode = 0
      },

      onClickSelection: e => {
        this.pianoRoll.mouseMode = 1
      },

      onClickScaleUp: e => {
        this.pianoRoll.noteScale = {
          x: this.pianoRoll.noteScale.x + 0.1,
          y: this.pianoRoll.noteScale.y,
        }
      },

      onClickScaleDown: e => {
        this.pianoRoll.noteScale = {
          x: Math.max(0.05, this.pianoRoll.noteScale.x - 0.1),
          y: this.pianoRoll.noteScale.y,
        }
      },

      onSelectTrack: e => {
        this.changeTrack(e.value)
      },

      onSelectQuantize: e => {
        SharedService.quantizer.denominator = e.value
      },

      onClickPlay: e => {
        SharedService.player.prepare(this.song)
        SharedService.player.play()
      },

      onClickStop: e => {
        if (SharedService.player.isPlaying) {
          SharedService.player.stop()
        } else {
          SharedService.player.stop()
          SharedService.player.position = 0
        }
      },

      onClickBackward: e => {
        SharedService.player.position -= TIME_BASE * 4
      },

      onClickForward: e => {
        SharedService.player.position += TIME_BASE * 4
      }
    })

    this.pianoRoll.emitter.on("select-notes", events => {
      this.propertyPane.update({notes: events})
    })

    this.pianoRoll.emitter.on("move-cursor", tick => {
        const t = SharedService.quantizer.round(tick)
        SharedService.player.seek(t)
    })

    this.propertyPane.emitter.on("update-note", e => {
      this.song.getTrack(this.trackId).updateEvent(e.id, e)
    })

    this.propertyPane.emitter.on("update-notes", changes => {
      this.song.getTrack(this.trackId).transaction(it => {
        changes.forEach(c => it.updateEvent(c.id, c))
      })
    })

    this.trackList.emitter.on("select-track", trackId => {
      this.changeTrack(trackId)
    })

    this.trackList.emitter.on("add-track", () => {
      this.song.addTrack(new Track)
    })

    this.trackInfoPane.update({
      onChangeName: e => {
        const track = this.song.getTrack(this.trackId)
        track.setName(e.target.value)
      },
      onChangeVolume: e => {
        const track = this.song.getTrack(this.trackId)
        const events = track.findVolumeEvents()
        if (events.length == 0) {
          return
        }
        track.updateEvent(events[0].id, {
          value: e.target.value
        })
      },
      onChangePan: e => {
        const track = this.song.getTrack(this.trackId)
        const events = track.findPanEvents()
        if (events.length == 0) {
          return
        }
        track.updateEvent(events[0].id, {
          value: e.target.value
        })
      },
      onClickInstrument: e => {
        const popup = new PopupComponent()
        const track = this.song.getTrack(this.trackId)
        const events = track.findProgramChangeEvents()
        if (events.length == 0) {
          return
        }

        const programNumber = events[0].value
        const ids = getGMMapIndexes(programNumber)
        riot.mount(popup.getContentElement(), "instrument-browser", {
          selectedCategoryId: ids[0],
          selectedInstrumentId: ids[1],
          onClickCancel: () => {
            popup.close()
          },
          onClickOK: e => {
            const programNumber = getGMMapProgramNumber(e.categoryId, e.instrumentId)
            track.updateEvent(events[0].id, {
              value: programNumber
            })
            popup.close()
          }
        })[0]
        popup.show()
      }
    })

    this.emitter.trigger("view-did-load")
  }
}
<|endoftext|>


<commit_before>'use strict'

const rollup = require('rollup')
const babel = require('rollup-plugin-babel')
const filesize = require('rollup-plugin-filesize')

rollup.rollup({
  entry: 'src/index.js',
  plugins: [
    babel({
      exclude: 'node_modules/**',
      presets: ['es2015-rollup']
    }),
    filesize()
  ]
}).then((bundle) => {
  console.log('server.js: ')
  bundle.write({
    format: 'iife',
    banner: '#!/usr/bin/env node',
    dest: 'server.js'})
})
<commit_msg>build(rollup): simplify rollup config file<commit_after>import babel from 'rollup-plugin-babel'
import filesize from 'rollup-plugin-filesize'

export default {
  entry: 'src/index.js',
  dest: 'server.js',
  format: 'iife',
  banner: '#!/usr/bin/env node',
  plugins: [
    babel({
      exclude: 'node_modules/**',
      presets: ['es2015-rollup']
    }),
    filesize()
  ]
}
<|endoftext|>


<commit_before>//////////////////////////////////////////
// Needle -- Node.js HTTP Client
// Written by Tomás Pollak <tomas@forkhq.com>
// (c) 2012 - Fork Ltd.
// MIT Licensed
//////////////////////////////////////////

var fs = require('fs'),
		path = require('path'),
		http = require('http'),
		https = require('https'),
		url = require('url'),
		stringify = require('qs').stringify,
		version = JSON.parse(fs.readFileSync(__dirname + '/../package.json').toString()).version;

// http.globalAgent.maxSockets = 128;
exports.version = version;
try { var unzip = require('zlib').unzip; } catch(e){ /* zlib not supported */ }

var default_user_agent = "Needle/" + version;
default_user_agent += " (Node.js " + process.version + "; " + process.platform + " " + process.arch + ")";

var parsers = {
	'application/json': function(data, callback){
		callback(data && JSON.parse(data));
	}
};

try {
	var xml2js = require('xml2js');
	parsers['application/xml'] = function(data, callback){

		var xml_parser = new xml2js.Parser();

		xml_parser.on('end', callback);
		xml_parser.on('error', function(result) {
			throw("Error parsing XML!")
//		callback(null);
		});

		xml_parser.parseString(data);

	};
} catch(e) { }

// utility function for flattening params in multipart POST's
function flatten(object, into, prefix){
	into = into || {};

	for(key in object){
		var prefix_key = prefix ? prefix + "[" + key + "]" : key;
		var prop = object[key];

		if(prop && typeof prop === "object" && !((prop.buffer || prop.file) && prop.content_type))
			flatten(prop, into, prefix_key)
		else
			into[prefix_key] = prop;
	}

	return into;
}

var Needle = {

	default_boundary: '--------------------NODENEEDLEHTTPCLIENT',
	default_user_agent: default_user_agent,

	request: function(uri, method, data, options, callback){

		var self = this, post_data = null;
		var callback = (typeof options == 'function') ? options : callback;
		var options = options || {};
		if(uri.indexOf('http') == -1) uri = 'http://' + uri;

		var method = options.method || 'GET';
		var request_compressed = (options.compressed && typeof unzip != 'undefined') || false;

		var config = {
			agent: options.agent,
			proxy: options.proxy,
			encoding: options.encoding || (options.multipart ? 'binary' : 'utf8'),
			parse_response: options.parse === false ? false : true,
			follow: options.follow === false ? 0 : options.follow || 10, // 10 by default
			timeout: (typeof options.timeout == 'number') ? options.timeout : 10000
		}

		config.headers = {
			"User-Agent": options.user_agent || this.default_user_agent,
			"Connection": "close",
			"Accept": "*/*"
		}

		if(request_compressed) config.headers['Accept-Encoding'] = 'gzip,deflate';

		for(h in options.headers)
			config.headers[h] = options.headers[h];

		if(options.username && options.password){
			var b = new Buffer([options.username, options.password].join(':'));
			config.headers['Authorization'] = "Basic " + b.toString('base64');
		}

		if(data) {
			if(options.multipart){

				var boundary = options.boundary || this.default_boundary;
				return this.build_multipart_body(data, boundary, function(err, body){

					if(err) throw(err);
					config.headers['Content-Type'] = 'multipart/form-data; boundary=' + boundary;
					config.headers['Content-Length'] = body.length;
					self.send_request(1, method, uri, config, body, callback);

				});

			} else {
				post_data = (typeof(data) === "string") ? data : stringify(data);
				config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
				config.headers['Content-Length'] = post_data.length;
			}

		}

		this.send_request(1, method, uri, config, post_data, callback);

	},

	get_request_opts: function(method, uri, headers, proxy){

		var remote = proxy ? url.parse(proxy) : url.parse(uri);
		headers["Host"] = proxy ? url.parse(uri).hostname : remote.hostname;

		var opts = {
			host: remote.hostname,
			port: remote.port || (remote.protocol == 'https:' ? 443 : 80),
			protocol: remote.protocol,
			path: proxy ? uri : remote.pathname + (remote.search || ''),
			method: method,
			headers: headers
		};

		return opts;
	},

	send_request: function(count, method, uri, config, post_data, callback){

		var self = this, timer, response_opts = {parse_response: config.parse_response};

		var request_opts = this.get_request_opts(method, uri, config.headers, config.proxy);
		if (typeof config.agent != 'undefined') request_opts.agent = config.agent;

		var protocol = request_opts.protocol == 'https:' ? https : http;
		var request = protocol.request(request_opts, function(response){

			if(timer) clearTimeout(timer);

			if((response.statusCode == 301 || response.statusCode == 302) && response.headers.location){
				if(count <= config.follow)
					return self.send_request(++count, 'GET', response.headers.location, config, null, callback);
				else if(config.follow > 0)
					return callback(new Error("Too many redirects. Possible redirect loop in " + response.headers.location))
			}

			var body = '';
			var compressed = /gzip|deflate/.test(response.headers['content-encoding']);
			response.setEncoding(compressed ? 'binary' : 'utf8');

			response.on('data', function(chunk){
				body += chunk;
			});

			response.on('end', function(){
				if(typeof unzip != 'undefined' && compressed)
					unzip(new Buffer(body, 'binary'), function(err, buff){
						self.response_end(response_opts, response, buff.toString(), callback);
					});
				else
					self.response_end(response_opts, response, body, callback);

			});

		});

		if(config.timeout > 0) {
			timer = setTimeout(function() {
				request.abort();
			}, config.timeout)
		}

		request.on('error', function(err) {
			if(process.env.DEBUG) console.log('Error on request: ' + err.toString());
			if(timer) clearTimeout(timer);
			if(callback) callback(err || new Error("Unkown error on request."));
		});

		if(post_data) request.write(post_data, config.encoding);
		request.end();

	},

	response_end: function(opts, response, body, callback){

		if(process.env.DEBUG) console.log(response.headers);
		if(!callback) return;
		var content_type = response.headers['content-type'] && response.headers['content-type'].split(';')[0];

		if(opts.parse_response && parsers[content_type]) {
			parsers[content_type](body, function(result){
				callback(null, response, result);
			});
		} else {
			callback(null, response, body);
		}

	},

	build_multipart_body: function(data, boundary, callback){

		var body = '';
		var object = flatten(data);
		var count = Object.keys(object).length;

		for(var key in object){

			var value = object[key];
			if(value === null || typeof value == 'undefined') return --count;

			var part = (value.buffer || value.file) && value.content_type ? value : {value: value};

			this.generate_part(key, part, boundary, function(err, section){
				if(err) return callback(err);
				body += section;
				--count || callback(null, body + '--' + boundary + '--');
			});

		}

	},

	generate_part: function(name, part, boundary, callback){

		var return_part = '--' + boundary + "\r\n";
		return_part += "Content-Disposition: form-data; name=\"" + name + "\"";

		var append = function(data, filename){

			if(data){
				return_part += "; filename=\"" + encodeURIComponent(filename) + "\"\r\n";
				return_part += "Content-Type: " + part.content_type + "\r\n\r\n";
				return_part += (part.content_type.indexOf('text') == -1)
					? data.toString('binary')
					: data.toString('utf8');
			}

			callback(null, return_part + '\r\n');
		};

		if((part.file || part.buffer) && part.content_type){

			var filename = part.filename ? part.filename : part.file ? path.basename(part.file) : name;
			if(part.buffer) return append(part.buffer, filename);

			fs.readFile(part.file, function(err, data){

				if(err) return callback(err);
				append(data, filename);

			});

		} else {

			return_part += "\r\n\r\n";
			return_part += part.value;
			append();

		}

	}

}

exports.head = function(uri, options, callback){
	return Needle.request(uri, 'HEAD', null, options, callback);
}

exports.get = function(uri, options, callback){
	return Needle.request(uri, 'GET', null, options, callback);
}

exports.post = function(uri, data, options, callback){
	if(!data) throw('POST request expects data.');
	return Needle.request(uri, 'POST', data, options, callback);
}

exports.put = function(uri, data, options, callback){
	if(!data) throw('PUT request expects data.');
	return Needle.request(uri, 'PUT', data, options, callback);
}

exports.delete = function(uri, data, options, callback){
	return Needle.request(uri, 'DELETE', null, options, callback);
}
<commit_msg>Simplified a few things, add support for additional Node HTTP(s) options.<commit_after>//////////////////////////////////////////
// Needle -- Node.js HTTP Client
// Written by Tomás Pollak <tomas@forkhq.com>
// (c) 2012 - Fork Ltd.
// MIT Licensed
//////////////////////////////////////////

var fs = require('fs'),
		path = require('path'),
		http = require('http'),
		https = require('https'),
		url = require('url'),
		stringify = require('qs').stringify,
		version = JSON.parse(fs.readFileSync(__dirname + '/../package.json').toString()).version;

// http.globalAgent.maxSockets = 128;
exports.version = version;
try { var unzip = require('zlib').unzip; } catch(e){ /* zlib not supported */ }

var default_user_agent = "Needle/" + version;
default_user_agent += " (Node.js " + process.version + "; " + process.platform + " " + process.arch + ")";

var additional_http_opts = ['agent', 'pfx', 'key', 'passphrase', 'cert', 'ca', 'rejectUnauthorized', 'requestCert'];

var parsers = {
	'application/json': function(data, callback){
		callback(data && JSON.parse(data));
	}
};

try {
	var xml2js = require('xml2js');
	parsers['application/xml'] = function(data, callback){

		var xml_parser = new xml2js.Parser();

		xml_parser.on('end', callback);
		xml_parser.on('error', function(result) {
			throw("Error parsing XML!")
//		callback(null);
		});

		xml_parser.parseString(data);

	};
} catch(e) { }

// utility function for flattening params in multipart POST's
function flatten(object, into, prefix){
	into = into || {};

	for(key in object){
		var prefix_key = prefix ? prefix + "[" + key + "]" : key;
		var prop = object[key];

		if(prop && typeof prop === "object" && !((prop.buffer || prop.file) && prop.content_type))
			flatten(prop, into, prefix_key)
		else
			into[prefix_key] = prop;
	}

	return into;
}

var Needle = {

	default_boundary: '--------------------NODENEEDLEHTTPCLIENT',
	default_user_agent: default_user_agent,

	request: function(uri, method, data, options, callback){

		var self = this, post_data = null;
		var callback = (typeof options == 'function') ? options : callback;
		var options = options || {};
		if(uri.indexOf('http') == -1) uri = 'http://' + uri;

		var method = options.method || 'GET';

		var config = {
			base_opts: {},
			proxy: options.proxy,
			encoding: options.encoding || (options.multipart ? 'binary' : 'utf8'),
			parse_response: options.parse === false ? false : true,
			follow: options.follow === false ? 0 : options.follow || 10, // 10 by default
			timeout: (typeof options.timeout == 'number') ? options.timeout : 10000
		}

		additional_http_opts.forEach(function(key){
			if(typeof options[key] != 'undefined')
				config.base_opts[key] = options[key];
		});

		config.headers = {
			"User-Agent": options.user_agent || this.default_user_agent,
			"Connection": "close",
			"Accept": "*/*"
		}

		if (options.compressed && typeof unzip != 'undefined')
			config.headers['Accept-Encoding'] = 'gzip,deflate';

		for(h in options.headers)
			config.headers[h] = options.headers[h];

		if(options.username && options.password){
			var b = new Buffer([options.username, options.password].join(':'));
			config.headers['Authorization'] = "Basic " + b.toString('base64');
		}

		if(data) {
			if(options.multipart){

				var boundary = options.boundary || this.default_boundary;
				return this.build_multipart_body(data, boundary, function(err, body){

					if(err) throw(err);
					config.headers['Content-Type'] = 'multipart/form-data; boundary=' + boundary;
					config.headers['Content-Length'] = body.length;
					self.send_request(1, method, uri, config, body, callback);

				});

			} else {
				post_data = (typeof(data) === "string") ? data : stringify(data);
				config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
				config.headers['Content-Length'] = post_data.length;
			}

		}

		this.send_request(1, method, uri, config, post_data, callback);

	},

	get_request_opts: function(method, uri, config){

		var opts = config.base_opts, proxy = config.proxy;
		var remote = proxy ? url.parse(proxy) : url.parse(uri);

		opts.host = remote.hostname;
		opts.port = remote.port || (remote.protocol == 'https:' ? 443 : 80);
		opts.protocol = remote.protocol;
		opts.path = proxy ? uri : remote.pathname + (remote.search || ''),
		opts.method = method;
		opts.headers = config.headers;
		opts.headers["Host"] = proxy ? url.parse(uri).hostname : remote.hostname;

		return opts;
	},

	send_request: function(count, method, uri, config, post_data, callback){

		var self = this, timer, response_opts = {parse_response: config.parse_response};
		var request_opts = this.get_request_opts(method, uri, config);

		var protocol = request_opts.protocol == 'https:' ? https : http;
		var request = protocol.request(request_opts, function(response){

			if(timer) clearTimeout(timer);

			if((response.statusCode == 301 || response.statusCode == 302) && response.headers.location){
				if(count <= config.follow)
					return self.send_request(++count, 'GET', response.headers.location, config, null, callback);
				else if(config.follow > 0)
					return callback(new Error("Too many redirects. Possible redirect loop in " + response.headers.location))
			}

			var body = '';
			var compressed = /gzip|deflate/.test(response.headers['content-encoding']);
			response.setEncoding(compressed ? 'binary' : 'utf8');

			response.on('data', function(chunk){
				body += chunk;
			});

			response.on('end', function(){
				if(typeof unzip != 'undefined' && compressed)
					unzip(new Buffer(body, 'binary'), function(err, buff){
						self.response_end(response_opts, response, buff.toString(), callback);
					});
				else
					self.response_end(response_opts, response, body, callback);

			});

		});

		if(config.timeout > 0) {
			timer = setTimeout(function() {
				request.abort();
			}, config.timeout)
		}

		request.on('error', function(err) {
			if(process.env.DEBUG) console.log('Error on request: ' + err.toString());
			if(timer) clearTimeout(timer);
			if(callback) callback(err || new Error("Unkown error on request."));
		});

		if(post_data) request.write(post_data, config.encoding);
		request.end();

	},

	response_end: function(opts, response, body, callback){

		if(process.env.DEBUG) console.log(response.headers);
		if(!callback) return;
		var content_type = response.headers['content-type'] && response.headers['content-type'].split(';')[0];

		if(opts.parse_response && parsers[content_type]) {
			parsers[content_type](body, function(result){
				callback(null, response, result);
			});
		} else {
			callback(null, response, body);
		}

	},

	build_multipart_body: function(data, boundary, callback){

		var body = '';
		var object = flatten(data);
		var count = Object.keys(object).length;

		for(var key in object){

			var value = object[key];
			if(value === null || typeof value == 'undefined') return --count;

			var part = (value.buffer || value.file) && value.content_type ? value : {value: value};

			this.generate_part(key, part, boundary, function(err, section){
				if(err) return callback(err);
				body += section;
				--count || callback(null, body + '--' + boundary + '--');
			});

		}

	},

	generate_part: function(name, part, boundary, callback){

		var return_part = '--' + boundary + "\r\n";
		return_part += "Content-Disposition: form-data; name=\"" + name + "\"";

		var append = function(data, filename){

			if(data){
				return_part += "; filename=\"" + encodeURIComponent(filename) + "\"\r\n";
				return_part += "Content-Type: " + part.content_type + "\r\n\r\n";
				return_part += (part.content_type.indexOf('text') == -1)
					? data.toString('binary')
					: data.toString('utf8');
			}

			callback(null, return_part + '\r\n');
		};

		if((part.file || part.buffer) && part.content_type){

			var filename = part.filename ? part.filename : part.file ? path.basename(part.file) : name;
			if(part.buffer) return append(part.buffer, filename);

			fs.readFile(part.file, function(err, data){

				if(err) return callback(err);
				append(data, filename);

			});

		} else {

			return_part += "\r\n\r\n";
			return_part += part.value;
			append();

		}

	}

}

exports.head = function(uri, options, callback){
	return Needle.request(uri, 'HEAD', null, options, callback);
}

exports.get = function(uri, options, callback){
	return Needle.request(uri, 'GET', null, options, callback);
}

exports.post = function(uri, data, options, callback){
	if(!data) throw('POST request expects data.');
	return Needle.request(uri, 'POST', data, options, callback);
}

exports.put = function(uri, data, options, callback){
	if(!data) throw('PUT request expects data.');
	return Needle.request(uri, 'PUT', data, options, callback);
}

exports.delete = function(uri, data, options, callback){
	return Needle.request(uri, 'DELETE', null, options, callback);
}
<|endoftext|>


<commit_before>// rollup.config.js
import typescript from 'rollup-plugin-typescript2';
import serve from 'rollup-plugin-serve';
import livereload from "rollup-plugin-livereload"

const pkg = require("./package.json");

export default {
  input: './src/index.ts',
  name: "flatpickr",
  output: {
    file: 'dist/flatpickr.js',
    format: 'umd',
    banner: `/* flatpickr v${pkg.version}, @license MIT */`
  },

  plugins: [
    typescript({
      abortOnError: false
    }),
    ...process.env.ROLLUP_WATCH ? [serve({
      open: true,
      contentBase: ''
    }),
    livereload()] : []
  ],
  watch: {
    include: 'src/**/*.ts',
  }
}
<commit_msg>rollup - ts - move rpt2 to /tmp<commit_after>// rollup.config.js
import typescript from 'rollup-plugin-typescript2';
import serve from 'rollup-plugin-serve';
import livereload from "rollup-plugin-livereload"

const pkg = require("./package.json");

export default {
  input: './src/index.ts',
  name: "flatpickr",
  output: {
    file: 'dist/flatpickr.js',
    format: 'umd',
    banner: `/* flatpickr v${pkg.version}, @license MIT */`
  },

  plugins: [
    typescript({
      abortOnError: false,
      cacheRoot: `/tmp/.rpt2_cache`
    }),
    ...process.env.ROLLUP_WATCH ? [serve({
      open: true,
      contentBase: ''
    }),
    livereload()] : []
  ],
  watch: {
    include: 'src/**/*.ts',
  }
}
<|endoftext|>


<commit_before>import nodeResolve from 'rollup-plugin-node-resolve';
import babel from 'rollup-plugin-babel';
import commonjs from 'rollup-plugin-commonjs';
import uglify from 'rollup-plugin-uglify';
import replace from 'rollup-plugin-replace';

const env = process.env.NODE_ENV;

const config = {
  entry: 'src/index.js',
  external: ['chart.js', 'react'],
  globals: {
    'chart.js': 'Chart',
    react: 'React'
  },
  exports: 'named',
  format: 'umd',
  moduleName: 'ReactChartjs2',
  plugins: [
    nodeResolve(),
    babel({
      exclude: '**/node_modules/**',
    }),
    commonjs(),
  ],
};

if (env === 'production') {
   config.plugins.push(
    uglify({
      compress: {
        pure_getters: true,
        unsafe: true,
        unsafe_comps: true,
        warnings: false
      },
    })
  );

  config.plugins.push(
    replace({
      'process.env.NODE_ENV': JSON.stringify( 'production' )
    })
  )
}

export default config;
<commit_msg>Replace deprecated uglify options compress.warnings with warnings (#510)<commit_after>import nodeResolve from 'rollup-plugin-node-resolve';
import babel from 'rollup-plugin-babel';
import commonjs from 'rollup-plugin-commonjs';
import uglify from 'rollup-plugin-uglify';
import replace from 'rollup-plugin-replace';

const env = process.env.NODE_ENV;

const config = {
  entry: 'src/index.js',
  external: ['chart.js', 'react'],
  globals: {
    'chart.js': 'Chart',
    react: 'React'
  },
  exports: 'named',
  format: 'umd',
  moduleName: 'ReactChartjs2',
  plugins: [
    nodeResolve(),
    babel({
      exclude: '**/node_modules/**',
    }),
    commonjs(),
  ],
};

if (env === 'production') {
   config.plugins.push(
    uglify({
      compress: {
        pure_getters: true,
        unsafe: true,
        unsafe_comps: true,
      },
      warnings: false
    })
  );

  config.plugins.push(
    replace({
      'process.env.NODE_ENV': JSON.stringify( 'production' )
    })
  )
}

export default config;
<|endoftext|>


<commit_before>import cleanup from "rollup-plugin-cleanup";
import resolve from "rollup-plugin-node-resolve";
import commonjs from "rollup-plugin-commonjs";
import executable from "rollup-plugin-executable";
import json from "rollup-plugin-json";
import pkg from "./package.json";

export default {
  output: {
    file: pkg.bin["rtsp-archive"],
    format: "cjs",
    banner:
      '#!/bin/sh\n":" //# comment; exec /usr/bin/env node --experimental-modules --experimental-worker "$0" "$@"',
    interop: false
  },
  plugins: [
    commonjs(),
    json({
      include: "package.json",
      preferConst: true,
      compact: true
    }),
    cleanup(),
    executable()
  ],
  external: [
    "fs",
    "util",
    "child_process",
    "path",
    "config-expander",
    "caporal"
  ],
  input: pkg.module
};
<commit_msg>fix(rollup): no exports fro config-expander<commit_after>import cleanup from "rollup-plugin-cleanup";
import resolve from "rollup-plugin-node-resolve";
import commonjs from "rollup-plugin-commonjs";
import executable from "rollup-plugin-executable";
import json from "rollup-plugin-json";
import pkg from "./package.json";

export default {
  output: {
    file: pkg.bin["rtsp-archive"],
    format: "cjs",
    banner:
      '#!/bin/sh\n":" //# comment; exec /usr/bin/env node --experimental-modules --experimental-worker "$0" "$@"',
    interop: false
  },
  plugins: [
    commonjs(),
    json({
      include: "package.json",
      preferConst: true,
      compact: true
    }),
    cleanup(),
    executable()
  ],
  external: ["fs", "util", "child_process", "path", "caporal"],
  input: pkg.module
};
<|endoftext|>


<commit_before>
  'use strict';

  /***
   * @package Number
   * @dependency core
   * @description Number formatting, rounding (with precision), and ranges. Aliases to Math methods.
   *
   ***/

  function getThousands() {
    var str = sugarNumber.thousands;
    return isString(str) ? str : ',';
  }

  function getDecimal() {
    var str = sugarNumber.decimal;
    return isString(str) ? str : '.';
  }

  function abbreviateNumber(num, roundTo, str, mid, limit, bytes) {
    var fixed        = num.toFixed(20),
        decimalPlace = fixed.search(/\./),
        numeralPlace = fixed.search(/[1-9]/),
        significant  = decimalPlace - numeralPlace,
        unit, i, divisor;
    if (significant > 0) {
      significant -= 1;
    }
    i = max(min(floor(significant / 3), limit === false ? str.length : limit), -mid);
    unit = str.charAt(i + mid - 1);
    if (significant < -9) {
      i = -3;
      roundTo = abs(significant) - 9;
      unit = str.slice(0,1);
    }
    divisor = bytes ? pow(2, 10 * i) : pow(10, i * 3);
    return numberFormat(withPrecision(num / divisor, roundTo || 0)) + unit.trim();
  }

  function numberFormat(num, place) {
    var i, str, split, integer, fraction, result = '';
    var thousands = getThousands();
    var decimal   = getDecimal();
    str      = (isNumber(place) ? withPrecision(num, place || 0).toFixed(max(place, 0)) : num.toString()).replace(/^-/, '');
    split    = str.split('.');
    integer  = split[0];
    fraction = split[1];
    for(i = integer.length; i > 0; i -= 3) {
      if (i < integer.length) {
        result = thousands + result;
      }
      result = integer.slice(max(0, i - 3), i) + result;
    }
    if (fraction) {
      result += decimal + repeatString('0', (place || 0) - fraction.length) + fraction;
    }
    return (num < 0 ? '-' : '') + result;
  }

  function isInteger(n) {
    return n % 1 === 0;
  }

  function isMultipleOf(n1, n2) {
    return n1 % n2 === 0;
  }

  function createRoundingFunction(fn) {
    return function (n, precision) {
      return precision ? withPrecision(n, precision, fn) : fn(n);
    }
  }

  defineStatic(sugarNumber, {

    /***
     * @method Number.random([n1], [n2])
     * @returns Number
     * @short Returns a random integer between [n1] and [n2].
     * @extra If only 1 number is passed, the other will be 0. If none are passed, the number will be either 0 or 1.
     * @example
     *
     *   Number.random(50, 100) -> ex. 85
     *   Number.random(50)      -> ex. 27
     *   Number.random()        -> ex. 0
     *
     ***/
    'random': function(n1, n2) {
      var minNum, maxNum;
      if (arguments.length == 1) n2 = n1, n1 = 0;
      minNum = min(n1 || 0, isUndefined(n2) ? 1 : n2);
      maxNum = max(n1 || 0, isUndefined(n2) ? 1 : n2) + 1;
      return floor((math.random() * (maxNum - minNum)) + minNum);
    },

    /***
     * @method Number.isNaN(<value>)
     * @returns Boolean
     * @short Returns true only if the number is %NaN%.
     * @extra This is differs from the global %isNaN%, which returns true for anything that is not a number.
     * @example
     *
     *   Number.isNaN(NaN) -> true
     *   Number.isNaN('n') -> false
     *
     ***/
    'isNaN': function(value) {
      return value !== value;
    }

  });

  defineInstance(sugarNumber, {

    /***
     * @method isInteger()
     * @returns Boolean
     * @short Returns true if the number has no trailing decimal.
     * @example
     *
     *   (420).isInteger() -> true
     *   (4.5).isInteger() -> false
     *
     ***/
    'isInteger': isInteger,

    /***
     * @method isOdd()
     * @returns Boolean
     * @short Returns true if the number is odd.
     * @example
     *
     *   (3).isOdd()  -> true
     *   (18).isOdd() -> false
     *
     ***/
    'isOdd': function(n) {
      return isInteger(n) && !isMultipleOf(n, 2);
    },

    /***
     * @method isEven()
     * @returns Boolean
     * @short Returns true if the number is even.
     * @example
     *
     *   (6).isEven()  -> true
     *   (17).isEven() -> false
     *
     ***/
    'isEven': function(n) {
      return isMultipleOf(n, 2);
    },

    /***
     * @method isMultipleOf(<num>)
     * @returns Boolean
     * @short Returns true if the number is a multiple of <num>.
     * @example
     *
     *   (6).isMultipleOf(2)  -> true
     *   (17).isMultipleOf(2) -> false
     *   (32).isMultipleOf(4) -> true
     *   (34).isMultipleOf(4) -> false
     *
     ***/
    'isMultipleOf': isMultipleOf,

    /***
     * @method log(<base> = Math.E)
     * @returns Number
     * @short Returns the logarithm of the number with base <base>, or natural logarithm of the number if <base> is undefined.
     * @example
     *
     *   (64).log(2) -> 6
     *   (9).log(3)  -> 2
     *   (5).log()   -> 1.6094379124341003
     *
     ***/
    'log': function(n, base) {
      return math.log(n) / (base ? math.log(base) : 1);
    },

    /***
     * @method abbr([precision] = 0)
     * @returns String
     * @short Returns an abbreviated form of the number.
     * @extra [precision] will round to the given precision. %Sugar.Number.thousands% and %Sugar.Number.decimal% allow custom markers to be used.
     * @example
     *
     *   (1000).abbr()    -> "1k"
     *   (1000000).abbr() -> "1m"
     *   (1280).abbr(1)   -> "1.3k"
     *
     ***/
    'abbr': function(n, precision) {
      return abbreviateNumber(n, precision, 'kmbt', 0, 4);
    },

    /***
     * @method metric([precision] = 0, [limit] = 1)
     * @returns String
     * @short Returns the number as a string in metric notation.
     * @extra [precision] will round to the given precision. Both very large numbers and very small numbers are supported. [limit] is the upper limit for the units. The default is %1%, which is "kilo". If [limit] is %false%, the upper limit will be "exa". The lower limit is "nano", and cannot be changed. %Sugar.Number.thousands% and %Sugar.Number.decimal% allow custom markers to be used.
     * @example
     *
     *   (1000).metric()            -> "1k"
     *   (1000000).metric()         -> "1,000k"
     *   (1000000).metric(0, false) -> "1M"
     *   (1249).metric(2) + 'g'     -> "1.25kg"
     *   (0.025).metric() + 'm'     -> "25mm"
     *
     ***/
    'metric': function(n, precision, limit) {
      return abbreviateNumber(n, precision, 'nμm kMGTPE', 4, isUndefined(limit) ? 1 : limit);
    },

    /***
     * @method bytes([precision] = 0, [limit] = 4, [si] = false)
     * @returns String
     * @short Returns an abbreviated form of the number, considered to be "Bytes".
     * @extra [precision] will round to the given precision. [limit] is the upper limit for the units. The default is %4%, which is "terabytes" (TB). If [limit] is %false%, the upper limit will be "exa". If [si] is %true%, the standard SI units of 1000 will be used instead of 1024. %Sugar.Number.thousands% and %Sugar.Number.decimal% allow custom markers to be used.
     * @example
     *
     *   (1000).bytes()                 -> "1kB"
     *   (1000).bytes(2)                -> "0.98kB"
     *   ((10).pow(20)).bytes()         -> "90,949,470TB"
     *   ((10).pow(20)).bytes(0, false) -> "87EB"
     *
     ***/
    'bytes': function(n, precision, limit, si) {
      return abbreviateNumber(n, precision, 'kMGTPE', 0, isUndefined(limit) ? 4 : limit, si !== true) + 'B';
    },

    /***
     * @method format([place] = 0)
     * @returns String
     * @short Formats the number to a readable string.
     * @extra If [place] is %undefined%, the place will automatically be determined. %Sugar.Number.thousands% and %Sugar.Number.decimal% allow custom markers to be used.
     * @example
     *
     *   (56782).format()    -> '56,782'
     *   (56782).format(2)   -> '56,782.00'
     *   (4388.43).format(2) -> '4,388.43'
     *
     ***/
    'format': numberFormat,

    /***
     * @method hex([pad] = 1)
     * @returns String
     * @short Converts the number to hexidecimal.
     * @extra [pad] will pad the resulting string to that many places.
     * @example
     *
     *   (255).hex()   -> 'ff';
     *   (255).hex(4)  -> '00ff';
     *   (23654).hex() -> '5c66';
     *
     ***/
    'hex': function(n, pad) {
      return padNumber(n, pad || 1, false, 16);
    },

    /***
     * @method times(<fn>)
     * @returns Number
     * @short Calls <fn> a number of times equivalent to the number.
     * @example
     *
     *   (8).times(function(i) {
     *     // This function is called 8 times.
     *   });
     *
     ***/
    'times': function(n, fn) {
      if (fn) {
        for(var i = 0; i < n; i++) {
          fn.call(n, i);
        }
      }
      return +n;
    },

    /***
     * @method chr()
     * @returns String
     * @short Returns a string at the code point of the number.
     * @example
     *
     *   (65).chr() -> "A"
     *   (75).chr() -> "K"
     *
     ***/
    'chr': function(n) {
      return string.fromCharCode(n);
    },

    /***
     * @method pad(<place> = 0, [sign] = false, [base] = 10)
     * @returns String
     * @short Pads a number with "0" to <place>.
     * @extra [sign] allows you to force the sign as well (+05, etc). [base] can change the base for numeral conversion.
     * @example
     *
     *   (5).pad(2)        -> '05'
     *   (-5).pad(4)       -> '-0005'
     *   (82).pad(3, true) -> '+082'
     *
     ***/
    'pad': padNumber,

    /***
     * @method ordinalize()
     * @returns String
     * @short Returns an ordinalized (English) string, i.e. "1st", "2nd", etc.
     * @example
     *
     *   (1).ordinalize() -> '1st';
     *   (2).ordinalize() -> '2nd';
     *   (8).ordinalize() -> '8th';
     *
     ***/
    'ordinalize': function(n) {
      var suffix, num = abs(n), last = parseInt(num.toString().slice(-2), 10);
      return n + getOrdinalizedSuffix(last);
    },

    /***
     * @method toNumber()
     * @returns Number
     * @short Identity function for compatibilty.
     * @example
     *
     *   (420).toNumber() -> 420
     *
     ***/
    'toNumber': function(n) {
      return n;
    },

    /***
     * @method round(<precision> = 0)
     * @returns Number
     * @short Shortcut for %Math.round% that also allows a <precision>.
     *
     * @example
     *
     *   (3.241).round()  -> 3
     *   (-3.841).round() -> -4
     *   (3.241).round(2) -> 3.24
     *   (3748).round(-2) -> 3800
     *
     ***/
    'round': createRoundingFunction(round),

    /***
     * @method ceil(<precision> = 0)
     * @returns Number
     * @short Shortcut for %Math.ceil% that also allows a <precision>.
     *
     * @example
     *
     *   (3.241).ceil()  -> 4
     *   (-3.241).ceil() -> -3
     *   (3.241).ceil(2) -> 3.25
     *   (3748).ceil(-2) -> 3800
     *
     ***/
    'ceil': createRoundingFunction(ceil),

    /***
     * @method floor(<precision> = 0)
     * @returns Number
     * @short Shortcut for %Math.floor% that also allows a <precision>.
     *
     * @example
     *
     *   (3.241).floor()  -> 3
     *   (-3.841).floor() -> -4
     *   (3.241).floor(2) -> 3.24
     *   (3748).floor(-2) -> 3700
     *
     ***/
    'floor': createRoundingFunction(floor)

  });

  /***
   * @method [math]()
   * @returns Number
   * @short Math related functions are mapped as shortcuts to numbers and are identical. Note that %Number#log% provides some special defaults.
   *
   * @set
   *   abs
   *   sin
   *   asin
   *   cos
   *   acos
   *   tan
   *   atan
   *   sqrt
   *   exp
   *   pow
   *
   * @example
   *
   *   (3).pow(3) -> 27
   *   (-3).abs() -> 3
   *   (1024).sqrt() -> 32
   *
   ***/
  defineInstanceSimilar(sugarNumber, 'abs,pow,sin,asin,cos,acos,tan,atan,exp,pow,sqrt', function(methods, name) {
    methods[name] = function mathAlias() {
      return math[name].apply(null, arguments);
    }
  });
<commit_msg>can call Math methods with 2 arguments instead of applying args<commit_after>
  'use strict';

  /***
   * @package Number
   * @dependency core
   * @description Number formatting, rounding (with precision), and ranges. Aliases to Math methods.
   *
   ***/

  function getThousands() {
    var str = sugarNumber.thousands;
    return isString(str) ? str : ',';
  }

  function getDecimal() {
    var str = sugarNumber.decimal;
    return isString(str) ? str : '.';
  }

  function abbreviateNumber(num, roundTo, str, mid, limit, bytes) {
    var fixed        = num.toFixed(20),
        decimalPlace = fixed.search(/\./),
        numeralPlace = fixed.search(/[1-9]/),
        significant  = decimalPlace - numeralPlace,
        unit, i, divisor;
    if (significant > 0) {
      significant -= 1;
    }
    i = max(min(floor(significant / 3), limit === false ? str.length : limit), -mid);
    unit = str.charAt(i + mid - 1);
    if (significant < -9) {
      i = -3;
      roundTo = abs(significant) - 9;
      unit = str.slice(0,1);
    }
    divisor = bytes ? pow(2, 10 * i) : pow(10, i * 3);
    return numberFormat(withPrecision(num / divisor, roundTo || 0)) + unit.trim();
  }

  function numberFormat(num, place) {
    var i, str, split, integer, fraction, result = '';
    var thousands = getThousands();
    var decimal   = getDecimal();
    str      = (isNumber(place) ? withPrecision(num, place || 0).toFixed(max(place, 0)) : num.toString()).replace(/^-/, '');
    split    = str.split('.');
    integer  = split[0];
    fraction = split[1];
    for(i = integer.length; i > 0; i -= 3) {
      if (i < integer.length) {
        result = thousands + result;
      }
      result = integer.slice(max(0, i - 3), i) + result;
    }
    if (fraction) {
      result += decimal + repeatString('0', (place || 0) - fraction.length) + fraction;
    }
    return (num < 0 ? '-' : '') + result;
  }

  function isInteger(n) {
    return n % 1 === 0;
  }

  function isMultipleOf(n1, n2) {
    return n1 % n2 === 0;
  }

  function createRoundingFunction(fn) {
    return function (n, precision) {
      return precision ? withPrecision(n, precision, fn) : fn(n);
    }
  }

  defineStatic(sugarNumber, {

    /***
     * @method Number.random([n1], [n2])
     * @returns Number
     * @short Returns a random integer between [n1] and [n2].
     * @extra If only 1 number is passed, the other will be 0. If none are passed, the number will be either 0 or 1.
     * @example
     *
     *   Number.random(50, 100) -> ex. 85
     *   Number.random(50)      -> ex. 27
     *   Number.random()        -> ex. 0
     *
     ***/
    'random': function(n1, n2) {
      var minNum, maxNum;
      if (arguments.length == 1) n2 = n1, n1 = 0;
      minNum = min(n1 || 0, isUndefined(n2) ? 1 : n2);
      maxNum = max(n1 || 0, isUndefined(n2) ? 1 : n2) + 1;
      return floor((math.random() * (maxNum - minNum)) + minNum);
    },

    /***
     * @method Number.isNaN(<value>)
     * @returns Boolean
     * @short Returns true only if the number is %NaN%.
     * @extra This is differs from the global %isNaN%, which returns true for anything that is not a number.
     * @example
     *
     *   Number.isNaN(NaN) -> true
     *   Number.isNaN('n') -> false
     *
     ***/
    'isNaN': function(value) {
      return value !== value;
    }

  });

  defineInstance(sugarNumber, {

    /***
     * @method isInteger()
     * @returns Boolean
     * @short Returns true if the number has no trailing decimal.
     * @example
     *
     *   (420).isInteger() -> true
     *   (4.5).isInteger() -> false
     *
     ***/
    'isInteger': isInteger,

    /***
     * @method isOdd()
     * @returns Boolean
     * @short Returns true if the number is odd.
     * @example
     *
     *   (3).isOdd()  -> true
     *   (18).isOdd() -> false
     *
     ***/
    'isOdd': function(n) {
      return isInteger(n) && !isMultipleOf(n, 2);
    },

    /***
     * @method isEven()
     * @returns Boolean
     * @short Returns true if the number is even.
     * @example
     *
     *   (6).isEven()  -> true
     *   (17).isEven() -> false
     *
     ***/
    'isEven': function(n) {
      return isMultipleOf(n, 2);
    },

    /***
     * @method isMultipleOf(<num>)
     * @returns Boolean
     * @short Returns true if the number is a multiple of <num>.
     * @example
     *
     *   (6).isMultipleOf(2)  -> true
     *   (17).isMultipleOf(2) -> false
     *   (32).isMultipleOf(4) -> true
     *   (34).isMultipleOf(4) -> false
     *
     ***/
    'isMultipleOf': isMultipleOf,

    /***
     * @method log(<base> = Math.E)
     * @returns Number
     * @short Returns the logarithm of the number with base <base>, or natural logarithm of the number if <base> is undefined.
     * @example
     *
     *   (64).log(2) -> 6
     *   (9).log(3)  -> 2
     *   (5).log()   -> 1.6094379124341003
     *
     ***/
    'log': function(n, base) {
      return math.log(n) / (base ? math.log(base) : 1);
    },

    /***
     * @method abbr([precision] = 0)
     * @returns String
     * @short Returns an abbreviated form of the number.
     * @extra [precision] will round to the given precision. %Sugar.Number.thousands% and %Sugar.Number.decimal% allow custom markers to be used.
     * @example
     *
     *   (1000).abbr()    -> "1k"
     *   (1000000).abbr() -> "1m"
     *   (1280).abbr(1)   -> "1.3k"
     *
     ***/
    'abbr': function(n, precision) {
      return abbreviateNumber(n, precision, 'kmbt', 0, 4);
    },

    /***
     * @method metric([precision] = 0, [limit] = 1)
     * @returns String
     * @short Returns the number as a string in metric notation.
     * @extra [precision] will round to the given precision. Both very large numbers and very small numbers are supported. [limit] is the upper limit for the units. The default is %1%, which is "kilo". If [limit] is %false%, the upper limit will be "exa". The lower limit is "nano", and cannot be changed. %Sugar.Number.thousands% and %Sugar.Number.decimal% allow custom markers to be used.
     * @example
     *
     *   (1000).metric()            -> "1k"
     *   (1000000).metric()         -> "1,000k"
     *   (1000000).metric(0, false) -> "1M"
     *   (1249).metric(2) + 'g'     -> "1.25kg"
     *   (0.025).metric() + 'm'     -> "25mm"
     *
     ***/
    'metric': function(n, precision, limit) {
      return abbreviateNumber(n, precision, 'nμm kMGTPE', 4, isUndefined(limit) ? 1 : limit);
    },

    /***
     * @method bytes([precision] = 0, [limit] = 4, [si] = false)
     * @returns String
     * @short Returns an abbreviated form of the number, considered to be "Bytes".
     * @extra [precision] will round to the given precision. [limit] is the upper limit for the units. The default is %4%, which is "terabytes" (TB). If [limit] is %false%, the upper limit will be "exa". If [si] is %true%, the standard SI units of 1000 will be used instead of 1024. %Sugar.Number.thousands% and %Sugar.Number.decimal% allow custom markers to be used.
     * @example
     *
     *   (1000).bytes()                 -> "1kB"
     *   (1000).bytes(2)                -> "0.98kB"
     *   ((10).pow(20)).bytes()         -> "90,949,470TB"
     *   ((10).pow(20)).bytes(0, false) -> "87EB"
     *
     ***/
    'bytes': function(n, precision, limit, si) {
      return abbreviateNumber(n, precision, 'kMGTPE', 0, isUndefined(limit) ? 4 : limit, si !== true) + 'B';
    },

    /***
     * @method format([place] = 0)
     * @returns String
     * @short Formats the number to a readable string.
     * @extra If [place] is %undefined%, the place will automatically be determined. %Sugar.Number.thousands% and %Sugar.Number.decimal% allow custom markers to be used.
     * @example
     *
     *   (56782).format()    -> '56,782'
     *   (56782).format(2)   -> '56,782.00'
     *   (4388.43).format(2) -> '4,388.43'
     *
     ***/
    'format': numberFormat,

    /***
     * @method hex([pad] = 1)
     * @returns String
     * @short Converts the number to hexidecimal.
     * @extra [pad] will pad the resulting string to that many places.
     * @example
     *
     *   (255).hex()   -> 'ff';
     *   (255).hex(4)  -> '00ff';
     *   (23654).hex() -> '5c66';
     *
     ***/
    'hex': function(n, pad) {
      return padNumber(n, pad || 1, false, 16);
    },

    /***
     * @method times(<fn>)
     * @returns Number
     * @short Calls <fn> a number of times equivalent to the number.
     * @example
     *
     *   (8).times(function(i) {
     *     // This function is called 8 times.
     *   });
     *
     ***/
    'times': function(n, fn) {
      if (fn) {
        for(var i = 0; i < n; i++) {
          fn.call(n, i);
        }
      }
      return +n;
    },

    /***
     * @method chr()
     * @returns String
     * @short Returns a string at the code point of the number.
     * @example
     *
     *   (65).chr() -> "A"
     *   (75).chr() -> "K"
     *
     ***/
    'chr': function(n) {
      return string.fromCharCode(n);
    },

    /***
     * @method pad(<place> = 0, [sign] = false, [base] = 10)
     * @returns String
     * @short Pads a number with "0" to <place>.
     * @extra [sign] allows you to force the sign as well (+05, etc). [base] can change the base for numeral conversion.
     * @example
     *
     *   (5).pad(2)        -> '05'
     *   (-5).pad(4)       -> '-0005'
     *   (82).pad(3, true) -> '+082'
     *
     ***/
    'pad': padNumber,

    /***
     * @method ordinalize()
     * @returns String
     * @short Returns an ordinalized (English) string, i.e. "1st", "2nd", etc.
     * @example
     *
     *   (1).ordinalize() -> '1st';
     *   (2).ordinalize() -> '2nd';
     *   (8).ordinalize() -> '8th';
     *
     ***/
    'ordinalize': function(n) {
      var suffix, num = abs(n), last = parseInt(num.toString().slice(-2), 10);
      return n + getOrdinalizedSuffix(last);
    },

    /***
     * @method toNumber()
     * @returns Number
     * @short Identity function for compatibilty.
     * @example
     *
     *   (420).toNumber() -> 420
     *
     ***/
    'toNumber': function(n) {
      return n;
    },

    /***
     * @method round(<precision> = 0)
     * @returns Number
     * @short Shortcut for %Math.round% that also allows a <precision>.
     *
     * @example
     *
     *   (3.241).round()  -> 3
     *   (-3.841).round() -> -4
     *   (3.241).round(2) -> 3.24
     *   (3748).round(-2) -> 3800
     *
     ***/
    'round': createRoundingFunction(round),

    /***
     * @method ceil(<precision> = 0)
     * @returns Number
     * @short Shortcut for %Math.ceil% that also allows a <precision>.
     *
     * @example
     *
     *   (3.241).ceil()  -> 4
     *   (-3.241).ceil() -> -3
     *   (3.241).ceil(2) -> 3.25
     *   (3748).ceil(-2) -> 3800
     *
     ***/
    'ceil': createRoundingFunction(ceil),

    /***
     * @method floor(<precision> = 0)
     * @returns Number
     * @short Shortcut for %Math.floor% that also allows a <precision>.
     *
     * @example
     *
     *   (3.241).floor()  -> 3
     *   (-3.841).floor() -> -4
     *   (3.241).floor(2) -> 3.24
     *   (3748).floor(-2) -> 3700
     *
     ***/
    'floor': createRoundingFunction(floor)

  });

  /***
   * @method [math]()
   * @returns Number
   * @short Math related functions are mapped as shortcuts to numbers and are identical. Note that %Number#log% provides some special defaults.
   *
   * @set
   *   abs
   *   sin
   *   asin
   *   cos
   *   acos
   *   tan
   *   atan
   *   sqrt
   *   exp
   *   pow
   *
   * @example
   *
   *   (3).pow(3) -> 27
   *   (-3).abs() -> 3
   *   (1024).sqrt() -> 32
   *
   ***/
  defineInstanceSimilar(sugarNumber, 'abs,pow,sin,asin,cos,acos,tan,atan,exp,pow,sqrt', function(methods, name) {
    methods[name] = function mathAlias(n, arg) {
      return math[name](n, arg);
    }
  });
<|endoftext|>


<commit_before>'use strict';

var fs = require('fs');
var path = require('path');
var dataUri = require('strong-data-uri');
var url = require('url');
var urllibsync = require('urllib-sync');
var xml = require('libxmljs');

exports.section = function(e) {
  var all = e.find('ancestor-or-self::section');
  var num = all.map(function(a){
    return a.get('count(preceding-sibling::section)')+1;
  }).join('.');
  if (e.get('ancestor::boilerplate')) {
    num = 'boilerplate-' + num;
  }
  return num;
};

exports.appendix = function(e) {
  var all = e.find('ancestor-or-self::section');
  return all.map(function(a, i){
    var c = a.get('count(preceding-sibling::section)')+1;
    if (i == 0) {
      c = String.fromCharCode(64 + c);
    }
    return c;
  }).join('.');
};

var parts = [
  'abstract',
  'artwork',
  'aside',
  'blockquote',
  'dt',
  'li',
  'ol',
  'references',
  'sourcecode',
  't',
  'ul',
];

exports.isPart = function(e) {
  if (e == null) {return false};
  if ((typeof(e.get) === "function") && e.get('ancestor::reference')) {
    return false;
  }
  var nm = e;
  if (typeof(e) !== "string") {
    var p = e.parent && e.parent()
    if (p && p.name && (p.name() === 't')) {
      return false;
    }
    nm = e.name();
  }
  return (parts.indexOf(nm) >= 0);
};

exports.partNumber = function(e) {
  if (!exports.isPart(e)) {
    return null;
  }

  var prev = e.get('preceding-sibling::*[@pn][1]/@pn');
  if (prev) {
    return prev.value().replace(/\d+$/, n => parseInt(n)+1)
  }
  var s = e.get('ancestor::*[@pn][1]');
  if (!s) {
    console.error('invalid doc')
    return null;
  }
  var pn = att(s, 'pn');
  if (s.name() == 'section') {
    return  pn + '-1';
  }
  return pn + '.1';
};

exports.sequentialNumber = function(e) {
  return "" + (e.find('count(preceding::' + e.name() + ")") + 1);
};

var TLPs = {
  'trust200902': ["", ""],
  'noModificationTrust200902':
    ["  This document may not be modified, and derivative works of it may not be created, except to format it for publication as an RFC or to translate it into languages other than English.",
     ""],
  'noDerivativesTrust200902':
    ["  This document may not be modified, and derivative works of it may not be created, and it may not be published except as an Internet-Draft.",
     ""],
  'pre5378Trust200902':
    ["",
     "This document may contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008.  The person(s) controlling the copyright in some of this material may not have granted the IETF Trust the right to allow modifications of such material outside the IETF Standards Process. Without obtaining an adequate license from the person(s) controlling the copyright in such materials, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process, except to format it for publication as an RFC or to translate it into languages other than English."]
};

exports.ipr = function(val) {
  return TLPs[val] || TLPs['trust200902'];
};

exports.normalize = function(t) {
  t = t.replace(/\.\s*\n\s+/gm, '.  ');
  return t.replace(/\s*\n\s+/gm, ' ');
};

var att = function(e, a) {
  var attr = e.attr(a);
  if (!attr) { return null; }
  return attr.value();
}

exports.defaultAttr = function(e, a, val) {
  if (e && a && val && !e.attr(a)) {
    e.attr(a, val);
  }
}

exports.scripts = function(text) {
  var punycode = require('punycode');
  var unicode = require('unicode-properties');
  var s = new Set();
  var decoded = punycode.ucs2.decode(text);
  var i;
  for (i=0; i<decoded.length; i++) {
    s.add(unicode.getScript(decoded[i]));
  }
  var all = [];
  s.forEach(function(scr){
     all.push(scr);
  });
  return all.sort();
}

exports.cmpAnchor = function(a, b) {
  var aa = att(a, 'anchor');
  var adr = a.get('//displayreference[@target="' + aa + '"]/@to')
  if (adr) {
    aa = adr.value();
  }

  var ba = att(b, 'anchor');
  var bdr = b.get('//displayreference[@target="' + ba + '"]/@to')
  if (bdr) {
    ba = bdr.value();
  }

  if (aa === ba) {
    return 0;
  }
  if (aa < ba) {
    return -1;
  }
  return 1;
}

exports.elementToDate = function(e) {
  var yr = att(e, 'year');
  var mn = att(e, 'month');
  var dy = att(e, 'day');
  if (!(yr && mn && dy)) {
    return null;
  }
  return new Date(yr, mn-1, dy);
}

exports.liNum = function(li) {
  const container = li.get('ancestor::*[self::ol or self::dl or self::ul][1]');

  // ol always has @start.  ul and dl don't.
  const start = parseInt(att(container, 'start')) || 1;
  const num = start + li.get('count(preceding-sibling::' + li.name() + ')')
  switch (att(container, 'type')) {
    case 'a':
      // TODO: lists longer than 26.
      return String.fromCodePoint('a'.charCodeAt(0) + num - 1);
    case 'A':
      // TODO: lists longer than 26.
      return String.fromCodePoint('A'.charCodeAt(0) + num - 1);
    case 'i':
      return require('roman-numerals').toRoman(num).toLowerCase();
    case 'I':
      return require('roman-numerals').toRoman(num);
  }
  return num;
}
<commit_msg>number dd, dl<commit_after>'use strict';

var fs = require('fs');
var path = require('path');
var dataUri = require('strong-data-uri');
var url = require('url');
var urllibsync = require('urllib-sync');
var xml = require('libxmljs');

exports.section = function(e) {
  var all = e.find('ancestor-or-self::section');
  var num = all.map(function(a){
    return a.get('count(preceding-sibling::section)')+1;
  }).join('.');
  if (e.get('ancestor::boilerplate')) {
    num = 'boilerplate-' + num;
  }
  return num;
};

exports.appendix = function(e) {
  var all = e.find('ancestor-or-self::section');
  return all.map(function(a, i){
    var c = a.get('count(preceding-sibling::section)')+1;
    if (i == 0) {
      c = String.fromCharCode(64 + c);
    }
    return c;
  }).join('.');
};

var parts = [
  'abstract',
  'artwork',
  'aside',
  'blockquote',
  'dd',
  'dl',
  'dt',
  'li',
  'ol',
  'references',
  'sourcecode',
  't',
  'ul',
];

exports.isPart = function(e) {
  if (e == null) {return false};
  if ((typeof(e.get) === "function") && e.get('ancestor::reference')) {
    return false;
  }
  var nm = e;
  if (typeof(e) !== "string") {
    var p = e.parent && e.parent()
    if (p && p.name && (p.name() === 't')) {
      return false;
    }
    nm = e.name();
  }
  return (parts.indexOf(nm) >= 0);
};

exports.partNumber = function(e) {
  if (!exports.isPart(e)) {
    return null;
  }

  var prev = e.get('preceding-sibling::*[@pn][1]/@pn');
  if (prev) {
    return prev.value().replace(/\d+$/, n => parseInt(n)+1)
  }
  var s = e.get('ancestor::*[@pn][1]');
  if (!s) {
    console.error('invalid doc')
    return null;
  }
  var pn = att(s, 'pn');
  if (s.name() == 'section') {
    return  pn + '-1';
  }
  return pn + '.1';
};

exports.sequentialNumber = function(e) {
  return "" + (e.find('count(preceding::' + e.name() + ")") + 1);
};

var TLPs = {
  'trust200902': ["", ""],
  'noModificationTrust200902':
    ["  This document may not be modified, and derivative works of it may not be created, except to format it for publication as an RFC or to translate it into languages other than English.",
     ""],
  'noDerivativesTrust200902':
    ["  This document may not be modified, and derivative works of it may not be created, and it may not be published except as an Internet-Draft.",
     ""],
  'pre5378Trust200902':
    ["",
     "This document may contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008.  The person(s) controlling the copyright in some of this material may not have granted the IETF Trust the right to allow modifications of such material outside the IETF Standards Process. Without obtaining an adequate license from the person(s) controlling the copyright in such materials, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process, except to format it for publication as an RFC or to translate it into languages other than English."]
};

exports.ipr = function(val) {
  return TLPs[val] || TLPs['trust200902'];
};

exports.normalize = function(t) {
  t = t.replace(/\.\s*\n\s+/gm, '.  ');
  return t.replace(/\s*\n\s+/gm, ' ');
};

var att = function(e, a) {
  var attr = e.attr(a);
  if (!attr) { return null; }
  return attr.value();
}

exports.defaultAttr = function(e, a, val) {
  if (e && a && val && !e.attr(a)) {
    e.attr(a, val);
  }
}

exports.scripts = function(text) {
  var punycode = require('punycode');
  var unicode = require('unicode-properties');
  var s = new Set();
  var decoded = punycode.ucs2.decode(text);
  var i;
  for (i=0; i<decoded.length; i++) {
    s.add(unicode.getScript(decoded[i]));
  }
  var all = [];
  s.forEach(function(scr){
     all.push(scr);
  });
  return all.sort();
}

exports.cmpAnchor = function(a, b) {
  var aa = att(a, 'anchor');
  var adr = a.get('//displayreference[@target="' + aa + '"]/@to')
  if (adr) {
    aa = adr.value();
  }

  var ba = att(b, 'anchor');
  var bdr = b.get('//displayreference[@target="' + ba + '"]/@to')
  if (bdr) {
    ba = bdr.value();
  }

  if (aa === ba) {
    return 0;
  }
  if (aa < ba) {
    return -1;
  }
  return 1;
}

exports.elementToDate = function(e) {
  var yr = att(e, 'year');
  var mn = att(e, 'month');
  var dy = att(e, 'day');
  if (!(yr && mn && dy)) {
    return null;
  }
  return new Date(yr, mn-1, dy);
}

exports.liNum = function(li) {
  const container = li.get('ancestor::*[self::ol or self::dl or self::ul][1]');

  // ol always has @start.  ul and dl don't.
  const start = parseInt(att(container, 'start')) || 1;
  const num = start + li.get('count(preceding-sibling::' + li.name() + ')')
  switch (att(container, 'type')) {
    case 'a':
      // TODO: lists longer than 26.
      return String.fromCodePoint('a'.charCodeAt(0) + num - 1);
    case 'A':
      // TODO: lists longer than 26.
      return String.fromCodePoint('A'.charCodeAt(0) + num - 1);
    case 'i':
      return require('roman-numerals').toRoman(num).toLowerCase();
    case 'I':
      return require('roman-numerals').toRoman(num);
  }
  return num;
}
<|endoftext|>


<commit_before>var util = require('util'),
   _ = require('underscore')
  , OAuth2Strategy = require('passport-oauth2')
  , InternalOAuthError = require('passport-oauth2').InternalOAuthError;

function Strategy(options, verify) {
  options = options || {};
  options.authorizationURL = options.authorizationURL || 'https://www.linkedin.com/oauth/v2/authorization';
  options.tokenURL = options.tokenURL || 'https://www.linkedin.com/oauth/v2/accessToken';

  // ULP-467: potential workaround for LinkedId profile API v1 problems
  // We store the scope and the profileFields to later recompute the profile
  // request URL with one fewer field: "public-profile-url". See implementation
  // of Strategy.prototype.userProfile below
  this.scope = options.scope = options.scope || ['r_basicprofile'];
  this.profileFields = options.profileFields = options.profileFields || null;

  //By default we want data in JSON
  options.customHeaders = options.customHeaders || {"x-li-format":"json"};

  OAuth2Strategy.call(this, options, verify);
  this.name = 'linkedin';
  this.profileUrl = getProfileUrl(options.scope, options.profileFields);
}

util.inherits(Strategy, OAuth2Strategy);

Strategy.prototype.userProfile = function(accessToken, done) {
  function parseBody(body) {
    try {
      var json = JSON.parse(body);

      var profile = { provider: 'linkedin' };

      profile.id = json.id;
      profile.displayName = json.formattedName;
      profile.name = {
                        familyName: json.lastName,
                        givenName:  json.firstName
                     };
      profile.emails = [{ value: json.emailAddress }];
      profile.photos = [];
      if (json.pictureUrl) {
          profile.photos.push({ value: json.pictureUrl });
      }
      profile._raw = body;
      profile._json = json;

      done(null, profile);
    } catch(e) {
      done(e);
    }
  }

  //LinkedIn uses a custom name for the access_token parameter
  this._oauth2.setAccessTokenName("oauth2_access_token");

  this._oauth2.get(this.profileUrl, accessToken, (err, body, res) => {
    if (err) {
      // See below to understand why we are doing this.
      if(this.profileUrl.indexOf('public-profile-url') === -1) {
        return done(new InternalOAuthError('failed to fetch user profile', err));
      }

      // Retry without the public-profile-url field. Requests to the
      // public profile URL fail if the user has decided to hide his profile.
      const profileUrl = getProfileUrl(this.scope, this.profileFields, ['public-profile-url']);
      this._oauth2.get(profileUrl, accessToken, (err, body, res) => {
        if(err) {
          return done(new InternalOAuthError('failed to fetch user profile', err));
        }

        return parseBody(body);
      });
    }

    return parseBody(body);
  });
}

Strategy.prototype.authorizationParams = function(options) {

  var params = {};

  // LinkedIn requires state parameter. It will return an error if not set.
  if (options.state) {
    params['state'] = options.state;
  }
  return params;
}

function getProfileUrl(scope, profileFields, skipFields) {
  return 'https://api.linkedin.com/v1/people/~:(' +
    convertScopeToUserProfileFields(scope, profileFields, skipFields) +
    ')';
}

function convertScopeToUserProfileFields(scope, profileFields, skipFields) {
  var map = {
    'r_basicprofile':   [
      'id',
      'first-name',
      'last-name',
      'picture-url',
      'picture-urls::(original)',
      'formatted-name',
      'maiden-name',
      'phonetic-first-name',
      'phonetic-last-name',
      'formatted-phonetic-name',
      'headline',
      'location:(name,country:(code))',
      'industry',
      'distance',
      'relation-to-viewer:(distance,connections)',
      'current-share',
      'num-connections',
      'num-connections-capped',
      'summary',
      'specialties',
      'positions',
      'site-standard-profile-request',
      'api-standard-profile-request:(headers,url)',
      'public-profile-url'
    ],
    'r_emailaddress':   ['email-address'],
    'r_fullprofile':   [
      'last-modified-timestamp',
      'proposal-comments',
      'associations',
      'interests',
      'publications',
      'patents',
      'languages',
      'skills',
      'certifications',
      'educations',
      'courses',
      'volunteer',
      'three-current-positions',
      'three-past-positions',
      'num-recommenders',
      'recommendations-received',
      'mfeed-rss-url',
      'following',
      'job-bookmarks',
      'suggestions',
      'date-of-birth',
      'member-url-resources:(name,url)',
      'related-profile-views',
      'honors-awards'
    ]
  };

  var fields = [];

  // To obtain pre-defined field mappings
  if(Array.isArray(scope) && profileFields === null)
  {
    if(scope.indexOf('r_basicprofile') === -1){
      scope.unshift('r_basicprofile');
    }

    scope.forEach(function(f) {
      if (typeof map[f] === 'undefined') return;

      if (Array.isArray(map[f])) {
        Array.prototype.push.apply(fields, map[f]);
      } else {
        fields.push(map[f]);
      }
    });
  } else if(Array.isArray(profileFields)){
    fields = profileFields;
  }

  if(Array.isArray(skipFields)) {
    fields = fields.filter(f => skipFields.indexOf(f) === -1)
  }

  return fields.join(',');
}

module.exports = Strategy;
<commit_msg>Fix double call to callback.<commit_after>var util = require('util'),
   _ = require('underscore')
  , OAuth2Strategy = require('passport-oauth2')
  , InternalOAuthError = require('passport-oauth2').InternalOAuthError;

function Strategy(options, verify) {
  options = options || {};
  options.authorizationURL = options.authorizationURL || 'https://www.linkedin.com/oauth/v2/authorization';
  options.tokenURL = options.tokenURL || 'https://www.linkedin.com/oauth/v2/accessToken';

  // ULP-467: potential workaround for LinkedId profile API v1 problems
  // We store the scope and the profileFields to later recompute the profile
  // request URL with one fewer field: "public-profile-url". See implementation
  // of Strategy.prototype.userProfile below
  this.scope = options.scope = options.scope || ['r_basicprofile'];
  this.profileFields = options.profileFields = options.profileFields || null;

  //By default we want data in JSON
  options.customHeaders = options.customHeaders || {"x-li-format":"json"};

  OAuth2Strategy.call(this, options, verify);
  this.name = 'linkedin';
  this.profileUrl = getProfileUrl(options.scope, options.profileFields);
}

util.inherits(Strategy, OAuth2Strategy);

Strategy.prototype.userProfile = function(accessToken, done) {
  function parseBody(body) {
    try {
      var json = JSON.parse(body);

      var profile = { provider: 'linkedin' };

      profile.id = json.id;
      profile.displayName = json.formattedName;
      profile.name = {
                        familyName: json.lastName,
                        givenName:  json.firstName
                     };
      profile.emails = [{ value: json.emailAddress }];
      profile.photos = [];
      if (json.pictureUrl) {
          profile.photos.push({ value: json.pictureUrl });
      }
      profile._raw = body;
      profile._json = json;

      done(null, profile);
    } catch(e) {
      done(e);
    }
  }

  //LinkedIn uses a custom name for the access_token parameter
  this._oauth2.setAccessTokenName("oauth2_access_token");

  this._oauth2.get(this.profileUrl, accessToken, (err, body, res) => {
    if (err) {
      // See below to understand why we are doing this.
      if(this.profileUrl.indexOf('public-profile-url') === -1) {
        return done(new InternalOAuthError('failed to fetch user profile', err));
      }

      // Retry without the public-profile-url field. Requests to the
      // public profile URL fail if the user has decided to hide his profile.
      const profileUrl = getProfileUrl(this.scope, this.profileFields, ['public-profile-url']);
      return this._oauth2.get(profileUrl, accessToken, (err, body, res) => {
        if(err) {
          return done(new InternalOAuthError('failed to fetch user profile', err));
        }

        return parseBody(body);
      });
    }

    return parseBody(body);
  });
}

Strategy.prototype.authorizationParams = function(options) {

  var params = {};

  // LinkedIn requires state parameter. It will return an error if not set.
  if (options.state) {
    params['state'] = options.state;
  }
  return params;
}

function getProfileUrl(scope, profileFields, skipFields) {
  return 'https://api.linkedin.com/v1/people/~:(' +
    convertScopeToUserProfileFields(scope, profileFields, skipFields) +
    ')';
}

function convertScopeToUserProfileFields(scope, profileFields, skipFields) {
  var map = {
    'r_basicprofile':   [
      'id',
      'first-name',
      'last-name',
      'picture-url',
      'picture-urls::(original)',
      'formatted-name',
      'maiden-name',
      'phonetic-first-name',
      'phonetic-last-name',
      'formatted-phonetic-name',
      'headline',
      'location:(name,country:(code))',
      'industry',
      'distance',
      'relation-to-viewer:(distance,connections)',
      'current-share',
      'num-connections',
      'num-connections-capped',
      'summary',
      'specialties',
      'positions',
      'site-standard-profile-request',
      'api-standard-profile-request:(headers,url)',
      'public-profile-url'
    ],
    'r_emailaddress':   ['email-address'],
    'r_fullprofile':   [
      'last-modified-timestamp',
      'proposal-comments',
      'associations',
      'interests',
      'publications',
      'patents',
      'languages',
      'skills',
      'certifications',
      'educations',
      'courses',
      'volunteer',
      'three-current-positions',
      'three-past-positions',
      'num-recommenders',
      'recommendations-received',
      'mfeed-rss-url',
      'following',
      'job-bookmarks',
      'suggestions',
      'date-of-birth',
      'member-url-resources:(name,url)',
      'related-profile-views',
      'honors-awards'
    ]
  };

  var fields = [];

  // To obtain pre-defined field mappings
  if(Array.isArray(scope) && profileFields === null)
  {
    if(scope.indexOf('r_basicprofile') === -1){
      scope.unshift('r_basicprofile');
    }

    scope.forEach(function(f) {
      if (typeof map[f] === 'undefined') return;

      if (Array.isArray(map[f])) {
        Array.prototype.push.apply(fields, map[f]);
      } else {
        fields.push(map[f]);
      }
    });
  } else if(Array.isArray(profileFields)){
    fields = profileFields;
  }

  if(Array.isArray(skipFields)) {
    fields = fields.filter(f => skipFields.indexOf(f) === -1)
  }

  return fields.join(',');
}

module.exports = Strategy;
<|endoftext|>


<commit_before>module.exports = function(schema, options) {
    options || (options = {});
    options.path || (options.path = '_acl');

    // Fields

    var fields = {};

    if (!schema.paths[options.path]) {
        fields[options.path] = {};
    }

    schema.add(fields);

    // Methods

    schema.methods.setAccess = function(key, perms) {
        perms || (perms = {});
        this[options.path] || (this[options.path] = {});
        this[options.path][key] = perms;
        this.markModified(options.path);
    };

    schema.methods.getAccess = function(key) {
        var acl = this[options.path] || {};
        return acl[key] || [];
    };

    schema.methods.keysWithAccess = function(perms) {
        perms || (perms = []);

        var acl = this[options.path] || {};
        var length = perms.length;
        var keys = [];

        for (var key in acl) {
            var count = 0;

            for (var i = 0; i < length; i++) {
                if (acl[key].indexOf(perms[i]) !== -1) {
                    count++;
                }
            }

            if (count === length) {
                keys.push(key);
            }
        }

        return keys;
    };

    var toJSON = schema.methods.toJSON;

    schema.methods.toJSON = function() {
        var data = toJSON ? toJSON.call(this) : this.toObject();
        delete data[options.path];
        return data;
    };

    // Statics

    schema.statics.withAccess = function(subject, perms, callback) {
        var keys = subject.getAccessKeys();

        var or = keys.map(function(key) {
            var query = {};
            var path = [options.path, key].join('.');

            query[path] = { $all: perms };
            return query;
        });

        var cursor = this.find({ $or: or });

        if (callback) {
            cursor.exec(callback);
        }

        return cursor;
    };
};<commit_msg>Fix default perms<commit_after>module.exports = function(schema, options) {
    options || (options = {});
    options.path || (options.path = '_acl');

    // Fields

    var fields = {};

    if (!schema.paths[options.path]) {
        fields[options.path] = {};
    }

    schema.add(fields);

    // Methods

    schema.methods.setAccess = function(key, perms) {
        perms || (perms = []);
        this[options.path] || (this[options.path] = {});
        this[options.path][key] = perms;
        this.markModified(options.path);
    };

    schema.methods.getAccess = function(key) {
        var acl = this[options.path] || {};
        return acl[key] || [];
    };

    schema.methods.keysWithAccess = function(perms) {
        perms || (perms = []);

        var acl = this[options.path] || {};
        var length = perms.length;
        var keys = [];

        for (var key in acl) {
            var count = 0;

            for (var i = 0; i < length; i++) {
                if (acl[key].indexOf(perms[i]) !== -1) {
                    count++;
                }
            }

            if (count === length) {
                keys.push(key);
            }
        }

        return keys;
    };

    var toJSON = schema.methods.toJSON;

    schema.methods.toJSON = function() {
        var data = toJSON ? toJSON.call(this) : this.toObject();
        delete data[options.path];
        return data;
    };

    // Statics

    schema.statics.withAccess = function(subject, perms, callback) {
        var keys = subject.getAccessKeys();

        var or = keys.map(function(key) {
            var query = {};
            var path = [options.path, key].join('.');

            query[path] = { $all: perms };
            return query;
        });

        var cursor = this.find({ $or: or });

        if (callback) {
            cursor.exec(callback);
        }

        return cursor;
    };
};<|endoftext|>


<commit_before>'use strict';

/**
 * Extend a prototype with properties.
 * Prototypes for objects.
 * (C) 2013 Alex Fernández.
 */

// requires
require('./string.js');
var core = require('./core.js');

// globals
var newObject = {};
var NewObject = {};

/**
 * Count the number of properties in an object. Params:
 *	- filter: can be a string that has to be contained in every key,
 *	or a function which will be used as a filter to pass keys.
 */
newObject.countProperties = function(filter)
{
	if (!filter)
	{
		return Object.keys(this).length;
	}
	var filterer = getFilterer(filter);
	var count = 0;
	for (var key in this)
	{
		if (!this.hasOwnProperty(key))
		{
			continue;
		}
		if (filterer(key))
		{
			count++;
		}
	}
	return count;
};

/**
 * Get a function to filter keys.
 */
function getFilterer(filter)
{
	if (typeof filter == 'function')
	{
		return filter;
	}
	return function(key)
	{
		return key.contains(filter);
	};

}

/**
 * Overwrite properties in the original with the given object.
 */
newObject.overwriteWith = function(overwriter)
{
	for (var key in overwriter)
	{
		var value = overwriter[key];
		if (value !== undefined)
		{
			this[key] = value;
		}
	}
	return this;
};

/**
 * Return a new object that contains the properties of this and the parameter object.
 */
newObject.concat = function(object)
{
	var result = {};
	result.overwriteWith(this);
	result.overwriteWith(object);
	return result;
};

/**
 * Call the callback for each property of the object.
 */
newObject.forEach = function(callback)
{
	for (var key in this)
	{
		callback(this[key], key, this);
	}
};

/**
 * Return a new object with just the properties that pass the callback.
 */
newObject.filterIn = function(callback)
{
	if (Array.isArray(this))
	{
		return this.filter(callback);
	}
	var result = {};
	for (var key in this)
	{
		var value = this[key];
		if (callback(value))
		{
			result[key] = value;
		}
	}
	return result;
};

/**
 * Return a new object with just the properties that *do not* pass the callback.
 */
newObject.filterOut = function(callback)
{
	return this.filterIn(function(element)
	{
		return (!callback(element));
	});
};

/**
 * For each property in the mapping object, if 'this' has a property of the same name, then the name of the property in 'this'
 * is renamed to the value corresponding to the property from the mapping object.
 * Example:
 * var bla = {'yo': 'hi', 'bo': 'hi'};
 * bla.renameProperties({'bo': 'do'});
 * THEN
 * bla.hasOwnProperty('do') === true
 * bla.do === 'hi'
 */
newObject.renameProperties = function(mappingObject)
{
	var self = this;
	newObject.forEach.call(mappingObject, function(newPropertyName, oldPropertyName)
	{
	    if (self.hasOwnProperty(oldPropertyName))
	    {
	    	self[newPropertyName] = self[oldPropertyName];
	        delete self[oldPropertyName];
	    }
	});
}

/**
 * Get all values for a parameter object in an array.
 * Note: operates on the global Object, not on the prototype.
 */
NewObject.values = function(object)
{
	var keys = Object.keys(object);
	return keys.map(function(key)
	{
		return object[key];
	});
};

// add new object functions as properties
core.addProperties(Object.prototype, newObject);
core.addProperties(Object, NewObject);

<commit_msg>Return self from renameProperties for chaining<commit_after>'use strict';

/**
 * Extend a prototype with properties.
 * Prototypes for objects.
 * (C) 2013 Alex Fernández.
 */

// requires
require('./string.js');
var core = require('./core.js');

// globals
var newObject = {};
var NewObject = {};

/**
 * Count the number of properties in an object. Params:
 *	- filter: can be a string that has to be contained in every key,
 *	or a function which will be used as a filter to pass keys.
 */
newObject.countProperties = function(filter)
{
	if (!filter)
	{
		return Object.keys(this).length;
	}
	var filterer = getFilterer(filter);
	var count = 0;
	for (var key in this)
	{
		if (!this.hasOwnProperty(key))
		{
			continue;
		}
		if (filterer(key))
		{
			count++;
		}
	}
	return count;
};

/**
 * Get a function to filter keys.
 */
function getFilterer(filter)
{
	if (typeof filter == 'function')
	{
		return filter;
	}
	return function(key)
	{
		return key.contains(filter);
	};

}

/**
 * Overwrite properties in the original with the given object.
 */
newObject.overwriteWith = function(overwriter)
{
	for (var key in overwriter)
	{
		var value = overwriter[key];
		if (value !== undefined)
		{
			this[key] = value;
		}
	}
	return this;
};

/**
 * Return a new object that contains the properties of this and the parameter object.
 */
newObject.concat = function(object)
{
	var result = {};
	result.overwriteWith(this);
	result.overwriteWith(object);
	return result;
};

/**
 * Call the callback for each property of the object.
 */
newObject.forEach = function(callback)
{
	for (var key in this)
	{
		callback(this[key], key, this);
	}
};

/**
 * Return a new object with just the properties that pass the callback.
 */
newObject.filterIn = function(callback)
{
	if (Array.isArray(this))
	{
		return this.filter(callback);
	}
	var result = {};
	for (var key in this)
	{
		var value = this[key];
		if (callback(value))
		{
			result[key] = value;
		}
	}
	return result;
};

/**
 * Return a new object with just the properties that *do not* pass the callback.
 */
newObject.filterOut = function(callback)
{
	return this.filterIn(function(element)
	{
		return (!callback(element));
	});
};

/**
 * For each property in the mapping object, if 'this' has a property of the same name, then the name of the property in 'this'
 * is renamed to the value corresponding to the property from the mapping object.
 * Example:
 * var bla = {'yo': 'hi', 'bo': 'hi'};
 * bla.renameProperties({'bo': 'do'});
 * THEN
 * bla.hasOwnProperty('do') === true
 * bla.do === 'hi'
 */
newObject.renameProperties = function(mappingObject)
{
	var self = this;

	newObject.forEach.call(mappingObject, function(newPropertyName, oldPropertyName)
	{
	    if (self.hasOwnProperty(oldPropertyName))
	    {
	    	self[newPropertyName] = self[oldPropertyName];
	        delete self[oldPropertyName];
	    }
	});

	return self;
}

/**
 * Get all values for a parameter object in an array.
 * Note: operates on the global Object, not on the prototype.
 */
NewObject.values = function(object)
{
	var keys = Object.keys(object);
	return keys.map(function(key)
	{
		return object[key];
	});
};

// add new object functions as properties
core.addProperties(Object.prototype, newObject);
core.addProperties(Object, NewObject);

<|endoftext|>


<commit_before>'use strict';

/* jshint -W098 */
/* jshint -W079 */

var fs = require('fs');
var path = require('path');
var Promise = require('bluebird');
var Handlebars = require('handlebars');
var fs = Promise.promisifyAll(require('fs'));

var colNumNames = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];

function render(outDir, data) {
	return Promise.attempt(function () {
		var assetPath = path.resolve(__dirname, '..', 'assets');
		var source = fs.readFileSync(path.join(assetPath, 'index.hbs'), 'utf8');
		var template = Handlebars.compile(source);

		var cols = 3;
		cols = (data.chapters.length < cols ? data.chapters.length : cols);
		data.colName = colNumNames[cols];
		var part = Math.round(data.chapters.length / cols);

		data.columns = [];

		data.chapters.sort(function(aa, bb) {
			if (aa.label < bb.label) {
				return -1;
			}
			else if (aa.label > bb.label) {
				return 1;
			}
			return 0;
		});

		for (var i = 0; i < cols; i++) {
			data.columns.push({
				chapters: data.chapters.slice(i * part, Math.min((i + 1) * part, data.chapters.length))
			});
		}

		var output = template(data);

		fs.writeFileSync(path.join(outDir, 'index.html'), output, 'utf8');
	});
}

module.exports = {
	render: render
};
<commit_msg>2 columns<commit_after>'use strict';

/* jshint -W098 */
/* jshint -W079 */

var fs = require('fs');
var path = require('path');
var Promise = require('bluebird');
var Handlebars = require('handlebars');
var fs = Promise.promisifyAll(require('fs'));

var colNumNames = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];

function render(outDir, data) {
	return Promise.attempt(function () {
		var assetPath = path.resolve(__dirname, '..', 'assets');
		var source = fs.readFileSync(path.join(assetPath, 'index.hbs'), 'utf8');
		var template = Handlebars.compile(source);

		var cols = 2;
		cols = (data.chapters.length < cols ? data.chapters.length : cols);
		data.colName = colNumNames[cols];
		var part = Math.round(data.chapters.length / cols);

		data.columns = [];

		data.chapters.sort(function(aa, bb) {
			if (aa.label < bb.label) {
				return -1;
			}
			else if (aa.label > bb.label) {
				return 1;
			}
			return 0;
		});

		for (var i = 0; i < cols; i++) {
			data.columns.push({
				chapters: data.chapters.slice(i * part, Math.min((i + 1) * part, data.chapters.length))
			});
		}

		var output = template(data);

		fs.writeFileSync(path.join(outDir, 'index.html'), output, 'utf8');
	});
}

module.exports = {
	render: render
};
<|endoftext|>