<commit_before>const convert = require('node-unit-conversion');

function parse_153(data) {
	// DSC off (DSC light on) (b0/b1)
	// 04 61 01 FF 00 FE FF 0
	// DSC on (DSC light off) (b0/b1)
	// 00 60 01 FF 00 FE FF 0C
	// ~5 sec on initial key in run
	// A4 61 01 FF 00 FE FF 0B
	//
	// B3 and B6 change during torque reduction
	let parse = {
		vehicle : {
			brake : bitmask.test(data.msg[1], 0x10),
			dsc   : {
				active             : !bitmask.test(data.msg[1], 0x01),
				torque_reduction_1 : data.msg[3] / 2.54,
				torque_reduction_2 : data.msg[6] / 2.54,
			},
		},
	};

	// Clean up torque reduction figures a bit
	if (parse.vehicle.dsc.torque_reduction_1 > 100) parse.vehicle.dsc.torque_reduction_1 = 100;
	if (parse.vehicle.dsc.torque_reduction_2 > 100) parse.vehicle.dsc.torque_reduction_2 = 100;
	if (parse.vehicle.dsc.torque_reduction_1 < 0)   parse.vehicle.dsc.torque_reduction_1 = 0;
	if (parse.vehicle.dsc.torque_reduction_2 < 0)   parse.vehicle.dsc.torque_reduction_2 = 0;

	// Apply maths
	parse.vehicle.dsc.torque_reduction_1 = parseFloat((100 - parse.vehicle.dsc.torque_reduction_1).toFixed(1));
	parse.vehicle.dsc.torque_reduction_2 = parseFloat((100 - parse.vehicle.dsc.torque_reduction_2).toFixed(1));

	// update.status('vehicle.brake',                  parse.vehicle.brake);
	update.status('vehicle.dsc.active',             parse.vehicle.dsc.active);
	update.status('vehicle.dsc.torque_reduction_1', parse.vehicle.dsc.torque_reduction_1);
	update.status('vehicle.dsc.torque_reduction_2', parse.vehicle.dsc.torque_reduction_2);
}

function parse_1f0(data) {
	let wheel_speed = {
		front : {
			left  : Math.round((data.msg[0] + parseInt('0x' + data.msg[1].toString(16).slice(-1)) * 256) / 16),
			right : Math.round((data.msg[2] + parseInt('0x' + data.msg[3].toString(16).slice(-1)) * 256) / 16),
		},
		rear : {
			left  : Math.round((data.msg[4] + parseInt('0x' + data.msg[5].toString(16).slice(-1)) * 256) / 16),
			right : Math.round((data.msg[6] + parseInt('0x' + data.msg[7].toString(16).slice(-1)) * 256) / 16),
		},
	};

	// Calculated data bottoms out at 2.75, let's address that
	// (lol, this is the same way the E38/E39/E53 cluster works - you can see it in the 'secret' menu)
	if (wheel_speed.front.left  <= 3) wheel_speed.front.left  = 0;
	if (wheel_speed.front.right <= 3) wheel_speed.front.right = 0;
	if (wheel_speed.rear.left   <= 3) wheel_speed.rear.left   = 0;
	if (wheel_speed.rear.right  <= 3) wheel_speed.rear.right  = 0;

	update.status('vehicle.wheel_speed.front.left',  wheel_speed.front.left,  false);
	update.status('vehicle.wheel_speed.front.right', wheel_speed.front.right, false);
	update.status('vehicle.wheel_speed.rear.left',   wheel_speed.rear.left,   false);
	update.status('vehicle.wheel_speed.rear.right',  wheel_speed.rear.right,  false);

	// Calculate vehicle speed from rear left wheel speed sensor
	// This is identical to the actual speedometer signal on E39
	// update.status('vehicle.speed.kmh', wheel_speed.rear.left, false);
	// let vehicle_speed_mph = Math.round(convert(status.vehicle.wheel_speed.rear.left).from('kilometre').to('us mile'));

	// Calculate vehicle speed from average of all 4 sensors
	let vehicle_speed_total = wheel_speed.front.left + wheel_speed.front.right + wheel_speed.rear.left + wheel_speed.rear.right;

	// Average all wheel speeds together and include accuracy offset multiplier
	let vehicle_speed_kmh = Math.round((vehicle_speed_total / 4) * config.speedometer.offset);

	// Calculate vehicle speed value in MPH
	let vehicle_speed_mph = Math.round(convert(vehicle_speed_kmh).from('kilometre').to('us mile'));

	// Trigger IKE speedometer refresh on value change
	// This should really be event based, but fuck it, you write this shit
	if (update.status('vehicle.speed.mph', vehicle_speed_mph)) IKE.hud_refresh();

	update.status('vehicle.speed.kmh', vehicle_speed_kmh);
}

function parse_1f5(data) {
	let angle = 0;
	if (data.msg[1] > 127) {
		angle = -1 * (((data.msg[1] - 128) * 256) + data.msg[0]);
	}
	else {
		angle = (data.msg[1] * 256) + data.msg[0];
	}

	let velocity = 0;
	if (data.msg[3] > 127) {
		velocity = -1 * (((data.msg[3] - 128) * 256) + data.msg[2]);
	}
	else {
		velocity = (data.msg[3] * 256) + data.msg[2];
	}

	// 0.043393 : 3.75 turns, lock to lock (1350 degrees of total rotation)
	let steering_multiplier = 0.043393;

	let steering = {
		angle    : Math.round(angle    * steering_multiplier) * -1, // Thanks babe
		velocity : Math.round(velocity * steering_multiplier) * -1,
	};

	update.status('vehicle.steering.angle',    steering.angle);
	update.status('vehicle.steering.velocity', steering.velocity, false);
}

// Parse data sent from module
function parse_out(data) {
	data.command = 'bro';

	switch (data.src.id) {
		case 0x153:
			parse_153(data);
			data.value = 'Speed/DSC light';
			break;

		case 0x1F0:
			parse_1f0(data);
			data.value = 'Wheel speeds';
			break;

		case 0x1F3:
			data.value = 'Transverse acceleration';
			break;

		case 0x1F5:
			parse_1f5(data);
			data.value = 'Steering angle';
			break;

		case 0x1F8:
			// Status sensors (21 06):
			// Positive pressure:
			// B8 29 F1 02 21 06 45
			// B8 F1 29 0F 61 06 00 00 C3 DC 14 8F 14 A4 00 00 00 00 11 06
			//
			// BrakeLinePressureFront = hex2dec('148F')/100 = 52.63 [bar]
			// BrakeLinePressureRear = hex2dec('14A4')/100 = 52.84 [bar]
			//
			//
			// BrakeLinePressureFront = hex2dec('1D31')/100 = 74.73 [bar]
			// BrakeLinePressureRear = hex2dec('1D1C')/100 = 74.52 [bar]
			//
			// Neg. pressure by twos complement:
			// B8 29 F1 02 21 06 45
			// B8 F1 29 0F 61 06 00 00 C3 DC F7ED F783 00 00 00 00 11 06
			//
			// BrakeLinePressureFront = (hex2dec('F7ED')-65536)/100 = -20.67 [bar]
			// BrakeLinePressureRear = (hex2dec('F783')-65536)/100 = -21.73 [bar]
			// BrakeLinePressureFront = (hex2dec('FFA5')-65536)/100 = -0.91 [bar]
			//
			//
			// Status sensor offset (21 02):
			// B8 29 F1 02 21 02 41
			// B8 F1 29 0C 61 02 FA89 FF18 1E81 FE5D 0000 A7
			//
			// B8 F1 29 0C 61 02 xxxx yyyy 1E81 FE5D 0000 A7
			// xxxx = hex value in telegram of Offset Front
			// yyyy = hex value in telegram of Offset Rear
			// BrakeLinePressureFrontOffset = 0.000625*x + 2.3315e-15
			// BrakeLinePressureRearOffset = 0.000625*y + 2.3315e-15
			// where x is twos complement of xxxx (or yyyy) if neg value in xxxx (or yyyy) (msb set), otherwise pos value of xxxx (or yyyy)
			// Example: 0xFA89 => neg value since msb=1. Twos complement of 0xFA89 = -1399 => -0.87438 [bar]
			data.value = 'Brake pressure';
			break;

		default:
			data.value = data.src.id.toString(16);
	}

	// log.bus(data);
}

module.exports = {
	parse_out : parse_out,
};
<commit_msg>Update<commit_after>const convert = require('node-unit-conversion');

function parse_153(data) {
	// DSC off (DSC light on) (b0/b1)
	// 04 61 01 FF 00 FE FF 0
	// DSC on (DSC light off) (b0/b1)
	// 00 60 01 FF 00 FE FF 0C
	// ~5 sec on initial key in run
	// A4 61 01 FF 00 FE FF 0B
	//
	// B3 and B6 change during torque reduction
	let parse = {
		vehicle : {
			brake : bitmask.test(data.msg[1], 0x10),
			dsc   : {
				active             : !bitmask.test(data.msg[1], 0x01),
				torque_reduction_1 : data.msg[3] / 2.54,
				torque_reduction_2 : data.msg[6] / 2.54,
			},
		},
	};

	// Clean up torque reduction figures a bit
	if (parse.vehicle.dsc.torque_reduction_1 > 100) parse.vehicle.dsc.torque_reduction_1 = 100;
	if (parse.vehicle.dsc.torque_reduction_2 > 100) parse.vehicle.dsc.torque_reduction_2 = 100;
	if (parse.vehicle.dsc.torque_reduction_1 < 0)   parse.vehicle.dsc.torque_reduction_1 = 0;
	if (parse.vehicle.dsc.torque_reduction_2 < 0)   parse.vehicle.dsc.torque_reduction_2 = 0;

	// Apply maths
	parse.vehicle.dsc.torque_reduction_1 = parseFloat((100 - parse.vehicle.dsc.torque_reduction_1).toFixed(1));
	parse.vehicle.dsc.torque_reduction_2 = parseFloat((100 - parse.vehicle.dsc.torque_reduction_2).toFixed(1));

	// update.status('vehicle.brake',                  parse.vehicle.brake);
	update.status('vehicle.dsc.active',             parse.vehicle.dsc.active);
	update.status('vehicle.dsc.torque_reduction_1', parse.vehicle.dsc.torque_reduction_1);
	update.status('vehicle.dsc.torque_reduction_2', parse.vehicle.dsc.torque_reduction_2);
}

