<commit_before>//   (c) 2004-2006 by MulchProductions, www.mulchprod.de
//   (c) 2007-2012 by Kajona, www.kajona.de
//       Published under the GNU LGPL v2.1, see /system/licence_lgpl.txt
//       $Id$

if (typeof KAJONA == "undefined") {
	var KAJONA = {
		util: {},
		portal: {
			lang: {}
		},
		admin: {
			lang: {}
		}
	};
}

/*
 * -------------------------------------------------------------------------
 * Global functions
 * -------------------------------------------------------------------------
 */

/*
 * -------------------------------------------------------------------------
 * Portaleditor-specific functions
 * -------------------------------------------------------------------------
 */

KAJONA.admin.portaleditor = {
	objPlaceholderWithElements: {},

    initPortaleditor : function() {

        KAJONA.admin.loader.loadFile([
            "/core/module_system/admin/scripts/jqueryui/jquery-ui.custom.min.js",
            "/core/module_system/admin/scripts/jqueryui/css/smoothness/jquery-ui.custom.css",
            "/core/module_system/admin/scripts/jquery/jquery.htmlClean.min.js",
            "/core/module_pages/admin/scripts/rangy/rangy-core.js",
            "/core/module_pages/admin/scripts/halloeditor/hallo-min.js",
            "/core/module_pages/admin/scripts/halloeditor/hallo.css",
            "/core/module_pages/admin/scripts/halloeditor/fontawesome/css/font-awesome.css",
        ], function() {

            KAJONA.admin.portaleditor.RTE.init();
        });

    },

	showActions: function (elementSysId) {
	    $('#container_'+elementSysId).attr('class', 'peContainerHover');
	    $('#menu_'+elementSysId).attr('class', 'menuHover');
	},

	hideActions: function (elementSysId) {
		$('#container_'+elementSysId).attr('class', 'peContainerOut');
		$('#menu_'+elementSysId).attr('class', 'menuOut');
	},

	switchEnabled: function (bitStatus) {
	    var strStatus = bitStatus == true ? 'true' : 'false';
		var url = window.location.href;
		var anchorPos = url.indexOf('#');
		if (anchorPos != -1) {
	    	url = url.substring(0, anchorPos);
		}

	    url = url.replace('&pe=false', '');
	    url = url.replace('&pe=true', '');
	    url = url.replace('?pe=false', '');
	    url = url.replace('?pe=true', '');

	    if(url.indexOf('?') == -1) {
	        window.location.replace(url+'?pe='+strStatus);
	    } else {
	        window.location.replace(url+'&pe='+strStatus);
	    }
	},

	openDialog: function (strUrl) {
		peDialog.setContentIFrame(strUrl);
		peDialog.init();
	},

	closeDialog: function () {
	    var bitClose = confirm(KAJONA.admin.lang["pe_dialog_close_warning"]);
	    if(bitClose) {
	    	peDialog.hide();

	    	//reset iframe
	    	peDialog.setContentRaw("");
	    }
	},

	addNewElements: function (strPlaceholder, strPlaceholderName, arrElements) {
		this.objPlaceholderWithElements[strPlaceholder] = {
			placeholderName: strPlaceholderName,
			elements: arrElements
		};
	}

};

KAJONA.admin.portaleditor.RTE = {};
KAJONA.admin.portaleditor.RTE.modifiedFields = {};

KAJONA.admin.portaleditor.RTE.savePage = function () {

    //console.group('savePage');

    $.each(KAJONA.admin.portaleditor.RTE.modifiedFields, function (key, value) {
        var keySplitted = key.split('#');

        var data = {
            systemid: keySplitted[0],
            property: keySplitted[1],
            value: value
        };

        $.post(KAJONA_WEBPATH + '/xml.php?admin=1&module=pages_content&action=updateObjectProperty', data, function () {
            //console.warn('server response');
            //console.log(this.responseText);
        });
    });
    //console.groupEnd('savePage');
    $('#savePageLink > img').attr('src', $('#savePageLink > img').attr('src').replace(".png", "Disabled.png"));
    KAJONA.admin.portaleditor.RTE.modifiedFields = {};
};

