<commit_before>document.addEventListener('DOMContentLoaded', () => {
  if(Func.$("#categories_list")) {
    var buttons;
    if(buttons = Func.$(".edit")) {
      for (var i = buttons.length - 1; i >= 0; i--) {
        buttons[i].onclick = function(event) {
          event.preventDefault();
          var href = this.href;
          var div_col_1 = this.parentNode;
          var li = div_col_1.parentNode;
          var category_name = li.children[2].innerHTML;
          console.log(category_name);
          var div_col_7 = li.children[2];
          div_col_7.innerHTML =
          `<form class="form-inline" action="${href}" method="post">
            <input type="text" name="name" placeholder=${category_name} required>
            <button type="submit" class="btn btn-primary rounded-circle"></button>
          </form>`
        };
      }
    }
  }
});
<commit_msg>Visual changes<commit_after>document.addEventListener('DOMContentLoaded', () => {
  if(Func.$("#categories_list")) {
    var buttons;
    if(buttons = Func.$(".edit")) {
      for (var i = buttons.length - 1; i >= 0; i--) {
        buttons[i].onclick = function(event) {
          event.preventDefault();
          var href = this.href;
          var div_col_1 = this.parentNode;
          var li = div_col_1.parentNode;
          var category_name = li.children[2].innerHTML;
          console.log(category_name);
          var div_col_7 = li.children[2];
          div_col_7.innerHTML =
          `<form class="form-inline" action="${href}" method="post">

                <input type="text" style="width: 95%;" name="name" placeholder=${category_name} required>

                <button type="submit" class="btn btn-primary btn-circle"></button>

          </form>`
        };
      }
    }
  }
});
<|endoftext|>