function parse_1f0(data) {
	let wheel_speed = {
		front : {
			left  : Math.round((data.msg[0] + parseInt('0x' + data.msg[1].toString(16).slice(-1)) * 256) / 16),
			right : Math.round((data.msg[2] + parseInt('0x' + data.msg[3].toString(16).slice(-1)) * 256) / 16),
		},
		rear : {
			left  : Math.round((data.msg[4] + parseInt('0x' + data.msg[5].toString(16).slice(-1)) * 256) / 16),
			right : Math.round((data.msg[6] + parseInt('0x' + data.msg[7].toString(16).slice(-1)) * 256) / 16),
		},
	};

	// Calculated data bottoms out at 2.75, let's address that
	// (lol, this is the same way the E38/E39/E53 cluster works - you can see it in the 'secret' menu)
	if (wheel_speed.front.left  <= 3) wheel_speed.front.left  = 0;
	if (wheel_speed.front.right <= 3) wheel_speed.front.right = 0;
	if (wheel_speed.rear.left   <= 3) wheel_speed.rear.left   = 0;
	if (wheel_speed.rear.right  <= 3) wheel_speed.rear.right  = 0;

	update.status('vehicle.wheel_speed.front.left',  wheel_speed.front.left,  false);
	update.status('vehicle.wheel_speed.front.right', wheel_speed.front.right, false);
	update.status('vehicle.wheel_speed.rear.left',   wheel_speed.rear.left,   false);
	update.status('vehicle.wheel_speed.rear.right',  wheel_speed.rear.right,  false);

	// Calculate vehicle speed from rear left wheel speed sensor
	// This is identical to the actual speedometer signal on E39
	// update.status('vehicle.speed.kmh', wheel_speed.rear.left, false);
	// let vehicle_speed_mph = Math.round(convert(status.vehicle.wheel_speed.rear.left).from('kilometre').to('us mile'));

	// Calculate vehicle speed from average of all 4 sensors
	let vehicle_speed_total = wheel_speed.front.left + wheel_speed.front.right + wheel_speed.rear.left + wheel_speed.rear.right;

	// Average all wheel speeds together and include accuracy offset multiplier
	let vehicle_speed_kmh = Math.round((vehicle_speed_total / 4) * config.speedometer.offset);

	// Calculate vehicle speed value in MPH
	let vehicle_speed_mph = Math.round(convert(vehicle_speed_kmh).from('kilometre').to('us mile'));

	// Trigger IKE speedometer refresh on value change
	// This should really be event based, but fuck it, you write this shit
	if (update.status('vehicle.speed.mph', vehicle_speed_mph, false)) IKE.hud_refresh();

	update.status('vehicle.speed.kmh', vehicle_speed_kmh, false);
}

function parse_1f5(data) {
	let angle = 0;
	if (data.msg[1] > 127) {
		angle = -1 * (((data.msg[1] - 128) * 256) + data.msg[0]);
	}
	else {
		angle = (data.msg[1] * 256) + data.msg[0];
	}

	let velocity = 0;
	if (data.msg[3] > 127) {
		velocity = -1 * (((data.msg[3] - 128) * 256) + data.msg[2]);
	}
	else {
		velocity = (data.msg[3] * 256) + data.msg[2];
	}

	// 0.043393 : 3.75 turns, lock to lock (1350 degrees of total rotation)
	let steering_multiplier = 0.043393;

	let steering = {
		angle    : Math.round(angle    * steering_multiplier) * -1, // Thanks babe
		velocity : Math.round(velocity * steering_multiplier) * -1,
	};

	update.status('vehicle.steering.angle',    steering.angle,    false);
	update.status('vehicle.steering.velocity', steering.velocity, false);
}

// Parse data sent from module
function parse_out(data) {
	data.command = 'bro';

	switch (data.src.id) {
		case 0x153:
			parse_153(data);
			data.value = 'Speed/DSC light';
			break;

		case 0x1F0:
			parse_1f0(data);
			data.value = 'Wheel speeds';
			break;

		case 0x1F3:
			data.value = 'Transverse acceleration';
			break;

		case 0x1F5:
			parse_1f5(data);
			data.value = 'Steering angle';
			break;

		case 0x1F8:
			// Status sensors (21 06):
			// Positive pressure:
			// B8 29 F1 02 21 06 45
			// B8 F1 29 0F 61 06 00 00 C3 DC 14 8F 14 A4 00 00 00 00 11 06
			//
			// BrakeLinePressureFront = hex2dec('148F')/100 = 52.63 [bar]
			// BrakeLinePressureRear = hex2dec('14A4')/100 = 52.84 [bar]
			//
			//
			// BrakeLinePressureFront = hex2dec('1D31')/100 = 74.73 [bar]
			// BrakeLinePressureRear = hex2dec('1D1C')/100 = 74.52 [bar]
			//
			// Neg. pressure by twos complement:
			// B8 29 F1 02 21 06 45
			// B8 F1 29 0F 61 06 00 00 C3 DC F7ED F783 00 00 00 00 11 06
			//
			// BrakeLinePressureFront = (hex2dec('F7ED')-65536)/100 = -20.67 [bar]
			// BrakeLinePressureRear = (hex2dec('F783')-65536)/100 = -21.73 [bar]
			// BrakeLinePressureFront = (hex2dec('FFA5')-65536)/100 = -0.91 [bar]
			//
			//
			// Status sensor offset (21 02):
			// B8 29 F1 02 21 02 41
			// B8 F1 29 0C 61 02 FA89 FF18 1E81 FE5D 0000 A7
			//
			// B8 F1 29 0C 61 02 xxxx yyyy 1E81 FE5D 0000 A7
			// xxxx = hex value in telegram of Offset Front
			// yyyy = hex value in telegram of Offset Rear
			// BrakeLinePressureFrontOffset = 0.000625*x + 2.3315e-15
			// BrakeLinePressureRearOffset = 0.000625*y + 2.3315e-15
			// where x is twos complement of xxxx (or yyyy) if neg value in xxxx (or yyyy) (msb set), otherwise pos value of xxxx (or yyyy)
			// Example: 0xFA89 => neg value since msb=1. Twos complement of 0xFA89 = -1399 => -0.87438 [bar]
			data.value = 'Brake pressure';
			break;

		default:
			data.value = data.src.id.toString(16);
	}

	// log.bus(data);
}

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


<commit_before>var _ = require('lodash');
var moment = require('moment');

module.exports = {
  construct: function(self, options) {
    // If set to true, the future flag allows us to get posts
    // with a publication date in the future. By default,
    // this is false by default
    self.addFilter('future', {
      def: false,
      finalize: function() {
        var future = self.get('future');
        if (future === null) {
          return;
        }

        var now = moment().format('YYYY-MM-DD');

        if (future) {
          self.and({
            publishedAt: { $gte: now }
          });
        } else {
          self.and({
            publishedAt: { $lte: now }
          });
        }
      },
      safeFor: 'public',
      launder: function(s) {
        return self.apos.launder.booleanOrNull(s);
      }
    });

    self.addFilter('year', {
      def: null,
      safeFor: 'public',
      finalize: function() {
        var year = self.get('year');

        if (year === null) {
          return;
        }

        self.and({
          publishedAt: { $regex: '^'+ year }
        });
      },
      launder: function(s) {
        return self.apos.launder.string(s);
      },
      choices: function(callback) {
        return self.toDistinct('publishedAt', function(err, results) {
          if (err) {
            return callback(err);
          }

          return callback(null, _.uniq(_.each(results, function(value, key) { results[key] = value.substr(0,4) })).sort());
        });
      }
    });

    self.addFilter('month', {
      def: null,
      safeFor: 'public',
      finalize: function() {
        var month = self.get('month');

        if (month === null) {
          return;
        }

        self.and({
          publishedAt: { $regex: '^'+ month }
        });
      },
      launder: function(s) {
        return self.apos.launder.string(s);
      },
      choices: function(callback) {
        return self.toDistinct('publishedAt', function(err, results) {
          if (err) {
            return callback(err);
          }

          return callback(null, _.uniq(_.each(results, function(value, key) { results[key] = value.substr(0,7) })).sort());
        });
      }
    });

    self.addFilter('day', {
      def: null,
      safeFor: 'public',
      finalize: function() {
        var day = self.get('day');

        if (day === null) {
          return;
        }

        self.and({
          publishedAt: day
        });
      },
      launder: function(s) {
        return self.apos.launder.string(s);
      },
      choices: function(callback) {
        return self.toDistinct('publishedAt', function(err, results) {
          if (err) {
            return callback(err);
          }

          return callback(null, results);
        });
      }
    });
  }
};
<commit_msg>validation of year/month filters see #13<commit_after>var _ = require('lodash');
var moment = require('moment');

module.exports = {
  construct: function(self, options) {
    // If set to true, the future flag allows us to get posts
    // with a publication date in the future. By default,
    // this is false by default
    self.addFilter('future', {
      def: false,
      finalize: function() {
        var future = self.get('future');
        if (future === null) {
          return;
        }

        var now = moment().format('YYYY-MM-DD');

        if (future) {
          self.and({
            publishedAt: { $gte: now }
          });
        } else {
          self.and({
            publishedAt: { $lte: now }
          });
        }
      },
      safeFor: 'public',
      launder: function(s) {
        return self.apos.launder.booleanOrNull(s);
      }
    });

    self.addFilter('year', {
      def: null,
      safeFor: 'public',
      finalize: function() {
        var year = self.get('year');

        if (year === null) {
          return;
        }

        self.and({
          publishedAt: { $regex: '^'+ year }
        });
      },
      launder: function(s) {
        s = self.apos.launder.string(s);

        if (!s.match(/^\d\d\d\d$/)) {
          return '';
        }

        return s;
      },
      choices: function(callback) {
        return self.toDistinct('publishedAt', function(err, results) {
          if (err) {
            return callback(err);
          }

          return callback(null, _.uniq(_.each(results, function(value, key) { results[key] = value.substr(0,4) })).sort());
        });
      }
    });

    self.addFilter('month', {
      def: null,
      safeFor: 'public',
      finalize: function() {
        var month = self.get('month');

        if (month === null) {
          return;
        }

        self.and({
          publishedAt: { $regex: '^'+ month }
        });
      },
      launder: function(s) {
        s = self.apos.launder.string(s);

        if (!s.match(/^\d\d\d\d\-\d\d$/)) {
          return '';
        }

        return s;
      },
      choices: function(callback) {
        return self.toDistinct('publishedAt', function(err, results) {
          if (err) {
            return callback(err);
          }

          return callback(null, _.uniq(_.each(results, function(value, key) { results[key] = value.substr(0,7) })).sort());
        });
      }
    });

    self.addFilter('day', {
      def: null,
      safeFor: 'public',
      finalize: function() {
        var day = self.get('day');

        if (day === null) {
          return;
        }

        self.and({
          publishedAt: day
        });
      },
      launder: function(s) {
        return self.apos.launder.string(s);
      },
      choices: function(callback) {
        return self.toDistinct('publishedAt', function(err, results) {
          if (err) {
            return callback(err);
          }

          return callback(null, results);
        });
      }
    });
  }
};
<|endoftext|>


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