KAJONA.admin.portaleditor.RTE.pasteHandler = function (event) {
    //disable resizing handles in FF
    document.execCommand("enableObjectResizing", false, false);

    var editable = $(event.currentTarget);

    //find the current cursor-position before creating the paste-container, used lateron
    var sel = rangy.getSelection();
    //var range = rangy.createRange();

    var offset = editable.offset();
    $('body').append('

');
    var pasteContainer = $('#pasteContainer');

    var keySplitted = editable.attr('data-kajona-editable').split('#');
    var isPlaintext = (keySplitted[2] && keySplitted[2] == 'plain') ? true : false;
    if (isPlaintext) {
        var htmlCleanConfig = {
            allowedTags:['']
        };
    } else {
        var htmlCleanConfig = {
            allowedTags:['br', 'p', 'ul', 'ol', 'li']
        };
    }

    editable.blur();
    pasteContainer.focus();

    window.setTimeout(function () {
        event.stopPropagation();

        var content = pasteContainer.html();
        var cleanContent = $.htmlClean.trim($.htmlClean(content, htmlCleanConfig));
        //console.warn('paste val: ', content, cleanContent);
        pasteContainer.html('');
        pasteContainer.remove();

        //enable resizing handles in FF again
        document.execCommand("enableObjectResizing", false, true);
        editable.focus();

        //update the old selection
        var strOldHtml = sel.anchorNode.data;
        var strNewHtml = strOldHtml.substr(0, sel.anchorOffset) + cleanContent + strOldHtml.substring(sel.focusOffset);
        sel.anchorNode.data = strNewHtml;
        //set the cursor to the end of the selection
        sel.collapse(sel.anchorNode, sel.anchorOffset + cleanContent.length);
    }, 10);
};

KAJONA.admin.portaleditor.RTE.init = function () {
    //console.log("RTE editor init");
    //loop over all editables
    $('*[data-kajona-editable]').each(function () {
        var editable = $(this);
        var keySplitted = editable.attr('data-kajona-editable').split('#');
        var isPlaintext = (keySplitted[2] && keySplitted[2] == 'plain') ? true : false;

        //attach paste handler
        editable.bind('paste', KAJONA.admin.portaleditor.RTE.pasteHandler);

        //prevent enter key when editable is a plaintext field
        if (isPlaintext) {
            editable.keypress(function (event) {
                if (event.which == 13) {
                    return false;
                }
            });
        }

        //always disable drag&drop
        editable.bind('drop drag', function () {
            return false;
        });

        //generate hallo editor config
        var halloConfig = {
            plugins: {
                halloreundo: {}
            },
            modified: function (event, obj) {
                var attr = $(this).attr('data-kajona-editable');

                $('#savePageLink > img').attr('src', $('#savePageLink > img').attr('src').replace("Disabled", ""));
                KAJONA.admin.portaleditor.RTE.modifiedFields[attr] = obj.content;
                //console.log('modified field', attr, obj.content);
            }
        };

        if (!isPlaintext) {
            halloConfig.plugins = {
                halloformat: {},
                hallolists: {},
                halloreundo: {}
            };
        }

        //finally init hallo editor
        editable.hallo(halloConfig);
    });

    // warn user if there are unsaved changes when leaving the page
    $(window).on('beforeunload', function () {
        // check if there are unsaved changes
        var unsavedChanges = false;
        $.each(KAJONA.admin.portaleditor.RTE.modifiedFields, function () {
            unsavedChanges = true;
            return false;
        });

        if (unsavedChanges) {
            return KAJONA.admin.lang.pe_rte_unsavedChanges;
        }
    });
};

/**
 * Loader for dynamically loading additional js and css files after the onDOMReady event
 *
 */
KAJONA.admin.loader = new KAJONA.util.Loader();

KAJONA.admin.tooltip = {
    initTooltip : function() {
        KAJONA.admin.loader.loadFile(['/core/module_system/admin/scripts/qtip2/jquery.qtip.min.js', '/core/module_system/admin/scripts/qtip2/jquery.qtip.min.css'], function() {

            $('*[rel=tooltip]').qtip({
                position: {
                    viewport: $(window)
                },
                style: {
                    classes: 'ui-tooltip-youtube ui-tooltip-shadow'
                }
            });
        });
    },

    addTooltip : function(objElement, strText) {
        KAJONA.admin.loader.loadFile(['/core/module_system/admin/scripts/qtip2/jquery.qtip.min.js', '/core/module_system/admin/scripts/qtip2/jquery.qtip.min.css'], function() {

            if(strText) {
                $(objElement).qtip({
                    position: {
                        viewport: $(window)
                    },
                    style: {
                        classes: 'ui-tooltip-youtube ui-tooltip-shadow'
                    },
                    content : {
                        text: strText
                    }
                });
            }
            else {
                $(objElement).qtip({
                    position: {
                        viewport: $(window)
                    },
                    style: {
                        classes: 'ui-tooltip-youtube ui-tooltip-shadow'
                    }
                });
            }
        });
    }

};

KAJONA.admin.tooltip.initTooltip();<commit_msg>typo in js file<commit_after>//   (c) 2004-2006 by MulchProductions, www.mulchprod.de
//   (c) 2007-2012 by Kajona, www.kajona.de
//       Published under the GNU LGPL v2.1, see /system/licence_lgpl.txt
//       $Id$

if (typeof KAJONA == "undefined") {
	var KAJONA = {
		util: {},
		portal: {
			lang: {}
		},
		admin: {
			lang: {}
		}
	};
}

/*
 * -------------------------------------------------------------------------
 * Global functions
 * -------------------------------------------------------------------------
 */

/*
 * -------------------------------------------------------------------------
 * Portaleditor-specific functions
 * -------------------------------------------------------------------------
 */

KAJONA.admin.portaleditor = {
	objPlaceholderWithElements: {},

    initPortaleditor : function() {

        KAJONA.admin.loader.loadFile([
            "/core/module_system/admin/scripts/jqueryui/jquery-ui.custom.min.js",
            "/core/module_system/admin/scripts/jqueryui/css/smoothness/jquery-ui.custom.css",
            "/core/module_system/admin/scripts/jquery/jquery.htmlClean.min.js",
            "/core/module_pages/admin/scripts/rangy/rangy-core.js",
            "/core/module_pages/admin/scripts/halloeditor/hallo-min.js",
            "/core/module_pages/admin/scripts/halloeditor/hallo.css",
            "/core/module_pages/admin/scripts/halloeditor/fontawesome/css/font-awesome.css"
        ], function() {

            KAJONA.admin.portaleditor.RTE.init();
        });

    },

	showActions: function (elementSysId) {
	    $('#container_'+elementSysId).attr('class', 'peContainerHover');
	    $('#menu_'+elementSysId).attr('class', 'menuHover');
	},

	hideActions: function (elementSysId) {
		$('#container_'+elementSysId).attr('class', 'peContainerOut');
		$('#menu_'+elementSysId).attr('class', 'menuOut');
	},

	switchEnabled: function (bitStatus) {
	    var strStatus = bitStatus == true ? 'true' : 'false';
		var url = window.location.href;
		var anchorPos = url.indexOf('#');
		if (anchorPos != -1) {
	    	url = url.substring(0, anchorPos);
		}

	    url = url.replace('&pe=false', '');
	    url = url.replace('&pe=true', '');
	    url = url.replace('?pe=false', '');
	    url = url.replace('?pe=true', '');

	    if(url.indexOf('?') == -1) {
	        window.location.replace(url+'?pe='+strStatus);
	    } else {
	        window.location.replace(url+'&pe='+strStatus);
	    }
	},

	openDialog: function (strUrl) {
		peDialog.setContentIFrame(strUrl);
		peDialog.init();
	},

	closeDialog: function () {
	    var bitClose = confirm(KAJONA.admin.lang["pe_dialog_close_warning"]);
	    if(bitClose) {
	    	peDialog.hide();

	    	//reset iframe
	    	peDialog.setContentRaw("");
	    }
	},

	addNewElements: function (strPlaceholder, strPlaceholderName, arrElements) {
		this.objPlaceholderWithElements[strPlaceholder] = {
			placeholderName: strPlaceholderName,
			elements: arrElements
		};
	}

};

KAJONA.admin.portaleditor.RTE = {};
KAJONA.admin.portaleditor.RTE.modifiedFields = {};

KAJONA.admin.portaleditor.RTE.savePage = function () {

    //console.group('savePage');

    $.each(KAJONA.admin.portaleditor.RTE.modifiedFields, function (key, value) {
        var keySplitted = key.split('#');

        var data = {
            systemid: keySplitted[0],
            property: keySplitted[1],
            value: value
        };

        $.post(KAJONA_WEBPATH + '/xml.php?admin=1&module=pages_content&action=updateObjectProperty', data, function () {
            //console.warn('server response');
            //console.log(this.responseText);
        });
    });
    //console.groupEnd('savePage');
    $('#savePageLink > img').attr('src', $('#savePageLink > img').attr('src').replace(".png", "Disabled.png"));
    KAJONA.admin.portaleditor.RTE.modifiedFields = {};
};

KAJONA.admin.portaleditor.RTE.pasteHandler = function (event) {
    //disable resizing handles in FF
    document.execCommand("enableObjectResizing", false, false);

    var editable = $(event.currentTarget);

    //find the current cursor-position before creating the paste-container, used lateron
    var sel = rangy.getSelection();
    //var range = rangy.createRange();

    var offset = editable.offset();
    $('body').append('

');
    var pasteContainer = $('#pasteContainer');

    var keySplitted = editable.attr('data-kajona-editable').split('#');
    var isPlaintext = (keySplitted[2] && keySplitted[2] == 'plain') ? true : false;
    if (isPlaintext) {
        var htmlCleanConfig = {
            allowedTags:['']
        };
    } else {
        var htmlCleanConfig = {
            allowedTags:['br', 'p', 'ul', 'ol', 'li']
        };
    }

    editable.blur();
    pasteContainer.focus();

    window.setTimeout(function () {
        event.stopPropagation();

        var content = pasteContainer.html();
        var cleanContent = $.htmlClean.trim($.htmlClean(content, htmlCleanConfig));
        //console.warn('paste val: ', content, cleanContent);
        pasteContainer.html('');
        pasteContainer.remove();

        //enable resizing handles in FF again
        document.execCommand("enableObjectResizing", false, true);
        editable.focus();

        //update the old selection
        var strOldHtml = sel.anchorNode.data;
        var strNewHtml = strOldHtml.substr(0, sel.anchorOffset) + cleanContent + strOldHtml.substring(sel.focusOffset);
        sel.anchorNode.data = strNewHtml;
        //set the cursor to the end of the selection
        sel.collapse(sel.anchorNode, sel.anchorOffset + cleanContent.length);
    }, 10);
};

KAJONA.admin.portaleditor.RTE.init = function () {
    //console.log("RTE editor init");
    //loop over all editables
    $('*[data-kajona-editable]').each(function () {
        var editable = $(this);
        var keySplitted = editable.attr('data-kajona-editable').split('#');
        var isPlaintext = (keySplitted[2] && keySplitted[2] == 'plain') ? true : false;

        //attach paste handler
        editable.bind('paste', KAJONA.admin.portaleditor.RTE.pasteHandler);

        //prevent enter key when editable is a plaintext field
        if (isPlaintext) {
            editable.keypress(function (event) {
                if (event.which == 13) {
                    return false;
                }
            });
        }

        //always disable drag&drop
        editable.bind('drop drag', function () {
            return false;
        });

        //generate hallo editor config
        var halloConfig = {
            plugins: {
                halloreundo: {}
            },
            modified: function (event, obj) {
                var attr = $(this).attr('data-kajona-editable');

                $('#savePageLink > img').attr('src', $('#savePageLink > img').attr('src').replace("Disabled", ""));
                KAJONA.admin.portaleditor.RTE.modifiedFields[attr] = obj.content;
                //console.log('modified field', attr, obj.content);
            }
        };

        if (!isPlaintext) {
            halloConfig.plugins = {
                halloformat: {},
                hallolists: {},
                halloreundo: {}
            };
        }

        //finally init hallo editor
        editable.hallo(halloConfig);
    });

    // warn user if there are unsaved changes when leaving the page
    $(window).on('beforeunload', function () {
        // check if there are unsaved changes
        var unsavedChanges = false;
        $.each(KAJONA.admin.portaleditor.RTE.modifiedFields, function () {
            unsavedChanges = true;
            return false;
        });

        if (unsavedChanges) {
            return KAJONA.admin.lang.pe_rte_unsavedChanges;
        }
    });
};

/**
 * Loader for dynamically loading additional js and css files after the onDOMReady event
 *
 */
KAJONA.admin.loader = new KAJONA.util.Loader();

KAJONA.admin.tooltip = {
    initTooltip : function() {
        KAJONA.admin.loader.loadFile(['/core/module_system/admin/scripts/qtip2/jquery.qtip.min.js', '/core/module_system/admin/scripts/qtip2/jquery.qtip.min.css'], function() {

            $('*[rel=tooltip]').qtip({
                position: {
                    viewport: $(window)
                },
                style: {
                    classes: 'ui-tooltip-youtube ui-tooltip-shadow'
                }
            });
        });
    },

    addTooltip : function(objElement, strText) {
        KAJONA.admin.loader.loadFile(['/core/module_system/admin/scripts/qtip2/jquery.qtip.min.js', '/core/module_system/admin/scripts/qtip2/jquery.qtip.min.css'], function() {

            if(strText) {
                $(objElement).qtip({
                    position: {
                        viewport: $(window)
                    },
                    style: {
                        classes: 'ui-tooltip-youtube ui-tooltip-shadow'
                    },
                    content : {
                        text: strText
                    }
                });
            }
            else {
                $(objElement).qtip({
                    position: {
                        viewport: $(window)
                    },
                    style: {
                        classes: 'ui-tooltip-youtube ui-tooltip-shadow'
                    }
                });
            }
        });
    }

};

KAJONA.admin.tooltip.initTooltip();<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/*global gadgets */
var gadgets;

/**
 * @fileoverview All functions in this file should be treated as deprecated legacy routines.
 * Gadget authors are explicitly discouraged from using any of them.
 */

var JSON = window.JSON || gadgets.json;

/**
 * @deprecated
 */
var _IG_Prefs = (function() {
  var instance = null;

  var _IG_Prefs = function() {
    if (!instance) {
      instance = new gadgets.Prefs();
      instance.setDontEscape_();
    }
    return instance;
  };

 _IG_Prefs._parseURL = gadgets.Prefs.parseUrl;

  return _IG_Prefs;
})();

function _IG_Fetch_wrapper(callback, obj) {
  callback(obj.data ? obj.data : "");
}

/**
 * @deprecated
 */
function _IG_FetchContent(url, callback, opt_params) {
  var params = opt_params || {};
  // This is really the only legacy parameter documented
  // at http://code.google.com/apis/gadgets/docs/remote-content.html#Params
  if (params.refreshInterval) {
    params['REFRESH_INTERVAL'] = params.refreshInterval;
  } else {
    params['REFRESH_INTERVAL'] = 3600;
  }
  // Other params, such as POST_DATA, were supported in lower case.
  // Upper-case all param keys as a convenience, since all valid values
  // are uppercased.
  for (var param in params) {
    var pvalue = params[param];
    delete params[param];
    params[param.toUpperCase()] = pvalue;
  }
  var cb = gadgets.util.makeClosure(null, _IG_Fetch_wrapper, callback);
  gadgets.io.makeRequest(url, cb, params);
}

/**
 * @deprecated
 */
function _IG_FetchXmlContent(url, callback, opt_params) {
  var params = opt_params || {};
  if (params.refreshInterval) {
    params['REFRESH_INTERVAL'] = params.refreshInterval;
  } else {
    params['REFRESH_INTERVAL'] = 3600;
  }
  params.CONTENT_TYPE = "DOM";
  var cb = gadgets.util.makeClosure(null, _IG_Fetch_wrapper, callback);
  gadgets.io.makeRequest(url, cb, params);
}

/**
 * @deprecated
 */
function _IG_FetchFeedAsJSON(url, callback, numItems, getDescriptions,
                             opt_params) {
  var params = opt_params || {};
  params.CONTENT_TYPE = "FEED";
  params.NUM_ENTRIES = numItems;
  params.GET_SUMMARIES = getDescriptions;
  gadgets.io.makeRequest(url,
      function(resp) {
        // special case error reporting for back-compatibility
        // see http://code.google.com/apis/gadgets/docs/legacy/remote-content.html#Fetch_JSON
        resp.data = resp.data || {};
        if (resp.errors && resp.errors.length > 0) {
          resp.data.ErrorMsg = resp.errors[0];
        }
        if (resp.data.link) {
          resp.data.URL = url;
        }
        if (resp.data.title) {
          resp.data.Title = resp.data.title;
        }
        if (resp.data.description) {
          resp.data.Description = resp.data.description;
        }
        if (resp.data.link) {
          resp.data.Link = resp.data.link;
        }
        if (resp.data.items && resp.data.items.length > 0) {
          resp.data.Entry = resp.data.items;
          for (var index = 0; index < resp.data.Entry.length; ++index) {
            var entry = resp.data.Entry[index];
            entry.Title = entry.title;
            entry.Link = entry.link;
            entry.Summary = entry.summary || entry.description;
            entry.Date = entry.pubDate;
          }
        }
        for (var ix = 0; ix < resp.data.Entry.length; ++ix) {
          var entry = resp.data.Entry[ix];
          entry.Date = (entry.Date / 1000);  // response in sec, not ms
        }
        // for Gadgets back-compatibility, return the feed obj directly
        callback(resp.data);
      }, params);
}

/**
 * @param {string} url
 * @param {Object=} opt_params
 * @deprecated
 */
function _IG_GetCachedUrl(url, opt_params) {
  var params = opt_params || {};
  params['REFRESH_INTERVAL'] = 3600;
  if (params.refreshInterval) {
    params['REFRESH_INTERVAL'] = params.refreshInterval;
  }
  return gadgets.io.getProxyUrl(url, params);
}
/**
 * @param {string} url
 * @param {Object=} opt_params
 * @deprecated
 */
function _IG_GetImageUrl(url, opt_params) {
  return _IG_GetCachedUrl(url, opt_params);
}

/**
 * @param {string} url
 * @return {Element}
 * @deprecated
 */
function _IG_GetImage(url) {
  var img = document.createElement('img');
  img.src = _IG_GetCachedUrl(url);
  return img;
}

/**
 * @deprecated
 */
function _IG_RegisterOnloadHandler(callback) {
  gadgets.util.registerOnLoadHandler(callback);
}

/**
 * _IG_Callback takes the arguments in the scope the callback is executed and
 * places them first in the argument array. MakeClosure takes the arguments
 * from the scope at callback construction and pushes them first in the array
 *
 * @deprecated
 */
function _IG_Callback(handler_func, var_args) {
  var orig_args = arguments;
  return function() {
    var combined_args = Array.prototype.slice.call(arguments);
    // call the handler with all args combined
    handler_func.apply(null,
      combined_args.concat(Array.prototype.slice.call(orig_args, 1)));
  };
}

var _args = gadgets.util.getUrlParameters;

/**
 * Fetches an object by document id.
 *
 * @param {string | Object} el The element you wish to fetch. You may pass
 *     an object in which allows this to be called regardless of whether or
 *     not the type of the input is known.
 * @return {HTMLElement} The element, if it exists in the document, or null.
 * @deprecated
 */
function _gel(el) {
  return document.getElementById ? document.getElementById(el) : null;
}

/**
 * Fetches elements by tag name.
 * This is functionally identical to document.getElementsByTagName()
 *
 * @param {string} tag The tag to match elements against.
 * @return {Array.<HTMLElement>} All elements of this tag type.
 * @deprecated
 */
function _gelstn(tag) {
  if (tag === "*" && document.all) {
    return document.all;
  }
  return document.getElementsByTagName ?
         document.getElementsByTagName(tag) : [];
}

/**
 * Fetches elements with ids matching a given regular expression.
 *
 * @param {string} tagName The tag to match elements against.
 * @param {RegEx} regex The expression to match.
 * @return {Array.<HTMLElement>} All elements of this tag type that match
 *     regex.
 * @deprecated
 */
function _gelsbyregex(tagName, regex) {
  var matchingTags = _gelstn(tagName);
  var matchingRegex = [];
  for (var i = 0, j = matchingTags.length; i < j; ++i) {
    if (regex.test(matchingTags[i].id)) {
      matchingRegex.push(matchingTags[i]);
    }
  }
  return matchingRegex;
}

/**
 * URI escapes the given string.
 * @param {string} str The string to escape.
 * @return {string} The escaped string.
 * @deprecated
 */
function _esc(str) {
  return window.encodeURIComponent ? encodeURIComponent(str) : escape(str);
}

/**
 * URI unescapes the given string.
 * @param {string} str The string to unescape.
 * @return {string} The unescaped string.
 * @deprecated
 */
function _unesc(str) {
  return window.decodeURIComponent ? decodeURIComponent(str) : unescape(str);
}

/**
 * Encodes HTML entities such as <, " and >.
 *
 * @param {string} str The string to escape.
 * @return {string} The escaped string.
 * @deprecated
 */
function _hesc(str) {
  return gadgets.util.escapeString(str);
}

/**
 * Removes HTML tags from the given input string.
 *
 * @param {string} str The string to strip.
 * @return {string} The stripped string.
 * @deprecated
 */
function _striptags(str) {
  return str.replace(/<\/?[^>]+>/g, "");
}

/**
 * Trims leading & trailing whitespace from the given string.
 *
 * @param {string} str The string to trim.
 * @return {string} The trimmed string.
 * @deprecated
 */
function _trim(str) {
  return str.replace(/^\s+|\s+$/g, "");
}

/**
 * Toggles the given element between being shown and block-style display.
 *
 * @param {string | HTMLElement} el The element to toggle.
 * @deprecated
 */
function _toggle(el) {
  el = (typeof el === "string") ? _gel(el) : el;
  if (el !== null) {
    if (el.style.display.length === 0 || el.style.display === "block") {
      el.style.display = "none";
    } else if (el.style.display === "none") {
      el.style.display = "block";
    }
  }
}

var _uid = (function() {
  /**
   * @type {number} A counter used by uniqueId().
   */
  var _legacy_uidCounter = 0;

  /**
   * @return {number} a unique number.
   * @deprecated
   */
  return function () {
    return _legacy_uidCounter++;
  };
})();

/**
 * @param {number} a
 * @param {number} b
 * @return {number} The lesser of a or b.
 * @deprecated
 */
function _min(a, b) {
  return (a < b ? a : b);
}

/**
 * @param {number} a
 * @param {number} b
 * @return {number} The greater of a or b.
 * @deprecated
 */
function _max(a, b) {
  return (a > b ? a : b);
}

/**
 * @param {string} name
 * @param {Array.<string | Object>} sym
 * @deprecated
 */
function _exportSymbols(name, sym) {
  var attach = window;
  var parts = name.split(".");
  for (var i = 0, j = parts.length; i < j; i++) {
    var part = parts[i];
    attach[part] = attach[part] || {};
    attach = attach[part];
  }
  for (var k = 0, l = sym.length; k < l; k += 2) {
    attach[sym[k]] = sym[k + 1];
  }
}
<commit_msg>SHINDIG-198 | legacy stub<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/*global gadgets */
var gadgets;

/**
 * @fileoverview All functions in this file should be treated as deprecated legacy routines.
 * Gadget authors are explicitly discouraged from using any of them.
 */

var JSON = window.JSON || gadgets.json;

/**
 * @deprecated
 */
var _IG_Prefs = (function() {
  var instance = null;

  var _IG_Prefs = function() {
    if (!instance) {
      instance = new gadgets.Prefs();
      instance.setDontEscape_();
    }
    return instance;
  };

 _IG_Prefs._parseURL = gadgets.Prefs.parseUrl;

  return _IG_Prefs;
})();

function _IG_Fetch_wrapper(callback, obj) {
  callback(obj.data ? obj.data : "");
}

/**
 * @deprecated
 */
function _IG_FetchContent(url, callback, opt_params) {
  var params = opt_params || {};
  // This is really the only legacy parameter documented
  // at http://code.google.com/apis/gadgets/docs/remote-content.html#Params
  if (params.refreshInterval) {
    params['REFRESH_INTERVAL'] = params.refreshInterval;
  } else {
    params['REFRESH_INTERVAL'] = 3600;
  }
  // Other params, such as POST_DATA, were supported in lower case.
  // Upper-case all param keys as a convenience, since all valid values
  // are uppercased.
  for (var param in params) {
    var pvalue = params[param];
    delete params[param];
    params[param.toUpperCase()] = pvalue;
  }
  var cb = gadgets.util.makeClosure(null, _IG_Fetch_wrapper, callback);
  gadgets.io.makeRequest(url, cb, params);
}

/**
 * @deprecated
 */
function _IG_FetchXmlContent(url, callback, opt_params) {
  var params = opt_params || {};
  if (params.refreshInterval) {
    params['REFRESH_INTERVAL'] = params.refreshInterval;
  } else {
    params['REFRESH_INTERVAL'] = 3600;
  }
  params.CONTENT_TYPE = "DOM";
  var cb = gadgets.util.makeClosure(null, _IG_Fetch_wrapper, callback);
  gadgets.io.makeRequest(url, cb, params);
}

/**
 * @deprecated
 */
function _IG_FetchFeedAsJSON(url, callback, numItems, getDescriptions,
                             opt_params) {
  var params = opt_params || {};
  params.CONTENT_TYPE = "FEED";
  params.NUM_ENTRIES = numItems;
  params.GET_SUMMARIES = getDescriptions;
  gadgets.io.makeRequest(url,
      function(resp) {
        // special case error reporting for back-compatibility
        // see http://code.google.com/apis/gadgets/docs/legacy/remote-content.html#Fetch_JSON
        resp.data = resp.data || {};
        if (resp.errors && resp.errors.length > 0) {
          resp.data.ErrorMsg = resp.errors[0];
        }
        if (resp.data.link) {
          resp.data.URL = url;
        }
        if (resp.data.title) {
          resp.data.Title = resp.data.title;
        }
        if (resp.data.description) {
          resp.data.Description = resp.data.description;
        }
        if (resp.data.link) {
          resp.data.Link = resp.data.link;
        }
        if (resp.data.items && resp.data.items.length > 0) {
          resp.data.Entry = resp.data.items;
          for (var index = 0; index < resp.data.Entry.length; ++index) {
            var entry = resp.data.Entry[index];
            entry.Title = entry.title;
            entry.Link = entry.link;
            entry.Summary = entry.summary || entry.description;
            entry.Date = entry.pubDate;
          }
        }
        for (var ix = 0; ix < resp.data.Entry.length; ++ix) {
          var entry = resp.data.Entry[ix];
          entry.Date = (entry.Date / 1000);  // response in sec, not ms
        }
        // for Gadgets back-compatibility, return the feed obj directly
        callback(resp.data);
      }, params);
}

/**
 * @param {string} url
 * @param {Object=} opt_params
 * @deprecated
 */
function _IG_GetCachedUrl(url, opt_params) {
  var params = opt_params || {};
  params['REFRESH_INTERVAL'] = 3600;
  if (params.refreshInterval) {
    params['REFRESH_INTERVAL'] = params.refreshInterval;
  }
  return gadgets.io.getProxyUrl(url, params);
}
/**
 * @param {string} url
 * @param {Object=} opt_params
 * @deprecated
 */
function _IG_GetImageUrl(url, opt_params) {
  return _IG_GetCachedUrl(url, opt_params);
}

/**
 * @param {string} url
 * @return {Element}
 * @deprecated
 */
function _IG_GetImage(url) {
  var img = document.createElement('img');
  img.src = _IG_GetCachedUrl(url);
  return img;
}

/**
 * @deprecated
 */
function _IG_RegisterOnloadHandler(callback) {
  gadgets.util.registerOnLoadHandler(callback);
}

/**
 * _IG_Callback takes the arguments in the scope the callback is executed and
 * places them first in the argument array. MakeClosure takes the arguments
 * from the scope at callback construction and pushes them first in the array
 *
 * @deprecated
 */
function _IG_Callback(handler_func, var_args) {
  var orig_args = arguments;
  return function() {
    var combined_args = Array.prototype.slice.call(arguments);
    // call the handler with all args combined
    handler_func.apply(null,
      combined_args.concat(Array.prototype.slice.call(orig_args, 1)));
  };
}

var _args = gadgets.util.getUrlParameters;

/**
 * Fetches an object by document id.
 *
 * @param {string | Object} el The element you wish to fetch. You may pass
 *     an object in which allows this to be called regardless of whether or
 *     not the type of the input is known.
 * @return {HTMLElement} The element, if it exists in the document, or null.
 * @deprecated
 */
function _gel(el) {
  return document.getElementById ? document.getElementById(el) : null;
}

/**
 * Fetches elements by tag name.
 * This is functionally identical to document.getElementsByTagName()
 *
 * @param {string} tag The tag to match elements against.
 * @return {Array.<HTMLElement>} All elements of this tag type.
 * @deprecated
 */
function _gelstn(tag) {
  if (tag === "*" && document.all) {
    return document.all;
  }
  return document.getElementsByTagName ?
         document.getElementsByTagName(tag) : [];
}

/**
 * Fetches elements with ids matching a given regular expression.
 *
 * @param {string} tagName The tag to match elements against.
 * @param {RegEx} regex The expression to match.
 * @return {Array.<HTMLElement>} All elements of this tag type that match
 *     regex.
 * @deprecated
 */
function _gelsbyregex(tagName, regex) {
  var matchingTags = _gelstn(tagName);
  var matchingRegex = [];
  for (var i = 0, j = matchingTags.length; i < j; ++i) {
    if (regex.test(matchingTags[i].id)) {
      matchingRegex.push(matchingTags[i]);
    }
  }
  return matchingRegex;
}

/**
 * URI escapes the given string.
 * @param {string} str The string to escape.
 * @return {string} The escaped string.
 * @deprecated
 */
function _esc(str) {
  return window.encodeURIComponent ? encodeURIComponent(str) : escape(str);
}

/**
 * URI unescapes the given string.
 * @param {string} str The string to unescape.
 * @return {string} The unescaped string.
 * @deprecated
 */
function _unesc(str) {
  return window.decodeURIComponent ? decodeURIComponent(str) : unescape(str);
}

/**
 * Encodes HTML entities such as <, " and >.
 *
 * @param {string} str The string to escape.
 * @return {string} The escaped string.
 * @deprecated
 */
function _hesc(str) {
  return gadgets.util.escapeString(str);
}

/**
 * Removes HTML tags from the given input string.
 *
 * @param {string} str The string to strip.
 * @return {string} The stripped string.
 * @deprecated
 */
function _striptags(str) {
  return str.replace(/<\/?[^>]+>/g, "");
}

/**
 * Trims leading & trailing whitespace from the given string.
 *
 * @param {string} str The string to trim.
 * @return {string} The trimmed string.
 * @deprecated
 */
function _trim(str) {
  return str.replace(/^\s+|\s+$/g, "");
}

/**
 * Toggles the given element between being shown and block-style display.
 *
 * @param {string | HTMLElement} el The element to toggle.
 * @deprecated
 */
function _toggle(el) {
  el = (typeof el === "string") ? _gel(el) : el;
  if (el !== null) {
    if (el.style.display.length === 0 || el.style.display === "block") {
      el.style.display = "none";
    } else if (el.style.display === "none") {
      el.style.display = "block";
    }
  }
}

var _uid = (function() {
  /**
   * @type {number} A counter used by uniqueId().
   */
  var _legacy_uidCounter = 0;

  /**
   * @return {number} a unique number.
   * @deprecated
   */
  return function () {
    return _legacy_uidCounter++;
  };
})();

/**
 * @param {number} a
 * @param {number} b
 * @return {number} The lesser of a or b.
 * @deprecated
 */
function _min(a, b) {
  return (a < b ? a : b);
}

/**
 * @param {number} a
 * @param {number} b
 * @return {number} The greater of a or b.
 * @deprecated
 */
function _max(a, b) {
  return (a > b ? a : b);
}

/**
 * @param {string} name
 * @param {Array.<string | Object>} sym
 * @deprecated
 */
function _exportSymbols(name, sym) {
  var attach = window;
  var parts = name.split(".");
  for (var i = 0, j = parts.length; i < j; i++) {
    var part = parts[i];
    attach[part] = attach[part] || {};
    attach = attach[part];
  }
  for (var k = 0, l = sym.length; k < l; k += 2) {
    attach[sym[k]] = sym[k + 1];
  }
}

/**
 * @deprecated
 * @param {Object} src
 * @param {string} etype
 * @param {function} func
 * TODO - implement
 */
function _IG_AddDOMEventHandler(src, etype, func) {
  gadgets.log.warn("_IG_AddDOMEventHandler not implemented - see SHINDIG-198");
}

<|endoftext|>


<commit_before>function homepage() {
  var date = moment().format("YYYY-MM-DD");
  //alert("HOMEPAGE");
  // DUE TODAY
  $.get("/work/"+date+"/all", function(data){
    if(data){
      console.log(data);
      if(data.error){
        console.log(data.error);
        $("#due-today").remove();
        return;
      }

      if(data.success){
        var courses = [];
        var total = data.hwItems.length;
        var doneC = 0;
        data.hwItems.forEach(function(item) {
          if(item.completed)
            doneC += 1;
          if(courses.indexOf(item.course.title) == -1)
            courses.push(item.course.title);
        });

        $("#due-today .progress-bar").animate({ width: percent+"%" }, 1000);

        if(doneC == 0){
          $("#due-today .content").html("You have not started any of your "+total+" homework items due Today! Get working!");
        }else if(doneC == total){
          $("#due-today .content").html("You have finished all of your "+total+" homework items due Today! Nice!");
          $("#due-today .progress").remove();
          $("#due-today .media-heading").html("Today's Work ");
        }else{
          var comment = "Keep going!";
          if(percent > 50)
            comment = "More than halfway done!";
          if(percent > 80)
            comment = "Almost there!";
          $("#due-today .content").html("You have "+(total - doneC)+" homework assignment(s) left for Today!
"+comment+"");
        }
      }
    }
  });

  // CLOSEST DAY DUE
  $.get("/work/"+$("#due-closest").data("closest")+"/all", function(data){
    if(data){
      console.log(data);
      if(data.error){
        console.log(data.error);
        $("#due-closest").remove();
        return;
      }

      if(data.success){
        var courses = [];
        var total = data.hwItems.length;
        var doneC = 0;
        data.hwItems.forEach(function(item) {
          if(item.completed)
            doneC += 1;
          if(courses.indexOf(item.course.title) == -1)
            courses.push(item.course.title);
        });

        var percent = Math.round((doneC/total)*100);
        $("#due-closest .progress-bar").animate({ width: percent+"%" }, 1000);

        if(doneC == 0){
          $("#due-closest .content").html("You have not started any of your "+total+" homework items due on "+moment($("#due-closest").data("closest"), "YYYY-MM-DD").format("dddd [the] Do")+"! Get working!");
        }else if(doneC == total){
          $("#due-closest .content").html("You have finished all of your "+total+" homework items due  "+moment($("#due-closest").data("closest"), "YYYY-MM-DD").format("dddd [the] Do")+"! Nice!");
          $("#due-closest .progress").remove();
          $("#due-closest .media-heading").html("Upcoming Work ");
        }else{
          var comment = "Keep going!";
          if(percent > 50)
            comment = "More than halfway done!";
          if(percent > 80)
            comment = "Almost there!";
          $("#due-closest .content").html("You have "+(total - doneC)+" homework assignment(s) left for "+moment($("#due-closest").data("closest"), "YYYY-MM-DD").format("dddd [the] Do")+"!
"+comment+"");
        }
      }
    }
  });
}
<commit_msg>Fixed homepage JS bug<commit_after>function homepage() {
  var date = moment().format("YYYY-MM-DD");
  //alert("HOMEPAGE");
  // DUE TODAY
  $.get("/work/"+date+"/all", function(data){
    if(data){
      console.log(data);
      if(data.error){
        console.log(data.error);

        $("#due-today").remove();
        return;
      }

      if(data.success){
        if(data.hwItems.length == 0)
          $("#due-today").remove();
        var courses = [];
        var total = data.hwItems.length;
        var doneC = 0;
        data.hwItems.forEach(function(item) {
          if(item.completed)
            doneC += 1;
          if(courses.indexOf(item.course.title) == -1)
            courses.push(item.course.title);
        });

        $("#due-today .progress-bar").animate({ width: percent+"%" }, 1000);

        if(doneC == 0){
          $("#due-today .content").html("You have not started any of your "+total+" homework items due Today! Get working!");
        }else if(doneC == total){
          $("#due-today .content").html("You have finished all of your "+total+" homework items due Today! Nice!");
          $("#due-today .progress").remove();
          $("#due-today .media-heading").html("Today's Work ");
        }else{
          var comment = "Keep going!";
          if(percent > 50)
            comment = "More than halfway done!";
          if(percent > 80)
            comment = "Almost there!";
          $("#due-today .content").html("You have "+(total - doneC)+" homework assignment(s) left for Today!
"+comment+"");
        }
      }
    }
  });

  // CLOSEST DAY DUE
  $.get("/work/"+$("#due-closest").data("closest")+"/all", function(data){
    if(data){
      console.log(data);
      if(data.error){
        console.log(data.error);
        $("#due-closest").remove();
        return;
      }

      if(data.success){
        if(data.hwItems.length == 0)
          $("#due-closest").remove();
        var courses = [];
        var total = data.hwItems.length;
        var doneC = 0;
        data.hwItems.forEach(function(item) {
          if(item.completed)
            doneC += 1;
          if(courses.indexOf(item.course.title) == -1)
            courses.push(item.course.title);
        });

        var percent = Math.round((doneC/total)*100);
        $("#due-closest .progress-bar").animate({ width: percent+"%" }, 1000);

        if(doneC == 0){
          $("#due-closest .content").html("You have not started any of your "+total+" homework items due on "+moment($("#due-closest").data("closest"), "YYYY-MM-DD").format("dddd [the] Do")+"! Get working!");
        }else if(doneC == total){
          $("#due-closest .content").html("You have finished all of your "+total+" homework items due  "+moment($("#due-closest").data("closest"), "YYYY-MM-DD").format("dddd [the] Do")+"! Nice!");
          $("#due-closest .progress").remove();
          $("#due-closest .media-heading").html("Upcoming Work ");
        }else{
          var comment = "Keep going!";
          if(percent > 50)
            comment = "More than halfway done!";
          if(percent > 80)
            comment = "Almost there!";
          $("#due-closest .content").html("You have "+(total - doneC)+" homework assignment(s) left for "+moment($("#due-closest").data("closest"), "YYYY-MM-DD").format("dddd [the] Do")+"!
"+comment+"");
        }
      }
    }
  });
}
<|endoftext|>


<commit_before>{
    "AssetAdmin.ADD_FOLDER_BUTTON": "Add folder",
    "AssetAdmin.BACK": "Back",
    "AssetAdmin.BULK_ACTIONS_CONFIRM": "Are you sure you want to %s these files?",
    "AssetAdmin.BULK_ACTIONS_DELETE_FOLDER": "These folders contain files which are currently in use, you must move or delete their contents before you can delete the folder.",
    "AssetAdmin.BULK_ACTIONS_DELETE_SINGLE_CONFIRM": "This file is currently in use in %s places, are you sure you want to delete it?",
    "AssetAdmin.BULK_ACTIONS_DELETE_MULTI_CONFIRM": "There are %s files currently in use, are you sure you want to delete these files?",
    "AssetAdmin.BULK_ACTIONS_DELETE": "Delete",
    "AssetAdmin.BULK_ACTIONS_PLACEHOLDER": "Select an action...",
    "AssetAdmin.CANCEL": "Cancel",
    "AssetAdmin.CONFIRMDELETE": "Are you sure you want to delete this record?",
    "AssetAdmin.CREATED": "First uploaded",
    "AssetAdmin.ConfirmDelete": "Do you really want to delete this folder and all contained files?",
    "AssetAdmin.DELETE": "Delete",
    "AssetAdmin.DIM": "Dimensions",
    "AssetAdmin.DROPZONE_CANCEL_UPLOAD": "Cancel upload",
    "AssetAdmin.DROPZONE_CANCEL_UPLOAD_CONFIRMATION": "Are you sure you want to cancel this upload?",
    "AssetAdmin.DROPZONE_DEFAULT_MESSAGE": "Drop files here to upload",
    "AssetAdmin.DROPZONE_FAILED_UPLOAD": "Failed to upload file",
    "AssetAdmin.DROPZONE_FALLBACK_MESSAGE": "Your browser does not support drag'n'drop file uploads.",
    "AssetAdmin.DROPZONE_FALLBACK_TEXT": "Please use the fallback form below to upload your files like in the olden days.",
    "AssetAdmin.DROPZONE_FILE_TOO_BIG": "File is too big. Max filesize: %sMiB.",
    "AssetAdmin.DROPZONE_INVALID_FILE_TYPE": "You can't upload files of this type.",
    "AssetAdmin.DROPZONE_MAX_FILES_EXCEEDED": "You can not upload any more files.",
    "AssetAdmin.DROPZONE_REMOVE_FILE": "Remove file",
    "AssetAdmin.DROPZONE_RESPONSE_ERROR": "Server responded with an error.",
    "AssetAdmin.DROPZONE_SUCCESS_UPLOAD": "File uploaded",
    "AssetAdmin.DROPZONE_UPLOAD": "Upload",
    "AssetAdmin.EDIT": "Edit",
    "AssetAdmin.FILENAME": "Filename",
    "AssetAdmin.FILES": "Files",
    "AssetAdmin.FILE_MISSING": "File cannot be found",
    "AssetAdmin.FILTER_DATE_ASC": "oldest",
    "AssetAdmin.FILTER_DATE_DESC": "newest",
    "AssetAdmin.FILTER_TITLE_ASC": "title a-z",
    "AssetAdmin.FILTER_TITLE_DESC": "title z-a",
    "AssetAdmin.LASTEDIT": "Last changed",
    "AssetAdmin.LOADMORE": "Load more",
    "AssetAdmin.NOITEMSFOUND": "No items found",
    "AssetAdmin.PROMPTFOLDERNAME": "Please enter a folder name (or blank to cancel)",
    "AssetAdmin.REPlACE_FILE_SUCCESS": "Upload successful, the file will be replaced when you Save.",
    "AssetAdmin.SAVE": "Save",
    "AssetAdmin.SELECT": "Select",
    "AssetAdmin.SIZE": "Size",
    "AssetAdmin.TITLE": "Title",
    "AssetAdmin.TYPE": "File type",
    "AssetAdmin.URL": "URL",
    "AssetAdminFileField.BROWSE": "Browse",
    "AssetGalleryField.ADD_FOLDER_BUTTON": "Add folder",
    "AssetGalleryField.BACK": "Back",
    "AssetGalleryField.BULK_ACTIONS_CONFIRM": "Are you sure you want to %s these files?",
    "AssetGalleryField.BULK_ACTIONS_DELETE": "Delete",
    "AssetGalleryField.BULK_ACTIONS_PLACEHOLDER": "Select an action...",
    "AssetGalleryField.CANCEL": "Cancel",
    "AssetGalleryField.CONFIRMDELETE": "Are you sure you want to delete this record?",
    "AssetGalleryField.CREATED": "First uploaded",
    "AssetGalleryField.DELETE": "Delete",
    "AssetGalleryField.DIM": "Dimensions",
    "AssetGalleryField.DROPZONE_CANCEL_UPLOAD": "Cancel upload",
    "AssetGalleryField.DROPZONE_CANCEL_UPLOAD_CONFIRMATION": "Are you sure you want to cancel this upload?",
    "AssetGalleryField.DROPZONE_DEFAULT_MESSAGE": "Drop files here to upload",
    "AssetGalleryField.DROPZONE_FAILED_UPLOAD": "Failed to upload file",
    "AssetGalleryField.DROPZONE_FALLBACK_MESSAGE": "Your browser does not support drag'n'drop file uploads.",
    "AssetGalleryField.DROPZONE_FALLBACK_TEXT": "Please use the fallback form below to upload your files like in the olden days.",
    "AssetGalleryField.DROPZONE_FILE_TOO_BIG": "File is too big. Max filesize: %sMiB.",
    "AssetGalleryField.DROPZONE_INVALID_FILE_TYPE": "You can't upload files of this type.",
    "AssetGalleryField.DROPZONE_MAX_FILES_EXCEEDED": "You can not upload any more files.",
    "AssetGalleryField.DROPZONE_REMOVE_FILE": "Remove file",
    "AssetGalleryField.DROPZONE_RESPONSE_ERROR": "Server responded with an error.",
    "AssetGalleryField.DROPZONE_SUCCESS_UPLOAD": "File uploaded",
    "AssetGalleryField.DROPZONE_UPLOAD": "Upload",
    "AssetGalleryField.EDIT": "Edit",
    "AssetGalleryField.FILENAME": "Filename",
    "AssetGalleryField.FILTER_DATE_ASC": "oldest",
    "AssetGalleryField.FILTER_DATE_DESC": "newest",
    "AssetGalleryField.FILTER_TITLE_ASC": "title a-z",
    "AssetGalleryField.FILTER_TITLE_DESC": "title z-a",
    "AssetGalleryField.LASTEDIT": "Last changed",
    "AssetGalleryField.LOADMORE": "Load more",
    "AssetGalleryField.NOITEMSFOUND": "No items found",
    "AssetGalleryField.SAVE": "Save",
    "AssetGalleryField.SELECT": "Select",
    "AssetGalleryField.SIZE": "Size",
    "AssetGalleryField.TITLE": "Title",
    "AssetGalleryField.TYPE": "File type",
    "AssetGalleryField.URL": "URL",
    "Folder.Name": "Folder name",
    "HTMLEditorField_Toolbar.ERROR_OEMBED_REMOTE": "Embed is only compatible with remote files",
    "Pagination.NEXT": "Next",
    "Pagination.PREVIOUS": "Previous",
}
<commit_msg>en.js JSON fix<commit_after>{
    "AssetAdmin.ADD_FOLDER_BUTTON": "Add folder",
    "AssetAdmin.BACK": "Back",
    "AssetAdmin.BULK_ACTIONS_CONFIRM": "Are you sure you want to %s these files?",
    "AssetAdmin.BULK_ACTIONS_DELETE_FOLDER": "These folders contain files which are currently in use, you must move or delete their contents before you can delete the folder.",
    "AssetAdmin.BULK_ACTIONS_DELETE_SINGLE_CONFIRM": "This file is currently in use in %s places, are you sure you want to delete it?",
    "AssetAdmin.BULK_ACTIONS_DELETE_MULTI_CONFIRM": "There are %s files currently in use, are you sure you want to delete these files?",
    "AssetAdmin.BULK_ACTIONS_DELETE": "Delete",
    "AssetAdmin.BULK_ACTIONS_PLACEHOLDER": "Select an action...",
    "AssetAdmin.CANCEL": "Cancel",
    "AssetAdmin.CONFIRMDELETE": "Are you sure you want to delete this record?",
    "AssetAdmin.CREATED": "First uploaded",
    "AssetAdmin.ConfirmDelete": "Do you really want to delete this folder and all contained files?",
    "AssetAdmin.DELETE": "Delete",
    "AssetAdmin.DIM": "Dimensions",
    "AssetAdmin.DROPZONE_CANCEL_UPLOAD": "Cancel upload",
    "AssetAdmin.DROPZONE_CANCEL_UPLOAD_CONFIRMATION": "Are you sure you want to cancel this upload?",
    "AssetAdmin.DROPZONE_DEFAULT_MESSAGE": "Drop files here to upload",
    "AssetAdmin.DROPZONE_FAILED_UPLOAD": "Failed to upload file",
    "AssetAdmin.DROPZONE_FALLBACK_MESSAGE": "Your browser does not support drag'n'drop file uploads.",
    "AssetAdmin.DROPZONE_FALLBACK_TEXT": "Please use the fallback form below to upload your files like in the olden days.",
    "AssetAdmin.DROPZONE_FILE_TOO_BIG": "File is too big. Max filesize: %sMiB.",
    "AssetAdmin.DROPZONE_INVALID_FILE_TYPE": "You can't upload files of this type.",
    "AssetAdmin.DROPZONE_MAX_FILES_EXCEEDED": "You can not upload any more files.",
    "AssetAdmin.DROPZONE_REMOVE_FILE": "Remove file",
    "AssetAdmin.DROPZONE_RESPONSE_ERROR": "Server responded with an error.",
    "AssetAdmin.DROPZONE_SUCCESS_UPLOAD": "File uploaded",
    "AssetAdmin.DROPZONE_UPLOAD": "Upload",
    "AssetAdmin.EDIT": "Edit",
    "AssetAdmin.FILENAME": "Filename",
    "AssetAdmin.FILES": "Files",
    "AssetAdmin.FILE_MISSING": "File cannot be found",
    "AssetAdmin.FILTER_DATE_ASC": "oldest",
    "AssetAdmin.FILTER_DATE_DESC": "newest",
    "AssetAdmin.FILTER_TITLE_ASC": "title a-z",
    "AssetAdmin.FILTER_TITLE_DESC": "title z-a",
    "AssetAdmin.LASTEDIT": "Last changed",
    "AssetAdmin.LOADMORE": "Load more",
    "AssetAdmin.NOITEMSFOUND": "No items found",
    "AssetAdmin.PROMPTFOLDERNAME": "Please enter a folder name (or blank to cancel)",
    "AssetAdmin.REPlACE_FILE_SUCCESS": "Upload successful, the file will be replaced when you Save.",
    "AssetAdmin.SAVE": "Save",
    "AssetAdmin.SELECT": "Select",
    "AssetAdmin.SIZE": "Size",
    "AssetAdmin.TITLE": "Title",
    "AssetAdmin.TYPE": "File type",
    "AssetAdmin.URL": "URL",
    "AssetAdminFileField.BROWSE": "Browse",
    "AssetGalleryField.ADD_FOLDER_BUTTON": "Add folder",
    "AssetGalleryField.BACK": "Back",
    "AssetGalleryField.BULK_ACTIONS_CONFIRM": "Are you sure you want to %s these files?",
    "AssetGalleryField.BULK_ACTIONS_DELETE": "Delete",
    "AssetGalleryField.BULK_ACTIONS_PLACEHOLDER": "Select an action...",
    "AssetGalleryField.CANCEL": "Cancel",
    "AssetGalleryField.CONFIRMDELETE": "Are you sure you want to delete this record?",
    "AssetGalleryField.CREATED": "First uploaded",
    "AssetGalleryField.DELETE": "Delete",
    "AssetGalleryField.DIM": "Dimensions",
    "AssetGalleryField.DROPZONE_CANCEL_UPLOAD": "Cancel upload",
    "AssetGalleryField.DROPZONE_CANCEL_UPLOAD_CONFIRMATION": "Are you sure you want to cancel this upload?",
    "AssetGalleryField.DROPZONE_DEFAULT_MESSAGE": "Drop files here to upload",
    "AssetGalleryField.DROPZONE_FAILED_UPLOAD": "Failed to upload file",
    "AssetGalleryField.DROPZONE_FALLBACK_MESSAGE": "Your browser does not support drag'n'drop file uploads.",
    "AssetGalleryField.DROPZONE_FALLBACK_TEXT": "Please use the fallback form below to upload your files like in the olden days.",
    "AssetGalleryField.DROPZONE_FILE_TOO_BIG": "File is too big. Max filesize: %sMiB.",
    "AssetGalleryField.DROPZONE_INVALID_FILE_TYPE": "You can't upload files of this type.",
    "AssetGalleryField.DROPZONE_MAX_FILES_EXCEEDED": "You can not upload any more files.",
    "AssetGalleryField.DROPZONE_REMOVE_FILE": "Remove file",
    "AssetGalleryField.DROPZONE_RESPONSE_ERROR": "Server responded with an error.",
    "AssetGalleryField.DROPZONE_SUCCESS_UPLOAD": "File uploaded",
    "AssetGalleryField.DROPZONE_UPLOAD": "Upload",
    "AssetGalleryField.EDIT": "Edit",
    "AssetGalleryField.FILENAME": "Filename",
    "AssetGalleryField.FILTER_DATE_ASC": "oldest",
    "AssetGalleryField.FILTER_DATE_DESC": "newest",
    "AssetGalleryField.FILTER_TITLE_ASC": "title a-z",
    "AssetGalleryField.FILTER_TITLE_DESC": "title z-a",
    "AssetGalleryField.LASTEDIT": "Last changed",
    "AssetGalleryField.LOADMORE": "Load more",
    "AssetGalleryField.NOITEMSFOUND": "No items found",
    "AssetGalleryField.SAVE": "Save",
    "AssetGalleryField.SELECT": "Select",
    "AssetGalleryField.SIZE": "Size",
    "AssetGalleryField.TITLE": "Title",
    "AssetGalleryField.TYPE": "File type",
    "AssetGalleryField.URL": "URL",
    "Folder.Name": "Folder name",
    "HTMLEditorField_Toolbar.ERROR_OEMBED_REMOTE": "Embed is only compatible with remote files",
    "Pagination.NEXT": "Next",
    "Pagination.PREVIOUS": "Previous"
}
<|endoftext|>


<commit_before>var LCD = require('lcd-pcf8574');

/**
 * Module for displaying onto the lcd screen (4*20 characters)
 * @param i2cDev I2C port (/dev/i2c-0 or /dev/i2c-1 according to Raspi version)
 * @param address I2C address of the module (0x27 for standard lcm1602 module)
 * @param nbLines Number of lines on the screen
 * @param nbCols Number of columns on the screen
 */
module.exports = function(i2cDev, address, nbLines, nbCols) {
	var lcd = new LCD(i2cDev, address);
	var curX = 0, curY = 0;

	/**
	 * Move the cursor to the selected position
	 * @param x horizontal position, starts at 0
	 * @param y vertical position, start at 0
	 */
	var goto = function(x, y) {
		lcd.setCursor(x, y);
		curX = x;
		curY = y;
		return this;
	};

	/**
	 * Print a string on the screen at the current location.
	 * If the string is too large for the screen, the string is cut and go to the next line.
	 * The cursor is reset to the initial location after the print.
	 * @param str String to print
	 */
	var print = function(str) {
		var maxStr = str,
			xOrig = curX,
			yOrig = curY;

		while (maxStr.length > (nbCols - curX) && (curY < nbLines - 1)) {
			var maxLength = (nbCols - curX),
				printStr = maxStr.substr(0, maxLength);
			maxStr = maxStr.substr(maxLength);
			lcd.print(printStr);
			goto(0, curY + 1);
		}

		//at this point, the string has the correct length to be print in the space left
		//or on the last line
		lcd.print(maxStr.substr(0, nbCols - curX));

		goto(xOrig, yOrig);
		return this;
	};

	/** Empty the LCD screen */
	var clear = function() {
		lcd.clear();
		return this;
	};

	return {
		goto: goto,
		print: print,
		clear: clear
	}
};<commit_msg>Handling accents on LCD<commit_after>var LCD = require('lcd-pcf8574');

/**
 * Module for displaying onto the lcd screen (4*20 characters)
 * @param i2cDev I2C port (/dev/i2c-0 or /dev/i2c-1 according to Raspi version)
 * @param address I2C address of the module (0x27 for standard lcm1602 module)
 * @param nbLines Number of lines on the screen
 * @param nbCols Number of columns on the screen
 */
module.exports = function(i2cDev, address, nbLines, nbCols) {
	var lcd = new LCD(i2cDev, address);
	var curX = 0, curY = 0;

	//init accents
	lcd .createChar(0, [ 130,132,142,145,159,144,142,128 ]) //é
		.createChar(1, [ 136,132,142,145,159,144,142,128 ]) //è
		.createChar(2, [ 132,138,142,145,159,144,142,128 ]) //ê
		.createChar(3, [ 136,134,128,142,145,147,141,128 ]) //à
		.createChar(4, [ 132,138,128,142,145,147,141,128 ]) //â
		.createChar(5, [ 132,138,128,140,132,132,142,128 ]) //î
		.createChar(6, [ 132,138,128,145,145,147,141,128 ]) //û
		.createChar(7, [ 136,134,128,145,145,147,141,128 ]) //ù
		;

	function replaceAccent(str) {
		var chars = ['é', 'è', 'ê', 'à', 'â', 'î', 'û', 'ù'];
		for (var i = 0; i < chars.length; i++) {
			var char = chars[i];
			str = str.replace(char, String.fromCharCode(i));
		}
		return str;
	}

	/**
	 * Move the cursor to the selected position
	 * @param x horizontal position, starts at 0
	 * @param y vertical position, start at 0
	 */
	var goto = function(x, y) {
		lcd.setCursor(x, y);
		curX = x;
		curY = y;
		return this;
	};

	/**
	 * Print a string on the screen at the current location.
	 * If the string is too large for the screen, the string is cut and go to the next line.
	 * The cursor is reset to the initial location after the print.
	 * @param str String to print
	 */
	var print = function(str) {
		var maxStr = str,
			xOrig = curX,
			yOrig = curY;

		while (maxStr.length > (nbCols - curX) && (curY < nbLines - 1)) {
			var maxLength = (nbCols - curX),
				printStr = maxStr.substr(0, maxLength);
			maxStr = maxStr.substr(maxLength);
			lcd.print(replaceAccent(printStr));
			goto(0, curY + 1);
		}

		//at this point, the string has the correct length to be print in the space left
		//or on the last line
		lcd.print(replaceAccent(maxStr.substr(0, nbCols - curX)));

		goto(xOrig, yOrig);
		return this;
	};

	/** Empty the LCD screen */
	var clear = function() {
		lcd.clear();
		return this;
	};

	return {
		goto: goto,
		print: print,
		clear: clear
	}
};<|endoftext|>


<commit_before>const assert = require('assert');
const Language = require('../models/Language');
const Submission = require('../models/Submission');
const docker = require('../engines/docker');
const io = require('./socket-io');
const discord = require('./discord');
const contests = require('../contests');

const markError = (submission, error) => {
	console.error(error);
	submission.status = 'error';
	submission.error.name = error.name;
	submission.error.stack = error.stack;
	submission.save();
};

module.exports.validate = async ({submission, language, solution, contest}) => {
	try {
		assert({}.hasOwnProperty.call(contests, contest.id));
		const {generateInput, isValidAnswer} = contests[contest.id];

		submission.input = generateInput();
		const newSubmission = await submission.save();
		const params = {
			id: language.slug,
			code: newSubmission.code,
			stdin: newSubmission.input,
		};

		const info = await docker(params);
		console.log('info:', info);

		if (typeof info !== 'object') {
			throw new Error('info is not object');
		}

		const {stdout, stderr, duration, error} = info;
		newSubmission.stdout = stdout;
		newSubmission.stderr = stderr;
		newSubmission.duration = duration;

		if (error) {
			await newSubmission.save();
			throw error;
		}

		if (isValidAnswer(newSubmission.input, stdout)) {
			newSubmission.status = 'success';

			Language.update(
				{slug: language.slug, contest},
				{$set: {solution: newSubmission._id}}
			).then(() => {
				io.emit('update-languages', {});
			});
		} else {
			newSubmission.status = 'failed';
		}

		const savedSubmission = await newSubmission.save();
		const populatedSubmission = await Submission.populate(savedSubmission, {
			path: 'user language',
		});

		if (populatedSubmission.status === 'success') {
			const bytesInfo = (() => {
				if (solution) {
					return `${
						[':heart:', ':blue_heart:', ':green_heart:'][
							solution.user.getTeam(contest)
						]
					} **${solution.size} bytes** => ${
						[':heart:', ':blue_heart:', ':green_heart:'][
							populatedSubmission.user.getTeam(contest)
						]
					} **${populatedSubmission.size} bytes**`;
				}

				return `:new: ${
					[':heart:', ':blue_heart:', ':green_heart:'][
						populatedSubmission.user.getTeam(contest)
					]
				} **${populatedSubmission.size} bytes**`;
			})();

			discord.send(
				`**${populatedSubmission.user.name()}** won the language **${
					language.name
				}**!! (${bytesInfo}) Congrats!!!\nhttps://esolang.hakatashi.com/submissions/${
					populatedSubmission._id
				}`
			);
		}
	} catch (error) {
		markError(submission, error);
	} finally {
		io.emit('update-submission', {_id: submission._id});
	}
};
<commit_msg>Fix notification<commit_after>const assert = require('assert');
const Language = require('../models/Language');
const Submission = require('../models/Submission');
const docker = require('../engines/docker');
const io = require('./socket-io');
const discord = require('./discord');
const contests = require('../contests');

const markError = (submission, error) => {
	console.error(error);
	submission.status = 'error';
	submission.error.name = error.name;
	submission.error.stack = error.stack;
	submission.save();
};

module.exports.validate = async ({submission, language, solution, contest}) => {
	try {
		assert({}.hasOwnProperty.call(contests, contest.id));
		const {generateInput, isValidAnswer} = contests[contest.id];

		submission.input = generateInput();
		const newSubmission = await submission.save();
		const params = {
			id: language.slug,
			code: newSubmission.code,
			stdin: newSubmission.input,
		};

		const info = await docker(params);
		console.log('info:', info);

		if (typeof info !== 'object') {
			throw new Error('info is not object');
		}

		const {stdout, stderr, duration, error} = info;
		newSubmission.stdout = stdout;
		newSubmission.stderr = stderr;
		newSubmission.duration = duration;

		if (error) {
			await newSubmission.save();
			throw error;
		}

		if (isValidAnswer(newSubmission.input, stdout)) {
			newSubmission.status = 'success';

			Language.update(
				{slug: language.slug, contest},
				{$set: {solution: newSubmission._id}}
			).then(() => {
				io.emit('update-languages', {});
			});
		} else {
			newSubmission.status = 'failed';
		}

		const savedSubmission = await newSubmission.save();
		const populatedSubmission = await Submission.populate(savedSubmission, {
			path: 'user language',
		});

		if (populatedSubmission.status === 'success') {
			const bytesInfo = (() => {
				if (solution) {
					return `${
						[':heart:', ':blue_heart:', ':green_heart:', ':yellow_heart:', ':purple_heart:'][
							solution.user.getTeam(contest)
						]
					} **${solution.size} bytes** => ${
						[':heart:', ':blue_heart:', ':green_heart:', ':yellow_heart:', ':purple_heart:'][
							populatedSubmission.user.getTeam(contest)
						]
					} **${populatedSubmission.size} bytes**`;
				}

				return `:new: ${
					[':heart:', ':blue_heart:', ':green_heart:', ':yellow_heart:', ':purple_heart:'][
						populatedSubmission.user.getTeam(contest)
					]
				} **${populatedSubmission.size} bytes**`;
			})();

			discord.send(
				`**${populatedSubmission.user.name()}** won the language **${
					language.name
				}**!! (${bytesInfo}) Congrats!!!\nhttps://esolang.hakatashi.com/submissions/${
					populatedSubmission._id
				}`
			);
		}
	} catch (error) {
		markError(submission, error);
	} finally {
		io.emit('update-submission', {_id: submission._id});
	}
};
<|endoftext|>


<commit_before>'use strict';

class Validators {
	static isTelephoneNumber(number) {
		return /^\+?[0-9]+$/g.test(number);
	}

	static isAllocatableNumber(number) {
		return /^\+?[0-9_]+$/g.test(number);
	}

	static stripWhitespace(number) {
		if(typeof number != 'string') {
			return '';
		}
		return number.replace(/[+\s]+/g, '');
	}

	static stripNonNumeric(text) {
		if(typeof text != 'string') {
			return '';
		}
		return text.replace(/[^0-9]+/g, '');
	}
}

module.exports = Validators;
<commit_msg>Fixed styling of validators.<commit_after>'use strict';

class Validators {
	static isTelephoneNumber(number) {
		return /^\+?[0-9]+$/g.test(number);
	}

	static isAllocatableNumber(number) {
		return /^\+?[0-9_]+$/g.test(number);
	}

	static stripWhitespace(number) {
		if (typeof number != 'string') {
			return '';
		}
		return number.replace(/[+\s]+/g, '');
	}

	static stripNonNumeric(text) {
		if (typeof text != 'string') {
			return '';
		}
		return text.replace(/[^0-9]+/g, '');
	}
}

module.exports = Validators;
<|endoftext|>


<commit_before>(function () {
  "use strict";
  const moment = require("moment");

  var validator = require("validator");
  var BLACKLISTED_CHARACTERS = /[`'";{}<>]+/gi;

  function sanitizeForValidation(value) {
    value = value ? validator.stripLow(value).replace(/ /g, "") : value;
    return value;
  }

  exports.InputDataValidator = function(params) {
    var validationErrors = [];

    function validatePayment(payment) {
      if(!validator.isIP(payment.ip)) {
        validationErrors.push({
          message: "Invalid payment IP address",
          translationKey: "invalid.payment.ip.address",
          value: payment.ip
        });
      }
      if(!validator.isEmail(payment.cardHolderEmail + "")) {
        validationErrors.push({
          message: "Invalid payment card holder email",
          translationKey: "invalid.payment.cardHolderEmail",
          value: payment.cardHolderEmail
        });
      }
      var cardHolderName = sanitizeForValidation(payment.cardHolderName);
      if(!cardHolderName ||
          cardHolderName.length < 2 ||
          cardHolderName.length > 52 ||
          cardHolderName.match(BLACKLISTED_CHARACTERS)) {
        validationErrors.push({
          message: "Invalid payment cardHolderName",
          translationKey: "invalid.payment.cardHolderName",
          value: payment.cardHolderName
        });
      }
      if(!validator.isAlpha(payment.paymentMethod)) {
        validationErrors.push({
          message: "Invalid payment method",
          translationKey: "invalid.payment.paymentMethod",
          value: payment.paymentMethod
        });
      }
      var creditCardNumber = sanitizeForValidation(payment.creditCardNumber);
      if(!validator.isCreditCard(creditCardNumber + "")) {
        validationErrors.push({
          message: "Invalid payment credit card number",
          translationKey: "invalid.payment.creditCardNumber",
          value: payment.creditCardNumber
        });
      }
      var ccv = sanitizeForValidation(payment.ccv);
      if(!ccv ||
         (ccv.length < 3 || ccv.length > 4) ||
         !validator.isInt(ccv)) {
        validationErrors.push({
          message: "Invalid payment ccv",
          translationKey: "invalid.payment.ccv",
          value: payment.ccv
        });
      }
      var month = sanitizeForValidation(payment.expiresMonth + "");
      if(!month ||
          month < 1 ||
          month > 12) {
        validationErrors.push({
          message: "Invalid payment expires month",
          translationKey: "invalid.payment.expiresMonth",
          value: payment.expiresMonth
        });
      }
      var year = sanitizeForValidation(payment.expiresYear + "");
      if(!year ||
          year < moment().year()) {
        validationErrors.push({
          message: "Invalid payment expires year",
          translationKey: "invalid.payment.expiresYear",
          value: payment.expiresYear
        });
      }
      if(moment(payment.expiresMonth + '-' + payment.expiresYear, 'MM-YYYY').isBefore(moment().startOf('month'))) {
        validationErrors.push({
          message: "Card has expired",
          translationKey: "invalid.payment.cardHasExpired",
          value: payment.expiresMonth + "/" + payment.expiresYear
        });
      }
    }

    function validateConsumer(consumer) {
      var name = sanitizeForValidation(consumer.name);
      if(!name ||
          name.length < 2 ||
          name.length > 52 ||
          name.match(BLACKLISTED_CHARACTERS)) {
        validationErrors.push({
          message: "Invalid consumer name",
          translationKey: "invalid.consumer.name",
          value: consumer.name
        });
      }
      if(consumer.co && consumer.co.length > 52 || consumer.co.match(BLACKLISTED_CHARACTERS)) {
        validationErrors.push({
          message: "Invalid consumer c/o",
          translationKey: "invalid.consumer.co",
          value: consumer.co
        });
      }
      var streetAddress = sanitizeForValidation(consumer.streetAddress);
      if(!streetAddress ||
          streetAddress.length < 2 ||
          streetAddress.length > 52 ||
          streetAddress.match(BLACKLISTED_CHARACTERS)) {
        validationErrors.push({
          message: "Invalid consumer street address",
          translationKey: "invalid.consumer.streetAddress",
          value: consumer.streetAddress
        });
      }
      if(consumer.streetAddress2 &&
         (consumer.streetAddress2.length > 52 ||
         consumer.streetAddress2.match(BLACKLISTED_CHARACTERS))) {
        validationErrors.push({
          message: "Invalid consumer street address 2",
          translationKey: "invalid.consumer.streetAddress2",
          value: consumer.streetAddress2
        });
      }
      var postalCode = sanitizeForValidation(consumer.postalCode);
      if(!postalCode ||
          postalCode.length < 2 ||
          postalCode.length > 10 ||
          postalCode.match(BLACKLISTED_CHARACTERS)) {
        validationErrors.push({
          message: "Invalid consumer postal code",
          translationKey: "invalid.consumer.postalCode",
          value: consumer.postalCode
        });
      }
      var city = sanitizeForValidation(consumer.city);
      if(!city ||
          city.length < 2 ||
          city.length > 53 ||
          city.match(BLACKLISTED_CHARACTERS)) {
        validationErrors.push({
          message: "Invalid consumer city",
          translationKey: "invalid.consumer.city",
          value: consumer.city
        });
      }
      if(consumer.stateOrProvince &&
         (consumer.stateOrProvince.length > 52 ||
         consumer.stateOrProvince.match(BLACKLISTED_CHARACTERS))) {
        validationErrors.push({
          message: "Invalid consumer state or province",
          translationKey: "invalid.consumer.stateOrProvince",
          value: consumer.stateOrProvince
        });
      }
      var country = sanitizeForValidation(consumer.country);
      if(!country ||
          country.length < 2 ||
          country.length > 53 ||
          country.match(BLACKLISTED_CHARACTERS)) {
        validationErrors.push({
          message: "Invalid consumer country",
          translationKey: "invalid.consumer.country",
          value: consumer.country
        });
      }
      var locale = sanitizeForValidation(consumer.locale) || "en-US";
      if(locale.length < 5 ||
         locale.length > 10 ||
         locale.match(BLACKLISTED_CHARACTERS)) {
        validationErrors.push({
          message: "Invalid consumer locale",
          translationKey: "invalid.consumer.locale",
          value: consumer.locale
        });
      }
    }

    function validateCents(params) {
      if(!validator.isInt(params.value + "", { min: 0, max: Number.MAX_SAFE_INTEGER })) {
        validationErrors.push({
          message: params.message,
          translationKey: params.translationKey,
          value: params.value
        });
      }
    }

    function validateOrder(order) {
      validateCents({
        value: order.sumInCentsIncVat,
        message: "Invalid sum in cents including VAT",
        translationKey: "invalid.order.sumInCentsIncVat"
      });
      validateCents({
        value: order.sumInCentsExcVat,
        message: "Invalid sum in cents excluding VAT",
        translationKey: "invalid.order.sumInCentsExcVat",
      });
      validateCents({
        value: order.vatInCents,
        message: "Invalid VAT in cents excluding VAT",
        translationKey: "invalid.order.vatInCents",
      });
      if(order.referenceId && order.referenceId.length > 255) {
        validationErrors.push({
          value: order.referenceId,
          message: "Invalid order reference ID",
          translationKey: "invalid.order.referenceId",
        });
      }
      if(order.referenceId && !validator.isAlphanumeric(order.referenceId)) {
        validationErrors.push({
          value: order.referenceId,
          message: "Invalid order reference ID",
          translationKey: "invalid.order.referenceId",
        });
      }
    }

    function validateSeller(seller) {
    }

    function validateProducts(products) {
    }

    function validateCallbacks(callbacks) {
    }

    return {
      validate: function() {
        validationErrors = [];
        if(!params.payment.locale) {
          params.payment.locale = "en-US";
        }
        validatePayment(params.payment);
        validateConsumer(params.consumer);
        validateOrder(params.order);
        validateSeller(params.seller);
        validateProducts(params.products);
        validateCallbacks(params.callbacks);
        return validationErrors;
      }
    };
  };
}());
<commit_msg>Fixed a few warnings<commit_after>(function () {
  "use strict";
  var moment = require("moment");

  var validator = require("validator");
  var BLACKLISTED_CHARACTERS = /[`'";{}<>]+/gi;

  function sanitizeForValidation(value) {
    value = value ? validator.stripLow(value).replace(/\s\s+/g, " ") : value;
    return value;
  }

  exports.InputDataValidator = function(params) {
    var validationErrors = [];

    function validatePayment(payment) {
      if(!validator.isIP(payment.ip)) {
        validationErrors.push({
          message: "Invalid payment IP address",
          translationKey: "invalid.payment.ip.address",
          value: payment.ip
        });
      }
      if(!validator.isEmail(payment.cardHolderEmail + "")) {
        validationErrors.push({
          message: "Invalid payment card holder email",
          translationKey: "invalid.payment.cardHolderEmail",
          value: payment.cardHolderEmail
        });
      }
      var cardHolderName = sanitizeForValidation(payment.cardHolderName);
      if(!cardHolderName ||
          cardHolderName.length < 2 ||
          cardHolderName.length > 52 ||
          cardHolderName.match(BLACKLISTED_CHARACTERS)) {
        validationErrors.push({
          message: "Invalid payment cardHolderName",
          translationKey: "invalid.payment.cardHolderName",
          value: payment.cardHolderName
        });
      }
      if(!validator.isAlpha(payment.paymentMethod)) {
        validationErrors.push({
          message: "Invalid payment method",
          translationKey: "invalid.payment.paymentMethod",
          value: payment.paymentMethod
        });
      }
      var creditCardNumber = sanitizeForValidation(payment.creditCardNumber);
      if(!validator.isCreditCard(creditCardNumber + "")) {
        validationErrors.push({
          message: "Invalid payment credit card number",
          translationKey: "invalid.payment.creditCardNumber",
          value: payment.creditCardNumber
        });
      }
      var ccv = sanitizeForValidation(payment.ccv);
      if(!ccv ||
         (ccv.length < 3 || ccv.length > 4) ||
         !validator.isInt(ccv)) {
        validationErrors.push({
          message: "Invalid payment ccv",
          translationKey: "invalid.payment.ccv",
          value: payment.ccv
        });
      }
      var month = sanitizeForValidation(payment.expiresMonth + "");
      if(!month ||
          month < 1 ||
          month > 12) {
        validationErrors.push({
          message: "Invalid payment expires month",
          translationKey: "invalid.payment.expiresMonth",
          value: payment.expiresMonth
        });
      }
      var year = sanitizeForValidation(payment.expiresYear + "");
      if(!year ||
          year < moment().year()) {
        validationErrors.push({
          message: "Invalid payment expires year",
          translationKey: "invalid.payment.expiresYear",
          value: payment.expiresYear
        });
      }
      if(moment(payment.expiresMonth + "-" + payment.expiresYear, "MM-YYYY").isBefore(moment().startOf("month"))) {
        validationErrors.push({
          message: "Card has expired",
          translationKey: "invalid.payment.cardHasExpired",
          value: payment.expiresMonth + "/" + payment.expiresYear
        });
      }
    }

    function validateConsumer(consumer) {
      var name = sanitizeForValidation(consumer.name);
      if(!name ||
          name.length < 2 ||
          name.length > 52 ||
          name.match(BLACKLISTED_CHARACTERS)) {
        validationErrors.push({
          message: "Invalid consumer name",
          translationKey: "invalid.consumer.name",
          value: consumer.name
        });
      }
      if(consumer.co && consumer.co.length > 52 || consumer.co.match(BLACKLISTED_CHARACTERS)) {
        validationErrors.push({
          message: "Invalid consumer c/o",
          translationKey: "invalid.consumer.co",
          value: consumer.co
        });
      }
      var streetAddress = sanitizeForValidation(consumer.streetAddress);
      if(!streetAddress ||
          streetAddress.length < 2 ||
          streetAddress.length > 52 ||
          streetAddress.match(BLACKLISTED_CHARACTERS)) {
        validationErrors.push({
          message: "Invalid consumer street address",
          translationKey: "invalid.consumer.streetAddress",
          value: consumer.streetAddress
        });
      }
      if(consumer.streetAddress2 &&
         (consumer.streetAddress2.length > 52 ||
         consumer.streetAddress2.match(BLACKLISTED_CHARACTERS))) {
        validationErrors.push({
          message: "Invalid consumer street address 2",
          translationKey: "invalid.consumer.streetAddress2",
          value: consumer.streetAddress2
        });
      }
      var postalCode = sanitizeForValidation(consumer.postalCode);
      if(!postalCode ||
          postalCode.length < 2 ||
          postalCode.length > 10 ||
          postalCode.match(BLACKLISTED_CHARACTERS)) {
        validationErrors.push({
          message: "Invalid consumer postal code",
          translationKey: "invalid.consumer.postalCode",
          value: consumer.postalCode
        });
      }
      var city = sanitizeForValidation(consumer.city);
      if(!city ||
          city.length < 2 ||
          city.length > 53 ||
          city.match(BLACKLISTED_CHARACTERS)) {
        validationErrors.push({
          message: "Invalid consumer city",
          translationKey: "invalid.consumer.city",
          value: consumer.city
        });
      }
      if(consumer.stateOrProvince &&
         (consumer.stateOrProvince.length > 52 ||
         consumer.stateOrProvince.match(BLACKLISTED_CHARACTERS))) {
        validationErrors.push({
          message: "Invalid consumer state or province",
          translationKey: "invalid.consumer.stateOrProvince",
          value: consumer.stateOrProvince
        });
      }
      var country = sanitizeForValidation(consumer.country);
      if(!country ||
          country.length < 2 ||
          country.length > 53 ||
          country.match(BLACKLISTED_CHARACTERS)) {
        validationErrors.push({
          message: "Invalid consumer country",
          translationKey: "invalid.consumer.country",
          value: consumer.country
        });
      }
      var locale = sanitizeForValidation(consumer.locale) || "en-US";
      if(locale.length < 5 ||
         locale.length > 10 ||
         locale.match(BLACKLISTED_CHARACTERS)) {
        validationErrors.push({
          message: "Invalid consumer locale",
          translationKey: "invalid.consumer.locale",
          value: consumer.locale
        });
      }
    }

    function validateCents(params) {
      if(!validator.isInt(params.value + "", { min: 0, max: Number.MAX_SAFE_INTEGER })) {
        validationErrors.push({
          message: params.message,
          translationKey: params.translationKey,
          value: params.value
        });
      }
    }

    function validateOrder(order) {
      validateCents({
        value: order.sumInCentsIncVat,
        message: "Invalid sum in cents including VAT",
        translationKey: "invalid.order.sumInCentsIncVat"
      });
      validateCents({
        value: order.sumInCentsExcVat,
        message: "Invalid sum in cents excluding VAT",
        translationKey: "invalid.order.sumInCentsExcVat",
      });
      validateCents({
        value: order.vatInCents,
        message: "Invalid VAT in cents excluding VAT",
        translationKey: "invalid.order.vatInCents",
      });
      if(order.referenceId && order.referenceId.length > 255) {
        validationErrors.push({
          value: order.referenceId,
          message: "Invalid order reference ID",
          translationKey: "invalid.order.referenceId",
        });
      }
      if(order.referenceId && !validator.isAlphanumeric(order.referenceId)) {
        validationErrors.push({
          value: order.referenceId,
          message: "Invalid order reference ID",
          translationKey: "invalid.order.referenceId",
        });
      }
    }

    function validateSeller(seller) {
    }

    function validateProducts(products) {
    }

    function validateCallbacks(callbacks) {
    }

    return {
      validate: function() {
        validationErrors = [];
        if(!params.payment.locale) {
          params.payment.locale = "en-US";
        }
        validatePayment(params.payment);
        validateConsumer(params.consumer);
        validateOrder(params.order);
        validateSeller(params.seller);
        validateProducts(params.products);
        validateCallbacks(params.callbacks);
        return validationErrors;
      }
    };
  };
}());
<|endoftext|>


<commit_before>module.exports = {

  types: [
    {value: 'feat',     name: 'feat:     A new feature'},
    {value: 'fix',      name: 'fix:      A bug fix'},
    {value: 'refactor', name: 'refactor: A code change that neither fixes a bug nor adds a feature'},
    {value: 'docs',     name: 'docs:     Documentation only changes'},
    {value: 'style',    name: 'style:    Markup, white-space, formatting, missing semi-colons...'},
    {value: 'perf',     name: 'perf:     A code change that improves performance'},
    {value: 'test',     name: 'test:     Adding missing tests'},
    {value: 'chore',    name: 'chore:    Build process or auxiliary tool changes'},
    {value: 'ci',       name: 'ci:       CI related changes'}
  ],

  scopes: [],

  scopeOverrides: {
    docs: [
      {name: 'readme'},
      {name: 'changelog'},
    ],
  },

  // override the messages, defaults are as follows
  messages: {
    type: 'Select the type of change that you\'re committing:',
    scope: '\nDenote the SCOPE of this change:',
    // used if allowCustomScopes is true
    customScope: 'Denote the SCOPE of this change (optional):',
    subject: 'Write a SHORT, IMPERATIVE tense description of the change:\n',
    body: 'Provide a LONGER description of the change (optional). Use "|" to break new line:\n',
    breaking: 'List any BREAKING CHANGES (optional):\n',
    footer: 'List any ISSUES CLOSED by this change (optional). E.g.: #31, #34:\n',
    confirmCommit: 'Are you sure you want to proceed with the commit above?'
  },

  allowCustomScopes: false,
  allowBreakingChanges: ['feat', 'fix'],

  // limit subject length
  subjectLimit: 100

};<commit_msg>feat: ✨ We now use emojis in our git commit messages again!<commit_after><|endoftext|>


<commit_before>var Snackbar = require('snackbarlightjs');
var Templates = require('../templates');
var getData = require('../lib/get-data.js');

module.exports = function (page) {
  page('/iiif/:type/:id', load, render);

  function load (ctx, next) {
    var opts = {
      headers: { Accept: 'application/vnd.api+json' }
    };
    var type = ctx.params.type;
    var id = ctx.params.id;
    var url = '/api/' + type + '/' + id + '?ajax=true';
    getData(url, opts, function (err, json) {
      if (err) {
        console.error(err);
        Snackbar.create('Error getting data from the server');
        return;
      }
      ctx.json = JSON.stringify(json, null, 2);
      next();
    });
  }

  function render (ctx, next) {
    var pageEl = document.getElementById('main-page');
    pageEl.innerHTML = Templates['api']({api: ctx.json});
  }
};
<commit_msg>fix iiif link<commit_after>var Snackbar = require('snackbarlightjs');
var Templates = require('../templates');
var getData = require('../lib/get-data.js');

module.exports = function (page) {
  page('/iiif/:type/:id', load, render);

  function load (ctx, next) {
    var opts = {
      headers: { Accept: 'application/vnd.api+json' }
    };
    var type = ctx.params.type;
    var id = ctx.params.id;
    var url = '/iiif/' + type + '/' + id;
    getData(url, opts, function (err, json) {
      if (err) {
        console.error(err);
        Snackbar.create('Error getting data from the server');
        return;
      }
      ctx.json = JSON.stringify(json, null, 2);
      next();
    });
  }

  function render (ctx, next) {
    var pageEl = document.getElementById('main-page');
    pageEl.innerHTML = Templates['api']({api: ctx.json});
  }
};
<|endoftext|>


<commit_before>// extends src/nodes/image.js which extends src/node-box-native-view.js

$(function(){

  Iframework.NativeNodes["image-palette"] = Iframework.NativeNodes["image"].extend({

    info: {
      title: "palette",
      author: "ticky+flickr+forresto",
      description: "monochrome by atkinson, bayer, floydsteinberg, or no dither"
    },
    _workerBusy: false,
    initializeModule: function(){
      // Clear canvas
      $(this.canvas).remove();
      delete this.context;
      delete this.canvas;

      // Info
      this.$(".info").text("input an image to make a palette");

      // Palette container
      var paletteDiv = $('

').css({
        "background-color": "black",
        "padding": "1px 0 0 1px"
      });
      this.$(".info").before( paletteDiv );

      // Setup worker
      var self = this;
      this._worker = new Worker('src/nodes/image-palette-worker.js');
      this._worker.addEventListener('message', function (e) {
        // HACK
        self.model.setValue({"palette":e.data});

        self._palette = e.data;
        self.renderPalette(self._palette);
        self.inputsend();
        self._workerBusy = false;
      }, false);
      this._worker.addEventListener('error', function (e) {
        console.log(e);
      }, false);
    },
    inputimage: function(image) {
      if (!this._worker || this._workerBusy) { return false; }

      // Reduce size of big images
      if (image.width > 2 && image.height > 2 && image.width * image.height > 500*500) {
        var width = image.width;
        var height = image.height;
        while (width > 2 && height > 2 && width * height > 500*500) {
          width = Math.floor(width/2);
          height = Math.floor(height/2);
        }
        var small = document.createElement("canvas");
        small.width = width;
        small.height = height;
        small.getContext('2d').drawImage( image, 0, 0, image.width, image.height, 0, 0, width, height );
        image = small;
      }

      try {
        var imageData = image.getContext('2d').getImageData( 0, 0, image.width, image.height );
        this._worker.postMessage({
          imageData: imageData,
          maxColors: this._max
        });
        // Don't process a new frame until this one is done
        this._workerBusy = true;
      } catch(e) {
        // Can't getImageData
        // console.log(e);
      }
    },
    inputpalette: function (palette) {
      this._palette = palette;
      this.renderPalette(palette);
    },
    renderPalette: function(palette){
      this.$(".info, .palette").empty();

      var self = this;
      var clickColor = function(){
        self.send("color", $(this).css("background-color"));
      };
      for (var i=0; i<palette.length; i++) {
        var button = $('<button title="'+palette[i]+'"></button>')
          .css({
            "background-color": palette[i],
            "width": "48px",
            "height": "48px",
            "margin": "0 1px 1px 0",
            "padding": 0,
            "border-width": 0,
            "border-radius": 0
          })
          .click(clickColor);
        this.$(".palette").append(button);
      }
      // this.$(".info").text( palette.toString() );
    },
    inputrandom: function (index) {
      if (this._palette && this._palette.length > 0) {
        var color = this._palette[ Math.floor(this._palette.length * Math.random()) ];
        this.send("color", color);
      }
    },
    inputsendOne: function (index) {
      if (this._palette && index < this._palette.length) {
        this.send("color", this._palette[index]);
      }
    },
    inputsend: function () {
      this.send("palette", this._palette);
    },
    inputs: {
      image: {
        type: "image",
        description: "extract palette from this image"
      },
      palette: {
        description: "color palette (array of css colors)",
        type: "array"
      },
      max: {
        description: "max number of colors in the palette",
        type: "int",
        min: 2,
        max: 256,
        "default": 16
      },
      random: {
        type: "bang",
        description: "send one random color from palette"
      },
      sendOne: {
        type: "int",
        description: "send the color with this index",
        min: 0
      },
      send: {
        type: "bang",
        description: "send the color palette"
      }
    },
    outputs: {
      palette: {
        description: "color palette (array of css colors)",
        type: "array"
      },
      color: {
        description: "one color",
        type: "color"
      }
    }

  });

});
<commit_msg>rgb and hex export<commit_after>// extends src/nodes/image.js which extends src/node-box-native-view.js

$(function(){

  function componentToHex(c) {
    var hex = parseInt( c, 10 ).toString(16);
    return hex.length === 1 ? "0" + hex : hex;
  }

  var rgbToHex = function ( rgb ) {
    var rgbRegex = /^rgb\((\d+),(\d+),(\d+)\)$/ ;
    var result, r, g, b, hex = "";
    if ( (result = rgbRegex.exec(rgb)) ) {
      hex = "#" + componentToHex(result[1]) + componentToHex(result[2]) + componentToHex(result[3]);
      return hex;
    }
    return false;
  };

  var template =
    '

'+
    '
input an image to make a palette
'+
    '<button class="export-rgb">export rgb</button>'+
    '<button class="export-hex">export hex</button>';

  Iframework.NativeNodes["image-palette"] = Iframework.NativeNodes["image"].extend({

    template: _.template(template),
    info: {
      title: "palette",
      author: "nrabinowitz",
      description: "get color palette from image color quantize"
    },
    events: {
      "click .export-rgb" : "exportRGB",
      "click .export-hex" : "exportHex"
    },
    _workerBusy: false,
    initializeModule: function(){
      // Clear canvas (we're extending image to get the droppable)
      $(this.canvas).remove();
      delete this.context;
      delete this.canvas;

      // Setup worker
      var self = this;
      this._worker = new Worker('src/nodes/image-palette-worker.js');
      this._worker.addEventListener('message', function (e) {
        // HACK
        self.set("palette", e.data);

        self._palette = e.data;
        self.renderPalette(self._palette);
        self.inputsend();
        self._workerBusy = false;
      }, false);
      this._worker.addEventListener('error', function (e) {
        console.log(e);
      }, false);
    },
    inputimage: function(image) {
      if (!this._worker || this._workerBusy) { return false; }

      // Reduce size of big images
      if (image.width > 2 && image.height > 2 && image.width * image.height > 500*500) {
        var width = image.width;
        var height = image.height;
        while (width > 2 && height > 2 && width * height > 500*500) {
          width = Math.floor(width/2);
          height = Math.floor(height/2);
        }
        var small = document.createElement("canvas");
        small.width = width;
        small.height = height;
        small.getContext('2d').drawImage( image, 0, 0, image.width, image.height, 0, 0, width, height );
        image = small;
      }

      try {
        var imageData = image.getContext('2d').getImageData( 0, 0, image.width, image.height );
        this._worker.postMessage({
          imageData: imageData,
          maxColors: this._max
        });
        // Don't process a new frame until this one is done
        this._workerBusy = true;
      } catch(e) {
        // Can't getImageData
        // console.log(e);
      }
    },
    inputpalette: function (palette) {
      this._palette = palette;
      this.renderPalette(palette);
    },
    renderPalette: function(palette){
      this.$(".info, .palette").empty();

      var self = this;
      var clickColor = function(){
        var color = $(this).css("background-color");
        self.send("color", color);
        self.$(".info").text(color);
      };
      for (var i=0; i<palette.length; i++) {
        var button = $('<button title="'+palette[i]+'"></button>')
          .css({
            "background-color": palette[i],
            "width": "48px",
            "height": "48px",
            "margin": "0 1px 1px 0",
            "padding": 0,
            "border-width": 0,
            "border-radius": 0
          })
          .click(clickColor);
        this.$(".palette").append(button);
      }
      // this.$(".info").text( palette.toString() );
    },
    exportRGB: function () {
      var code = JSON.stringify(this._palette, null, "  ");
      // window.alert(code);
      window.open( "data:text/javascript," + window.escape(code) );
    },
    exportHex: function () {
      var hexen = [];
      for (var i=0; i<this._palette.length; i++) {
        var hex;
        if ( (hex=rgbToHex(this._palette[i])) ) {
          hexen.push( hex );
        }
      }
      var code = JSON.stringify(hexen, null, "  ");
      // window.alert(code);
      window.open( "data:text/javascript," + window.escape(code) );
    },
    inputrandom: function (index) {
      if (this._palette && this._palette.length > 0) {
        var color = this._palette[ Math.floor(this._palette.length * Math.random()) ];
        this.send("color", color);
      }
    },
    inputsendOne: function (index) {
      if (this._palette && index < this._palette.length) {
        this.send("color", this._palette[index]);
      }
    },
    inputsend: function () {
      this.send("palette", this._palette);
    },
    inputs: {
      image: {
        type: "image",
        description: "extract palette from this image"
      },
      palette: {
        description: "color palette (array of css colors)",
        type: "array"
      },
      max: {
        description: "max number of colors in the palette",
        type: "int",
        min: 2,
        max: 256,
        "default": 16
      },
      random: {
        type: "bang",
        description: "send one random color from palette"
      },
      sendOne: {
        type: "int",
        description: "send the color with this index",
        min: 0
      },
      send: {
        type: "bang",
        description: "send the color palette"
      }
    },
    outputs: {
      palette: {
        description: "color palette (array of css colors)",
        type: "array"
      },
      color: {
        description: "one color",
        type: "color"
      }
    }

  });

});
<|endoftext|>