<commit_before>//= require jquery
//= require jquery-ui

//= require jquery/jquery.ui.menubar
//= require select2-4.0.0/dist/js/select2.min.js

if(typeof String.prototype.endsWith === "undefined")
	String.prototype.endsWith = function(suffix) {
	    return this.indexOf(suffix, this.length - suffix.length) !== -1;
	};

this.CMEditorMenu = (function(){
	"use strict";

	function CMEditorMenu(cmeditor, rootElem, options, instanceName){
		var self = this;
		self.state = {};

		self.state.instanceNo = CMEditorMenu.instanciated++;
		self.state.instanceName = instanceName !== undefined ? instanceName : "";

		self.cmeditor = cmeditor;
		self.rootElem = rootElem = $(rootElem);
		self.options  = options  = options !== undefined ? options : {};

		initMenus(self);
		registerMenuCallbacks(self);
		decorateMenuItems(self);
		initDialogs(self);


		self.menuBar = self.rootElem.find(".menu").menubar();

		self.cmeditor.focus();

		registerInstance(self.state.instanceName, self.state.instanceNo, self);
	}

	/*************************************************************************
	 *                    Begin 'static' methods                             *
	 *************************************************************************/
	var clazz = CMEditorMenu;

	clazz.instanciated = 0;
	clazz.instancesNumber = {};
	clazz.instancesString = {};
	clazz.instances = [];

	/*
	 * Logs to the console. If possible prefixed by class name, instance number. The default logLevel is INFO.
	 * Possible values are: ERROR, WARNING, INFO, DEBUG. If Data is supplied, its entries will be printed
	 * one per line
	 *
	 * Possible Parameter combinations:
	 * Message (String), [Loglevel (String, "INFO"), [Data (List of Objects)]]
	 * Instance (Object), Message (String), [Loglevel (String, "INFO"), [Data (Object|List of Objects)]]]
	 */
	var LOGLEVELS = {ERROR: 0, WARNING: 5, INFO: 10, DEBUG: 15}
	var log = clazz.log = function(arg0, arg1, arg2, arg3){
		var className = ((typeof clazz.name != "undefined") ? clazz.name : "IE,really?");
		var instance = "";
		var message = "";
		var logLevel = LOGLEVELS.INFO;
		var data = [];

		if(arg0 instanceof clazz){
			instance = " #" + arg0.state.instanceNo + " '" + arg0.state.instanceName +"'";
			message = arg1;
			logLevel = (typeof arg2 != "undefined") ? LOGLEVELS[arg2] : LOGLEVELS.INFO;
			data = ((typeof arg3 != "undefined")? ((arg3 instanceof Array)? arg3 : [arg3]) : []);
		}else{
			message = arg0;
			logLevel = (typeof arg1 != "undefined") ? LOGLEVELS[arg1] : LOGLEVELS.INFO;
			data = ((typeof arg2 != "undefined")? ((arg2 instanceof Array)? arg2 : [arg2]) : []);
		}

		if(logLevel == LOGLEVELS.DEBUG)    var logF = function(data){console.log(data);}
		if(logLevel == LOGLEVELS.INFO)     var logF = function(data){console.info(data);}
		if(logLevel == LOGLEVELS.WARNING)  var logF = function(data){console.warn(data);}
		if(logLevel == LOGLEVELS.ERROR)    var logF = function(data){console.error(data);}

		logF(className + instance + ": " + message);
		if(data.length != 0){
			console.groupCollapsed != undefined && data.length > 1 && console.groupCollapsed();
			for(var i=0; i<data.length; i++){
				logF(data[i]);
			}
			console.groupEnd != undefined && data.length > 1 &&  console.groupEnd();
		}
	}

	/*
	 * Registers an instance so that it can be accessed with `getInstance`
	 */
	var registerInstance = clazz.registerInstance = function(instanceName, instanceNo, instance){
		clazz.instancesString[instanceName] = instance;
		clazz.instancesNumber[instanceNo]   = instance;
		clazz.instances.push(instance);
		log("registered new CMEditorMenu instance #" + instanceNo + " '" + instanceName + "'", "INFO");
	}

	/*
	 * Returns an instance of this class
	 *
	 * Parameters: identifier (String|Number): the instance name or number
	 */
	 var getInstance = clazz.getInstance = function(identifier){
	 	if(typeof identifier == "number")
	 		return clazz.instancesNumber[identifier];
	 	else
	 		return clazz.instancesString[identifier];
	}

	/*
	 * Returns all instances of this class
	 */
	 var getInstances = clazz.getInstances = function(){
	 	return clazz.instances;
	}

	/*************************************************************************
	 *                    Begin 'private' methods                            *
	 *************************************************************************/

	/*
	 * Initialises menu objects where the keys are the menu items' anchor's names and the values are callbacks
	 */
	function initMenus(self){
		self.menus = {};

		self.menus.fileMenu = {
			new: function(cm) {
				var nameElem = self.dialogs.newFileDialog.find("input[name=name]");
				var folderElem = self.dialogs.newFileDialog.find("input[name=folder]");

				nameElem.val("");
				folderElem.val("/");

				var buttons = {};
				buttons[self.options.menu.messages.buttons.cancel] = function(){
					self.dialogs.newFileDialog.dialog("close");
				};
				buttons[self.options.menu.messages.buttons.create] = function(){
					var name = nameElem.val().trim();
					var folder = folderElem.val().trim();

					if(name === ""){
						alert(self.options.menu.messages.errors.supplyaname);
						return;
					}
					if(folder === ""){
						folder = null;
						self.cmeditor.displayMessage(self.options.menu.messages.hints.filewillbehidden);
					}else{
						folder = folder.endsWith("/")?folder:folder+"/"
					}

					var unambigousName = self.cmeditor.getUnambiguousName(name, folder);
					if(name !== unambigousName){
						self.cmeditor.displayMessage(self.options.menu.messages.hints.numberappended);
					}

					self.cmeditor.newDoc(unambigousName, folder);
					self.dialogs.newFileDialog.dialog("close");
				};

				self.dialogs.newFileDialog.dialog("option", "defaultButton", buttons[self.options.menu.messages.buttons.create]);
				self.dialogs.newFileDialog.dialog("option", "buttons", buttons);
				self.dialogs.newFileDialog.dialog("open");
			},
			open: function(cm) {

				var errorMsg = self.dialogs.openDialog.find(".noFiles");
				errorMsg.hide(0).siblings().remove();

				var s = $("<select class=\"fileSelect\" name=\"cmeditor-menu-open-select\" multiple=\"multiple\" style=\"width:100%\"/><div class=\"fileSelectTree\" />");

				if(self.options.ajax.listURL){
					$.get(self.options.ajax.listURL, function(data){
						if (data.status == "success") {
							var available = false;
							var buttons = {};
							for(var i=0; i < data.result.length; ++i) {
								s.append($("<option />", {value: data.result[i][self.options.mapping["idField"]], text: data.result[i][self.options.mapping["name"]]}));
								available = true;
							}
							if (available == true) {
								s.appendTo(self.dialogs.openDialog);
								self.dialogs.openDialog.find(".fileSelect").select2({placeholder: self.options.menu.messages.fileselectplaceholder,
																			 allowClear: true});

								self.dialogs.openDialog.find(".fileSelectTree").fileTree({script:function(fileTreeData){
									//this is called each time the user opens a directory (including root)
									var val = $('<ul class="jqueryFileTree" style="display: none;"></ul>');

									var curPathElems = fileTreeData.dir.split("/");
									var folders = {};

									for(var i=0; i < data.result.length; ++i) {
										if(typeof data.result[i][self.options.mapping["folder"]] !== "undefined" &&
											data.result[i][self.options.mapping["folder"]] !== null) {

											var absPath = data.result[i][self.options.mapping["folder"]];
											absPath = absPath.endsWith("/") ? absPath : absPath+"/";

											if (absPath === fileTreeData.dir) {
												var fileName = data.result[i][self.options.mapping["name"]];
												var fileId = data.result[i][self.options.mapping["idField"]];
												val.append($('<li class="file ext_'+fileName+'"><a href="#" rel='+fileId+'>'+fileName+'</a></li>'));
											}else{
												//save each folder once for later adding
												var pathElems = absPath.split("/");

												if (absPath.startsWith(fileTreeData.dir) && pathElems.length - 1 == curPathElems.length){
													folders[absPath] = pathElems[pathElems.length-2];
												}
											}
										}
									}

									for(absPath in folders){
										val.append($('<li class="directory collapsed"><a href="#" rel="'+absPath+'"">'+folders[absPath]+'</a></li>'));
									}

									return val;
								}}, function(fileId){
									//this is called each time a user selects a file
									var option = self.dialogs.openDialog.find(".fileSelect option[value="+fileId+"]");
									option.attr("selected", !option.attr("selected")).trigger("change");
								});

								//workaround a width calculation bug in select2
								self.dialogs.openDialog.find(".select2-search__field").css("width", "auto");

								buttons[self.options.menu.messages.buttons.cancel] = function() {
									 self.dialogs.openDialog.dialog( "close" );
								};
								buttons[self.options.menu.messages.buttons.open] = function() {
									var vals = self.dialogs.openDialog.find(".fileSelect").val();
									for (var i in vals) {
										self.cmeditor.open(vals[i]);
									}
									self.dialogs.openDialog.dialog( "close" );
								};
							} else {
								buttons[self.options.menu.messages.buttons.cancel] = function() {
									 self.dialogs.openDialog.dialog( "close" );
								};
								errorMsg.show(0)
							}

							self.dialogs.openDialog.dialog("option", "defaultButton", buttons[self.options.menu.messages.buttons.open]);
							self.dialogs.openDialog.dialog("option", "buttons", buttons);
							self.dialogs.openDialog.dialog("open");
						} else {
							self.cmeditor.displayMessage(data.msg ? data.msg : "An unknown error occured");
						}
					}).fail(function(XMLHttpRequest,textStatus,errorThrown){self.cmeditor.displayMessage(self.options.menu.messages.errorIntro+" "+ textStatus +" " + errorThrown);});
				}
			},
			save: function(cm) { self.cmeditor.saveDoc(); },<commit_msg>set focus to input in open dialog<commit_after>//= require jquery
//= require jquery-ui

//= require jquery/jquery.ui.menubar
//= require select2-4.0.0/dist/js/select2.min.js

if(typeof String.prototype.endsWith === "undefined")
	String.prototype.endsWith = function(suffix) {
	    return this.indexOf(suffix, this.length - suffix.length) !== -1;
	};

this.CMEditorMenu = (function(){
	"use strict";

	function CMEditorMenu(cmeditor, rootElem, options, instanceName){
		var self = this;
		self.state = {};

		self.state.instanceNo = CMEditorMenu.instanciated++;
		self.state.instanceName = instanceName !== undefined ? instanceName : "";

		self.cmeditor = cmeditor;
		self.rootElem = rootElem = $(rootElem);
		self.options  = options  = options !== undefined ? options : {};

		initMenus(self);
		registerMenuCallbacks(self);
		decorateMenuItems(self);
		initDialogs(self);


		self.menuBar = self.rootElem.find(".menu").menubar();

		self.cmeditor.focus();

		registerInstance(self.state.instanceName, self.state.instanceNo, self);
	}

	/*************************************************************************
	 *                    Begin 'static' methods                             *
	 *************************************************************************/
	var clazz = CMEditorMenu;

	clazz.instanciated = 0;
	clazz.instancesNumber = {};
	clazz.instancesString = {};
	clazz.instances = [];

	/*
	 * Logs to the console. If possible prefixed by class name, instance number. The default logLevel is INFO.
	 * Possible values are: ERROR, WARNING, INFO, DEBUG. If Data is supplied, its entries will be printed
	 * one per line
	 *
	 * Possible Parameter combinations:
	 * Message (String), [Loglevel (String, "INFO"), [Data (List of Objects)]]
	 * Instance (Object), Message (String), [Loglevel (String, "INFO"), [Data (Object|List of Objects)]]]
	 */
	var LOGLEVELS = {ERROR: 0, WARNING: 5, INFO: 10, DEBUG: 15}
	var log = clazz.log = function(arg0, arg1, arg2, arg3){
		var className = ((typeof clazz.name != "undefined") ? clazz.name : "IE,really?");
		var instance = "";
		var message = "";
		var logLevel = LOGLEVELS.INFO;
		var data = [];

		if(arg0 instanceof clazz){
			instance = " #" + arg0.state.instanceNo + " '" + arg0.state.instanceName +"'";
			message = arg1;
			logLevel = (typeof arg2 != "undefined") ? LOGLEVELS[arg2] : LOGLEVELS.INFO;
			data = ((typeof arg3 != "undefined")? ((arg3 instanceof Array)? arg3 : [arg3]) : []);
		}else{
			message = arg0;
			logLevel = (typeof arg1 != "undefined") ? LOGLEVELS[arg1] : LOGLEVELS.INFO;
			data = ((typeof arg2 != "undefined")? ((arg2 instanceof Array)? arg2 : [arg2]) : []);
		}

		if(logLevel == LOGLEVELS.DEBUG)    var logF = function(data){console.log(data);}
		if(logLevel == LOGLEVELS.INFO)     var logF = function(data){console.info(data);}
		if(logLevel == LOGLEVELS.WARNING)  var logF = function(data){console.warn(data);}
		if(logLevel == LOGLEVELS.ERROR)    var logF = function(data){console.error(data);}

		logF(className + instance + ": " + message);
		if(data.length != 0){
			console.groupCollapsed != undefined && data.length > 1 && console.groupCollapsed();
			for(var i=0; i<data.length; i++){
				logF(data[i]);
			}
			console.groupEnd != undefined && data.length > 1 &&  console.groupEnd();
		}
	}

	/*
	 * Registers an instance so that it can be accessed with `getInstance`
	 */
	var registerInstance = clazz.registerInstance = function(instanceName, instanceNo, instance){
		clazz.instancesString[instanceName] = instance;
		clazz.instancesNumber[instanceNo]   = instance;
		clazz.instances.push(instance);
		log("registered new CMEditorMenu instance #" + instanceNo + " '" + instanceName + "'", "INFO");
	}

	/*
	 * Returns an instance of this class
	 *
	 * Parameters: identifier (String|Number): the instance name or number
	 */
	 var getInstance = clazz.getInstance = function(identifier){
	 	if(typeof identifier == "number")
	 		return clazz.instancesNumber[identifier];
	 	else
	 		return clazz.instancesString[identifier];
	}

	/*
	 * Returns all instances of this class
	 */
	 var getInstances = clazz.getInstances = function(){
	 	return clazz.instances;
	}

	/*************************************************************************
	 *                    Begin 'private' methods                            *
	 *************************************************************************/

	/*
	 * Initialises menu objects where the keys are the menu items' anchor's names and the values are callbacks
	 */
	function initMenus(self){
		self.menus = {};

		self.menus.fileMenu = {
			new: function(cm) {
				var nameElem = self.dialogs.newFileDialog.find("input[name=name]");
				var folderElem = self.dialogs.newFileDialog.find("input[name=folder]");

				nameElem.val("");
				folderElem.val("/");

				var buttons = {};
				buttons[self.options.menu.messages.buttons.cancel] = function(){
					self.dialogs.newFileDialog.dialog("close");
				};
				buttons[self.options.menu.messages.buttons.create] = function(){
					var name = nameElem.val().trim();
					var folder = folderElem.val().trim();

					if(name === ""){
						alert(self.options.menu.messages.errors.supplyaname);
						return;
					}
					if(folder === ""){
						folder = null;
						self.cmeditor.displayMessage(self.options.menu.messages.hints.filewillbehidden);
					}else{
						folder = folder.endsWith("/")?folder:folder+"/"
					}

					var unambigousName = self.cmeditor.getUnambiguousName(name, folder);
					if(name !== unambigousName){
						self.cmeditor.displayMessage(self.options.menu.messages.hints.numberappended);
					}

					self.cmeditor.newDoc(unambigousName, folder);
					self.dialogs.newFileDialog.dialog("close");
				};

				self.dialogs.newFileDialog.dialog("option", "defaultButton", buttons[self.options.menu.messages.buttons.create]);
				self.dialogs.newFileDialog.dialog("option", "buttons", buttons);
				self.dialogs.newFileDialog.dialog("open");
			},
			open: function(cm) {

				var errorMsg = self.dialogs.openDialog.find(".noFiles");
				errorMsg.hide(0).siblings().remove();

				var s = $("<select class=\"fileSelect\" name=\"cmeditor-menu-open-select\" multiple=\"multiple\" style=\"width:100%\"/><div class=\"fileSelectTree\" />");

				if(self.options.ajax.listURL){
					$.get(self.options.ajax.listURL, function(data){
						if (data.status == "success") {
							var available = false;
							var buttons = {};
							for(var i=0; i < data.result.length; ++i) {
								s.append($("<option />", {value: data.result[i][self.options.mapping["idField"]], text: data.result[i][self.options.mapping["name"]]}));
								available = true;
							}
							if (available == true) {
								s.appendTo(self.dialogs.openDialog);
								self.dialogs.openDialog.find(".fileSelect").select2({placeholder: self.options.menu.messages.fileselectplaceholder,
																			 allowClear: true});

								self.dialogs.openDialog.find(".fileSelectTree").fileTree({script:function(fileTreeData){
									//this is called each time the user opens a directory (including root)
									var val = $('<ul class="jqueryFileTree" style="display: none;"></ul>');

									var curPathElems = fileTreeData.dir.split("/");
									var folders = {};

									for(var i=0; i < data.result.length; ++i) {
										if(typeof data.result[i][self.options.mapping["folder"]] !== "undefined" &&
											data.result[i][self.options.mapping["folder"]] !== null) {

											var absPath = data.result[i][self.options.mapping["folder"]];
											absPath = absPath.endsWith("/") ? absPath : absPath+"/";

											if (absPath === fileTreeData.dir) {
												var fileName = data.result[i][self.options.mapping["name"]];
												var fileId = data.result[i][self.options.mapping["idField"]];
												val.append($('<li class="file ext_'+fileName+'"><a href="#" rel='+fileId+'>'+fileName+'</a></li>'));
											}else{
												//save each folder once for later adding
												var pathElems = absPath.split("/");

												if (absPath.startsWith(fileTreeData.dir) && pathElems.length - 1 == curPathElems.length){
													folders[absPath] = pathElems[pathElems.length-2];
												}
											}
										}
									}

									for(absPath in folders){
										val.append($('<li class="directory collapsed"><a href="#" rel="'+absPath+'"">'+folders[absPath]+'</a></li>'));
									}

									return val;
								}}, function(fileId){
									//this is called each time a user selects a file
									var option = self.dialogs.openDialog.find(".fileSelect option[value="+fileId+"]");
									option.attr("selected", !option.attr("selected")).trigger("change");
								});

								//workaround a width calculation bug in select2
								self.dialogs.openDialog.find(".select2-search__field").css("width", "auto");

								buttons[self.options.menu.messages.buttons.cancel] = function() {
									 self.dialogs.openDialog.dialog( "close" );
								};
								buttons[self.options.menu.messages.buttons.open] = function() {
									var vals = self.dialogs.openDialog.find(".fileSelect").val();
									for (var i in vals) {
										self.cmeditor.open(vals[i]);
									}
									self.dialogs.openDialog.dialog( "close" );
								};
							} else {
								buttons[self.options.menu.messages.buttons.cancel] = function() {
									 self.dialogs.openDialog.dialog( "close" );
								};
								errorMsg.show(0)
							}

							self.dialogs.openDialog.dialog("option", "defaultButton", buttons[self.options.menu.messages.buttons.open]);
							self.dialogs.openDialog.dialog("option", "buttons", buttons);
							self.dialogs.openDialog.dialog("open");

							//there is no focus method, so open and close once to set focus
							self.dialogs.openDialog.find(".fileSelect").select2("open");
							self.dialogs.openDialog.find(".fileSelect").select2("close");
						} else {
							self.cmeditor.displayMessage(data.msg ? data.msg : "An unknown error occured");
						}
					}).fail(function(XMLHttpRequest,textStatus,errorThrown){self.cmeditor.displayMessage(self.options.menu.messages.errorIntro+" "+ textStatus +" " + errorThrown);});
				}
			},
			save: function(cm) { self.cmeditor.saveDoc(); },
{'fraction_non_alphanumeric': 0.1857996346220313, 'fraction_numerical': 0.005036290919863724, 'mean_word_length': 3.2461215932914045, 'pattern_counts': {'":': 2, '<': 35, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5752855', 'n_tokens_mistral': 7783, 'n_tokens_neox': 6040, 'n_words': 1181}