module.exports = Object.assign( {}, base, {
    list: [
        'alpine-ace-can',
        'alpine-ace-fra',
        'alpine-ace-gbr',
        'alpine-ace-ger',
        'alpine-ace-kor',
        'alpine-ace-usa',
        'arctic-assassin',
        'beetlejess',
        'black-knight',
        'blue-squire',
        'blue-team-leader',
        'brilliant-striker',
        'brite-bomber',
        'burnout',
        'catstructor',
        'circuit-breaker',
        'commando',
        'constructor1',
        'constructor2',
        'cuddle-team-leader',
        'dark-voyager',
        'default',
        'desperado',
        'dragonsarah',
        'elite-agent',
        'energythief',
        'funk-ops',
        'ghoul-trooper',
        'ginger-gunner',
        'grenadier',
        'gunblazer',
        'havoc',
        'hazardkyle',
        'hero-assassin',
        'hero-base',
        'hero-beetlejess',
        'hero-brawler',
        'hero-catstructor',
        'hero-centurion',
        'hero-commando',
        'hero-controller',
        'hero-dim-mak',
        'hero-dragon',
        'hero-dragonsarah',
        'hero-electro-pulse',
        'hero-energythief',
        'hero-enforcer',
        'hero-fleetfoot',
        'hero-gunblazer',
        'hero-hazardkyle',
        'hero-hotfixer',
        'hero-kinetic-guardian',
        'hero-machinist',
        'hero-marinecorpse',
        'hero-master-grenadier',
        'hero-megabase',
        'hero-pathfinder',
        'hero-phase-scout',
        'hero-plasma-sentinel',
        'hero-plasma-shielder',
        'hero-poisoner',
        'hero-power-base',
        'hero-raider',
        'hero-ranger',
        'hero-recon-scout',
        'hero-rescue-trooper',
        'hero-shock-specialist',
        'hero-shock-trooper',
        'hero-shuriken-master',
        'hero-skirmisher',
        'hero-skullshot',
        'hero-special-forces',
        'hero-stonefoot',
        'hero-striker',
        'hero-support-specialist',
        'hero-survivalist',
        'hero-swordmaster',
        'hero-tank',
        'hero-trailblaster',
        'hero-trailblazer',
        'hero-urban-assault',
        'hero-vanguard',
        'hero-warlord',
        'hyperion',
        'jungle-scout',
        'lama1',
        'lamahero-master-grenadier1',
        'llama',
        'llamamaster',
        'love-ranger',
        'machinist',
        'marinecorpse',
        'mastergoat',
        'merry-marauder',
        'mogul-master-can',
        'mogul-master-fra',
        'mogul-master-gbr',
        'mogul-master-ger',
        'mogul-master-kor',
        'mogul-master-usa',
        'munitions-expert',
        'ninja1',
        'ninja2',
        'outlander4',
        'outlander6png',
        'pathfinder',
        'raider',
        'raptor',
        'recon-specialist',
        'red-knight',
        'red-nosed-raider',
        'renegade-raider',
        'rex',
        'rogue-agent',
        'rust-lord',
        'sash-sergeant',
        'shadow-ops',
        'shurikenmasternew',
        'skull-trooper',
        'skullshot',
        'snorkel-ops',
        'soldier2',
        'soldier3',
        'sparkle-specialist',
        'the-reaper',
        'trooper',
        'wukong',
    ],
    type: 'author_flair_css_class',
} );
<commit_msg>even moar<commit_after>const base = require( './base.js' );

module.exports = Object.assign( {}, base, {
    list: [
        'alpine-ace-can',
        'alpine-ace-fra',
        'alpine-ace-gbr',
        'alpine-ace-ger',
        'alpine-ace-kor',
        'alpine-ace-usa',
        'arctic-assassin',
        'beetlejess',
        'black-knight',
        'blue-squire',
        'blue-team-leader',
        'brilliant-striker',
        'brite-bomber',
        'burnout',
        'catstructor',
        'circuit-breaker',
        'commando',
        'constructor1',
        'constructor2',
        'cuddle-team-leader',
        'dark-voyager',
        'default',
        'desperado',
        'dragonsarah',
        'elite-agent',
        'energythief',
        'funk-ops',
        'ghoul-trooper',
        'ginger-gunner',
        'grenadier',
        'gunblazer',
        'havoc',
        'hazardkyle',
        'hero-assassin',
        'hero-base',
        'hero-beetlejess',
        'hero-brawler',
        'hero-catstructor',
        'hero-centurion',
        'hero-commando',
        'hero-controller',
        'hero-dim-mak',
        'hero-dragon',
        'hero-dragonsarah',
        'hero-electro-pulse',
        'hero-energythief',
        'hero-enforcer',
        'hero-fleetfoot',
        'hero-gunblazer',
        'hero-hazardkyle',
        'hero-hotfixer',
        'hero-kinetic-guardian',
        'hero-machinist',
        'hero-marinecorpse',
        'hero-master-grenadier',
        'hero-megabase',
        'hero-pathfinder',
        'hero-phase-scout',
        'hero-plasma-sentinel',
        'hero-plasma-shielder',
        'hero-poisoner',
        'hero-power-base',
        'hero-raider',
        'hero-ranger',
        'hero-recon-scout',
        'hero-rescue-trooper',
        'hero-shock-specialist',
        'hero-shock-trooper',
        'hero-shuriken-master',
        'hero-skirmisher',
        'hero-skullshot',
        'hero-special-forces',
        'hero-stonefoot',
        'hero-striker',
        'hero-support-specialist',
        'hero-survivalist',
        'hero-swordmaster',
        'hero-tank',
        'hero-trailblaster',
        'hero-trailblazer',
        'hero-urban-assault',
        'hero-vanguard',
        'hero-warlord',
        'hyperion',
        'jungle-scout',
        'lama1',
        'lamahero-master-grenadier1',
        'llama',
        'llamamaster',
        'love-ranger',
        'machinist',
        'marinecorpse',
        'mastergoat',
        'merry-marauder',
        'mission-specialist',
        'mogul-master-can',
        'mogul-master-fra',
        'mogul-master-gbr',
        'mogul-master-ger',
        'mogul-master-kor',
        'mogul-master-usa',
        'munitions-expert',
        'ninja1',
        'ninja2',
        'outlander4',
        'outlander6png',
        'pathfinder',
        'raider',
        'raptor',
        'recon-specialist',
        'red-knight',
        'red-nosed-raider',
        'renegade-raider',
        'rex',
        'rogue-agent',
        'rust-lord',
        'sash-sergeant',
        'scarlet-defender',
        'shadow-ops',
        'shurikenmasternew',
        'skull-trooper',
        'skullshot',
        'snorkel-ops',
        'soldier2',
        'soldier3',
        'sparkle-specialist',
        'sub-commander',
        'the-reaper',
        'tower-recon-specialist',
        'trooper',
        'wukong',
    ],
    type: 'author_flair_css_class',
} );
<|endoftext|>


<commit_before>// View model for the courses page
function pageViewModel(gvm) {
    gvm.userId = -1;
    gvm.studentlistName = ko.observable('Name');
    gvm.listId = -1
    // Page specific i18n bindings
    gvm.title = ko.computed(function(){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("AccountTitle");}, gvm);
    gvm.pageHeader = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("EditListTitle");}, gvm);

    gvm.addBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AddBtn")}, gvm);

    gvm.myLists = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("myLists");}, gvm);
    gvm.addStudListBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("addStudListBtn");}, gvm);
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);

    gvm.codeTableTitle = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("CodeTableTitle");}, gvm);
    gvm.nameTableTitle = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("NameTableTitle");}, gvm);
    gvm.descTableTitle = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("DescTableTitle");}, gvm);
    gvm.actionTableTitle = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ActionTableTitle");}, gvm);

    gvm.firstname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Firstname");}, gvm);
    gvm.lastname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Lastname");}, gvm);
    gvm.email = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Email");}, gvm);
    gvm.memberSince = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("MemberSince");}, gvm);
    gvm.myProjects = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("MyProjects");}, gvm);

    gvm.tabledata = ko.observableArray([]);

    gvm.addTableData = function(id, firstname, lastname, username) {
        // Push data
        var tblOject = {tid: id, tfirstname: firstname, tlastname: lastname, tusername: username};
        gvm.tabledata.push(tblOject);

        $('#editbtn-' + id).bind('click', function(event, data) {
            showEditStudentModal(tblOject);
            event.stopPropagation();
        });

        $('#removebtn-' + id).bind('click', function(event, data){
            // Delete the table item
            deleteTableItem(id, tblOject);
            event.stopPropagation();
        });
    }

    gvm.clearTable = function() {
        gvm.tabledata.removeAll();
    }

}

function showEditStudentModal(tblObject) {
    resetGeneralModal();
    setGeneralModalTitle("Edit Student");
    setGeneralModalBody('<form id="updateStudent"> \

 \
                <input type="text" class="form-control input-lg" placeholder="' + tblObject.tfirstname + '" " name="firstname" value="' + tblObject.tfirstname + '"> \

 \

 \
                <input type="text" class="form-control input-lg" placeholder="' + tblObject.tlastname + '" name="lastname" value="' + tblObject.tlastname + '"> \

 \

 \
                <input type="text" class="form-control input-lg" placeholder="' + tblObject.tusername + '" name="username" value="' + tblObject.tusername + '"> \

 \
        </form>');
    $.getJSON()

    addGeneralModalButton(i18n.__("SaveBtn"), function(){
        updateStudent(tblObject.tid, $('#updateStudent').serialize(), function(result){
            hideModal();
        });
    });

    addGeneralModalButton(i18n.__("CancelBtn"), function(){
        hideModal();
    })

    showGeneralModal();
}

function showNewStudentModal() {
    resetGeneralModal();
    setGeneralModalTitle("Add Student");
    setGeneralModalBody('<form id="newStudentFrom" class="form-inline"> \

 \
                <input type="text" class="form-control input-lg col-md-5" placeholder="' + i18n.__('NameTableTitle') + '" " name="name"> \
                <button id="searchStudent" class="btn btn-default">Search</button> \

 \
        </form>');
    $.getJSON();

    addGeneralModalButton(i18n.__("AddBtn"), function(){
        addNewStudent($('#newStudentFrom').serialize(), function(result){
            hideModal();
        });
    });

    addGeneralModalButton(i18n.__("CancelBtn"), function(){
        hideModal();
    })

    showGeneralModal();
}

function addNewStudent(serialData, callback) {
    console.log(serialData);
    $.ajax({
        url: "/api/newstudent/" + viewModel.listId,
        type: "POST",
        data: serialData,
        success: function(data) {
            viewModel.addTableData(data['id'], data['firstname'], data['lastname'], data['mail']);
            callback(true);
        },
        error: function(data) {
            callback(false);
        }
    });
}

function updateStudent(id, object, callback) {
    $.ajax({
        url: "/api/studentrapport/" + id,
        type: "PUT",
        data: object,
        success: function(data) {
            loadStudentTable();
            callback(true);
        },
        error: function(data) {
            callback(false);
        }
    });
}

function deleteTableItem(id, tblObject){
    showYesNoModal("Bent u zeker dat u dit item wil verwijderen?", function(val){
        if(val){
            $.ajax({
                url: '/api/studentlistrapport/' + $("#page-header").data('value') + '/delete/student/' + id,
                type: "DELETE",
                success: function() {
                    viewModel.tabledata.remove(tblObject);
                }
            });
        }
    });
}

function loadStudentTable() {
    $.getJSON('/api/studentlistrapporten/students/' + $("#page-header").data('value'), function(data) {
        viewModel.clearTable();
        // Load table data
        $.each(data, function(i, item) {
            viewModel.addTableData(item.id, item.firstname, item.lastname, item.username);
        });
    });
}

function initPage() {
    $.getJSON('/api/studentlistrapport/info/' + $("#page-header").data('value'), function(data) {
        console.log(data[0].id);
        viewModel.studentlistName(data[0].name);
        viewModel.listId = (data[0].id);
    });

    $('#addStudent').click(function(){
        showNewStudentModal();
    });

    $('#searchStudent').click(function() {
        console.log('Clicked search');
    });

    loadStudentTable();

}<commit_msg>autocomplete weggesmeten, search functie in de plaats :p<commit_after>// View model for the courses page
function pageViewModel(gvm) {
    gvm.userId = -1;
    gvm.studentlistName = ko.observable('Name');
    gvm.listId = -1
    // Page specific i18n bindings
    gvm.title = ko.computed(function(){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("AccountTitle");}, gvm);
    gvm.pageHeader = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("EditListTitle");}, gvm);

    gvm.addBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AddBtn")}, gvm);

    gvm.myLists = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("myLists");}, gvm);
    gvm.addStudListBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("addStudListBtn");}, gvm);
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);

    gvm.codeTableTitle = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("CodeTableTitle");}, gvm);
    gvm.nameTableTitle = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("NameTableTitle");}, gvm);
    gvm.descTableTitle = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("DescTableTitle");}, gvm);
    gvm.actionTableTitle = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ActionTableTitle");}, gvm);

    gvm.firstname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Firstname");}, gvm);
    gvm.lastname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Lastname");}, gvm);
    gvm.email = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Email");}, gvm);
    gvm.memberSince = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("MemberSince");}, gvm);
    gvm.myProjects = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("MyProjects");}, gvm);

    gvm.tabledata = ko.observableArray([]);

    gvm.addTableData = function(id, firstname, lastname, username) {
        // Push data
        var tblOject = {tid: id, tfirstname: firstname, tlastname: lastname, tusername: username};
        gvm.tabledata.push(tblOject);

        $('#editbtn-' + id).bind('click', function(event, data) {
            showEditStudentModal(tblOject);
            event.stopPropagation();
        });

        $('#removebtn-' + id).bind('click', function(event, data){
            // Delete the table item
            deleteTableItem(id, tblOject);
            event.stopPropagation();
        });
    }

    gvm.clearTable = function() {
        gvm.tabledata.removeAll();
    }

}