<commit_before>/*
	Name: autoComplete
	Authors:
		Andy Matthews: @commadelimited
		Raymond Camden: @cfjedimaster

	Website: http://andyMatthews.net
	Version: 1.5.1
*/
(function($) {

	"use strict";

	var defaults = {
		method: 'GET',
		icon: 'arrow-r',
		cancelRequests: false,
		target: $(),
		source: null,
		callback: null,
		link: null,
		minLength: 0,
		transition: 'fade',
		matchFromStart: true,
		labelHTML: function(value) { return value; },
		onNoResults: function() { return; },
		onLoading: function() { return; },
		onLoadingFinished: function() { return; },
		termParam : 'term',
		loadingHtml : '
Searching...
',
		interval : 0,
		builder : null
	},
	openXHR = {},
	buildItems = function($this, data, settings) {
		var str;
		if (settings.builder) {
			str = settings.builder.apply($this.eq(0), [data, settings]);
		} else {
			str = [];
			if (data) {
				$.each(data, function(index, value) {
					// are we working with objects or strings?
					if ($.isPlainObject(value)) {
						str.push('
' + settings.labelHTML(value.label) + '
');
					} else {
						str.push('
' + settings.labelHTML(value) + '
');
					}
				});
			}
		}
		if ($.isArray(str)) {
			str = str.join('');
		}
		$(settings.target).html(str).listview("refresh");

		// is there a callback?
		if (settings.callback !== null && $.isFunction(settings.callback)) {
			attachCallback(settings);
		}

		if (str.length > 0) {
			$this.trigger("targetUpdated.autocomplete");
		} else {
			$this.trigger("targetCleared.autocomplete");

			if (settings.onNoResults) {
				settings.onNoResults();
			}
		}
	},
	attachCallback = function(settings) {
		$('li a', $(settings.target)).bind('click.autocomplete',function(e){
			e.stopPropagation();
			e.preventDefault();
			settings.callback(e);
		});
	},
	clearTarget = function($this, $target) {
		$target.html('').listview('refresh').closest("fieldset").removeClass("ui-search-active");
		$this.trigger("targetCleared.autocomplete");
	},
	handleInput = function(e) {
		var $this = $(this),
			id = $this.attr("id"),
			text,
			data,
			settings = $this.jqmData("autocomplete"),
			element_text,
			re;

		// Fix For IE8 and earlier versions.
		if (!Date.now) {
			Date.now = function() {
				return new Date().valueOf();
			};
		}

		if (e) {
			if (e.keyCode === 38) { // up
				$('.ui-btn-active', $(settings.target))
					.removeClass('ui-btn-active').prevAll('li.ui-btn:eq(0)')
					.addClass('ui-btn-active').length ||
						$('.ui-btn:last', $(settings.target)).addClass('ui-btn-active');
			} else if (e.keyCode === 40) {
				$('.ui-btn-active', $(settings.target))
					.removeClass('ui-btn-active').nextAll('li.ui-btn:eq(0)')
					.addClass('ui-btn-active').length ||
						$('.ui-btn:first', $(settings.target)).addClass('ui-btn-active');
			} else if (e.keyCode === 13) {
				$('.ui-btn-active a', $(settings.target)).click().length  || $('.ui-btn:first a', $(settings.target)).click();
			}
		}

		if (settings) {
			// get the current text of the input field
			text = $this.val();
			// check if it's the same as the last one
			if (settings._lastText === text) {
				return;
			}
			// reset the timeout...
			if (settings._retryTimeout) {
				window.clearTimeout(settings._retryTimeout);
				settings._retryTimeout = null;
			}
			// dont change the result the user is browsing...
			if (e && (e.keyCode === 13 || e.keyCode === 38 || e.keyCode === 40)) {
				return;
			}
			// if we don't have enough text zero out the target
			if (text.length < settings.minLength) {
				clearTarget($this, $(settings.target));
			} else {
				if (settings.interval && Date.now() - settings._lastRequest < settings.interval) {
					settings._retryTimeout = window.setTimeout($.proxy(handleInput, this), settings.interval - Date.now() + settings._lastRequest );
					return;
				}
				settings._lastRequest = Date.now();
				// store last text
				settings._lastText = text;

				// are we looking at a source array or remote data?
				if ($.isArray(settings.source)) {
					data = settings.source.sort().filter(function(element) {
						// matching from start, or anywhere in the string?
						if (settings.matchFromStart) {
							// from start
							element_text, re = new RegExp('^' + text, 'i');
						} else {
							// anywhere
							element_text, re = new RegExp(text, 'i');
						}
						if ($.isPlainObject(element)) {
							element_text = element.label;
						} else {
							element_text = element;
						}
						return re.test(element_text);
					});
					buildItems($this, data, settings);
				}
				// Accept a function as source.
				// Function needs to call the callback, which is the first parameter.
				// source:function(text,callback) { mydata = [1,2]; callback(mydata); }
				else if (typeof settings.source === 'function') {
					settings.source(text,function(data){
						buildItems($this, data, settings);
					});
				} else {
					var ajax = {
						type: settings.method,
						data: {},
						dataType: 'json',
						beforeSend: function(jqXHR) {
							if (settings.cancelRequests) {
								if (openXHR[id]) {
									// If we have an open XML HTTP Request for this autoComplete ID, abort it
									openXHR[id].abort();
								} else {
								}
								// Set this request to the open XML HTTP Request list for this ID
								openXHR[id] = jqXHR;
							}

							if (settings.onLoading && settings.onLoadingFinished) {
								settings.onLoading();
							}

							if (settings.loadingHtml) {
								// Set a loading indicator as a temporary stop-gap to the response time issue
								$(settings.target).html(settings.loadingHtml).listview('refresh');
								$(settings.target).closest("fieldset").addClass("ui-search-active");
							}
						},
						success: function(data) {
							buildItems($this, data, settings);
						},
						complete: function () {
							// Clear this ID's open XML HTTP Request from the list
							if (settings.cancelRequests) {
								openXHR[id] = null;
							}
							if (settings.onLoadingFinished) {
								settings.onLoadingFinished();
							}
						}
					};

					if ($.isPlainObject(settings.source)) {
						if (settings.source.callback) {
							settings.source.callback(text, ajax);
						}
						for (var k in settings.source) {
							if (k !== 'callback') {
								ajax[k] = settings.source[k];
							}
						}
					} else {
						ajax.url = settings.source;
					}
					if (settings.termParam) {
						ajax.data[settings.termParam] = text;
					}
					$.ajax(ajax);
				}
			}
		}
	},
	methods = {
		init: function(options) {
			var el = this;
			el.jqmData("autocomplete", $.extend({}, defaults, options));
			var settings = el.jqmData("autocomplete");
			return el.unbind("keyup.autocomplete")
						.bind("keyup.autocomplete", handleInput)
						.next('.ui-input-clear')
						.bind('click', function(){
							clearTarget(el, $(settings.target));
						});
		},
		// Allow dynamic update of source and link
		update: function(options) {
			var settings = this.jqmData("autocomplete");
			if (settings) {
				this.jqmData("autocomplete", $.extend(settings, options));
			}
			return this;
		},
		// Method to forcibly clear our target
		clear: function() {
			var settings = this.jqmData("autocomplete");
			if (settings) {
				clearTarget(this, $(settings.target));
			}
			return this;
		},
		// Method to destroy (cleanup) plugin
		destroy: function() {
			var settings = this.jqmData("autocomplete");
			if (settings) {
				clearTarget(this, $(settings.target));
				this.jqmRemoveData("autocomplete");
				this.unbind(".autocomplete");
			}
			return this;
		}
	};

	$.fn.autocomplete = function(method) {
		if (methods[method]) {
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		} else if (typeof method === 'object' || !method) {
			return methods.init.apply(this, arguments);
		}
	};

})(jQuery);
<commit_msg>When an option was for an object, and that object had a property with a ' in it, the html that is written out is invalid. In the callback function when $(e.currentTarget).data("autocomplete") is used, some of the properties would end up undefined. Encode ' as ' when writing out the json value of an object.<commit_after>/*
	Name: autoComplete
	Authors:
		Andy Matthews: @commadelimited
		Raymond Camden: @cfjedimaster

	Website: http://andyMatthews.net
	Version: 1.5.1
*/
(function($) {

	"use strict";

	var defaults = {
		method: 'GET',
		icon: 'arrow-r',
		cancelRequests: false,
		target: $(),
		source: null,
		callback: null,
		link: null,
		minLength: 0,
		transition: 'fade',
		matchFromStart: true,
		labelHTML: function(value) { return value; },
		onNoResults: function() { return; },
		onLoading: function() { return; },
		onLoadingFinished: function() { return; },
		termParam : 'term',
		loadingHtml : '
Searching...
',
		interval : 0,
		builder : null
	},
	openXHR = {},
	buildItems = function($this, data, settings) {
		var str;
		if (settings.builder) {
			str = settings.builder.apply($this.eq(0), [data, settings]);
		} else {
			str = [];
			if (data) {
				$.each(data, function(index, value) {
					// are we working with objects or strings?
					if ($.isPlainObject(value)) {
						str.push('
' + settings.labelHTML(value.label) + '
');
					} else {
						str.push('
' + settings.labelHTML(value) + '
');
					}
				});
			}
		}
		if ($.isArray(str)) {
			str = str.join('');
		}
		$(settings.target).html(str).listview("refresh");

		// is there a callback?
		if (settings.callback !== null && $.isFunction(settings.callback)) {
			attachCallback(settings);
		}

		if (str.length > 0) {
			$this.trigger("targetUpdated.autocomplete");
		} else {
			$this.trigger("targetCleared.autocomplete");

			if (settings.onNoResults) {
				settings.onNoResults();
			}
		}
	},
	attachCallback = function(settings) {
		$('li a', $(settings.target)).bind('click.autocomplete',function(e){
			e.stopPropagation();
			e.preventDefault();
			settings.callback(e);
		});
	},
	clearTarget = function($this, $target) {
		$target.html('').listview('refresh').closest("fieldset").removeClass("ui-search-active");
		$this.trigger("targetCleared.autocomplete");
	},
	handleInput = function(e) {
		var $this = $(this),
			id = $this.attr("id"),
			text,
			data,
			settings = $this.jqmData("autocomplete"),
			element_text,
			re;

		// Fix For IE8 and earlier versions.
		if (!Date.now) {
			Date.now = function() {
				return new Date().valueOf();
			};
		}

		if (e) {
			if (e.keyCode === 38) { // up
				$('.ui-btn-active', $(settings.target))
					.removeClass('ui-btn-active').prevAll('li.ui-btn:eq(0)')
					.addClass('ui-btn-active').length ||
						$('.ui-btn:last', $(settings.target)).addClass('ui-btn-active');
			} else if (e.keyCode === 40) {
				$('.ui-btn-active', $(settings.target))
					.removeClass('ui-btn-active').nextAll('li.ui-btn:eq(0)')
					.addClass('ui-btn-active').length ||
						$('.ui-btn:first', $(settings.target)).addClass('ui-btn-active');
			} else if (e.keyCode === 13) {
				$('.ui-btn-active a', $(settings.target)).click().length  || $('.ui-btn:first a', $(settings.target)).click();
			}
		}

		if (settings) {
			// get the current text of the input field
			text = $this.val();
			// check if it's the same as the last one
			if (settings._lastText === text) {
				return;
			}
			// reset the timeout...
			if (settings._retryTimeout) {
				window.clearTimeout(settings._retryTimeout);
				settings._retryTimeout = null;
			}
			// dont change the result the user is browsing...
			if (e && (e.keyCode === 13 || e.keyCode === 38 || e.keyCode === 40)) {
				return;
			}
			// if we don't have enough text zero out the target
			if (text.length < settings.minLength) {
				clearTarget($this, $(settings.target));
			} else {
				if (settings.interval && Date.now() - settings._lastRequest < settings.interval) {
					settings._retryTimeout = window.setTimeout($.proxy(handleInput, this), settings.interval - Date.now() + settings._lastRequest );
					return;
				}
				settings._lastRequest = Date.now();
				// store last text
				settings._lastText = text;

				// are we looking at a source array or remote data?
				if ($.isArray(settings.source)) {
					data = settings.source.sort().filter(function(element) {
						// matching from start, or anywhere in the string?
						if (settings.matchFromStart) {
							// from start
							element_text, re = new RegExp('^' + text, 'i');
						} else {
							// anywhere
							element_text, re = new RegExp(text, 'i');
						}
						if ($.isPlainObject(element)) {
							element_text = element.label;
						} else {
							element_text = element;
						}
						return re.test(element_text);
					});
					buildItems($this, data, settings);
				}
				// Accept a function as source.
				// Function needs to call the callback, which is the first parameter.
				// source:function(text,callback) { mydata = [1,2]; callback(mydata); }
				else if (typeof settings.source === 'function') {
					settings.source(text,function(data){
						buildItems($this, data, settings);
					});
				} else {
					var ajax = {
						type: settings.method,
						data: {},
						dataType: 'json',
						beforeSend: function(jqXHR) {
							if (settings.cancelRequests) {
								if (openXHR[id]) {
									// If we have an open XML HTTP Request for this autoComplete ID, abort it
									openXHR[id].abort();
								} else {
								}
								// Set this request to the open XML HTTP Request list for this ID
								openXHR[id] = jqXHR;
							}

							if (settings.onLoading && settings.onLoadingFinished) {
								settings.onLoading();
							}

							if (settings.loadingHtml) {
								// Set a loading indicator as a temporary stop-gap to the response time issue
								$(settings.target).html(settings.loadingHtml).listview('refresh');
								$(settings.target).closest("fieldset").addClass("ui-search-active");
							}
						},
						success: function(data) {
							buildItems($this, data, settings);
						},
						complete: function () {
							// Clear this ID's open XML HTTP Request from the list
							if (settings.cancelRequests) {
								openXHR[id] = null;
							}
							if (settings.onLoadingFinished) {
								settings.onLoadingFinished();
							}
						}
					};

					if ($.isPlainObject(settings.source)) {
						if (settings.source.callback) {
							settings.source.callback(text, ajax);
						}
						for (var k in settings.source) {
							if (k !== 'callback') {
								ajax[k] = settings.source[k];
							}
						}
					} else {
						ajax.url = settings.source;
					}
					if (settings.termParam) {
						ajax.data[settings.termParam] = text;
					}
					$.ajax(ajax);
				}
			}
		}
	},
	methods = {
		init: function(options) {
			var el = this;
			el.jqmData("autocomplete", $.extend({}, defaults, options));
			var settings = el.jqmData("autocomplete");
			return el.unbind("keyup.autocomplete")
						.bind("keyup.autocomplete", handleInput)
						.next('.ui-input-clear')
						.bind('click', function(){
							clearTarget(el, $(settings.target));
						});
		},
		// Allow dynamic update of source and link
		update: function(options) {
			var settings = this.jqmData("autocomplete");
			if (settings) {
				this.jqmData("autocomplete", $.extend(settings, options));
			}
			return this;
		},
		// Method to forcibly clear our target
		clear: function() {
			var settings = this.jqmData("autocomplete");
			if (settings) {
				clearTarget(this, $(settings.target));
			}
			return this;
		},
		// Method to destroy (cleanup) plugin
		destroy: function() {
			var settings = this.jqmData("autocomplete");
			if (settings) {
				clearTarget(this, $(settings.target));
				this.jqmRemoveData("autocomplete");
				this.unbind(".autocomplete");
			}
			return this;
		}
	};

	$.fn.autocomplete = function(method) {
		if (methods[method]) {
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		} else if (typeof method === 'object' || !method) {
			return methods.init.apply(this, arguments);
		}
	};

})(jQuery);
<|endoftext|>


<commit_before>require('babel-register');
const os = require('os');

const dotenv = require('dotenv');

dotenv.config();
dotenv.config({path: '.env.default'});

// eslint-disable-next-line prefer-destructuring
const argv = require('yargs').argv;

const uuid = require('uuid');

const {inject} = require('./scripts/tests/openh264');
const beforeSuite = require('./scripts/tests/beforeSuite');

const port = process.env.PORT || 4567;
const isSauceEnabled = (process.env.SAUCE === 'true');
let baseUrl = process.env.JOURNEY_TEST_BASE_URL;

if (!baseUrl) {
  baseUrl = process.env.TAP ? 'https://code.s4d.io' : `http://localhost:${port}`;
}
const browser = process.env.BROWSER || 'chrome';
const version = process.env.VERSION || 'latest';
const platform = process.env.PLATFORM || 'mac 10.12';
const build = process.env.BUILD_NUMBER || `local-${process.env.USER}-wdio-${Date.now()}`;

process.env.BUILD_NUMBER = build;
const tunnelId = uuid.v4();
const suite = argv.suite || 'smoke';
const screenResolutionMac = '2360x1770';
const screenResolutionWin = '1920x1080';
const screenResolution = platform.toLowerCase().includes('os x') || platform === 'darwin' || platform.includes('mac') ? screenResolutionMac : screenResolutionWin;

const chromeCapabilities = {
  browserName: 'chrome',
  'goog:chromeOptions': {
    args: [
      '--use-fake-device-for-media-stream',
      '--use-fake-ui-for-media-stream',
      '--disable-infobars'
    ],
    prefs: {
      'profile.default_content_setting_values.notifications': 2
    }
  }
};
const firefoxCapabilities = {
  browserName: 'firefox',
  'moz:firefoxOptions': {
    prefs: {
      'media.navigator.permission.disabled': true,
      'media.peerconnection.video.h264_enabled': true,
      'media.navigator.streams.fake': true,
      'media.getusermedia.screensharing.enabled': true,
      'media.getusermedia.screensharing.allowed_domains': 'localhost, 127.0.0.1',
      'dom.webnotifications.enabled': false,
      'media.gmp-manager.updateEnabled': true
    }
  }
};
let mochaTimeout = 60000;

if (process.env.DEBUG_JOURNEYS) {
  mochaTimeout = 99999999;
}
if (isSauceEnabled) {
  mochaTimeout = 120000;
}
const services = [];

services.push('firefox-profile');
if (isSauceEnabled) {
  services.push('sauce');
}
else {
  services.push('selenium-standalone');
}
if (!process.env.TAP) {
  services.push('static-server');
}

let staticServerFolders = [
  {mount: '/dist-space', path: './packages/node_modules/@ciscospark/widget-space/dist'},
  {mount: '/dist-recents', path: './packages/node_modules/@ciscospark/widget-recents/dist'},
  {mount: '/', path: './test/journeys/server/'},
  {mount: '/axe-core', path: './node_modules/axe-core/'},
  {mount: '/dist-demo', path: './packages/node_modules/@ciscospark/widget-demo/dist'}
];

if (process.env.STATIC_SERVER_PATH) {
  staticServerFolders = [
    {mount: '/', path: process.env.STATIC_SERVER_PATH}
  ];
}

exports.config = {
  build,
  seleniumInstallArgs: {version: '3.4.0'},
  seleniumArgs: {version: '3.4.0'},
  //
  // ==================
  // Specify Test Files
  // ==================
  // Define which test specs should run. The pattern is relative to the directory
  // from which `wdio` was called. Notice that, if you are calling `wdio` from an
  // NPM script (see https://docs.npmjs.com/cli/run-script) then the current working
  // directory is where your package.json resides, so `wdio` will be called from there.
  //
  specs: ['./test/journeys/specs/**/*.js'],
  suites: {
    smoke: [
      './test/journeys/specs/smoke/widget-space/index.js',
      './test/journeys/specs/smoke/widget-recents/index.js',
      './test/journeys/specs/smoke/multiple/index.js',
      './test/journeys/specs/smoke/demo.js'
    ],
    tap: [
      './test/journeys/specs/tap/**/*.js'
    ],
    space: [
      './test/journeys/specs/space/index.js',
      './test/journeys/specs/space/guest.js',
      './test/journeys/specs/space/startup-settings.js',
      './test/journeys/specs/space/data-api.js'
    ],
    recents: [
      './test/journeys/specs/recents/dataApi/basic.js',
      './test/journeys/specs/recents/global/basic.js',
      './test/journeys/specs/recents/dataApi/space-list-filter.js',
      './test/journeys/specs/recents/global/space-list-filter.js',
      './test/journeys/specs/recents/global/startup-settings.js'
    ]
  },
  // Patterns to exclude.
  exclude: [],
  //
  // ============
  // Capabilities
  // ============
  // Define your capabilities here. WebdriverIO can run multiple capabilities at the same
  // time. Depending on the number of capabilities, WebdriverIO launches several test
  // sessions. Within your capabilities you can overwrite the spec and exclude options in
  // order to group specific specs to a specific capability.
  //
  // First, you can define how many instances should be started at the same time. Let's
  // say you have 3 different capabilities (Chrome, Firefox, and Safari) and you have
  // set maxInstances to 1; wdio will spawn 3 processes. Therefore, if you have 10 spec
  // files and you set maxInstances to 10, all spec files will get tested at the same time
  // and 30 processes will get spawned. The property handles how many capabilities
  // from the same test should run tests.
  //
  //
  // If you have trouble getting all important capabilities together, check out the
  // Sauce Labs platform configurator - a great tool to configure your capabilities:
  // https://docs.saucelabs.com/reference/platforms-configurator
  //
  capabilities: browser === 'chrome' ? {
    browserLocal: {
      desiredCapabilities: chromeCapabilities
    },
    browserRemote: {
      desiredCapabilities: chromeCapabilities
    }
  } : {
    browserLocal: {
      desiredCapabilities: firefoxCapabilities
    },
    browserRemote: {
      desiredCapabilities: firefoxCapabilities
    }
  },
  //
  // ===================
  // Test Configurations
  // ===================
  // Define all options that are relevant for the WebdriverIO instance here
  //
  // By default WebdriverIO commands are executed in a synchronous way using
  // the wdio-sync package. If you still want to run your tests in an async way
  // e.g. using promises you can set the sync option to false.
  sync: true,
  //
  // Level of logging verbosity: silent | verbose | command | data | result | error
  logLevel: 'silent',
  //
  // Enables colors for log output.
  coloredLogs: true,
  //
  // If you only want to run your tests until a specific amount of tests have failed use
  // bail (default is 0 - don't bail, run all tests).
  bail: 1,
  //
  // Saves a screenshot to a given path if a command fails.
  // screenshotPath: './errorShots/',
  //
  // Set a base URL in order to shorten url command calls. If your url parameter starts
  // with "/", then the base url gets prepended.
  baseUrl,
  //
  // Default timeout for all waitFor* commands.
  waitforTimeout: 120000,
  //
  // Default timeout in milliseconds for request
  // if Selenium Grid doesn't send response
  connectionRetryTimeout: 90000,
  //
  // Default request retries count
  connectionRetryCount: 3,
  //
  // Initialize the browser instance with a WebdriverIO plugin. The object should have the
  // plugin name as key and the desired plugin options as properties. Make sure you have
  // the plugin installed before running any tests. The following plugins are currently
  // available:
  // WebdriverCSS: https://github.com/webdriverio/webdrivercss
  // WebdriverRTC: https://github.com/webdriverio/webdriverrtc
  // Browserevent: https://github.com/webdriverio/browserevent
  // plugins: {
  //   webdrivercss: {
  //     screenshotRoot: 'my-shots',
  //     failedComparisonsRoot: 'diffs',
  //     misMatchTolerance: 0.05,
  //     screenWidth: [320,480,640,1024]
  //   },
  //   webdriverrtc: {},
  //   browserevent: {}
  // },
  //
  // Test runner services
  // Services take over a specific job you don't want to take care of. They enhance
  // your test setup with almost no effort. Unlike plugins, they don't add new
  // commands. Instead, they hook themselves up into the test process.
  services,
  //
  // Framework you want to run your specs with.
  // The following are supported: Mocha, Jasmine, and Cucumber
  // see also: http://webdriver.io/guide/testrunner/frameworks.html
  //
  // Make sure you have the wdio adapter package for the specific framework installed
  // before running any tests.
  framework: 'mocha',
  //
  // Test reporter for stdout.
  // The only one supported by default is 'dot'
  // see also: http://webdriver.io/guide/testrunner/reporters.html
  // NOTE: Omitting `xunit` for now. We can revisit that on another pass
  reporters: ['spec', 'junit'],
  reporterOptions: {
    junit: {
      outputDir: './reports/junit/wdio/',
      outputFileFormat() {
        return `results-${suite}-${browser}-${platform}.xml`;
      },
      packageName: `${suite}-${browser}-${platform}`
    }
  },

  //
  // Options to be passed to Mocha.
  // See the full list at http://mochajs.org/
  mochaOpts: {
    ui: 'bdd',
    timeout: mochaTimeout,
    bail: 1,
    retries: 3
  },

  // =====
  // Hooks
  // =====
  beforeSuite,

  // Static Server setup
  staticServerFolders,
  staticServerPort: port,
  onPrepare(config, capabilities) {
    const defs = [
      capabilities.browserRemote.desiredCapabilities,
      capabilities.browserLocal.desiredCapabilities
    ];

    /* eslint-disable no-param-reassign */
    defs.forEach((d) => {
      if (isSauceEnabled) {
        d.build = build;
        // Set the base to SauceLabs so that inject() does its thing.
        d.base = 'SauceLabs';

        d.version = d.version || 'latest';
        d.platform = d.platform || 'OS X 10.12';
      }
      else {
        // Copy the base over so that inject() does its thing.
        d.base = d.browserName;
        d.platform = os.platform();
      }
    });
    /* eslint-enable no-param-reassign */

    return inject(defs)
      .then(() => {
        // Remove the base because it's not actually a selenium property
        defs.forEach((d) => Reflect.deleteProperty(d, 'base'));
      });
  }
};

if (isSauceEnabled) {
  const sauceCapabilities = (remoteName = 'browser') => {
    if (browser === 'chrome') {
      return Object.assign({}, chromeCapabilities, {
        name: `react-widget-${suite}-unnamed-${remoteName}`,
        idleTimeout: 300,
        commandTimeout: 600,
        maxDuration: 3600,
        seleniumVersion: '3.4.0',
        extendedDebugging: true,
        screenResolution,
        platform,
        version
      });
    }

    return Object.assign({}, firefoxCapabilities, {
      name: `react-widget-${suite}-unnamed-${remoteName}`,
      idleTimeout: 300,
      commandTimeout: 600,
      maxDuration: 3600,
      seleniumVersion: '3.4.0',
      extendedDebugging: true,
      // extended debugging
      'moz:firefoxOptions': {
        args: [
          '-start-debugger-server',
          '9222'
        ],
        prefs: {
          'devtools.chrome.enabled': true,
          'devtools.debugger.prompt-connection': false,
          'devtools.debugger.remote-enabled': true
        }
      },
      screenResolution,
      platform,
      version
    });
  };

  exports.config = Object.assign(exports.config, {
    deprecationWarnings: false, // Deprecation warnings on sauce just make the logs noisy
    user: process.env.SAUCE_USERNAME,
    key: process.env.SAUCE_ACCESS_KEY,
    build: process.env.BUILD_NUMBER,
    sauceConnect: !process.env.TAP,
    sauceConnectOpts: {
      noSslBumpDomains: [
        'all'
      ],
      tunnelDomains: [
        '127.0.0.1',
        'localhost'
      ],
      tunnelIdentifier: tunnelId,
      port: process.env.SAUCE_CONNECT_PORT || 4445,
      // retry to establish a tunnel multiple times. (optional)
      connectRetries: 4,
      // time to wait between connection retries in ms. (optional)
      connectRetryTimeout: 2000,
      // retry to download the sauce connect archive multiple times. (optional)
      downloadRetries: 4,
      // time to wait between download retries in ms. (optional)
      downloadRetryTimeout: 1000
    },
    capabilities: {
      browserLocal: {
        desiredCapabilities: sauceCapabilities('local')
      },
      browserRemote: {
        desiredCapabilities: sauceCapabilities('remote')
      }
    }
  });
}
<commit_msg>test(wdio): use @webex packages<commit_after>require('babel-register');
const os = require('os');

const dotenv = require('dotenv');

dotenv.config();
dotenv.config({path: '.env.default'});

// eslint-disable-next-line prefer-destructuring
const argv = require('yargs').argv;

const uuid = require('uuid');

const {inject} = require('./scripts/tests/openh264');
const beforeSuite = require('./scripts/tests/beforeSuite');

const port = process.env.PORT || 4567;
const isSauceEnabled = (process.env.SAUCE === 'true');
let baseUrl = process.env.JOURNEY_TEST_BASE_URL;

if (!baseUrl) {
  baseUrl = process.env.TAP ? 'https://code.s4d.io' : `http://localhost:${port}`;
}
const browser = process.env.BROWSER || 'chrome';
const version = process.env.VERSION || 'latest';
const platform = process.env.PLATFORM || 'mac 10.12';
const build = process.env.BUILD_NUMBER || `local-${process.env.USER}-wdio-${Date.now()}`;

process.env.BUILD_NUMBER = build;
const tunnelId = uuid.v4();
const suite = argv.suite || 'smoke';
const screenResolutionMac = '2360x1770';
const screenResolutionWin = '1920x1080';
const screenResolution = platform.toLowerCase().includes('os x') || platform === 'darwin' || platform.includes('mac') ? screenResolutionMac : screenResolutionWin;

const chromeCapabilities = {
  browserName: 'chrome',
  'goog:chromeOptions': {
    args: [
      '--use-fake-device-for-media-stream',
      '--use-fake-ui-for-media-stream',
      '--disable-infobars'
    ],
    prefs: {
      'profile.default_content_setting_values.notifications': 2
    }
  }
};
const firefoxCapabilities = {
  browserName: 'firefox',
  'moz:firefoxOptions': {
    prefs: {
      'media.navigator.permission.disabled': true,
      'media.peerconnection.video.h264_enabled': true,
      'media.navigator.streams.fake': true,
      'media.getusermedia.screensharing.enabled': true,
      'media.getusermedia.screensharing.allowed_domains': 'localhost, 127.0.0.1',
      'dom.webnotifications.enabled': false,
      'media.gmp-manager.updateEnabled': true
    }
  }
};
let mochaTimeout = 60000;

if (process.env.DEBUG_JOURNEYS) {
  mochaTimeout = 99999999;
}
if (isSauceEnabled) {
  mochaTimeout = 120000;
}
const services = [];

services.push('firefox-profile');
if (isSauceEnabled) {
  services.push('sauce');
}
else {
  services.push('selenium-standalone');
}
if (!process.env.TAP) {
  services.push('static-server');
}

let staticServerFolders = [
  {mount: '/dist-space', path: './packages/node_modules/@webex/widget-space/dist'},
  {mount: '/dist-recents', path: './packages/node_modules/@webex/widget-recents/dist'},
  {mount: '/', path: './test/journeys/server/'},
  {mount: '/axe-core', path: './node_modules/axe-core/'},
  {mount: '/dist-demo', path: './packages/node_modules/@webex/widget-demo/dist'}
];

if (process.env.STATIC_SERVER_PATH) {
  staticServerFolders = [
    {mount: '/', path: process.env.STATIC_SERVER_PATH}
  ];
}

exports.config = {
  build,
  seleniumInstallArgs: {version: '3.4.0'},
  seleniumArgs: {version: '3.4.0'},
  //
  // ==================
  // Specify Test Files
  // ==================
  // Define which test specs should run. The pattern is relative to the directory
  // from which `wdio` was called. Notice that, if you are calling `wdio` from an
  // NPM script (see https://docs.npmjs.com/cli/run-script) then the current working
  // directory is where your package.json resides, so `wdio` will be called from there.
  //
  specs: ['./test/journeys/specs/**/*.js'],
  suites: {
    smoke: [
      './test/journeys/specs/smoke/widget-space/index.js',
      './test/journeys/specs/smoke/widget-recents/index.js',
      './test/journeys/specs/smoke/multiple/index.js',
      './test/journeys/specs/smoke/demo.js'
    ],
    tap: [
      './test/journeys/specs/tap/**/*.js'
    ],
    space: [
      './test/journeys/specs/space/index.js',
      './test/journeys/specs/space/guest.js',
      './test/journeys/specs/space/startup-settings.js',
      './test/journeys/specs/space/data-api.js'
    ],
    recents: [
      './test/journeys/specs/recents/dataApi/basic.js',
      './test/journeys/specs/recents/global/basic.js',
      './test/journeys/specs/recents/dataApi/space-list-filter.js',
      './test/journeys/specs/recents/global/space-list-filter.js',
      './test/journeys/specs/recents/global/startup-settings.js'
    ]
  },
  // Patterns to exclude.
  exclude: [],
  //
  // ============
  // Capabilities
  // ============
  // Define your capabilities here. WebdriverIO can run multiple capabilities at the same
  // time. Depending on the number of capabilities, WebdriverIO launches several test
  // sessions. Within your capabilities you can overwrite the spec and exclude options in
  // order to group specific specs to a specific capability.
  //
  // First, you can define how many instances should be started at the same time. Let's
  // say you have 3 different capabilities (Chrome, Firefox, and Safari) and you have
  // set maxInstances to 1; wdio will spawn 3 processes. Therefore, if you have 10 spec
  // files and you set maxInstances to 10, all spec files will get tested at the same time
  // and 30 processes will get spawned. The property handles how many capabilities
  // from the same test should run tests.
  //
  //
  // If you have trouble getting all important capabilities together, check out the
  // Sauce Labs platform configurator - a great tool to configure your capabilities:
  // https://docs.saucelabs.com/reference/platforms-configurator
  //
  capabilities: browser === 'chrome' ? {
    browserLocal: {
      desiredCapabilities: chromeCapabilities
    },
    browserRemote: {
      desiredCapabilities: chromeCapabilities
    }
  } : {
    browserLocal: {
      desiredCapabilities: firefoxCapabilities
    },
    browserRemote: {
      desiredCapabilities: firefoxCapabilities
    }
  },
  //
  // ===================
  // Test Configurations
  // ===================
  // Define all options that are relevant for the WebdriverIO instance here
  //
  // By default WebdriverIO commands are executed in a synchronous way using
  // the wdio-sync package. If you still want to run your tests in an async way
  // e.g. using promises you can set the sync option to false.
  sync: true,
  //
  // Level of logging verbosity: silent | verbose | command | data | result | error
  logLevel: 'silent',
  //
  // Enables colors for log output.
  coloredLogs: true,
  //
  // If you only want to run your tests until a specific amount of tests have failed use
  // bail (default is 0 - don't bail, run all tests).
  bail: 1,
  //
  // Saves a screenshot to a given path if a command fails.
  // screenshotPath: './errorShots/',
  //
  // Set a base URL in order to shorten url command calls. If your url parameter starts
  // with "/", then the base url gets prepended.
  baseUrl,
  //
  // Default timeout for all waitFor* commands.
  waitforTimeout: 120000,
  //
  // Default timeout in milliseconds for request
  // if Selenium Grid doesn't send response
  connectionRetryTimeout: 90000,
  //
  // Default request retries count
  connectionRetryCount: 3,
  //
  // Initialize the browser instance with a WebdriverIO plugin. The object should have the
  // plugin name as key and the desired plugin options as properties. Make sure you have
  // the plugin installed before running any tests. The following plugins are currently
  // available:
  // WebdriverCSS: https://github.com/webdriverio/webdrivercss
  // WebdriverRTC: https://github.com/webdriverio/webdriverrtc
  // Browserevent: https://github.com/webdriverio/browserevent
  // plugins: {
  //   webdrivercss: {
  //     screenshotRoot: 'my-shots',
  //     failedComparisonsRoot: 'diffs',
  //     misMatchTolerance: 0.05,
  //     screenWidth: [320,480,640,1024]
  //   },
  //   webdriverrtc: {},
  //   browserevent: {}
  // },
  //
  // Test runner services
  // Services take over a specific job you don't want to take care of. They enhance
  // your test setup with almost no effort. Unlike plugins, they don't add new
  // commands. Instead, they hook themselves up into the test process.
  services,
  //
  // Framework you want to run your specs with.
  // The following are supported: Mocha, Jasmine, and Cucumber
  // see also: http://webdriver.io/guide/testrunner/frameworks.html
  //
  // Make sure you have the wdio adapter package for the specific framework installed
  // before running any tests.
  framework: 'mocha',
  //
  // Test reporter for stdout.
  // The only one supported by default is 'dot'
  // see also: http://webdriver.io/guide/testrunner/reporters.html
  // NOTE: Omitting `xunit` for now. We can revisit that on another pass
  reporters: ['spec', 'junit'],
  reporterOptions: {
    junit: {
      outputDir: './reports/junit/wdio/',
      outputFileFormat() {
        return `results-${suite}-${browser}-${platform}.xml`;
      },
      packageName: `${suite}-${browser}-${platform}`
    }
  },

  //
  // Options to be passed to Mocha.
  // See the full list at http://mochajs.org/
  mochaOpts: {
    ui: 'bdd',
    timeout: mochaTimeout,
    bail: 1,
    retries: 3
  },

  // =====
  // Hooks
  // =====
  beforeSuite,

  // Static Server setup
  staticServerFolders,
  staticServerPort: port,
  onPrepare(config, capabilities) {
    const defs = [
      capabilities.browserRemote.desiredCapabilities,
      capabilities.browserLocal.desiredCapabilities
    ];

    /* eslint-disable no-param-reassign */
    defs.forEach((d) => {
      if (isSauceEnabled) {
        d.build = build;
        // Set the base to SauceLabs so that inject() does its thing.
        d.base = 'SauceLabs';

        d.version = d.version || 'latest';
        d.platform = d.platform || 'OS X 10.12';
      }
      else {
        // Copy the base over so that inject() does its thing.
        d.base = d.browserName;
        d.platform = os.platform();
      }
    });
    /* eslint-enable no-param-reassign */

    return inject(defs)
      .then(() => {
        // Remove the base because it's not actually a selenium property
        defs.forEach((d) => Reflect.deleteProperty(d, 'base'));
      });
  }
};

if (isSauceEnabled) {
  const sauceCapabilities = (remoteName = 'browser') => {
    if (browser === 'chrome') {
      return Object.assign({}, chromeCapabilities, {
        name: `react-widget-${suite}-unnamed-${remoteName}`,
        idleTimeout: 300,
        commandTimeout: 600,
        maxDuration: 3600,
        seleniumVersion: '3.4.0',
        extendedDebugging: true,
        screenResolution,
        platform,
        version
      });
    }

    return Object.assign({}, firefoxCapabilities, {
      name: `react-widget-${suite}-unnamed-${remoteName}`,
      idleTimeout: 300,
      commandTimeout: 600,
      maxDuration: 3600,
      seleniumVersion: '3.4.0',
      extendedDebugging: true,
      // extended debugging
      'moz:firefoxOptions': {
        args: [
          '-start-debugger-server',
          '9222'
        ],
        prefs: {
          'devtools.chrome.enabled': true,
          'devtools.debugger.prompt-connection': false,
          'devtools.debugger.remote-enabled': true
        }
      },
      screenResolution,
      platform,
      version
    });
  };

  exports.config = Object.assign(exports.config, {
    deprecationWarnings: false, // Deprecation warnings on sauce just make the logs noisy
    user: process.env.SAUCE_USERNAME,
    key: process.env.SAUCE_ACCESS_KEY,
    build: process.env.BUILD_NUMBER,
    sauceConnect: !process.env.TAP,
    sauceConnectOpts: {
      noSslBumpDomains: [
        'all'
      ],
      tunnelDomains: [
        '127.0.0.1',
        'localhost'
      ],
      tunnelIdentifier: tunnelId,
      port: process.env.SAUCE_CONNECT_PORT || 4445,
      // retry to establish a tunnel multiple times. (optional)
      connectRetries: 4,
      // time to wait between connection retries in ms. (optional)
      connectRetryTimeout: 2000,
      // retry to download the sauce connect archive multiple times. (optional)
      downloadRetries: 4,
      // time to wait between download retries in ms. (optional)
      downloadRetryTimeout: 1000
    },
    capabilities: {
      browserLocal: {
        desiredCapabilities: sauceCapabilities('local')
      },
      browserRemote: {
        desiredCapabilities: sauceCapabilities('remote')
      }
    }
  });
}
<|endoftext|>


<commit_before>Po.NS('Service');

Service.Errors = Ember.Object.extend({

    /**
     * @DI ErrorController
     */
    errorController: null,

    /**
     * @DI router:main
     */
    router: null,
    errorRoute: 'ErrorGeneric',

    rendering: false,

    init: function () {
        this._super();
        var ravenKey = this.get('config.raven_key');
        if (ravenKey) {
            Raven.config(ravenKey, {
                whitelistUrls: []
            }).install();
        }
    },

    parseError: function (error) {
        var data = {
            title: 'Ooops! Something wrong happened',
            message: 'Fatal error',
            template: 'ErrorGeneric',
            error: error
        };

        if (error && (error.message || error.detail)) {
            data.message = error.message || error.detail;
        }

        if (error && error.title) {
            data.title = error.title;
        }

        if (error && error.status == 403) {
            data.title = 'Access denied!';
            data.message = 'You are not allowed to enter this part of the site';
        }

        if (error && error.status == 404) {
            data.template = 'Error404';
        }

        return data;
    },

    consoleError: function (error, level) {
        level = level || 'error';
        // log error
        if (error.stack) {
            console[level](error.stack)
        } else {
            console[level](error);
        }

    },

    renderError: function (error) {
        var ctrl = this.get('errorController');
        var data = this.parseError(error);
        ctrl.set('error', error);
        ctrl.set('content', data);

        var router = this.get('router');
        var errorRoute = this.get('errorRoute');
        router.intermediateTransitionTo(errorRoute);
        ApplicationLoader.hideLoader();
    },

    logError: function (error) {
        var c = this.get('container');

        this.consoleError(error);

        // capture user
        Raven.setUser(null);
        var auth = c.lookup('service:auth');
        var user;
        if (auth && (user = auth.get('user'))) {
            user = {
                email: user.get('email'),
                id: user.get('id')
            };
            Raven.setUser(user);
        }
        // capture current path
        var a = c.lookup('controller:application');
        var currentPath = '';
        if (a) {
            currentPath = a.get('currentPath');
        }

        //capture tags
        var tags = {};
        tags['type'] = error.type;
        tags['errorDuringRendering'] = this.get('rendering');
        tags['currentPath'] = currentPath;

        Raven.captureException(error, {extra: tags});
    },

    processError: function (error) {
        try {
            this.logError(error);
        } catch (e) {
            console.error('--CANNOT-CAPTURE-ERROR');
            console.log(e.stack);
        }
        try {
            this.renderError(error)
        } catch (e) {
            console.error('--CANNOT-RENDER-ERROR--');
            console.error(e.stack);
        }
    }

});<commit_msg>#273 Raven does not work<commit_after>Po.NS('Service');

Service.Errors = Ember.Object.extend({

    /**
     * @DI ErrorController
     */
    errorController: null,

    /**
     * @DI router:main
     */
    router: null,
    errorRoute: 'ErrorGeneric',

    rendering: false,

    /**
     * Allow sentry logging
     */
    remoteLoggingToSentry: false,

    init: function () {
        this._super();
        var ravenKey = this.get('config.raven_key');
        if (ravenKey) {
            window.onerror = Raven.process;
            Raven.config(ravenKey).install();
            this.remoteLoggingToSentry = true;
        }
    },

    parseError: function (error) {
        var data = {
            title: 'Ooops! Something wrong happened',
            message: 'Fatal error',
            template: 'ErrorGeneric',
            error: error
        };

        if (error && (error.message || error.detail)) {
            data.message = error.message || error.detail;
        }

        if (error && error.title) {
            data.title = error.title;
        }

        if (error && error.status == 403) {
            data.title = 'Access denied!';
            data.message = 'You are not allowed to enter this part of the site';
        }

        if (error && error.status == 404) {
            data.template = 'Error404';
        }

        return data;
    },

    consoleError: function (error, level) {
        level = level || 'error';
        // log error
        if (error.stack) {
            console[level](error.stack)
        } else {
            console[level](error);
        }

    },

    renderError: function (error) {
        var ctrl = this.get('errorController');
        var data = this.parseError(error);
        ctrl.set('error', error);
        ctrl.set('content', data);

        var router = this.get('router');
        var errorRoute = this.get('errorRoute');
        router.intermediateTransitionTo(errorRoute);
        ApplicationLoader.hideLoader();
    },

    logError: function (error) {
        var c = this.get('container');

        this.consoleError(error);
        if (this.remoteLoggingToSentry) {
            // capture user
            Raven.setUser(null);
            var auth = c.lookup('service:auth');
            var user;
            if (auth && (user = auth.get('user'))) {
                user = {
                    email: user.get('email'),
                    id: user.get('id')
                };
                Raven.setUser(user);
            }
            // capture current path
            var a = c.lookup('controller:application');
            var currentPath = '';
            if (a) {
                currentPath = a.get('currentPath');
            }

            //capture tags
            var tags = {};
            tags['type'] = error.type;
            tags['errorDuringRendering'] = this.get('rendering');
            tags['currentPath'] = currentPath;

            Raven.captureException(error, {extra: tags});
        }
    },

    processError: function (error) {
        try {
            this.logError(error);
        } catch (e) {
            console.error('--CANNOT-CAPTURE-ERROR');
            console.log(e.stack);
        }
        try {
            this.renderError(error)
        } catch (e) {
            console.error('--CANNOT-RENDER-ERROR--');
            console.error(e.stack);
        }
    }

});<|endoftext|>


<commit_before>// ===================================================================================================
//                           _  __     _ _
//                          | |/ /__ _| | |_ _  _ _ _ __ _
//                          | ' </ _` | |  _| || | '_/ _` |
//                          |_|\_\__,_|_|\__|\_,_|_| \__,_|
//
// This file is part of the Kaltura Collaborative Media Suite which allows users
// to do with audio, video, and animation what Wiki platfroms allow them to do with
// text.
//
// Copyright (C) 2006-2019  Kaltura Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// @ignore
// ===================================================================================================
/**
 * The Kaltura Client - this is the facade through which all service actions should be called.
 * @param config the Kaltura configuration object holding partner credentials (type: KalturaConfiguration).
 */
var util = require('util');
var kaltura = require('./KalturaClientBase');
kaltura.services = require('./KalturaServices');
kaltura.objects = require('./KalturaModel');
kaltura.enums = require('./KalturaTypes');

class Client extends kaltura.ClientBase {

	/**
	 * @param Configuration config
	 */
	constructor(config) {
		super(config);
		this.setApiVersion('15.7.0');
		this.setClientTag('node:19-09-10');
	}
}

module.exports = kaltura;
module.exports.Client = Client;

<commit_msg>New clientlib ver<commit_after>// ===================================================================================================
//                           _  __     _ _
//                          | |/ /__ _| | |_ _  _ _ _ __ _
//                          | ' </ _` | |  _| || | '_/ _` |
//                          |_|\_\__,_|_|\__|\_,_|_| \__,_|
//
// This file is part of the Kaltura Collaborative Media Suite which allows users
// to do with audio, video, and animation what Wiki platfroms allow them to do with
// text.
//
// Copyright (C) 2006-2019  Kaltura Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// @ignore
// ===================================================================================================
/**
 * The Kaltura Client - this is the facade through which all service actions should be called.
 * @param config the Kaltura configuration object holding partner credentials (type: KalturaConfiguration).
 */
var util = require('util');
var kaltura = require('./KalturaClientBase');
kaltura.services = require('./KalturaServices');
kaltura.objects = require('./KalturaModel');
kaltura.enums = require('./KalturaTypes');

class Client extends kaltura.ClientBase {

	/**
	 * @param Configuration config
	 */
	constructor(config) {
		super(config);
		this.setApiVersion('15.7.0');
		this.setClientTag('node:19-09-11');
	}
}

module.exports = kaltura;
module.exports.Client = Client;

<|endoftext|>


<commit_before>config = {
    baseUrl: '/src',
    paths: {
        "jquery": "bower_components/jquery/jquery",
        "logging": "bower_components/logging/src/logging",
        "jquery.form": "bower_components/jquery-form/jquery.form",
        "jquery.anythingslider": "bower_components/AnythingSlider/js/jquery.anythingslider",
        "jcrop": "bower_components/jcrop/js/jquery.Jcrop",
        "klass": "bower_components/klass/src/klass",
        "photoswipe": "legacy/photoswipe",
        "parsley": "bower_components/parsleyjs/parsley",
        "parsley.extend": "bower_components/parsleyjs/parsley.extend",
        "patternslib.slides": "bower_components/slides/src/slides",
        "modernizr": "bower_components/modernizr/modernizr",
        "less": "bower_components/less.js/dist/less-1.6.2",
        "prefixfree": "bower_components/prefixfree/prefixfree.min",
        "Markdown.Converter": "legacy/Markdown.Converter",
        "Markdown.Extra": "legacy/Markdown.Extra",
        "Markdown.Sanitizer": "legacy/Markdown.Sanitizer",
        "select2": "bower_components/select2/select2.min",
        "jquery.chosen": "bower_components/chosen/chosen/chosen.jquery",
        "jquery.fullcalendar": "bower_components/fullcalendar/fullcalendar.min",
        "jquery.fullcalendar.dnd": "bower_components/fullcalendar/lib/jquery-ui.custom.min",
        "jquery.placeholder": "bower_components/jquery-placeholder/jquery.placeholder.min",
        "jquery.textchange": "bower_components/jquery-textchange/jquery.textchange",
        "tinymce": "bower_components/jquery.tinymce/jscripts/tiny_mce/jquery.tinymce",
        "spectrum": "bower_components/spectrum/spectrum",
        // Core
        "pat-utils": "core/utils",
        "pat-compat": "core/compat",
        "pat-jquery-ext": "core/jquery-ext",
        "pat-logger": "core/logger",
        "pat-parser": "core/parser",
        "pat-remove": "core/remove",
        "pat-url": "core/url",
        "pat-store": "core/store",
        "pat-registry": "core/registry",
        "pat-htmlparser": "lib/htmlparser",
        "pat-depends_parse": "lib/depends_parse",
        "pat-dependshandler": "lib/dependshandler",
        "pat-input-change-events": "lib/input-change-events",
        // Patterns
        "patterns": "patterns",
        "pat-ajax": "pat/ajax",
        "pat-autofocus": "pat/autofocus",
        "pat-autoscale": "pat/autoscale",
        "pat-autosubmit": "pat/autosubmit",
        "pat-autosuggest": "pat/autosuggest",
        "pat-breadcrumbs": "pat/breadcrumbs",
        "pat-bumper": "pat/bumper",
        "pat-carousel": "pat/carousel",
        "pat-checkedflag": "pat/checkedflag",
        "pat-checklist": "pat/checklist",
        "pat-chosen": "pat/chosen",
        "pat-collapsible": "pat/collapsible",
        "pat-colour-picket": "pat/colour-picker",
        "pat-depends": "pat/depends",
        "pat-edit-tinymce": "pat/edit-tinymce",
        "pat-equaliser": "pat/equaliser",
        "pat-expandable": "pat/expandable",
        "pat-focus": "pat/focus",
        "pat-formstate": "pat/form-state",
        "pat-forward": "pat/forward",
        "pat-fullcalendar": "pat/fullcalendar",
        "pat-gallery": "pat/gallery",
        "pat-image-crop": "pat/image-crop",
        "pat-inject": "pat/inject",
        "pat-legend": "pat/legend",
        "pat-markdown": "pat/markdown",
        "pat-menu": "pat/menu",
        "pat-modal": "pat/modal",
        "pat-navigation": "pat/navigation",
        "pat-notification": "pat/notification",
        "pat-placeholder": "pat/placeholder",
        "pat-selectbox": "pat/selectbox",
        "pat-skeleton": "pat/skeleton",
        "pat-slides": "pat/slides",
        "pat-slideshow-builder": "pat/slideshow-builder",
        "pat-sortable": "pat/sortable",
        "pat-stacks": "pat/stacks",
        "pat-subform": "pat/subform",
        "pat-switch": "pat/switch",
        "pat-toggle": "pat/toggle",
        "pat-tooltip": "pat/tooltip",
        "pat-validate": "pat/validate",
        "pat-zoom": "pat/zoom",
        // Calendar pattern
        "moment": "bower_components/moment/moment",
        "moment-timezone": "bower_components/moment-timezone/moment-timezone",
        "pat-calendar": "pat/calendar/calendar",
        "pat-calendar-dnd": "pat/calendar/dnd",
        "pat-calendar-moment-timezone-data": "pat/calendar/moment-timezone-data"
    },

    shim: {
        "jcrop":                        { deps: ["jquery"] },
        "jquery":                       { exports: ["jQuery"] },
        "jquery.anythingslider":        { deps: ["jquery"] },
        "jquery.chosen":                { deps: ["jquery"] },
        "jquery.fullcalendar.dnd":      { deps: ["jquery"] },
        "jquery.placeholder":           { deps: ["jquery"] },
        "jquery.textchange":            { deps: ["jquery"] },
        "parsley":                      { deps: ["jquery"] },
        "parsley.extend":               { deps: ["jquery"] },
        "photoswipe":                   { deps: ["klass"] },
        "select2":                      { deps: ["jquery"] },
        "spectrum":                     { deps: ["jquery"] },
        "tinymce":                      { deps: ["jquery"] }
    },
};

if (typeof(require) !== 'undefined') {
    require.config(config);
    require(["patterns"], function(patterns) {});
}
<commit_msg>Add imagesloaded, eventEmitter and eventie to demo, otherwise demo won't load<commit_after>config = {
    baseUrl: '/src',
    paths: {
        "jquery": "bower_components/jquery/jquery",
        "logging": "bower_components/logging/src/logging",
        "jquery.form": "bower_components/jquery-form/jquery.form",
        "jquery.anythingslider": "bower_components/AnythingSlider/js/jquery.anythingslider",
        "jcrop": "bower_components/jcrop/js/jquery.Jcrop",
        "klass": "bower_components/klass/src/klass",
        "photoswipe": "legacy/photoswipe",
        "parsley": "bower_components/parsleyjs/parsley",
        "parsley.extend": "bower_components/parsleyjs/parsley.extend",
        "patternslib.slides": "bower_components/slides/src/slides",
        "modernizr": "bower_components/modernizr/modernizr",
        "less": "bower_components/less.js/dist/less-1.6.2",
        "prefixfree": "bower_components/prefixfree/prefixfree.min",
        "Markdown.Converter": "legacy/Markdown.Converter",
        "Markdown.Extra": "legacy/Markdown.Extra",
        "Markdown.Sanitizer": "legacy/Markdown.Sanitizer",
        "select2": "bower_components/select2/select2.min",
        "jquery.chosen": "bower_components/chosen/chosen/chosen.jquery",
        "jquery.fullcalendar": "bower_components/fullcalendar/fullcalendar.min",
        "jquery.fullcalendar.dnd": "bower_components/fullcalendar/lib/jquery-ui.custom.min",
        "jquery.placeholder": "bower_components/jquery-placeholder/jquery.placeholder.min",
        "jquery.textchange": "bower_components/jquery-textchange/jquery.textchange",
        "tinymce": "bower_components/jquery.tinymce/jscripts/tiny_mce/jquery.tinymce",
        "spectrum": "bower_components/spectrum/spectrum",
        "imagesloaded": "bower_components/imagesloaded/imagesloaded",
        "eventEmitter": "bower_components/eventEmitter",
        "eventie": "bower_components/eventie",
        // Core
        "pat-utils": "core/utils",
        "pat-compat": "core/compat",
        "pat-jquery-ext": "core/jquery-ext",
        "pat-logger": "core/logger",
        "pat-parser": "core/parser",
        "pat-remove": "core/remove",
        "pat-url": "core/url",
        "pat-store": "core/store",
        "pat-registry": "core/registry",
        "pat-htmlparser": "lib/htmlparser",
        "pat-depends_parse": "lib/depends_parse",
        "pat-dependshandler": "lib/dependshandler",
        "pat-input-change-events": "lib/input-change-events",
        // Patterns
        "patterns": "patterns",
        "pat-ajax": "pat/ajax",
        "pat-autofocus": "pat/autofocus",
        "pat-autoscale": "pat/autoscale",
        "pat-autosubmit": "pat/autosubmit",
        "pat-autosuggest": "pat/autosuggest",
        "pat-breadcrumbs": "pat/breadcrumbs",
        "pat-bumper": "pat/bumper",
        "pat-carousel": "pat/carousel",
        "pat-checkedflag": "pat/checkedflag",
        "pat-checklist": "pat/checklist",
        "pat-chosen": "pat/chosen",
        "pat-collapsible": "pat/collapsible",
        "pat-colour-picket": "pat/colour-picker",
        "pat-depends": "pat/depends",
        "pat-edit-tinymce": "pat/edit-tinymce",
        "pat-equaliser": "pat/equaliser",
        "pat-expandable": "pat/expandable",
        "pat-focus": "pat/focus",
        "pat-formstate": "pat/form-state",
        "pat-forward": "pat/forward",
        "pat-fullcalendar": "pat/fullcalendar",
        "pat-gallery": "pat/gallery",
        "pat-image-crop": "pat/image-crop",
        "pat-inject": "pat/inject",
        "pat-legend": "pat/legend",
        "pat-markdown": "pat/markdown",
        "pat-menu": "pat/menu",
        "pat-modal": "pat/modal",
        "pat-navigation": "pat/navigation",
        "pat-notification": "pat/notification",
        "pat-placeholder": "pat/placeholder",
        "pat-selectbox": "pat/selectbox",
        "pat-skeleton": "pat/skeleton",
        "pat-slides": "pat/slides",
        "pat-slideshow-builder": "pat/slideshow-builder",
        "pat-sortable": "pat/sortable",
        "pat-stacks": "pat/stacks",
        "pat-subform": "pat/subform",
        "pat-switch": "pat/switch",
        "pat-toggle": "pat/toggle",
        "pat-tooltip": "pat/tooltip",
        "pat-validate": "pat/validate",
        "pat-zoom": "pat/zoom",
        // Calendar pattern
        "moment": "bower_components/moment/moment",
        "moment-timezone": "bower_components/moment-timezone/moment-timezone",
        "pat-calendar": "pat/calendar/calendar",
        "pat-calendar-dnd": "pat/calendar/dnd",
        "pat-calendar-moment-timezone-data": "pat/calendar/moment-timezone-data"
    },

    shim: {
        "jcrop":                        { deps: ["jquery"] },
        "jquery":                       { exports: ["jQuery"] },
        "jquery.anythingslider":        { deps: ["jquery"] },
        "jquery.chosen":                { deps: ["jquery"] },
        "jquery.fullcalendar.dnd":      { deps: ["jquery"] },
        "jquery.placeholder":           { deps: ["jquery"] },
        "jquery.textchange":            { deps: ["jquery"] },
        "parsley":                      { deps: ["jquery"] },
        "parsley.extend":               { deps: ["jquery"] },
        "photoswipe":                   { deps: ["klass"] },
        "select2":                      { deps: ["jquery"] },
        "spectrum":                     { deps: ["jquery"] },
        "tinymce":                      { deps: ["jquery"] }
    },
};

if (typeof(require) !== 'undefined') {
    require.config(config);
    require(["patterns"], function(patterns) {});
}
<|endoftext|>


<commit_before>/*
* Moon 0.0.0
* Copyright 2016, Kabir Shah
* https://github.com/KingPixil/moon/
* Free to use under the MIT license.
* https://kingpixil.github.io/license
*/

"use strict";
(function(window) {
    function Moon(opts) {
        var _el = opts.el;
        var _data = opts.data;
        var _methods = opts.methods;
        this.$el = document.getElementById(_el);
        this.dom = {type: this.$el.nodeName, children: [], node: this.$el};

        // Change state when $data is changed
        Object.defineProperty(this, '$data', {
            get: function() {
                return _data;
            },
            set: function(value) {
                _data = value;
                this.build(this.dom.children);
            }
        });

        // Utility: Raw Attributes -> Key Value Pairs
        var extractAttrs = function(node) {
          var attrs = {};
          if(!node.attributes) return attrs;
          var rawAttrs = node.attributes;
          for(var i = 0; i < rawAttrs.length; i++) {
            attrs[rawAttrs[i].name] = rawAttrs[i].value
          }

          return attrs;
        }

        // Utility: Create Elements Recursively For all Children
        var recursiveChildren = function(children) {
          var recursiveChildrenArr = [];
          for(var i = 0; i < children.length; i++) {
            var child = children[i];
            recursiveChildrenArr.push(this.createElement(child.nodeName, recursiveChildren(child.childNodes), child.textContent, extractAttrs(child), child));
          }
          return recursiveChildrenArr;
        }

        // Utility: Create Virtual DOM Instance
        var createVirtualDOM = function(node) {
          var vdom = this.createElement(node.nodeName, recursiveChildren(node.childNodes), node.textContent, extractAttrs(node), node);
          this.dom = vdom;
        }

        // Build the DOM with $data
        this.build = function(children) {
          var tempData = this.$data;
          for(var i = 0; i < children.length; i++) {
            var el = children[i];
            if(el.type === "#text") {
              var tmpVal = el.val;
              el.val.replace(/{{(\w+)}}/gi, function(match, p1) {
                var newVal = tmpVal.replace(match, tempData[p1]);
                el.node.textContent = newVal;
                tmpVal = newVal;
              });
            } else {
                for(var prop in el.props) {
                  var tmpVal = el.props[prop];
                  el.props[prop].replace(/{{(\w+)}}/gi, function(match, p1) {
                    var dataToAdd = tempData[p1];
                    var newVal = tmpVal.replace(new RegExp(match, "gi"), dataToAdd);
                    el.node.setAttribute(prop, newVal);
                    tmpVal = newVal;
                  });
                }
                this.build(el.children);
            }
          }
        }

        // Create Virtual DOM Object from Params
        this.createElement = function(type, children, val, props, node) {
          return {type: type, children: children, val: val, props: props, node: node};
        }

        // Set any value in $data
        this.set = function(key, val) {
          this.$data[key] = val;
          this.build(this.dom.children);
        }

        // Get any value in $data
        this.get = function(key) {
          return this.$data[key];
        }

        // Make AJAX GET/POST requests
        this.ajax = function(method, url, params, cb) {
          var xmlHttp = new XMLHttpRequest();
          method = method.toUpperCase();
          if(typeof params === "function") {
            cb = params;
          }
          var urlParams = "?";
          if(method === "POST") {
            http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            for(var param in params) {
              urlParams += param + "=" + params[param] + "&";
            }
          }
          xmlHttp.onreadystatechange = function() {
          if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
            cb(JSON.parse(xmlHttp.responseText));
          }
          xmlHttp.open(method, url, true);
          xmlHttp.send(method === "POST" ? urlParams : null);
        }

        // Call a method defined in _methods
        this.method = function(method) {
          _methods[method]();
        }

        // Initialize
        createVirtualDOM(this.$el);
        this.build(this.dom.children);
    }

    window.Moon = Moon;
    window.$ = function(el) {
      el = document.querySelectorAll(el);
      return el.length === 1 ? el[0] : el;
    }

})(window);
<commit_msg>create virtual dom is this<commit_after>/*
* Moon 0.0.0
* Copyright 2016, Kabir Shah
* https://github.com/KingPixil/moon/
* Free to use under the MIT license.
* https://kingpixil.github.io/license
*/

"use strict";
(function(window) {
    function Moon(opts) {
        var _el = opts.el;
        var _data = opts.data;
        var _methods = opts.methods;
        this.$el = document.getElementById(_el);
        this.dom = {type: this.$el.nodeName, children: [], node: this.$el};

        // Change state when $data is changed
        Object.defineProperty(this, '$data', {
            get: function() {
                return _data;
            },
            set: function(value) {
                _data = value;
                this.build(this.dom.children);
            }
        });

        // Utility: Raw Attributes -> Key Value Pairs
        var extractAttrs = function(node) {
          var attrs = {};
          if(!node.attributes) return attrs;
          var rawAttrs = node.attributes;
          for(var i = 0; i < rawAttrs.length; i++) {
            attrs[rawAttrs[i].name] = rawAttrs[i].value
          }

          return attrs;
        }

        // Utility: Create Elements Recursively For all Children
        var recursiveChildren = function(children) {
          var recursiveChildrenArr = [];
          for(var i = 0; i < children.length; i++) {
            var child = children[i];
            recursiveChildrenArr.push(this.createElement(child.nodeName, recursiveChildren(child.childNodes), child.textContent, extractAttrs(child), child));
          }
          return recursiveChildrenArr;
        }

        // Utility: Create Virtual DOM Instance
        var this.createVirtualDOM = function(node) {
          var vdom = this.createElement(node.nodeName, recursiveChildren(node.childNodes), node.textContent, extractAttrs(node), node);
          this.dom = vdom;
        }

        // Build the DOM with $data
        this.build = function(children) {
          var tempData = this.$data;
          for(var i = 0; i < children.length; i++) {
            var el = children[i];
            if(el.type === "#text") {
              var tmpVal = el.val;
              el.val.replace(/{{(\w+)}}/gi, function(match, p1) {
                var newVal = tmpVal.replace(match, tempData[p1]);
                el.node.textContent = newVal;
                tmpVal = newVal;
              });
            } else {
                for(var prop in el.props) {
                  var tmpVal = el.props[prop];
                  el.props[prop].replace(/{{(\w+)}}/gi, function(match, p1) {
                    var dataToAdd = tempData[p1];
                    var newVal = tmpVal.replace(new RegExp(match, "gi"), dataToAdd);
                    el.node.setAttribute(prop, newVal);
                    tmpVal = newVal;
                  });
                }
                this.build(el.children);
            }
          }
        }

        // Create Virtual DOM Object from Params
        this.createElement = function(type, children, val, props, node) {
          return {type: type, children: children, val: val, props: props, node: node};
        }

        // Set any value in $data
        this.set = function(key, val) {
          this.$data[key] = val;
          this.build(this.dom.children);
        }

        // Get any value in $data
        this.get = function(key) {
          return this.$data[key];
        }

        // Make AJAX GET/POST requests
        this.ajax = function(method, url, params, cb) {
          var xmlHttp = new XMLHttpRequest();
          method = method.toUpperCase();
          if(typeof params === "function") {
            cb = params;
          }
          var urlParams = "?";
          if(method === "POST") {
            http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            for(var param in params) {
              urlParams += param + "=" + params[param] + "&";
            }
          }
          xmlHttp.onreadystatechange = function() {
          if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
            cb(JSON.parse(xmlHttp.responseText));
          }
          xmlHttp.open(method, url, true);
          xmlHttp.send(method === "POST" ? urlParams : null);
        }

        // Call a method defined in _methods
        this.method = function(method) {
          _methods[method]();
        }

        // Initialize
        createVirtualDOM(this.$el);
        this.build(this.dom.children);
    }

    window.Moon = Moon;
    window.$ = function(el) {
      el = document.querySelectorAll(el);
      return el.length === 1 ? el[0] : el;
    }

})(window);
<|endoftext|>


<commit_before>var roomQuestionList = new QuestionList();

/********** MODEL ***************/

//Question object - this mirrors server/database entry

function Question(q, uId, qId) {
  this.details = q;
  this.votes = 0;
  this.answered = false;
  this.paused = false;
  this.userId = uId;
  this.id = qId;
}

//Question object methods

Question.prototype.upVote = function() {
  this.votes = this.votes + 1;
};

Question.prototype.answer = function() {
  this.answered = true;
};

// Question list object - this is an array of Question Objects
function QuestionList() {
  this.questions = [];
}

//Question list methods
QuestionList.prototype.sort = function() {
  this.questions = _.sortBy(this.questions, function(element){return element.votes;});
};

QuestionList.prototype.addQuestion = function( qObj ) {
  this.questions.push( qObj );
  this.sort();
};

//======= end of model =========//

/********** VIEWS ***************/
/* Answer
/* Question
/* Votes
/* Listeners
/********************************/

//if the question is answerable by the user, add this to the div.
function viewRenderAnswerable(question){
  var myDiv = $('div[data-val=' + question.id + ']');
  var answerableDiv = $("
√
");

  $(myDiv.children()[1]).append(answerableDiv);
}

//render a question
function viewRenderQuestion(question){
  var colors = ["purple", "orange", "red", "blue", "yellow", "green"];
  var outerDiv = $('
');

  var innerDiv = $("
");
  innerDiv.text(question.details);
  innerDiv.css("background", _.sample(colors));

  // build the upvote button & attach it to the inner div
  var upButton = $('
⊕
');
  innerDiv.append(upButton);

  //build the votes div
  var votesDiv = $("
0
");
  innerDiv.append(votesDiv);

  //append the div with the new question.
  outerDiv.append(innerDiv);
  $('div.packery').append(outerDiv);
  pckry.appended( outerDiv[0] );
}

//remove a question from the DOM (aka, it was answered)
function viewRemoveQuestion(question){
  var myDiv = $('div[data-val=' + question.id + ']');
  myDiv.remove();
}

//display how many votes the question has
function viewRenderVotes(question){
  var myDiv = $('div[data-val=' + question.id + ']');
  $(myDiv.children()[1]).html(question.votes);
}

//add a listener to the form to allow new questions to be created
function viewFormListener(){
  var form = $('.question-form');
  var session_id = $('#session_id').text();
  form.submit( function( event ) {
    event.preventDefault();

    //get the question
    var question = $('input.question').val();

    //clear input box now that we have input
    $('input.question').val("");

    //create ajax request with the question and the user_id
    $.ajax({
      url: "/json/questions",
      type: "POST",
      data: { question: {details: question, user_id: session_id}},
      success: controllerUpdateNewQuestion
    });
  });
}

//using delegated listeners for all the little actions
function viewAddDelegatedListeners(){
  $('div.packery').on('click', 'div.upButton', controllerUpVote);
  $('div.packery').on('click', 'div.answerable', controllerAnswer);
}

//======= end of views =========//

/********** CONTROLLER **********/

//called to setup everything on a page refresh
function controllerSetup(){
  $.ajax({
    url: "/json/questions",
    type: "GET",
    success: controllerBuildModel
  });
}

//build the model from a list of unanswered questions returned from the server.
//called only once with the page loads.
function controllerBuildModel(serverResponse){
  var numQuestions = serverResponse[0].questions.length;

  for (var i = 0; i < numQuestions; i++){
    var tempQuestion = new Question(serverResponse[0].questions[i].details, serverResponse[0].questions[i].user_id, serverResponse[0].questions[i].id);
    roomQuestionList.addQuestion(tempQuestion);
    viewRenderQuestion(tempQuestion);
  }
  controllerVoteSetup();
  controllerAnswerableSetup();
}

//setup the votes -
//for every question in the roomQuestionList
//    ask the server how many votes the question has!
function controllerVoteSetup(){
  var numQuestions = roomQuestionList.questions.length;
  for (var i = 0; i < numQuestions; i++){

    $.ajax({
    url: "/json/questions/" + roomQuestionList.questions[i].id + "/getvotes",
    type: "GET",
    data: { question: {id: roomQuestionList.questions[i].id}},
            success:controllerUpdateVotes
        });
    };
}

//update the votes - the success handler for the vote ajax request.
//when the votes are updated, sort the roomQuestionList, then render votes.
function controllerUpdateVotes(serverResponse){
  var tempArray = $.map(roomQuestionList.questions, function(question, i) { return question.id });
  var index = $.inArray(serverResponse[0].question.id, tempArray);

  roomQuestionList.questions[index].votes = serverResponse[1].votes;
  roomQuestionList.sort();
  viewRenderVotes(roomQuestionList.questions[index]);
  //redisplay();
}

//the hander that accepts the response from sending a new question.
function controllerUpdateNewQuestion(serverResponse){
  tempQuestion = new Question(serverResponse.details, serverResponse.user_id, serverResponse.id);
  roomQuestionList.addQuestion(tempQuestion);
  viewRenderQuestion(tempQuestion);
  viewRenderAnswerable(tempQuestion);
}

//launch an ajax request to the server to upvote a question
function controllerUpVote(){
  var session_id = $('#session_id').text();
  var question_id = $(this.parentElement).data().val;
  var url = "/json/questions/" + question_id + "/vote_up";

  $.ajax({
      url: url,
      type: "POST",
      data: { question: {id: question_id}},
      success: controllerUpdateVotes
    });
}

//ajax request for each question - can the user who is logged in answer it?
function controllerAnswerableSetup(){
  var numQuestions = roomQuestionList.questions.length;
  for (var i = 0; i < numQuestions; i++){

    $.ajax({
    url: "/json/questions/" + roomQuestionList.questions[i].id + "/getanswerable",
    type: "GET",
    data: { question: {id: roomQuestionList.questions[i].id}},
      success: controllerUpdateAnswerable
      });
  }
}

//the server has decided i can answer this - so render an answer button.
function controllerUpdateAnswerable(serverResponse){
  //TODO: dry this up into a helper function aka controllerHelperMap(serverResponse)
  var tempArray = $.map(roomQuestionList.questions, function(question, i) { return question.id });
  var index = $.inArray(serverResponse[0].question.id, tempArray);

  viewRenderAnswerable(roomQuestionList.questions[index]);
}

//when the user clicks on answer, send an ajax request to server.
function controllerAnswer(){
  console.log("this question was just answered!");
  // now go tell the server this question was answered!
  // TODO - this is one level higher than vote because of the nesting
  // that is happening - it shouldn't be.
  var question_id = $(this.parentElement.parentElement).data().val;

  var url = "/json/questions/" + question_id + "/answered";

  $.ajax({
      url: url,
      type: "POST",
      data: { question: {id: question_id}},
      success: controllerUpdateAnswer
    });
}

//when the server comes back, update the model and display
function controllerUpdateAnswer(serverResponse){
  //remove from the model - find it in the model.  then mark it answered
  var tempArray = $.map(roomQuestionList.questions, function(question, i) { return question.id });
  var index = $.inArray(serverResponse[0].question.id, tempArray);
  roomQuestionList.questions[index].answer();

  //remove from the dom
  viewRemoveQuestion(roomQuestionList.questions[index]);
}

function redisplay(){
  //delete this shit.
  elems = pckry.getItemElements();
  for (var i=0; i<elems.length; i++){
    pckry.remove(elems[i]);
  }

  //sort local model
  roomQuestionList.sort();

  //build this shit.
  numberOfQuestions = roomQuestionList.questions.length;
  for( i=0; i<numberOfQuestions; i++){
    var question = roomQuestionList.questions[i];

    var colors = ["purple", "orange", "red", "blue", "yellow", "green"];
    var outerDiv = $('
');

    var innerDiv = $("
");
    innerDiv.text(question.details);

    if (question.votes > 5) {
      innerDiv.css("background", "red");
    } else if ((question.votes > 3) && (question.votes < 5)) {
      innerDiv.css("background", "yellow");
    } else if (question.votes <= 3) {
      innerDiv.css("background", "green");
    }

    // build the upvote button & attach it to the inner div
    var upButton = $('
⊕
');
    innerDiv.append(upButton);

    //build the votes div
    var votesDiv = $("
"+question.votes+"
");
    innerDiv.append(votesDiv);

    //append the div with the new question.
    outerDiv.append(innerDiv);

    $('div.packery').append(outerDiv);
    pckry.prepended( outerDiv );
  }

  //should we remove answerable here?
  //setTimeout(controllerAnswerableSetup(),200);
}

function viewToggleList() {
  $("p").hide();
  $("h1").click(function() {
    $(this).next().slideToggle(300);
  });
}

function timedRefresh(timeoutPeriod) {

  var answerTO = timeoutPeriod + 2000;
  setTimeout(redisplay, timeoutPeriod);
  setTimeout(controllerAnswerableSetup, answerTO);
}

window.onload = function(){

  controllerSetup();

  viewFormListener();
  viewAddDelegatedListeners();

  viewToggleList();
  timedRefresh(10000);

};<commit_msg>fine tune colors<commit_after>var roomQuestionList = new QuestionList();

/********** MODEL ***************/

//Question object - this mirrors server/database entry

function Question(q, uId, qId) {
  this.details = q;
  this.votes = 0;
  this.answered = false;
  this.paused = false;
  this.userId = uId;
  this.id = qId;
}

//Question object methods

Question.prototype.upVote = function() {
  this.votes = this.votes + 1;
};

Question.prototype.answer = function() {
  this.answered = true;
};

// Question list object - this is an array of Question Objects
function QuestionList() {
  this.questions = [];
}

//Question list methods
QuestionList.prototype.sort = function() {
  this.questions = _.sortBy(this.questions, function(element){return element.votes;});
};

QuestionList.prototype.addQuestion = function( qObj ) {
  this.questions.push( qObj );
  this.sort();
};

//======= end of model =========//

/********** VIEWS ***************/
/* Answer
/* Question
/* Votes
/* Listeners
/********************************/

//if the question is answerable by the user, add this to the div.
function viewRenderAnswerable(question){
  var myDiv = $('div[data-val=' + question.id + ']');
  var answerableDiv = $("
√
");

  $(myDiv.children()[1]).append(answerableDiv);
}

//render a question
function viewRenderQuestion(question){
  var colors = ["purple", "orange", "red", "blue", "yellow", "green"];
  var outerDiv = $('
');

  var innerDiv = $("
");
  innerDiv.text(question.details);
  innerDiv.css("background", _.sample(colors));

  // build the upvote button & attach it to the inner div
  var upButton = $('
⊕
');
  innerDiv.append(upButton);

  //build the votes div
  var votesDiv = $("
0
");
  innerDiv.append(votesDiv);

  //append the div with the new question.
  outerDiv.append(innerDiv);
  $('div.packery').append(outerDiv);
  pckry.appended( outerDiv[0] );
}

//remove a question from the DOM (aka, it was answered)
function viewRemoveQuestion(question){
  var myDiv = $('div[data-val=' + question.id + ']');
  myDiv.remove();
}

//display how many votes the question has
function viewRenderVotes(question){
  var myDiv = $('div[data-val=' + question.id + ']');
  $(myDiv.children()[1]).html(question.votes);
}

//add a listener to the form to allow new questions to be created
function viewFormListener(){
  var form = $('.question-form');
  var session_id = $('#session_id').text();
  form.submit( function( event ) {
    event.preventDefault();

    //get the question
    var question = $('input.question').val();

    //clear input box now that we have input
    $('input.question').val("");

    //create ajax request with the question and the user_id
    $.ajax({
      url: "/json/questions",
      type: "POST",
      data: { question: {details: question, user_id: session_id}},
      success: controllerUpdateNewQuestion
    });
  });
}

//using delegated listeners for all the little actions
function viewAddDelegatedListeners(){
  $('div.packery').on('click', 'div.upButton', controllerUpVote);
  $('div.packery').on('click', 'div.answerable', controllerAnswer);
}

//======= end of views =========//

/********** CONTROLLER **********/

//called to setup everything on a page refresh
function controllerSetup(){
  $.ajax({
    url: "/json/questions",
    type: "GET",
    success: controllerBuildModel
  });
}

//build the model from a list of unanswered questions returned from the server.
//called only once with the page loads.
function controllerBuildModel(serverResponse){
  var numQuestions = serverResponse[0].questions.length;

  for (var i = 0; i < numQuestions; i++){
    var tempQuestion = new Question(serverResponse[0].questions[i].details, serverResponse[0].questions[i].user_id, serverResponse[0].questions[i].id);
    roomQuestionList.addQuestion(tempQuestion);
    viewRenderQuestion(tempQuestion);
  }
  controllerVoteSetup();
  controllerAnswerableSetup();
}

//setup the votes -
//for every question in the roomQuestionList
//    ask the server how many votes the question has!
function controllerVoteSetup(){
  var numQuestions = roomQuestionList.questions.length;
  for (var i = 0; i < numQuestions; i++){

    $.ajax({
    url: "/json/questions/" + roomQuestionList.questions[i].id + "/getvotes",
    type: "GET",
    data: { question: {id: roomQuestionList.questions[i].id}},
            success:controllerUpdateVotes
        });
    };
}

//update the votes - the success handler for the vote ajax request.
//when the votes are updated, sort the roomQuestionList, then render votes.
function controllerUpdateVotes(serverResponse){
  var tempArray = $.map(roomQuestionList.questions, function(question, i) { return question.id });
  var index = $.inArray(serverResponse[0].question.id, tempArray);

  roomQuestionList.questions[index].votes = serverResponse[1].votes;
  roomQuestionList.sort();
  viewRenderVotes(roomQuestionList.questions[index]);
  //redisplay();
}

//the hander that accepts the response from sending a new question.
function controllerUpdateNewQuestion(serverResponse){
  tempQuestion = new Question(serverResponse.details, serverResponse.user_id, serverResponse.id);
  roomQuestionList.addQuestion(tempQuestion);
  viewRenderQuestion(tempQuestion);
  viewRenderAnswerable(tempQuestion);
}

//launch an ajax request to the server to upvote a question
function controllerUpVote(){
  var session_id = $('#session_id').text();
  var question_id = $(this.parentElement).data().val;
  var url = "/json/questions/" + question_id + "/vote_up";

  $.ajax({
      url: url,
      type: "POST",
      data: { question: {id: question_id}},
      success: controllerUpdateVotes
    });
}

//ajax request for each question - can the user who is logged in answer it?
function controllerAnswerableSetup(){
  var numQuestions = roomQuestionList.questions.length;
  for (var i = 0; i < numQuestions; i++){

    $.ajax({
    url: "/json/questions/" + roomQuestionList.questions[i].id + "/getanswerable",
    type: "GET",
    data: { question: {id: roomQuestionList.questions[i].id}},
      success: controllerUpdateAnswerable
      });
  }
}

//the server has decided i can answer this - so render an answer button.
function controllerUpdateAnswerable(serverResponse){
  //TODO: dry this up into a helper function aka controllerHelperMap(serverResponse)
  var tempArray = $.map(roomQuestionList.questions, function(question, i) { return question.id });
  var index = $.inArray(serverResponse[0].question.id, tempArray);

  viewRenderAnswerable(roomQuestionList.questions[index]);
}

//when the user clicks on answer, send an ajax request to server.
function controllerAnswer(){
  console.log("this question was just answered!");
  // now go tell the server this question was answered!
  // TODO - this is one level higher than vote because of the nesting
  // that is happening - it shouldn't be.
  var question_id = $(this.parentElement.parentElement).data().val;

  var url = "/json/questions/" + question_id + "/answered";

  $.ajax({
      url: url,
      type: "POST",
      data: { question: {id: question_id}},
      success: controllerUpdateAnswer
    });
}

//when the server comes back, update the model and display
function controllerUpdateAnswer(serverResponse){
  //remove from the model - find it in the model.  then mark it answered
  var tempArray = $.map(roomQuestionList.questions, function(question, i) { return question.id });
  var index = $.inArray(serverResponse[0].question.id, tempArray);
  roomQuestionList.questions[index].answer();

  //remove from the dom
  viewRemoveQuestion(roomQuestionList.questions[index]);
}

function redisplay(){
  //delete this shit.
  elems = pckry.getItemElements();
  for (var i=0; i<elems.length; i++){
    pckry.remove(elems[i]);
  }

  //sort local model
  roomQuestionList.sort();

  //build this shit.
  numberOfQuestions = roomQuestionList.questions.length;
  for( i=0; i<numberOfQuestions; i++){
    var question = roomQuestionList.questions[i];

    var colors = ["purple", "orange", "red", "blue", "yellow", "green"];
    var outerDiv = $('
');

    var innerDiv = $("
");
    innerDiv.text(question.details);

    if (question.votes >= 5) {
      innerDiv.css("background", "red");
    } else if ((question.votes >= 3) && (question.votes < 5)) {
      innerDiv.css("background", "yellow");
    } else if (question.votes < 2) {
      innerDiv.css("background", "green");
    }

    // build the upvote button & attach it to the inner div
    var upButton = $('
⊕
');
    innerDiv.append(upButton);

    //build the votes div
    var votesDiv = $("
"+question.votes+"
");
    innerDiv.append(votesDiv);

    //append the div with the new question.
    outerDiv.append(innerDiv);

    $('div.packery').append(outerDiv);
    pckry.prepended( outerDiv );
  }

  //should we remove answerable here?
  //setTimeout(controllerAnswerableSetup(),200);
}

function viewToggleList() {
  $("p").hide();
  $("h1").click(function() {
    $(this).next().slideToggle(300);
  });
}

function timedRefresh(timeoutPeriod) {

  var answerTO = timeoutPeriod + 2000;
  setTimeout(redisplay, timeoutPeriod);
  setTimeout(controllerAnswerableSetup, answerTO);
}

window.onload = function(){

  controllerSetup();

  viewFormListener();
  viewAddDelegatedListeners();

  viewToggleList();
  timedRefresh(10000);

};<|endoftext|>