function showEditStudentModal(tblObject) {
    resetGeneralModal();
    setGeneralModalTitle("Edit Student");
    setGeneralModalBody('<form id="updateStudent"> \

 \
                <input type="text" class="form-control input-lg" placeholder="' + tblObject.tfirstname + '" " name="firstname" value="' + tblObject.tfirstname + '"> \

 \

 \
                <input type="text" class="form-control input-lg" placeholder="' + tblObject.tlastname + '" name="lastname" value="' + tblObject.tlastname + '"> \

 \

 \
                <input type="text" class="form-control input-lg" placeholder="' + tblObject.tusername + '" name="username" value="' + tblObject.tusername + '"> \

 \
        </form>');
    $.getJSON()

    addGeneralModalButton(i18n.__("SaveBtn"), function(){
        updateStudent(tblObject.tid, $('#updateStudent').serialize(), function(result){
            hideModal();
        });
    });

    addGeneralModalButton(i18n.__("CancelBtn"), function(){
        hideModal();
    })

    showGeneralModal();
}

function showNewStudentModal() {
    resetGeneralModal();
    setGeneralModalTitle("Add Student");
    setGeneralModalBody('<form id="newStudentFrom" class="form-inline"> \

 \
                <input type="text" class="form-control input-lg col-md-6" placeholder="' + i18n.__('NameTableTitle') + '" " name="name"> \
                <button id="searchStudent" class="btn btn-default" style="margin-left: 20px">Search</button> \

 \
        </form>');
    $.getJSON();

    addGeneralModalButton(i18n.__("AddBtn"), function(){
        addNewStudent($('#newStudentFrom').serialize(), function(result){
            hideModal();
        });
    });

    addGeneralModalButton(i18n.__("CancelBtn"), function(){
        hideModal();
    })

    showGeneralModal();
}

function addNewStudent(serialData, callback) {
    console.log(serialData);
    $.ajax({
        url: "/api/newstudent/" + viewModel.listId,
        type: "POST",
        data: serialData,
        success: function(data) {
            viewModel.addTableData(data['id'], data['firstname'], data['lastname'], data['mail']);
            callback(true);
        },
        error: function(data) {
            callback(false);
        }
    });
}

function updateStudent(id, object, callback) {
    $.ajax({
        url: "/api/studentrapport/" + id,
        type: "PUT",
        data: object,
        success: function(data) {
            loadStudentTable();
            callback(true);
        },
        error: function(data) {
            callback(false);
        }
    });
}

function deleteTableItem(id, tblObject){
    showYesNoModal("Bent u zeker dat u dit item wil verwijderen?", function(val){
        if(val){
            $.ajax({
                url: '/api/studentlistrapport/' + $("#page-header").data('value') + '/delete/student/' + id,
                type: "DELETE",
                success: function() {
                    viewModel.tabledata.remove(tblObject);
                }
            });
        }
    });
}

function loadStudentTable() {
    $.getJSON('/api/studentlistrapporten/students/' + $("#page-header").data('value'), function(data) {
        viewModel.clearTable();
        // Load table data
        $.each(data, function(i, item) {
            viewModel.addTableData(item.id, item.firstname, item.lastname, item.username);
        });
    });
}

function initPage() {
    $.getJSON('/api/studentlistrapport/info/' + $("#page-header").data('value'), function(data) {
        console.log(data[0].id);
        viewModel.studentlistName(data[0].name);
        viewModel.listId = (data[0].id);
    });

    $('#addStudent').click(function(){
        showNewStudentModal();
    });

    $('#searchStudent').click(function() {
        console.log('Clicked search');
    });

    loadStudentTable();

}<|endoftext|>


<commit_before>angular.module('mrlapp.service.WebGuiGui', []).controller('WebGuiGuiCtrl', ['$scope', '$log', 'mrl', function($scope, $log, mrl) {
    $log.info('WebGuiGuiCtrl')
    var _self = this
    var msg = this.msg
    $scope.mrl = mrl
    $scope.panel = mrl.getPanel('runtime')

    $scope.activePanel = 'settings'

     // $scope.displayImages =  mrl.getDisplayImages()

    // GOOD TEMPLATE TO FOLLOW
    this.updateState = function(service) {
        $scope.service = service
        $scope.port = service.port
    }

    $scope.setActive = function(val) {
        var index = array.indexOf(5);
        if (index > -1) {
            array.splice(index, 1);
        }
    }

    //$scope.saveP
    this.onMsg = function(inMsg) {
        let data = inMsg.data[0]
        switch (inMsg.method) {
        case 'display':
            console.info('display - ' + data)
            mrl.display(data)
            $scope.$apply()
            break
        case 'onState':
            _self.updateState(data)
            $scope.$apply()
            break
        case 'onShowAll':
            // panelSvc.showAll(inMsg.data[0]) TODO - fix
            break
        case 'onShow':
            // panelSvc.show(inMsg.data[0]) TODO - fix
            break
        case 'onHide':
            // panelSvc.hide(inMsg.data[0]) TODO - fix
            break
        case 'onPanel':
            // panelSvc.setPanel(inMsg.data[0]) TODO - fix
            break
        default:
            $log.error("ERROR - unhandled method " + $scope.name + " " + inMsg.method)
            break
        }
    }

    //mrl.subscribe($scope.service.name, 'pulse')
    msg.subscribe('publishShowAll')
    // msg.subscribe('publishHideAll') FIXME ? not symmetric
    msg.subscribe('publishHide')
    msg.subscribe('publishShow')
    msg.subscribe('publishSet')
    msg.subscribe('publishPanel')
    msg.send("publishPanels")
    // msg.subscribe('loadPanels')
    msg.subscribe(this)
}
])
<commit_msg>removed all homepage stuff<commit_after>angular.module('mrlapp.service.WebGuiGui', []).controller('WebGuiGuiCtrl', ['$scope', '$log', 'mrl', function($scope, $log, mrl) {
    $log.info('WebGuiGuiCtrl')
    var _self = this
    var msg = this.msg
    $scope.mrl = mrl

     // $scope.displayImages =  mrl.getDisplayImages()

    // GOOD TEMPLATE TO FOLLOW
    this.updateState = function(service) {
        $scope.service = service
        $scope.port = service.port
    }

    // init scope variables
    $scope.pulseData = ''
    //$scope.saveP
    this.onMsg = function(inMsg) {
        let data = inMsg.data[0]
        switch (inMsg.method) {
        case 'display':
            console.info('display - ' + data)
            mrl.display(data)
            $scope.$apply()
            break
        case 'onState':
            _self.updateState(data)
            $scope.$apply()
            break
        case 'onShowAll':
            // panelSvc.showAll(inMsg.data[0]) TODO - fix
            break
        case 'onShow':
            // panelSvc.show(inMsg.data[0]) TODO - fix
            break
        case 'onHide':
            // panelSvc.hide(inMsg.data[0]) TODO - fix
            break
        case 'onPanel':
            // panelSvc.setPanel(inMsg.data[0]) TODO - fix
            break
        default:
            $log.error("ERROR - unhandled method " + $scope.name + " " + inMsg.method)
            break
        }
    }

    // $scope.panel = mrl.getPanel($scope.service.name)
	$scope.panel = mrl.getPanel('runtime')

    //mrl.subscribe($scope.service.name, 'pulse')
    msg.subscribe('publishShowAll')
    // msg.subscribe('publishHideAll') FIXME ? not symmetric
    msg.subscribe('publishHide')
    msg.subscribe('publishShow')
    msg.subscribe('publishSet')
    msg.subscribe('publishPanel')
    msg.send("publishPanels")
    // msg.subscribe('loadPanels')
    msg.subscribe(this)
}
])

<|endoftext|>


<commit_before>/*
 Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
 For licensing, see LICENSE.html or http://ckeditor.com/license
 */

CKEDITOR.editorConfig = function( config )
{
  // Define changes to default configuration here. For example:
  config.language = 'nb';
  // config.uiColor = '#AADC6E';

  /* Filebrowser routes */
  // The location of an external file browser, that should be launched when "Browse Server" button is pressed.
  config.filebrowserBrowseUrl = "/ckeditor/attachment_files";

  // The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Flash dialog.
  config.filebrowserFlashBrowseUrl = "/ckeditor/attachment_files";

  // The location of a script that handles file uploads in the Flash dialog.
  config.filebrowserFlashUploadUrl = "/ckeditor/attachment_files";

  // The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Link tab of Image dialog.
  config.filebrowserImageBrowseLinkUrl = "/ckeditor/pictures";

  // The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Image dialog.
  config.filebrowserImageBrowseUrl = "/ckeditor/pictures";

  // The location of a script that handles file uploads in the Image dialog.
  config.filebrowserImageUploadUrl = "/ckeditor/pictures";

  // The location of a script that handles file uploads.
  config.filebrowserUploadUrl = "/ckeditor/attachment_files";

  config.allowedContent = true;

  // Rails CSRF token
  config.filebrowserParams = function(){
    var csrf_token, csrf_param, meta,
        metas = document.getElementsByTagName('meta'),
        params = new Object();

    for ( var i = 0 ; i < metas.length ; i++ ){
      meta = metas[i];

      switch(meta.name) {
        case "csrf-token":
          csrf_token = meta.content;
          break;
        case "csrf-param":
          csrf_param = meta.content;
          break;
        default:
          continue;
      }
    }

    if (csrf_param !== undefined && csrf_token !== undefined) {
      params[csrf_param] = csrf_token;
    }

    return params;
  };

  config.addQueryString = function( url, params ){
    var queryString = [];

    if ( !params ) {
      return url;
    } else {
      for ( var i in params )
        queryString.push( i + "=" + encodeURIComponent( params[ i ] ) );
    }

    return url + ( ( url.indexOf( "?" ) != -1 ) ? "&" : "?" ) + queryString.join( "&" );
  };

  // Integrate Rails CSRF token into file upload dialogs (link, image, attachment and flash)
  CKEDITOR.on( 'dialogDefinition', function( ev ){
    // Take the dialog name and its definition from the event data.
    var dialogName = ev.data.name;
    var dialogDefinition = ev.data.definition;
    var content, upload;

    if (CKEDITOR.tools.indexOf(['link', 'image', 'attachment', 'flash'], dialogName) > -1) {
      content = (dialogDefinition.getContents('Upload') || dialogDefinition.getContents('upload'));
      upload = (content == null ? null : content.get('upload'));

      if (upload && upload.filebrowser && upload.filebrowser['params'] === undefined) {
        upload.filebrowser['params'] = config.filebrowserParams();
        upload.action = config.addQueryString(upload.action, upload.filebrowser['params']);
      }
    }
  });

  // Toolbar groups configuration.
  config.toolbar = [
    { name: 'document', groups: [ 'mode', 'document', 'doctools' ], items: [ 'Source'] },
    { name: 'clipboard', groups: [ 'clipboard', 'undo' ], items: [ 'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo' ] },
    // { name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ], items: [ 'Find', 'Replace', '-', 'SelectAll', '-', 'Scayt' ] },
    // { name: 'forms', items: [ 'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField' ] },
    { name: 'links', items: [ 'Link', 'Unlink', 'Anchor' ] },
    { name: 'insert', items: [ 'Image', 'Flash', 'Table', 'HorizontalRule', 'SpecialChar' ] },
    { name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ], items: [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock' ] },
    '/',
    { name: 'styles', items: [ 'Styles', 'Format', 'Font', 'FontSize' ] },
    { name: 'colors', items: [ 'TextColor', 'BGColor' ] },
    { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ], items: [ 'Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat' ] }
  ];

  config.toolbar_mini = [
    { name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ], items: [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock' ] },
    { name: 'styles', items: [ 'Font', 'FontSize' ] },
    { name: 'colors', items: [ 'TextColor', 'BGColor' ] },
    { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ], items: [ 'Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat' ] },
    { name: 'insert', items: [ 'Image', 'Table', 'HorizontalRule', 'SpecialChar' ] }
  ];
};
<commit_msg>Use default language<commit_after>/*
 Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
 For licensing, see LICENSE.html or http://ckeditor.com/license
 */

CKEDITOR.editorConfig = function( config )
{
  // Define changes to default configuration here. For example:
  //config.language = 'nb';
  // config.uiColor = '#AADC6E';

  /* Filebrowser routes */
  // The location of an external file browser, that should be launched when "Browse Server" button is pressed.
  config.filebrowserBrowseUrl = "/ckeditor/attachment_files";

  // The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Flash dialog.
  config.filebrowserFlashBrowseUrl = "/ckeditor/attachment_files";

  // The location of a script that handles file uploads in the Flash dialog.
  config.filebrowserFlashUploadUrl = "/ckeditor/attachment_files";

  // The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Link tab of Image dialog.
  config.filebrowserImageBrowseLinkUrl = "/ckeditor/pictures";

  // The location of an external file browser, that should be launched when "Browse Server" button is pressed in the Image dialog.
  config.filebrowserImageBrowseUrl = "/ckeditor/pictures";

  // The location of a script that handles file uploads in the Image dialog.
  config.filebrowserImageUploadUrl = "/ckeditor/pictures";

  // The location of a script that handles file uploads.
  config.filebrowserUploadUrl = "/ckeditor/attachment_files";

  config.allowedContent = true;

  // Rails CSRF token
  config.filebrowserParams = function(){
    var csrf_token, csrf_param, meta,
        metas = document.getElementsByTagName('meta'),
        params = new Object();

    for ( var i = 0 ; i < metas.length ; i++ ){
      meta = metas[i];

      switch(meta.name) {
        case "csrf-token":
          csrf_token = meta.content;
          break;
        case "csrf-param":
          csrf_param = meta.content;
          break;
        default:
          continue;
      }
    }

    if (csrf_param !== undefined && csrf_token !== undefined) {
      params[csrf_param] = csrf_token;
    }

    return params;
  };

  config.addQueryString = function( url, params ){
    var queryString = [];

    if ( !params ) {
      return url;
    } else {
      for ( var i in params )
        queryString.push( i + "=" + encodeURIComponent( params[ i ] ) );
    }

    return url + ( ( url.indexOf( "?" ) != -1 ) ? "&" : "?" ) + queryString.join( "&" );
  };

  // Integrate Rails CSRF token into file upload dialogs (link, image, attachment and flash)
  CKEDITOR.on( 'dialogDefinition', function( ev ){
    // Take the dialog name and its definition from the event data.
    var dialogName = ev.data.name;
    var dialogDefinition = ev.data.definition;
    var content, upload;

    if (CKEDITOR.tools.indexOf(['link', 'image', 'attachment', 'flash'], dialogName) > -1) {
      content = (dialogDefinition.getContents('Upload') || dialogDefinition.getContents('upload'));
      upload = (content == null ? null : content.get('upload'));

      if (upload && upload.filebrowser && upload.filebrowser['params'] === undefined) {
        upload.filebrowser['params'] = config.filebrowserParams();
        upload.action = config.addQueryString(upload.action, upload.filebrowser['params']);
      }
    }
  });

  // Toolbar groups configuration.
  config.toolbar = [
    { name: 'document', groups: [ 'mode', 'document', 'doctools' ], items: [ 'Source'] },
    { name: 'clipboard', groups: [ 'clipboard', 'undo' ], items: [ 'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo' ] },
    // { name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ], items: [ 'Find', 'Replace', '-', 'SelectAll', '-', 'Scayt' ] },
    // { name: 'forms', items: [ 'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField' ] },
    { name: 'links', items: [ 'Link', 'Unlink', 'Anchor' ] },
    { name: 'insert', items: [ 'Image', 'Flash', 'Table', 'HorizontalRule', 'SpecialChar' ] },
    { name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ], items: [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock' ] },
    '/',
    { name: 'styles', items: [ 'Styles', 'Format', 'Font', 'FontSize' ] },
    { name: 'colors', items: [ 'TextColor', 'BGColor' ] },
    { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ], items: [ 'Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat' ] }
  ];

  config.toolbar_mini = [
    { name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ], items: [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock' ] },
    { name: 'styles', items: [ 'Font', 'FontSize' ] },
    { name: 'colors', items: [ 'TextColor', 'BGColor' ] },
    { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ], items: [ 'Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat' ] },
    { name: 'insert', items: [ 'Image', 'Table', 'HorizontalRule', 'SpecialChar' ] }
  ];
};
<|endoftext|>


<commit_before>'use strict';

// requires
const electron = require('electron');

// Remote profile object, Core layer objects
let _remoteProfile = null;

// ==========================
// exports
// ==========================

/**
 * @module profile
 */
let profile = {};
module.exports = profile;

/**
 * @method load
 * @param {string} url - The url of the profile.
 * @param {function} cb - Callback function.
 *
 * Load profile.
 */
profile.load = function (url) {
  if (!_remoteProfile) {
    _remoteProfile = electron.remote.getGlobal('__electron_profile__');
  }

  if (!_remoteProfile) {
    console.error('Failed to init electron-profile, make sure you require it in main process');
    return null;
  }

  return _remoteProfile.load(url);
};<commit_msg>No need to check for errors every time<commit_after>'use strict';

// requires
const electron = require('electron');

// Remote profile object, Core layer objects
let _remoteProfile = electron.remote.getGlobal('__electron_profile__');

if (!_remoteProfile) {
  console.error('Failed to init electron-profile, make sure you require it in main process');
}

// ==========================
// exports
// ==========================

/**
 * @module profile
 */
let profile = {};
module.exports = profile;

/**
 * @method load
 * @param {string} url - The url of the profile.
 * @param {function} cb - Callback function.
 *
 * Load profile.
 */
profile.load = function (url) {
  if (!_remoteProfile) {
    return null;
  }

  return _remoteProfile.load(url);
};<|endoftext|>


<commit_before>import React, { PropTypes } from 'react'
import { injectIntl, intlShape } from 'react-intl'

class SearchFilterItem extends React.Component {
  constructor (props) {
    super(props)
    this.handleClick = this.handleClick.bind(this)
  }

  handleClick (event) {
    event.preventDefault()
    const { filter: { id } } = this.props
    this.props.toggleFilter(id)
  }

  render () {
    const { filter } = this.props
    const id = `filter_${filter.id}`
    return (

        <input type="checkbox" id={id} name="filter" checked={filter.active} />

            {this.props.intl.formatMessage({ id: filter.bucket })}{/* ({filter.count}) */}

    )
  }
}

SearchFilterItem.propTypes = {
  filter: PropTypes.object.isRequired,
  toggleFilter: PropTypes.func.isRequired,
  intl: intlShape.isRequired
}

export default injectIntl(SearchFilterItem)
<commit_msg>DEICH-12 Patron client - Update filter checkboxes to use icons intead of images<commit_after>import React, { PropTypes } from 'react'
import { injectIntl, intlShape } from 'react-intl'

class SearchFilterItem extends React.Component {
  constructor (props) {
    super(props)
    this.handleClick = this.handleClick.bind(this)
  }

  handleClick (event) {
    event.preventDefault()
    const { filter: { id } } = this.props
    this.props.toggleFilter(id)
  }

  render () {
    const { filter } = this.props
    const id = `filter_${filter.id}`
    return (

        <input type="checkbox" id={id} name="filter" checked={filter.active} onChange={this.handleClick} />

            {this.props.intl.formatMessage({ id: filter.bucket })}{/* ({filter.count}) */}

    )
  }
}

SearchFilterItem.propTypes = {
  filter: PropTypes.object.isRequired,
  toggleFilter: PropTypes.func.isRequired,
  intl: intlShape.isRequired
}

export default injectIntl(SearchFilterItem)
<|endoftext|>


<commit_before>kWidget.addReadyCallback( function( playerId ){
	var kdp = document.getElementById( playerId );
	/**
	 * The main chaptersEdit object:
	 */
	var chaptersEdit = function(kdp){
		return this.init(kdp);
	}
	chaptersEdit.prototype = {
		// the left offset of the cuepoint
		leftOffset: 20,

		// flag to control seeking on playhead updates:
		seekOnPlayHeadUpdate: false,

		// The current active cuePoint
		activeCuePoint: null,

		// Current time of the playhead
		currentTime: 0,

		init: function( kdp ){
			var _this = this;
			this.kdp = kdp;
			// init the cuePoints data controller with the current entryId:
			this.cuePoints = new cuePointsDataController(
				this.getAttr( 'configProxy.kw.id' ),
				this.getAttr( 'mediaProxy.entry.id' ),
				this.getConfig('parentName') || 'chaptering'
			);
			// setup app targets:
			this.$prop = this.getConfig( 'editPropId') ?
					$('#' + this.getConfig( 'editPropId') ) :
					$('<div>').insertAfter( kdp );

			this.$timeline =  this.getConfig( 'editTimelineId' ) ?
					$( '#' + this.getConfig( 'editTimelineId' ) ) :
					$('<div>').insertAfter( this.$prop );

			// Add classes for css styles:
			this.$prop.addClass( 'k-prop' ).text('loading');
			this.$timeline.addClass( 'k-timeline' ).text('loading');

			// Add in default metadata:
			this.cuePoints.load(function(){
				_this.displayPropEdit();
				_this.refreshTimeline();
				_this.addTimelineBindings();
				// set the playhead at zero for startup:
				_this.updatePlayhead( 0 );
				// activate playhead seek:
				_this.seekOnPlayHeadUpdate = true;
			});
		},
		displayPropEdit: function(){
			var _this = this;
			// check if we have a KS ( required for edit and display )
			// check if we have an active cuePoint
			if( this.activeCuePoint){
				this.showEditCuePoint();
			} else{
				this.showAddCuePoint();
			}
		},
		showEditCuePoint: function(){
			var _this = this;
			this.$prop.empty().append(
				$('<h3>').text('Edit CuePoint:'),
				this.getEditCuePoint()
			);
		},
		showAddCuePoint: function(){
			var _this = this;
			this.$prop.empty().append(
				$('<h3>').text( 'Add Chapter:' ),
				this.getEditCuePoint(),

			);
		},
		getEditCuePoint: function(){
			var _this = this;
			var curCuePoint = this.activeCuePoint || new cuePoint( {} )
			// get the edit table for the cuePoint
			$editTable = curCuePoint.getEditTable();
			// add special binding for time update:
			$editTable.find( 'k-currentTime' ).blur(function(){
				_this.updatePlayhead(
					kWidget.npt2seconds( $( this ).val() )
				);
			})
			return $editTable;
		},
		addTimelineBindings: function(){
			var _this = this;
			this.$timeline.click(function( event ){
				var clickTime;
				if( event.offsetX < _this.leftOffset ){
					clickTime = 0;
				} else{
					// update the playhead tracker
					clickTime = ( (event.offsetX - _this.leftOffset ) / _this.getTimelineWidth() ) *  _this.getAttr('duration');
				}
				_this.deselectCuePoint();
				// update playhead
				_this.updatePlayhead( clickTime );
			});
			// add playhead tracker
			kdp.kBind('playerUpdatePlayhead', function( ct ){
				_this.updatePlayhead( ct );
			} )
		},
		updatePlayhead: function( time ){
			// update the current time:
			this.currentTime = time;
			// seek to that time
			if( this.seekOnPlayHeadUpdate ){
				kdp.sendNotification( 'doSeek', time );
			}
			// time target:
			var timeTarget = (  time /  this.getAttr('duration') ) * this.getTimelineWidth();
			// update playhead on timeline:
			this.$timeline.find( '.k-playhead' ).css({
				'left': (  this.leftOffset + timeTarget)  + 'px'
			})
			// Check if we can update current time:
			this.$prop.find( '.k-currentTime' ).val(
				kWidget.seconds2npt( time, true  )
			)
		},
		getTimelineWidth: function(){
			return ( this.$timeline.width() - this.leftOffset );
		},
		refreshTimeline: function(){
			this.$timeline.empty();
			var numOfTimeIncludes = 8;
			// have a max of 10 time listings across the width
			var listingWidth = this.$timeline.width() / numOfTimeIncludes;
			// draw main top level timeline
			this.$timeline.append(
				$('<div>').addClass( 'k-baseline').css({
					'position': 'absolute',
					'top': '30px',
					'width' : '100%',
					'height': '2px',
					'background':'black'
				})
			).css({
				'position': 'relative',
				'height': '100px'
			})

			// draw the playhead marker
			this.$timeline.append(
				$('<div>')
				.addClass('k-playhead')
				.css({
					'position': 'absolute',
					'top': '25px',
					'left': this.leftOffset + 'px',
					'width' : '1px',
					'height': '60px',
					'background':'red'
				})
			)

			// Draw all vertical measurement lines:
			var j =0;
			for( var i = this.leftOffset; i< this.$timeline.width(); i+= ( listingWidth / 4 ) ){
				if( j == 0 ){
					var curMarker = i - this.leftOffset;
					var markerTime = ( curMarker / this.getTimelineWidth() ) * this.getAttr('duration');
					// append large marker
					this.$timeline.append(
						$('<div>').css({
							'position': 'absolute',
							'top': '25px',
							'left': i + 'px',
							'width' : '3px',
							'height': '14px',
							'background':'black'
						}),
						$('<span>').css({
							'position': 'absolute',
							'top': '5px',
							'margin-left': '-10px',
							'left': i + 'px',
							'width' : '70px',
							'height': '14px',
						}).text(
							kWidget.seconds2npt( markerTime )
						)
					);
				} else {
					this.$timeline.append(
						$('<div>').css({
							'position': 'absolute',
							'top': '30px',
							'left': i + 'px',
							'width' : '2px',
							'height': '8px',
							'background':'gray'
						})
					);
				}
				j++;
				if( j == 6 ){
					j= 0;
				}
			}
			// draw the cuePoints:
			this.drawCuePoints();

			// add buttons for adding a cuePoint

			// add cuePoint details:

		},
		deselectCuePoint: function(){
			// make sure no other cuePoint is active:
			this.$timeline.find( '.k-cuepoint').removeClass('active');
			this.displayPropEdit();
			this.activeCuePoint = null
		},
		selectCuePoint: function( cuePoint ){
			var _this = this;
			// unselect other cuePoints:
			_this.deselectCuePoint();
			// activate the current :
			_this.activeCuePoint = cuePoint;
			// select the current cueTime
			_this.updatePlayhead( cuePoint.get('startTime') / 1000 );
			$( '#k-cuepoint-' + cuePoint.id ).addClass( 'active' );
			// update the cue point editor:
			_this.displayPropEdit();
		},
		/**
		 * Draw all the cuePoints to the screen.
		 */
		drawCuePoints: function(){
			var _this = this;
			// remove all old cue points
			_this.$timeline.find( '.k-cuepoint').remove();
			$.each( this.cuePoints.get(), function( inx, cuePoint){
				var cueTime = cuePoint.get( 'startTime' ) / 1000;
				var timeTarget = (  cueTime /  _this.getAttr('duration') ) * _this.getTimelineWidth();
				console.log('cuePoint at: ' + cueTime);
				_this.$timeline.append(
					$('<div>')
					.addClass( 'k-cuepoint' )
					.attr( 'id', 'k-cuepoint-' + cuePoint.id )
					.css({
						'left': (  _this.leftOffset + timeTarget)  + 'px'
					})
					.click(function(){
						// select the current cuePoint
						_this.selectCuePoint( cuePoint );
						// don't propagate down to parent timeline:
						return false;
					})
				)
			});
		},
		getAttr: function( attr ){
			return kdp.evaluate( '{' + attr + '}' );
		},
		getConfig : function( attr ){
			return kdp.evaluate('{chaptersEdit.' + attr + '}' );
		}
	}

	/*****************************************************************
	 * Cue Points Data Controller
	 *
	 * Keeps server, cuePoints in sync
	 ****************************************************************/

	/**
	 * Init the cuePointsDataController
	 * @param entryId {string} The media entry id
	 * @param parentName {string} The controller cuePoint filter name
	 */
	var cuePointsDataController = function(wid, entryId, parentName ){
		return this.init( wid, entryId, parentName );
	}
	cuePointsDataController.prototype = {
		cuePoints: [],
		init: function( wid, entryId, parentName ){
			this.wid = wid;
			this.entryId = entryId;
			this.parentName = parentName;

			// setup api object
			this.api = new kWidget.api( this.wid );
		},
		add: function( cuePoint ){
			cuePoints.push( cuePoint );
		},
		/**
		 * gets all active cuepoints
		 */
		get: function(){
			return this.cuePoints;
		},
		/**
		 * loads cuepoints from server
		 */
		load: function( callback ){
			var _this = this;
			// do an api request
			this.api.doRequest({
				'service': 'cuepoint_cuepoint',
				'action': 'list',
				'filter:entryIdEqual': this.entryId,
				'filter:objectType':'KalturaCuePointFilter',
				//'filter:cuePointTypeEqual':	'annotation.Annotation'
			}, function( data ){
				$.each( data.objects, function(inx, rawCuePoint){
					_this.cuePoints.push( new cuePoint( rawCuePoint) );
				});
				if( callback ) {
					callback();
				}
			})
		}
	}
	/**
	 * The cuePoint object, created with a raw db entry, supports edit views
	 */
	var cuePoint =  function( rawCuePoint ){
		return this.init( rawCuePoint );
	}
	cuePoint.prototype = {
		init: function( rawCuePoint ){
			this.rawCuePoint = rawCuePoint;
		},
		/**
		 * get a cuePoint property
		 */
		get: function( attr ){
			if(! attr ){
				return this.rawCuePoint;
			}
			return this.rawCuePoint[ attr ];
		},
		inputMap: {
			'startTime': {
				'w': '100px',
				'msg': 'Start Time',
				'type': 'time'
			},
			'text':{
				'w': '150px',
				'msg': "Chapter title",
				'type': 'string'
			},
			'partnerData': {
				'w': '150px',
				'msg': "JSON Custom data",
				'type': 'customData'
			}
		},
		getInput: function( inputKey ){
			var _this = this;
			$input = $('<input>')
				.css( 'width', this.inputMap[ inputKey ].w )
				.attr({
					'type': 'text',
				})
				.addClass( )
				.blur(function(){
					// Update the given input
					_this.rawCuePoint[inputKey] = $( this ).val();
				});
			// add any per type customizations
			switch( inputKey ){
				case 'startTime':
					$input
					.addClass( 'k-currentTime' )
				break;
			}

			return $input;
		},
		/**
		 * Get a series of edit rows
		 */
		getEditTable: function(){
			var _this = this;
			$table = $( '<table class="table table-bordered table-striped" >' );
			// map all input types:
			$.each( this.inputMap, function( inputKey, inputMap ){
				$table.append(
					$('<tr>').append(
						$( '<td>' ).text( inputMap.msg ),
						$( '<td>').append(
							_this.getInput( inputKey )
						)
					)
				)
			});
			return $table;
		}
	}

	/*****************************************************************
	 * Application initialization
	 ****************************************************************/
	window['chaptersEditMediaReady'] = function(){
		// make sure we have jQuery
		if( !window.jQuery ){
			kWidget.appendScriptUrl( '//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js', function(){
				new chaptersEdit(kdp)
			});
			return ;
		}
		new chaptersEdit(kdp);
	};
	kdp.addJsListener( "mediaReady", "chaptersEditMediaReady" );
});<commit_msg>move dev to chapter branch, clear active cue point if adding new<commit_after>kWidget.addReadyCallback( function( playerId ){
	var kdp = document.getElementById( playerId );
	/**
	 * The main chaptersEdit object:
	 */
	var chaptersEdit = function(kdp){
		return this.init(kdp);
	}
	chaptersEdit.prototype = {
		// the left offset of the cuepoint
		leftOffset: 20,

		// flag to control seeking on playhead updates:
		seekOnPlayHeadUpdate: false,

		// The current active cuePoint
		activeCuePoint: null,

		// Current time of the playhead
		currentTime: 0,

		init: function( kdp ){
			var _this = this;
			this.kdp = kdp;
			// init the cuePoints data controller with the current entryId:
			this.cuePoints = new cuePointsDataController(
				this.getAttr( 'configProxy.kw.id' ),
				this.getAttr( 'mediaProxy.entry.id' ),
				this.getConfig('parentName') || 'chaptering'
			);
			// setup app targets:
			this.$prop = this.getConfig( 'editPropId') ?
					$('#' + this.getConfig( 'editPropId') ) :
					$('<div>').insertAfter( kdp );

			this.$timeline =  this.getConfig( 'editTimelineId' ) ?
					$( '#' + this.getConfig( 'editTimelineId' ) ) :
					$('<div>').insertAfter( this.$prop );

			// Add classes for css styles:
			this.$prop.addClass( 'k-prop' ).text('loading');
			this.$timeline.addClass( 'k-timeline' ).text('loading');

			// Add in default metadata:
			this.cuePoints.load(function(){
				_this.displayPropEdit();
				_this.refreshTimeline();
				_this.addTimelineBindings();
				// set the playhead at zero for startup:
				_this.updatePlayhead( 0 );
				// activate playhead seek:
				_this.seekOnPlayHeadUpdate = true;
			});
		},
		displayPropEdit: function(){
			var _this = this;
			// check if we have a KS ( required for edit and display )
			// check if we have an active cuePoint
			if( this.activeCuePoint){
				this.showEditCuePoint();
			} else{
				this.showAddCuePoint();
			}
		},
		showEditCuePoint: function(){
			var _this = this;
			this.$prop.empty().append(
				$('<h3>').text('Edit CuePoint:'),
				this.getEditCuePoint()
			);
		},
		showAddCuePoint: function(){
			var _this = this;
			this.activeCuePoint = null;
			this.$prop.empty().append(
				$('<h3>').text( 'Add Chapter:' ),
				this.getEditCuePoint(),
			);
		},
		getEditCuePoint: function(){
			var _this = this;
			var curCuePoint = this.activeCuePoint || new cuePoint( {} )
			// get the edit table for the cuePoint
			$editTable = curCuePoint.getEditTable();
			// add special binding for time update:
			$editTable.find( 'k-currentTime' ).blur(function(){
				_this.updatePlayhead(
					kWidget.npt2seconds( $( this ).val() )
				);
			})
			return $editTable;
		},
		addTimelineBindings: function(){
			var _this = this;
			this.$timeline.click(function( event ){
				var clickTime;
				if( event.offsetX < _this.leftOffset ){
					clickTime = 0;
				} else{
					// update the playhead tracker
					clickTime = ( (event.offsetX - _this.leftOffset ) / _this.getTimelineWidth() ) *  _this.getAttr('duration');
				}
				_this.deselectCuePoint();
				// update playhead
				_this.updatePlayhead( clickTime );
			});
			// add playhead tracker
			kdp.kBind('playerUpdatePlayhead', function( ct ){
				_this.updatePlayhead( ct );
			} )
		},
		updatePlayhead: function( time ){
			// update the current time:
			this.currentTime = time;
			// seek to that time
			if( this.seekOnPlayHeadUpdate ){
				kdp.sendNotification( 'doSeek', time );
			}
			// time target:
			var timeTarget = (  time /  this.getAttr('duration') ) * this.getTimelineWidth();
			// update playhead on timeline:
			this.$timeline.find( '.k-playhead' ).css({
				'left': (  this.leftOffset + timeTarget)  + 'px'
			})
			// Check if we can update current time:
			this.$prop.find( '.k-currentTime' ).val(
				kWidget.seconds2npt( time, true  )
			)
		},
		getTimelineWidth: function(){
			return ( this.$timeline.width() - this.leftOffset );
		},
		refreshTimeline: function(){
			this.$timeline.empty();
			var numOfTimeIncludes = 8;
			// have a max of 10 time listings across the width
			var listingWidth = this.$timeline.width() / numOfTimeIncludes;
			// draw main top level timeline
			this.$timeline.append(
				$('<div>').addClass( 'k-baseline').css({
					'position': 'absolute',
					'top': '30px',
					'width' : '100%',
					'height': '2px',
					'background':'black'
				})
			).css({
				'position': 'relative',
				'height': '100px'
			})

			// draw the playhead marker
			this.$timeline.append(
				$('<div>')
				.addClass('k-playhead')
				.css({
					'position': 'absolute',
					'top': '25px',
					'left': this.leftOffset + 'px',
					'width' : '1px',
					'height': '60px',
					'background':'red'
				})
			)

			// Draw all vertical measurement lines:
			var j =0;
			for( var i = this.leftOffset; i< this.$timeline.width(); i+= ( listingWidth / 4 ) ){
				if( j == 0 ){
					var curMarker = i - this.leftOffset;
					var markerTime = ( curMarker / this.getTimelineWidth() ) * this.getAttr('duration');
					// append large marker
					this.$timeline.append(
						$('<div>').css({
							'position': 'absolute',
							'top': '25px',
							'left': i + 'px',
							'width' : '3px',
							'height': '14px',
							'background':'black'
						}),
						$('<span>').css({
							'position': 'absolute',
							'top': '5px',
							'margin-left': '-10px',
							'left': i + 'px',
							'width' : '70px',
							'height': '14px',
						}).text(
							kWidget.seconds2npt( markerTime )
						)
					);
				} else {
					this.$timeline.append(
						$('<div>').css({
							'position': 'absolute',
							'top': '30px',
							'left': i + 'px',
							'width' : '2px',
							'height': '8px',
							'background':'gray'
						})
					);
				}
				j++;
				if( j == 6 ){
					j= 0;
				}
			}
			// draw the cuePoints:
			this.drawCuePoints();

			// add buttons for adding a cuePoint

			// add cuePoint details:

		},
		deselectCuePoint: function(){
			// make sure no other cuePoint is active:
			this.$timeline.find( '.k-cuepoint').removeClass('active');
			this.displayPropEdit();
			this.activeCuePoint = null
		},
		selectCuePoint: function( cuePoint ){
			var _this = this;
			// unselect other cuePoints:
			_this.deselectCuePoint();
			// activate the current :
			_this.activeCuePoint = cuePoint;
			// select the current cueTime
			_this.updatePlayhead( cuePoint.get('startTime') / 1000 );
			$( '#k-cuepoint-' + cuePoint.id ).addClass( 'active' );
			// update the cue point editor:
			_this.displayPropEdit();
		},
		/**
		 * Draw all the cuePoints to the screen.
		 */
		drawCuePoints: function(){
			var _this = this;
			// remove all old cue points
			_this.$timeline.find( '.k-cuepoint').remove();
			$.each( this.cuePoints.get(), function( inx, cuePoint){
				var cueTime = cuePoint.get( 'startTime' ) / 1000;
				var timeTarget = (  cueTime /  _this.getAttr('duration') ) * _this.getTimelineWidth();
				console.log('cuePoint at: ' + cueTime);
				_this.$timeline.append(
					$('<div>')
					.addClass( 'k-cuepoint' )
					.attr( 'id', 'k-cuepoint-' + cuePoint.id )
					.css({
						'left': (  _this.leftOffset + timeTarget)  + 'px'
					})
					.click(function(){
						// select the current cuePoint
						_this.selectCuePoint( cuePoint );
						// don't propagate down to parent timeline:
						return false;
					})
				)
			});
		},
		getAttr: function( attr ){
			return kdp.evaluate( '{' + attr + '}' );
		},
		getConfig : function( attr ){
			return kdp.evaluate('{chaptersEdit.' + attr + '}' );
		}
	}

	/*****************************************************************
	 * Cue Points Data Controller
	 *
	 * Keeps server, cuePoints in sync
	 ****************************************************************/

	/**
	 * Init the cuePointsDataController
	 * @param entryId {string} The media entry id
	 * @param parentName {string} The controller cuePoint filter name
	 */
	var cuePointsDataController = function(wid, entryId, parentName ){
		return this.init( wid, entryId, parentName );
	}
	cuePointsDataController.prototype = {
		cuePoints: [],
		init: function( wid, entryId, parentName ){
			this.wid = wid;
			this.entryId = entryId;
			this.parentName = parentName;

			// setup api object
			this.api = new kWidget.api( this.wid );
		},
		add: function( cuePoint ){
			cuePoints.push( cuePoint );
		},
		/**
		 * gets all active cuepoints
		 */
		get: function(){
			return this.cuePoints;
		},
		/**
		 * loads cuepoints from server
		 */
		load: function( callback ){
			var _this = this;
			// do an api request
			this.api.doRequest({
				'service': 'cuepoint_cuepoint',
				'action': 'list',
				'filter:entryIdEqual': this.entryId,
				'filter:objectType':'KalturaCuePointFilter',
				//'filter:cuePointTypeEqual':	'annotation.Annotation'
			}, function( data ){
				$.each( data.objects, function(inx, rawCuePoint){
					_this.cuePoints.push( new cuePoint( rawCuePoint) );
				});
				if( callback ) {
					callback();
				}
			})
		}
	}
	/**
	 * The cuePoint object, created with a raw db entry, supports edit views
	 */
	var cuePoint =  function( rawCuePoint ){
		return this.init( rawCuePoint );
	}
	cuePoint.prototype = {
		init: function( rawCuePoint ){
			this.rawCuePoint = rawCuePoint;
		},
		/**
		 * get a cuePoint property
		 */
		get: function( attr ){
			if(! attr ){
				return this.rawCuePoint;
			}
			return this.rawCuePoint[ attr ];
		},
		inputMap: {
			'startTime': {
				'w': '100px',
				'msg': 'Start Time',
				'type': 'time'
			},
			'text':{
				'w': '150px',
				'msg': "Chapter title",
				'type': 'string'
			},
			'partnerData': {
				'w': '150px',
				'msg': "JSON Custom data",
				'type': 'customData'
			}
		},
		getInput: function( inputKey ){
			var _this = this;
			$input = $('<input>')
				.css( 'width', this.inputMap[ inputKey ].w )
				.attr({
					'type': 'text',
				})
				.addClass( )
				.blur(function(){
					// Update the given input
					_this.rawCuePoint[inputKey] = $( this ).val();
				});
			// add any per type customizations
			switch( inputKey ){
				case 'startTime':
					$input
					.addClass( 'k-currentTime' )
				break;
			}

			return $input;
		},
		/**
		 * Get a series of edit rows
		 */
		getEditTable: function(){
			var _this = this;
			$table = $( '<table class="table table-bordered table-striped" >' );
			// map all input types:
			$.each( this.inputMap, function( inputKey, inputMap ){
				$table.append(
					$('<tr>').append(
						$( '<td>' ).text( inputMap.msg ),
						$( '<td>').append(
							_this.getInput( inputKey )
						)
					)
				)
			});
			return $table;
		}
	}

	/*****************************************************************
	 * Application initialization
	 ****************************************************************/
	window['chaptersEditMediaReady'] = function(){
		// make sure we have jQuery
		if( !window.jQuery ){
			kWidget.appendScriptUrl( '//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js', function(){
				new chaptersEdit(kdp)
			});
			return ;
		}
		new chaptersEdit(kdp);
	};
	kdp.addJsListener( "mediaReady", "chaptersEditMediaReady" );
});<|endoftext|>


<commit_before>#!/usr/bin/env node

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

var request = require('request');
var dbModels = require('../lib/db-models');

module.exports = function (mongoose, dbconn, makeAPIPublisher) {
  var Component = dbModels.get('Component');
  var App = dbModels.get('App');

  var checkAuthorised = function(request, response, next) {
    if (! request.session.email) {
      response.json(401, {error: 'need to be signed in'});
      return false;
    }
    if(next) next();
    return true;
  };

  return {
    apps: function(request, response) {
      if (!checkAuthorised(request, response)) return;

      App.find({author:request.session.email}).sort({"name":1}).exec(function (err, apps) {
        if (err){
          console.log('Unable to retrieve apps');
          return response.json(500, 'Unable to retrieve apps: ' + err);
        }
        return response.json(apps);
      });
    },
    app: function(request, response) {
      if (!checkAuthorised(request, response)) return;

      App.findOne({author:request.session.email, name: request.query.name}, function(err, obj) {
        if (!obj) {
          console.warn('Unable to find app for %s', request.query.name);
          return response.json(500, {error: 'Unable to find app: ' + err});
        } else {
          return response.json(obj);
        }
      });
    },
    renameApp: function(request, response) {
      if (!checkAuthorised(request, response)) return;

      var setObj = {};
      var oldName = request.body.oldName;
      var newName = request.body.newName;

      //Check if app with same name already exists
      App.findOne({author:request.session.email, name: newName}, function(err, obj) {
        if (obj) {
          return response.json(500, {error: 'App name must be unique.'});
        }
        else {

          setObj.name = newName;
          setObj['modified-date'] = new Date();

          App.update(
            {author:request.session.email, name: oldName},
            {
              $set: setObj
            },
            {},
            function(err,obj){
              if(err){
                return response.json(500, {error: 'App was not renamed due to ' + err});
              } else {
                return response.json(200, {message: 'App was renamed successfully'});
              }
            }
          );
        }
      });
    },
    deleteApp: function(request,response){
      if (!checkAuthorised(request, response)) return;

      var name = request.body.name;

      if (!name) {
        // app doesn't exist anymore, likely deleted in another tab.
        return;
      }

      App.findOne({author:request.session.email, name: name},function(err, app){
        if (err) {
          console.log("Error finding app to delete!");
          return response.json(500, {error: 'App was not deleted due to ' + err});
        }

        if (!app) {
          return response.json(200, {message: "app was deleted"});
        }

        var makeId = app['makeapi-id'];
        App.remove({author:request.session.email, name: request.body.name}, function(err) {
          if(err){
            console.warn("Error deleting this app!");
            return response.json(500, {error: 'App was not deleted due to ' + err});
          }
          return response.json(200, {message: "app was deleted"});
        });
        if (makeId) {
          makeAPIPublisher.remove(makeId, function(err) {
            if (err) console.warn("Error deleting make: " + err);
          });
        }
      });
    },
    saveApp: function(request, response) {
      if (!checkAuthorised(request, response)) return;

      // Check if app with same name already exists
      App.findOne({author:request.session.email, name: request.body.name}, function(err, obj) {
        if (obj) {
          return response.json(500, {error: 'App name must be unique.'});
        }
        else {
          var appObj = JSON.parse(JSON.stringify(request.body)) // make a copy
          appObj.author = request.session.email;
          appObj.appid = request.body.appid;
          appObj['created-date'] = appObj['modified-date'] = new Date();
          var newApp = new App(appObj);
          newApp.save(function(err, app){
            if (err){
              return response.json(500, {error: 'App was not saved due to ' + err});
            }
            return response.json(app);
          });
          response.json(200);
        }
      });
    },
    updateApp: function(request, response) {
      if (!checkAuthorised(request, response)) return;

      var name = request.body.name;
      //TODO query by appid instead of name https://github.com/mozilla-appmaker/appmaker/issues/898
      var html = request.body.html || false;
      var url = request.body.url || false;

      if(html === false) {
          return response.json(409, {error: 'App was not updated as no data was sent with the request'});
      }

      var setObj = {};
      if(html) setObj.html = html;
      if(url) setObj['last-published-url'] = url;
      setObj['modified-date'] = new Date();
      App.update(
        {author:request.session.email, name: name},
        { $set: setObj },
        {},
        function(err,obj){
          if(err){
            return response.json(500, {error: 'App was not updated due to ' + err});
          } else {
            return response.json(200, {message: 'App was updated successfully'});
          }
        });
    },
    components: function(request, response) {
      if (!checkAuthorised(request, response)) return;

      Component.find({author:request.session.email}).sort({"name":1}).exec(function (err, components) {
        if (err){
          console.log('Unable to retrieve components');
          return response.json(500, 'Unable to retrieve components: ' + err);
        }
        return response.json(components);
      });
    },
    learnComponent: function(request, response) {
      if (!checkAuthorised(request, response)) return;

      //Check if component with same url already exists
      Component.findOne({author:request.session.email, url: request.body.url}, function(err, obj) {
        if (obj) {
          return response.json(500, {error: 'We already know the component at '+obj.url+' (as '+obj.name+')'});
        }
        var compObj = JSON.parse(JSON.stringify(request.body)) // make a copy
        compObj.author = request.session.email;
        compObj['created-date'] = compObj['modified-date'] = new Date();
        var newComponent = new Component(compObj);
        newComponent.save(function(err, component){
          if (err) {
            return response.json(500, {error: 'Component was not learned due to ' + err});
          }
          return response.json(component);
        });
        response.json(200);
      });
    },
    forgetComponent: function(request, response) {
      if (!checkAuthorised(request, response)) return;

      Component.remove({author:request.session.email, url: request.body.url}, function(err){
        if(err){
          console.warn("Error forgetting this component!");
          return response.json(500, {error: 'Component was not deleted due to ' + err});
        }
      });
      response.json(200);
    }
  }
};
<commit_msg>Ripped out server-side sort of app list<commit_after>#!/usr/bin/env node

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

var request = require('request');
var dbModels = require('../lib/db-models');

module.exports = function (mongoose, dbconn, makeAPIPublisher) {
  var Component = dbModels.get('Component');
  var App = dbModels.get('App');

  var checkAuthorised = function(request, response, next) {
    if (! request.session.email) {
      response.json(401, {error: 'need to be signed in'});
      return false;
    }
    if(next) next();
    return true;
  };

  return {
    apps: function(request, response) {
      if (!checkAuthorised(request, response)) return;

      App.find({author:request.session.email}).exec(function (err, apps) {
        if (err){
          console.log('Unable to retrieve apps');
          return response.json(500, 'Unable to retrieve apps: ' + err);
        }
        return response.json(apps);
      });
    },
    app: function(request, response) {
      if (!checkAuthorised(request, response)) return;

      App.findOne({author:request.session.email, name: request.query.name}, function(err, obj) {
        if (!obj) {
          console.warn('Unable to find app for %s', request.query.name);
          return response.json(500, {error: 'Unable to find app: ' + err});
        } else {
          return response.json(obj);
        }
      });
    },
    renameApp: function(request, response) {
      if (!checkAuthorised(request, response)) return;

      var setObj = {};
      var oldName = request.body.oldName;
      var newName = request.body.newName;

      //Check if app with same name already exists
      App.findOne({author:request.session.email, name: newName}, function(err, obj) {
        if (obj) {
          return response.json(500, {error: 'App name must be unique.'});
        }
        else {

          setObj.name = newName;
          setObj['modified-date'] = new Date();

          App.update(
            {author:request.session.email, name: oldName},
            {
              $set: setObj
            },
            {},
            function(err,obj){
              if(err){
                return response.json(500, {error: 'App was not renamed due to ' + err});
              } else {
                return response.json(200, {message: 'App was renamed successfully'});
              }
            }
          );
        }
      });
    },
    deleteApp: function(request,response){
      if (!checkAuthorised(request, response)) return;

      var name = request.body.name;

      if (!name) {
        // app doesn't exist anymore, likely deleted in another tab.
        return;
      }

      App.findOne({author:request.session.email, name: name},function(err, app){
        if (err) {
          console.log("Error finding app to delete!");
          return response.json(500, {error: 'App was not deleted due to ' + err});
        }

        if (!app) {
          return response.json(200, {message: "app was deleted"});
        }

        var makeId = app['makeapi-id'];
        App.remove({author:request.session.email, name: request.body.name}, function(err) {
          if(err){
            console.warn("Error deleting this app!");
            return response.json(500, {error: 'App was not deleted due to ' + err});
          }
          return response.json(200, {message: "app was deleted"});
        });
        if (makeId) {
          makeAPIPublisher.remove(makeId, function(err) {
            if (err) console.warn("Error deleting make: " + err);
          });
        }
      });
    },
    saveApp: function(request, response) {
      if (!checkAuthorised(request, response)) return;

      // Check if app with same name already exists
      App.findOne({author:request.session.email, name: request.body.name}, function(err, obj) {
        if (obj) {
          return response.json(500, {error: 'App name must be unique.'});
        }
        else {
          var appObj = JSON.parse(JSON.stringify(request.body)) // make a copy
          appObj.author = request.session.email;
          appObj.appid = request.body.appid;
          appObj['created-date'] = appObj['modified-date'] = new Date();
          var newApp = new App(appObj);
          newApp.save(function(err, app){
            if (err){
              return response.json(500, {error: 'App was not saved due to ' + err});
            }
            return response.json(app);
          });
          response.json(200);
        }
      });
    },
    updateApp: function(request, response) {
      if (!checkAuthorised(request, response)) return;

      var name = request.body.name;
      //TODO query by appid instead of name https://github.com/mozilla-appmaker/appmaker/issues/898
      var html = request.body.html || false;
      var url = request.body.url || false;

      if(html === false) {
          return response.json(409, {error: 'App was not updated as no data was sent with the request'});
      }

      var setObj = {};
      if(html) setObj.html = html;
      if(url) setObj['last-published-url'] = url;
      setObj['modified-date'] = new Date();
      App.update(
        {author:request.session.email, name: name},
        { $set: setObj },
        {},
        function(err,obj){
          if(err){
            return response.json(500, {error: 'App was not updated due to ' + err});
          } else {
            return response.json(200, {message: 'App was updated successfully'});
          }
        });
    },
    components: function(request, response) {
      if (!checkAuthorised(request, response)) return;

      Component.find({author:request.session.email}).sort({"name":1}).exec(function (err, components) {
        if (err){
          console.log('Unable to retrieve components');
          return response.json(500, 'Unable to retrieve components: ' + err);
        }
        return response.json(components);
      });
    },
    learnComponent: function(request, response) {
      if (!checkAuthorised(request, response)) return;

      //Check if component with same url already exists
      Component.findOne({author:request.session.email, url: request.body.url}, function(err, obj) {
        if (obj) {
          return response.json(500, {error: 'We already know the component at '+obj.url+' (as '+obj.name+')'});
        }
        var compObj = JSON.parse(JSON.stringify(request.body)) // make a copy
        compObj.author = request.session.email;
        compObj['created-date'] = compObj['modified-date'] = new Date();
        var newComponent = new Component(compObj);
        newComponent.save(function(err, component){
          if (err) {
            return response.json(500, {error: 'Component was not learned due to ' + err});
          }
          return response.json(component);
        });
        response.json(200);
      });
    },
    forgetComponent: function(request, response) {
      if (!checkAuthorised(request, response)) return;

      Component.remove({author:request.session.email, url: request.body.url}, function(err){
        if(err){
          console.warn("Error forgetting this component!");
          return response.json(500, {error: 'Component was not deleted due to ' + err});
        }
      });
      response.json(200);
    }
  }
};
<|endoftext|>