<commit_before>/*
 * Copyright (c) 2009-2015. Authors: see NOTICE file.
 *
 * Licensed 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.
 */

/**
 * Created by IntelliJ IDEA.
 * User: lrollus
 * Date: 13/04/11
 * Time: 14:15
 * To change this template use File | Settings | File Templates.
 */
var OntologyTreeView = Backbone.View.extend({
    tagName: "div",
    annotationTerm: {},
    //template : _.template($('#project-view-tpl').html()),
    initialize: function (options) {
        this.tree = null;
        this.activeEvent = true;
        this.browseImageView = options.browseImageView;
        this.idAnnotation = null;
    },
    showColors: function () {
        $(this.el).find('.tree').dynatree("getRoot").visit(function (node) {

            if (node.children != null) {
                return;
            } //title is ok

            var title = node.data.title
            var color = node.data.color
            var htmlNode = "<%=   title %> <span style='background-color:<%=   color %>'>   ";
            if (!node.data.isFolder) {
                htmlNode = htmlNode + "(0)";
                htmlNode = htmlNode + " Show: <input type='checkbox' data-term="+node.data.key+" id='showTerm"+node.data.key+"' class='termVisible' checked>";
            }

            var nodeTpl = _.template(htmlNode, {title: title, color: color});

            node.setTitle(nodeTpl);
        });
    },
    render: function () {
        var self = this;
        require(["text!application/templates/explorer/OntologyTreeWrapper.tpl.html"], function (tpl) {
            self.doLayout(tpl);
        });
        return this;
    },
    doLayout: function (tpl) {
        $(this.el).html(_.template(tpl, {isDesktop: !window.app.view.isMobile}));
        this.tree = $(this.el).find('.tree');
        var self = this;

        $(this.el).find('.tree').dynatree({
            checkbox: true,
            selectMode: 2,
            expand: true,
            onExpand: function () {
                self.computeCorrectTextSize();
            },
            children: this.model.toJSON(),
            onSelect: function (select, node) {

                if (!self.activeEvent) {
                    return;
                }
                if (self.idAnnotation == null) {
                    return;
                } // nothing to do

                if (node.isSelected()) {
                    if (self.browseImageView.isCurrentAnnotationUser()) {
                        console.log("link");

                        if (self.browseImageView.currentAnnotation.get("class") == "be.cytomine.ontology.ReviewedAnnotation") {
                            window.app.view.message("Reviewed annotation", "You cannot add a term to an accepted annotation, you must reject it before!", "error");
                            self.activeEvent = false;
                            node.select(false);
                            self.activeEvent = true;

                        } else {
                            self.linkTerm(node.data.key);
                        }

                    } else {
                        self.browseImageView.addTermToReviewPanel(node.data.key);
                    }

                } else if (!node.isSelected()) {
                    if (self.browseImageView.isCurrentAnnotationUser()) {
                        self.unlinkTerm(node.data.key);
                    } else {
                        self.browseImageView.deleteTermFromReviewPanel(node.data.key);
                    }
                }
            },
            onDblClick: function (node, event) {
                node.toggleSelect();
            },
            onRender: function (node, nodeSpan) {
                $(nodeSpan).find("span.dynatree-icon").css({"background-image": "url(css/custom-theme/images/ui-icons_ffffff_256x240.png)"});
//                self.checkTerm();
//

            },

            // The following options are only required, if we have more than one tree on one page:
            initId: "treeData" + this.model.id,
            cookieId: "dynatree-Cb" + this.model.id,
            idPrefix: "dynatree-Cb" + this.model.id + "-"
        });

        self.showColors();

        //expand root, simpliest way ?
        $(this.el).find('.tree').dynatree("getRoot").visit(function (node) {
            if (node.data.key == self.model.id) {
                node.expand(true);
            }
        });

         self.computeCorrectTextSize();

        $(this.el).find(".seeAllTerm").click(function() {
            $(self.el).find('.tree').dynatree("getRoot").visit(function(node){
                node.expand(true);
            });
            $(self.el).find(".termVisible").prop('checked', true);
            self.browseImageView.refreshLayers();
        });
        $(this.el).find(".hideAllTerm").click(function() {
            $(self.el).find('.tree').dynatree("getRoot").visit(function(node){
                node.expand(true);
            });
            $(self.el).find(".termVisible").prop('checked', false);
            self.browseImageView.refreshLayers();
        });

        $(this.el).find(".termVisible").change(function() {
            self.browseImageView.refreshLayers();
        });

        $(this.el).find(".dynatree-title").removeAttr("href");

        return this;
    },
//    checkTerm : function() {
//        console.log("*****************");
//        console.log($(this.el));
//        console.log($(this.el).find(".termVisible"));
//
//        $(this.el).find(".termVisible").prop('checked', true);
//    },

    computeCorrectTextSize :function() {
        var originalFontSize = 12;
       	var sectionWidth = $(this.el).find('.dynatree-container').width()-75;

        $(this.el).find(".dynatree-node").each(function() {
               var spanWidth = $(this).width();
                if(spanWidth>0) {
                    $(this).css({"font-size" : originalFontSize, "line-height" : originalFontSize/1.2 + "px"});
                }

           });

        $(this.el).find(".dynatree-node").each(function() {
               var spanWidth = $(this).width();
                if(spanWidth>0) {
                    var newFontSize = (sectionWidth/spanWidth) * originalFontSize;
                     newFontSize = Math.min(originalFontSize,newFontSize);
                    $(this).css({"font-size" : newFontSize, "line-height" : newFontSize/1.2 + "px"});
                }

           });
        $(this.el).find(".dynatree-title").removeAttr("href");
    },
    expand: function () {
        $(this.el).find('.tree').dynatree("getRoot").visit(function (node) {
            node.expand(true);
        });
    },
    clear: function () {
        var self = this;
        this.activeEvent = false;
        $(this.el).find('.otherUsersTerms').empty();
        $(this.el).find('.tree').dynatree("getRoot").visit(function (node) {
            node.select(false);
            $("#usercount" + node.data.key).text("0");
        });
        this.activeEvent = true;
    },
    clearAnnotation: function () {
        this.idAnnotation = null;
    },
    check: function (idTerm) {
        var self = this;
        self.activeEvent = false;
        $(this.el).find('.tree').dynatree("getRoot").visit(function (node) {
            if (node.data.key == idTerm) {
                node.select(true);
            }
        });
        self.activeEvent = true;
    },
    uncheck: function (idTerm) {
        var self = this;
        self.activeEvent = false;
        $(this.el).find('.tree').dynatree("getRoot").visit(function (node) {
            if (node.data.key == idTerm) {
                node.select(false);
            }
        });
        self.activeEvent = true;
    },
    refresh: function (idAnnotation) {
        var self = this;
        console.log("refresh term for annotation " + idAnnotation);

        //if(self.browseImageView.currentAnnotation.get("class")=="be.cytomine.ontology.ReviewedAnnotation")  return;

        this.idAnnotation = idAnnotation;
        var refreshTree = function (collection, response) {
            console.log("collection.lenght=" + collection.length);
            self.annotationTerm = collection;
            self.clear();
            self.activeEvent = false;
            //check all term for logged user
            var userAnnotationTerm = collection.filter(function (annotationTerm) {
                return annotationTerm.get("user") == window.app.status.user.id;
            });
            _.each(userAnnotationTerm, function (annotationTerm) {
                var idTerm = annotationTerm.get('term');
                self.check(idTerm);
            });
            //update counters

            if(!window.app.status.currentProjectModel.get('blindMode')) {
                //in blind mode, disable counter
                var idTerms = [];
                collection.each(function (annotationTerm) {
                    idTerms.push(annotationTerm.get("term"));
                });
                idTerms = _.uniq(idTerms);
                _.each(idTerms, function (idTerm) {
                    var annotationTerms = collection.filter(function (annotationTerm) {
                        return annotationTerm.get("term") == idTerm;
                    });
                    $("#usercount" + idTerm).text(_.size(annotationTerms));
                });
            }

            self.activeEvent = true;
        }

        new AnnotationTermCollection({idAnnotation: idAnnotation}).fetch({success: refreshTree});
    },
    getTermsChecked: function () {
        var terms = [];
        $(this.el).find('.tree').dynatree("getRoot").visit(function (node) {
            if (node.isSelected()) {
                terms.push(node.data.key);
            }
        });
        return terms;
    },
    linkTerm: function (idTerm) {
        var self = this;
        new AnnotationTermModel({userannotation: this.idAnnotation, term: idTerm}).save({userannotation: this.idAnnotation, term: idTerm},
            {
                success: function (model, response) {
                    window.app.view.message("Annotation Term", response.message, "success");
                    self.browseImageView.reloadAnnotation(self.idAnnotation);
                    self.browseImageView.refreshAnnotationTabs(idTerm);
                },
                error: function (model, response) {
                    var json = $.parseJSON(response.responseText);
                    window.app.view.message("Annotation-Term", json.errors, "error");
                }
            }
        );
    },
    unlinkTerm: function (idTerm) {
        var self = this;
        console.log("unlinkTerm IdTerm " + idTerm + " : " + this.idAnnotation);

        var annotationTerm = self.annotationTerm.find(function (annotationTerm) {
            return (annotationTerm.get("term") == idTerm && annotationTerm.get("user") == window.app.status.user.id);
        });
        new AnnotationTermModel({ id: annotationTerm.id, userannotation: self.idAnnotation, term: idTerm}).destroy({
                success: function (model, response) {
                    window.app.view.message("Annotation Term", response.message, "success");
                    self.browseImageView.reloadAnnotation(self.idAnnotation);
                    self.browseImageView.refreshAnnotationTabs(idTerm);
                },
                error: function (model, response) {
                    var json = $.parseJSON(response.responseText);
                    window.app.view.message("Annotation-Term", json.errors, "error");
                }
            }
        );
    },

    getTermToShow : function() {
        var terms = []
        _.each($(this.el).find(".termVisible:checked"),function(item) {
            var term = $(item).data("term");
            terms.push(term);

        });
        return terms;
    },

    isTermRestriction : function() {
        //check if 1 or N terms are unchecked
        var all = $(this.el).find(".termVisible").length;
        var visible = $(this.el).find(".termVisible:checked").length;

        return all != visible;
    }

});
<commit_msg>double click on show change attached term<commit_after>/*
 * Copyright (c) 2009-2015. Authors: see NOTICE file.
 *
 * Licensed 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.
 */

/**
 * Created by IntelliJ IDEA.
 * User: lrollus
 * Date: 13/04/11
 * Time: 14:15
 * To change this template use File | Settings | File Templates.
 */
var OntologyTreeView = Backbone.View.extend({
    tagName: "div",
    annotationTerm: {},
    //template : _.template($('#project-view-tpl').html()),
    initialize: function (options) {
        this.tree = null;
        this.activeEvent = true;
        this.browseImageView = options.browseImageView;
        this.idAnnotation = null;
    },
    showColors: function () {
        $(this.el).find('.tree').dynatree("getRoot").visit(function (node) {

            if (node.children != null) {
                return;
            } //title is ok

            var title = node.data.title
            var color = node.data.color
            var htmlNode = "<%=   title %> <span style='background-color:<%=   color %>'>   ";
            if (!node.data.isFolder) {
                htmlNode = htmlNode + "(0)";
                htmlNode = htmlNode + " Show: <input type='checkbox' data-term="+node.data.key+" id='showTerm"+node.data.key+"' class='termVisible' checked>";
            }

            var nodeTpl = _.template(htmlNode, {title: title, color: color});

            node.setTitle(nodeTpl);
        });
    },
    render: function () {
        var self = this;
        require(["text!application/templates/explorer/OntologyTreeWrapper.tpl.html"], function (tpl) {
            self.doLayout(tpl);
        });
        return this;
    },
    doLayout: function (tpl) {
        $(this.el).html(_.template(tpl, {isDesktop: !window.app.view.isMobile}));
        this.tree = $(this.el).find('.tree');
        var self = this;

        $(this.el).find('.tree').dynatree({
            checkbox: true,
            selectMode: 2,
            expand: true,
            onExpand: function () {
                self.computeCorrectTextSize();
            },
            children: this.model.toJSON(),
            onSelect: function (select, node) {

                if (!self.activeEvent) {
                    return;
                }
                if (self.idAnnotation == null) {
                    return;
                } // nothing to do

                if (node.isSelected()) {
                    if (self.browseImageView.isCurrentAnnotationUser()) {
                        console.log("link");

                        if (self.browseImageView.currentAnnotation.get("class") == "be.cytomine.ontology.ReviewedAnnotation") {
                            window.app.view.message("Reviewed annotation", "You cannot add a term to an accepted annotation, you must reject it before!", "error");
                            self.activeEvent = false;
                            node.select(false);
                            self.activeEvent = true;

                        } else {
                            self.linkTerm(node.data.key);
                        }

                    } else {
                        self.browseImageView.addTermToReviewPanel(node.data.key);
                    }

                } else if (!node.isSelected()) {
                    if (self.browseImageView.isCurrentAnnotationUser()) {
                        self.unlinkTerm(node.data.key);
                    } else {
                        self.browseImageView.deleteTermFromReviewPanel(node.data.key);
                    }
                }
            },
            onDblClick: function (node, event) {
                if(event.target.id.indexOf("Term")<0) { // else we can link or unling term by dbl click on showTerm
                    node.toggleSelect();
                }
            },
            onRender: function (node, nodeSpan) {
                $(nodeSpan).find("span.dynatree-icon").css({"background-image": "url(css/custom-theme/images/ui-icons_ffffff_256x240.png)"});
//                self.checkTerm();
//

            },

            // The following options are only required, if we have more than one tree on one page:
            initId: "treeData" + this.model.id,
            cookieId: "dynatree-Cb" + this.model.id,
            idPrefix: "dynatree-Cb" + this.model.id + "-"
        });

        self.showColors();

        //expand root, simpliest way ?
        $(this.el).find('.tree').dynatree("getRoot").visit(function (node) {
            if (node.data.key == self.model.id) {
                node.expand(true);
            }
        });

         self.computeCorrectTextSize();

        $(this.el).find(".seeAllTerm").click(function() {
            $(self.el).find('.tree').dynatree("getRoot").visit(function(node){
                node.expand(true);
            });
            $(self.el).find(".termVisible").prop('checked', true);
            self.browseImageView.refreshLayers();
        });
        $(this.el).find(".hideAllTerm").click(function() {
            $(self.el).find('.tree').dynatree("getRoot").visit(function(node){
                node.expand(true);
            });
            $(self.el).find(".termVisible").prop('checked', false);
            self.browseImageView.refreshLayers();
        });

        $(this.el).find(".termVisible").change(function() {
            self.browseImageView.refreshLayers();
        });

        $(this.el).find(".dynatree-title").removeAttr("href");

        return this;
    },
//    checkTerm : function() {
//        console.log("*****************");
//        console.log($(this.el));
//        console.log($(this.el).find(".termVisible"));
//
//        $(this.el).find(".termVisible").prop('checked', true);
//    },

    computeCorrectTextSize :function() {
        var originalFontSize = 12;
       	var sectionWidth = $(this.el).find('.dynatree-container').width()-75;

        $(this.el).find(".dynatree-node").each(function() {
               var spanWidth = $(this).width();
                if(spanWidth>0) {
                    $(this).css({"font-size" : originalFontSize, "line-height" : originalFontSize/1.2 + "px"});
                }

           });

        $(this.el).find(".dynatree-node").each(function() {
               var spanWidth = $(this).width();
                if(spanWidth>0) {
                    var newFontSize = (sectionWidth/spanWidth) * originalFontSize;
                     newFontSize = Math.min(originalFontSize,newFontSize);
                    $(this).css({"font-size" : newFontSize, "line-height" : newFontSize/1.2 + "px"});
                }

           });
        $(this.el).find(".dynatree-title").removeAttr("href");
    },
    expand: function () {
        $(this.el).find('.tree').dynatree("getRoot").visit(function (node) {
            node.expand(true);
        });
    },
    clear: function () {
        var self = this;
        this.activeEvent = false;
        $(this.el).find('.otherUsersTerms').empty();
        $(this.el).find('.tree').dynatree("getRoot").visit(function (node) {
            node.select(false);
            $("#usercount" + node.data.key).text("0");
        });
        this.activeEvent = true;
    },
    clearAnnotation: function () {
        this.idAnnotation = null;
    },
    check: function (idTerm) {
        var self = this;
        self.activeEvent = false;
        $(this.el).find('.tree').dynatree("getRoot").visit(function (node) {
            if (node.data.key == idTerm) {
                node.select(true);
            }
        });
        self.activeEvent = true;
    },
    uncheck: function (idTerm) {
        var self = this;
        self.activeEvent = false;
        $(this.el).find('.tree').dynatree("getRoot").visit(function (node) {
            if (node.data.key == idTerm) {
                node.select(false);
            }
        });
        self.activeEvent = true;
    },
    refresh: function (idAnnotation) {
        var self = this;
        console.log("refresh term for annotation " + idAnnotation);

        //if(self.browseImageView.currentAnnotation.get("class")=="be.cytomine.ontology.ReviewedAnnotation")  return;

        this.idAnnotation = idAnnotation;
        var refreshTree = function (collection, response) {
            console.log("collection.lenght=" + collection.length);
            self.annotationTerm = collection;
            self.clear();
            self.activeEvent = false;
            //check all term for logged user
            var userAnnotationTerm = collection.filter(function (annotationTerm) {
                return annotationTerm.get("user") == window.app.status.user.id;
            });
            _.each(userAnnotationTerm, function (annotationTerm) {
                var idTerm = annotationTerm.get('term');
                self.check(idTerm);
            });
            //update counters

            if(!window.app.status.currentProjectModel.get('blindMode')) {
                //in blind mode, disable counter
                var idTerms = [];
                collection.each(function (annotationTerm) {
                    idTerms.push(annotationTerm.get("term"));
                });
                idTerms = _.uniq(idTerms);
                _.each(idTerms, function (idTerm) {
                    var annotationTerms = collection.filter(function (annotationTerm) {
                        return annotationTerm.get("term") == idTerm;
                    });
                    $("#usercount" + idTerm).text(_.size(annotationTerms));
                });
            }

            self.activeEvent = true;
        }

        new AnnotationTermCollection({idAnnotation: idAnnotation}).fetch({success: refreshTree});
    },
    getTermsChecked: function () {
        var terms = [];
        $(this.el).find('.tree').dynatree("getRoot").visit(function (node) {
            if (node.isSelected()) {
                terms.push(node.data.key);
            }
        });
        return terms;
    },
    linkTerm: function (idTerm) {
        var self = this;
        new AnnotationTermModel({userannotation: this.idAnnotation, term: idTerm}).save({userannotation: this.idAnnotation, term: idTerm},
            {
                success: function (model, response) {
                    window.app.view.message("Annotation Term", response.message, "success");
                    self.browseImageView.reloadAnnotation(self.idAnnotation);
                    self.browseImageView.refreshAnnotationTabs(idTerm);
                },
                error: function (model, response) {
                    var json = $.parseJSON(response.responseText);
                    window.app.view.message("Annotation-Term", json.errors, "error");
                }
            }
        );
    },
    unlinkTerm: function (idTerm) {
        var self = this;
        console.log("unlinkTerm IdTerm " + idTerm + " : " + this.idAnnotation);

        var annotationTerm = self.annotationTerm.find(function (annotationTerm) {
            return (annotationTerm.get("term") == idTerm && annotationTerm.get("user") == window.app.status.user.id);
        });
        new AnnotationTermModel({ id: annotationTerm.id, userannotation: self.idAnnotation, term: idTerm}).destroy({
                success: function (model, response) {
                    window.app.view.message("Annotation Term", response.message, "success");
                    self.browseImageView.reloadAnnotation(self.idAnnotation);
                    self.browseImageView.refreshAnnotationTabs(idTerm);
                },
                error: function (model, response) {
                    var json = $.parseJSON(response.responseText);
                    window.app.view.message("Annotation-Term", json.errors, "error");
                }
            }
        );
    },

    getTermToShow : function() {
        var terms = []
        _.each($(this.el).find(".termVisible:checked"),function(item) {
            var term = $(item).data("term");
            terms.push(term);

        });
        return terms;
    },

    isTermRestriction : function() {
        //check if 1 or N terms are unchecked
        var all = $(this.el).find(".termVisible").length;
        var visible = $(this.el).find(".termVisible:checked").length;

        return all != visible;
    }

});
<|endoftext|>


<commit_before>'use strict';

let paper = require('js/paper-core.min');

const SHADOW_ITERATIONS = 50;

class IconShadow {

    /**
     * @param iconPath path of the icon used to construct the shadow
     * @param iconBase of the icon used to cut the shadow
     */
    constructor(iconPath, iconBase) {
        this.iconPath = iconPath;
        this.iconBase = iconBase;
    }

    /**
     * Calculates the shadow but does not (!) apply it.
     */
    calculateShadow() {
        var iconShadowPath = this.iconPath.clone();
        var iconPathCopy = this.iconPath.clone();

        // calculate translation such that icon is at least (!) moved (iconDiagonal, iconDiagonal) to bottom right
        var iconPathDiagonal = this.getIconPathDiagonal();
        var shadowOffset = iconPathDiagonal * 1.1 / SHADOW_ITERATIONS;
        var translation = new paper.Point(shadowOffset, shadowOffset);

        // create + translate + unite copies of shadow
        for (var i = 1; i <= SHADOW_ITERATIONS; ++i) {
            iconPathCopy.translate(translation);
            var newShadowPath = iconShadowPath.unite(iconPathCopy);
            iconShadowPath.remove();
            iconShadowPath = newShadowPath;
        }
        iconPathCopy.remove();

        // convert CompoundPath to regular Path
        newShadowPath = new paper.Path(iconShadowPath.pathData);
        iconShadowPath.remove();
        iconShadowPath = newShadowPath;

        // create 'nicer' shadow path
        this.simplifyShadowPath(iconShadowPath, shadowOffset);

        // store original shadow and apply
        iconShadowPath.visible = false;
        this.iconShadowPath = iconShadowPath;
        this.assertLongShadow();
    }

    /**
     * @param scale factor to scale this shadow by
     */
    scale(scale) {
        this.iconShadowPath.scale(scale, this.iconPath.position);
        this.applyShadow();
    }

    /**
     * Remove this shadow form the canvas.
     */
    remove() {
        this.iconShadowPath.remove();
        if (this.appliedIconShadowPath) this.appliedIconShadowPath.remove();
    }

    /**
     * this.iconShadowPath is not actually visible on the canvas, but
     * rather serves as a template for the actual shadow path which is
     * cut to fit the base.
     */
    applyShadow() {
        if (this.appliedIconShadowPath) this.appliedIconShadowPath.remove();

        // cut shadow to base
        var basePath = this.iconBase.getPathWithoutShadows();
        this.appliedIconShadowPath = this.iconShadowPath.intersect(basePath);

        // shadow color
        this.appliedIconShadowPath.fillColor = {
            gradient: {
                stops:  [
                    [new paper.Color(0, 0, 0, 0.3), 0.1],
                    [new paper.Color(0, 0, 0, 0), 0.8]
                ]
            },
            origin: basePath.bounds.topLeft,
            destination: basePath.bounds.bottomRight
        };

        // move shadow below icon
        this.appliedIconShadowPath.moveBelow(this.iconPath);
    }

    /**
     * Asserts that the template shadow is very (!) long such that
     * its bottom right edge will never show when moving / scaling the shadow.
     */
    assertLongShadow() {
        var points = this.getBottomRightShadowVertices();
        for (var i = 0; i < points.length; ++i) {
            var point = points[i];
            point.x = point.x + 1000000; // very long ;)
            point.y = point.y + 1000000;
        }
    }

    /**
     * Returns all vertices which belong to the bottom right edge of the shadow
     * (vertices which have to be moved to extend the length of the shadow).
     */
    getBottomRightShadowVertices() {
        var iconPathDiagonal = this.getIconPathDiagonal();
        var topLeft = this.iconShadowPath.bounds.topLeft;
        var result = [];
        for (var i = 0; i < this.iconShadowPath.segments.length; ++i) {
            var point = this.iconShadowPath.segments[i].point;
            if (topLeft.getDistance(point) <= iconPathDiagonal) continue;
            result.push(point);
        }
        return result;
    }

    getIconPathDiagonal() {
        return Math.sqrt(Math.pow(Math.max(this.iconPath.bounds.width, this.iconPath.bounds.height), 2) * 2);
    }

    /**
     * Simplifies the path of a shadow by searching for unnecessary points which were created
     * while shifting the original icon path.
     *
     * Example:
     *
     * o
     *   o
     *     o
     *
     * Would be simplified to:
     *
     * o
     *
     *     o
     */
    simplifyShadowPath(iconShadowPath, shadowOffset) {
        var offsetDistance = Math.round(100 * Math.sqrt(shadowOffset * shadowOffset * 2)) / 100;
        var doubleOffsetDistance = Math.round(100 * Math.sqrt(shadowOffset * shadowOffset * 2) * 2) / 100;
        var secondLastPoint;
        var lastPoint;

        var matchCount = 0;
        var endOfMatch = false;
        var indicesToRemove = [];

        // iterate over all path points and find 'close' pairs (distance equal to the offset used for creating the shadow)
        for (var i = 0; i < iconShadowPath.segments.length; ++i) {
            var point = iconShadowPath.segments[i].point;
            if (secondLastPoint) {
                var distance = Math.round(100 * point.getDistance(secondLastPoint)) / 100;
                if (distance === offsetDistance || distance === doubleOffsetDistance) {
                    ++matchCount;
                    endOfMatch = false;
                } else {
                    endOfMatch = true;
                }
            }

            if (endOfMatch === true && matchCount > 0) {
                var msg = '';
                for (var pointIdx = i - 1 - matchCount; pointIdx < i - 1; ++pointIdx) {
                    msg = msg + pointIdx + ', ';
                    indicesToRemove.push(pointIdx);
                }
                matchCount = 0;
                endOfMatch = true;
            }

            secondLastPoint = lastPoint;
            lastPoint = point;
        }

        // actually remove indices from iconShadowPath
        indicesToRemove.reverse();
        for (i = 0; i < indicesToRemove.length; ++i) {
            iconShadowPath.removeSegment(indicesToRemove[i]);
        }
    }

}

module.exports = IconShadow;
<commit_msg>Do not export shadow template<commit_after>'use strict';

let paper = require('js/paper-core.min');

const SHADOW_ITERATIONS = 50;

class IconShadow {

    /**
     * @param iconPath path of the icon used to construct the shadow
     * @param iconBase of the icon used to cut the shadow
     */
    constructor(iconPath, iconBase) {
        this.iconPath = iconPath;
        this.iconBase = iconBase;
    }

    /**
     * Calculates the shadow but does not (!) apply it.
     */
    calculateShadow() {
        var iconShadowPath = this.iconPath.clone();
        var iconPathCopy = this.iconPath.clone();

        // calculate translation such that icon is at least (!) moved (iconDiagonal, iconDiagonal) to bottom right
        var iconPathDiagonal = this.getIconPathDiagonal();
        var shadowOffset = iconPathDiagonal * 1.1 / SHADOW_ITERATIONS;
        var translation = new paper.Point(shadowOffset, shadowOffset);

        // create + translate + unite copies of shadow
        for (var i = 1; i <= SHADOW_ITERATIONS; ++i) {
            iconPathCopy.translate(translation);
            var newShadowPath = iconShadowPath.unite(iconPathCopy);
            iconShadowPath.remove();
            iconShadowPath = newShadowPath;
        }
        iconPathCopy.remove();

        // convert CompoundPath to regular Path
        newShadowPath = new paper.Path(iconShadowPath.pathData);
        iconShadowPath.remove();
        iconShadowPath = newShadowPath;

        // create 'nicer' shadow path
        this.simplifyShadowPath(iconShadowPath, shadowOffset);

        // store original shadow and apply
        iconShadowPath.remove();
        this.iconShadowPath = iconShadowPath;
        this.assertLongShadow();
    }

    /**
     * @param scale factor to scale this shadow by
     */
    scale(scale) {
        this.iconShadowPath.scale(scale, this.iconPath.position);
        this.applyShadow();
    }

    /**
     * Remove this shadow form the canvas.
     */
    remove() {
        this.iconShadowPath.remove();
        if (this.appliedIconShadowPath) this.appliedIconShadowPath.remove();
    }

    /**
     * this.iconShadowPath is not actually visible on the canvas, but
     * rather serves as a template for the actual shadow path which is
     * cut to fit the base.
     */
    applyShadow() {
        if (this.appliedIconShadowPath) this.appliedIconShadowPath.remove();

        // cut shadow to base
        var basePath = this.iconBase.getPathWithoutShadows();
        this.appliedIconShadowPath = this.iconShadowPath.intersect(basePath);

        // shadow color
        this.appliedIconShadowPath.fillColor = {
            gradient: {
                stops:  [
                    [new paper.Color(0, 0, 0, 0.3), 0.1],
                    [new paper.Color(0, 0, 0, 0), 0.8]
                ]
            },
            origin: basePath.bounds.topLeft,
            destination: basePath.bounds.bottomRight
        };

        // move shadow below icon
        this.appliedIconShadowPath.moveBelow(this.iconPath);
    }

    /**
     * Asserts that the template shadow is very (!) long such that
     * its bottom right edge will never show when moving / scaling the shadow.
     */
    assertLongShadow() {
        var points = this.getBottomRightShadowVertices();
        for (var i = 0; i < points.length; ++i) {
            var point = points[i];
            point.x = point.x + 1000000; // very long ;)
            point.y = point.y + 1000000;
        }
    }

    /**
     * Returns all vertices which belong to the bottom right edge of the shadow
     * (vertices which have to be moved to extend the length of the shadow).
     */
    getBottomRightShadowVertices() {
        var iconPathDiagonal = this.getIconPathDiagonal();
        var topLeft = this.iconShadowPath.bounds.topLeft;
        var result = [];
        for (var i = 0; i < this.iconShadowPath.segments.length; ++i) {
            var point = this.iconShadowPath.segments[i].point;
            if (topLeft.getDistance(point) <= iconPathDiagonal) continue;
            result.push(point);
        }
        return result;
    }

    getIconPathDiagonal() {
        return Math.sqrt(Math.pow(Math.max(this.iconPath.bounds.width, this.iconPath.bounds.height), 2) * 2);
    }

    /**
     * Simplifies the path of a shadow by searching for unnecessary points which were created
     * while shifting the original icon path.
     *
     * Example:
     *
     * o
     *   o
     *     o
     *
     * Would be simplified to:
     *
     * o
     *
     *     o
     */
    simplifyShadowPath(iconShadowPath, shadowOffset) {
        var offsetDistance = Math.round(100 * Math.sqrt(shadowOffset * shadowOffset * 2)) / 100;
        var doubleOffsetDistance = Math.round(100 * Math.sqrt(shadowOffset * shadowOffset * 2) * 2) / 100;
        var secondLastPoint;
        var lastPoint;

        var matchCount = 0;
        var endOfMatch = false;
        var indicesToRemove = [];

        // iterate over all path points and find 'close' pairs (distance equal to the offset used for creating the shadow)
        for (var i = 0; i < iconShadowPath.segments.length; ++i) {
            var point = iconShadowPath.segments[i].point;
            if (secondLastPoint) {
                var distance = Math.round(100 * point.getDistance(secondLastPoint)) / 100;
                if (distance === offsetDistance || distance === doubleOffsetDistance) {
                    ++matchCount;
                    endOfMatch = false;
                } else {
                    endOfMatch = true;
                }
            }

            if (endOfMatch === true && matchCount > 0) {
                var msg = '';
                for (var pointIdx = i - 1 - matchCount; pointIdx < i - 1; ++pointIdx) {
                    msg = msg + pointIdx + ', ';
                    indicesToRemove.push(pointIdx);
                }
                matchCount = 0;
                endOfMatch = true;
            }

            secondLastPoint = lastPoint;
            lastPoint = point;
        }

        // actually remove indices from iconShadowPath
        indicesToRemove.reverse();
        for (i = 0; i < indicesToRemove.length; ++i) {
            iconShadowPath.removeSegment(indicesToRemove[i]);
        }
    }

}

module.exports = IconShadow;
<|endoftext|>


<commit_before>'use strict';

define(['app', 'extended-route-provider','scbd-angularjs-services', 'services', 'filters', 'realm-configuration'], function (app) {

    app.value("realm", {value:"ABS"});
    app.value("schemaTypes", [ "absNationalReport", "absPermit", "absCheckpoint", "absCheckpointCommunique", "authority", "measure", "database", "resource", "modelContractualClause", "communityProtocol" ]);
    app.value("showHelp", {value:{ 'show':true, 'glossary':true, 'showTour':false, 'hasTour':false}});

    app.config(['extendedRouteProvider', '$locationProvider', function ($routeProvider, $locationProvider) {

        $locationProvider.html5Mode(true);
        $locationProvider.hashPrefix('!');

        $routeProvider.
            when('/',                            { templateUrl: '/app/views/home/index.html',                       label:'ABSCH',                              resolveController: true, resolveUser: true}).
            when('/commonformat',                { templateUrl: '/app/views/common-formats.html',                   label:'Common Formats',                     resolveController: true, resolveUser: true}).
            when('/help',                        { templateUrl: '/app/views/help/help.html',                        label:'Help',                               resolveController: true, resolveUser: true}).
            when('/help/about',                  { templateUrl: '/app/views/help/about/about.html',                 label:'About the ABSCH',                    resolveController: true, resolveUser: true}).
            when('/about', { redirectTo: '/help/about/absch' }).
            when('/help/presentations/',         { templateUrl: '/app/views/help/presentations/home.html',          label:'Presentations',                      resolveController: true, resolveUser: true}).
            when('/help/accounts',               { templateUrl: '/app/views/help/accounts/accounts.html',           label:'CBD Accounts',                       resolveController: true, resolveUser: true}).
            when('/help/search',                 { templateUrl: '/app/views/help/search/search.html',               label:'Finding Information',                resolveController: true, resolveUser: true}).
            when('/help/tours',                  { templateUrl: '/app/views/help/tours/tours.html',                 label:'Tours',                              resolveController: true, resolveUser: true}).
            when('/help/register',               { templateUrl: '/app/views/help/register/register.html',           label:'Submitting Information',             resolveController: true, resolveUser: true}).

            when('/forums',                        { templateUrl: '/app/views/forums/forum-list-view.html',         label:'Forums',       resolveController: true, resolveUser: true }).

            when('/forums/iac-trg',          { redirectTo:'/forums/iac'}).
            when('/forums/iac',              { templateUrl: '/app/views/forums/thread-list-view.html'   ,label:'IAC', resolveController: true, resolveUser: true, forumId:17433, postUrl:'/forums/iac', text:'IAC' }).
            when('/forums/iac/:threadId',    { templateUrl: '/app/views/forums/post-list-view.html'     ,label:'Thread-Subject', resolveController: true, resolveUser: true, forumId:17433, forumListUrl:'/forums/iac/', text:'IAC'}).

            when('/forums/vlr',                    { templateUrl: '/app/views/forums/thread-list-view.html'  ,label:'VLR'  ,resolveController: true, resolveUser: true, forumId:17384, postUrl:'/forums/vlr', text:'VLR' }).
            when('/forums/vlr/:threadId',          { templateUrl: '/app/views/forums/post-list-view.html'    ,label:'Thread-Subject'  ,resolveController: true, resolveUser: true, forumId:17384, forumListUrl:'/forums/vlr/', text:'VLR'}).
            when('/forums/caribbean',              { templateUrl: '/app/views/forums/thread-list-view.html'  ,label:'Caribbean'  ,resolveController: true, resolveUser: true, forumId:17378, postUrl:'/forums/caribbean', text:'Caribbean Region Forum' }).
            when('/forums/caribbean/:threadId',    { templateUrl: '/app/views/forums/post-list-view.html'    ,label:'Thread-Subject'  ,resolveController: true, resolveUser: true, forumId:17378, forumListUrl:'/forums/caribbean/', text:'Caribbean Region Forum'}).
            //when('/forums/caribbean region',              { templateUrl: '/app/views/forums/thread-list-view.html'   ,resolveController: true, resolveUser: true, forumId:17378, postUrl:'/forums/caribbean region' }).
            //when('/forums/caribbean region/:threadId',    { templateUrl: '/app/views/forums/post-list-view.html'     ,resolveController: true, resolveUser: true, forumId:17378, forumListUrl:'/forums/caribbean region/'}).
            when('/forums/art10_groups',              { templateUrl: '/app/views/forums/thread-list-view.html' ,label:'Art 10 Groups'  ,resolveController: true, resolveUser: true, forumId:17316, postUrl:'/forums/art10_groups', text:'Forum on Article 10' }).
            when('/forums/art10_groups/:threadId',    { templateUrl: '/app/views/forums/post-list-view.html'   ,label:'Thread-Subject'  ,resolveController: true, resolveUser: true, forumId:17316, forumListUrl:'/forums/art10_groups/', text:'Forum on Article 10' }).

            when('/mailbox',                        { templateUrl: '/app/views/mailbox/inbox.html',         label:'Mailbox',       resolveController: true, resolveUser: true }).
            when('/mailbox/:mailId',                { templateUrl: '/app/views/mailbox/inbox.html',         label:'Mailbox',       resolveController: true, resolveUser: true }).

            when('/search/new',                             { templateUrl: '/app/views/search/search.html',   label:'Search',         resolveController: true, resolveUser: true}).
            when('/search/new/byCountry',                   { templateUrl: '/app/views/search/country-search.html',   label:'Search',         resolveController: true, resolveUser: true}).

            // when('/search/new/measurematrix',                   { templateUrl: '/app/views/search/measure-matrix.html',   label:'Matrix',         resolveController: true, resolveUser: true}).
            // when('/search/new/measurematrix/:uniqueId',         { templateUrl: '/app/views/search/measure-matrix.html',   label:'Matrix',         resolveController: true, resolveUser: true}).
            when('/measurematrix/:code',            { templateUrl: '/app/views/search/measure-matrix-countries.html',   label:'Measures Matrix',         resolveController: true, resolveUser: true}).

            when('/find',                                 { templateUrl: '/app/views/search/find.html',   label:'Find Information',         resolveController: true, resolveUser: true}).
            when('/search',                                 { templateUrl: '/app/views/search/find.html',   label:'Find Information',         resolveController: true, resolveUser: true}).
            // when('/search/:documentSchema',                 { templateUrl: '/app/views/search/search.html',   label:'Search',         resolveController: true, resolveUser: true}).
            // when('/search/:documentSchema/:countryCode',    { templateUrl: '/app/views/search/search.html',   label:'Search',         resolveController: true, resolveUser: true}).
            // when('/find/simple',                            { templateUrl: '/app/views/find/simple.html',   label:'Simple Search',  resolveController: true, resolveUser: true}).
            when('/search/national-records/:documentSchema',              { templateUrl: '/app/views/search/search.html',   label:'Search',         resolveController: true, resolveUser: true, type:'national'}).
            when('/search/countries/:countryCode?',                       { templateUrl: '/app/views/search/search.html',   label:'Search',         resolveController: true, resolveUser: true, type:'countryProfile'}).
            when('/search/reference-records/:documentSchema',             { templateUrl: '/app/views/search/search.html',   label:'Search',         resolveController: true, resolveUser: true, type:'reference'}).
            // when('/find',                                   { redirectTo:'/search'}).

            when('/countries',                   { templateUrl: '/app/views/countries/index.html',       label:'Country Information',      resolveController: true, resolveUser: true}).
            when('/countries/:code',             { templateUrl: '/app/views/countries/profiles.html',       label:'Country Profile', param:'true',      resolveController: true, resolveUser: true}).
            when('/countries/:code/:schema',     { templateUrl: '/app/views/countries/profiles.html',       label:'Country Profile', param:'true',      resolveController: true, resolveUser: true}).

            when('/database/record',             { templateUrl: '/app/views/forms/view/records-id.html'     ,resolveController: true, resolveUser: true}).
            when('/database/record/:documentID',  { templateUrl: '/app/views/forms/view/records-id.html'     ,resolveController: true, resolveUser: true}).
            when('/database/record/:documentID/:revision', { templateUrl: '/app/views/forms/view/records-id.html'     ,resolveController: true, resolveUser: true}).
            when('/database/:documentID',                           { templateUrl: '/app/views/forms/view/records-id.html', label:'Record',  param:'true',  resolveController: true, resolveUser: true}).
            when('/database/:documentSchema/:documentID',           { templateUrl: '/app/views/forms/view/records-id.html', label:'Record',  param:'true',  resolveController: true, resolveUser: true}).
            when('/database/:documentSchema/:documentID/:revision', { templateUrl: '/app/views/forms/view/records-id.html', label:'Record',  param:'true',  resolveController: true, resolveUser: true}).

            when('/register/tasks/:id',                                 {templateUrl: '/app/views/tasks/tasks-id.html',             label:'Management Center',  param:'true', resolveController: true, resolveUser: true}).
            when('/register/tasks/:id/:activity',                       {templateUrl: '/app/views/tasks/tasks-id-activity.html',    label:'Management Center',  param:'true', resolveController: true, resolveUser: true}).
            when('/register/dashboard',                                 {templateUrl: '/app/views/register/register.html',          label:'Management Center',  param:'true', resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/register/dashboard.html',}).
            when('/dashboard',                                          {redirectTo:  '/register/dashboard'}).

            when('/register',                                           {templateUrl: '/app/views/register/register.html',          label:'Management Center',  param:'true', resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/register/dashboard.html',}).
            when('/register/requests',                                  {templateUrl: '/app/views/register/register.html',          label:'Requests',  param:'true', resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/tasks/my-tasks.directive.html',    type : 'all'}).
            when('/register/requests/:workflowId',                      {templateUrl: '/app/views/register/register.html',          label:'Requests',  param:'true', resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/tasks/my-tasks.directive.html',type : 'all'}).
            when('/register/requests/:type/:status',                    {templateUrl: '/app/views/register/register.html',          label:'Requests',  param:'true', resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/tasks/my-tasks.directive.html',}).
            when('/register/:document_type',                            {templateUrl: '/app/views/register/register.html',          label:'document_type',  param:'true', resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/register/type_document_list.html',}).
            when('/register/:document_type/new',                        {templateUrl: '/app/views/register/register.html',          label:'New',  param:'true', resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/forms/edit/edit--', }).
            when('/register/:document_type/help',                       {templateUrl: '/app/views/register/register.html',          label:'document_type',  param:'true', resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/register/type_document_list.html',}).
            when('/register/:document_type/:identifier/edit',           {templateUrl: '/app/views/register/register.html',          label:'Edit',  param:'true', resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/forms/edit/edit--', }).
            when('/register/:document_type/:identifier/edit/:tour',     {templateUrl: '/app/views/register/register.html',          label:'Edit',  param:'true', resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/forms/edit/edit--',  }).

            when('/workshops/lac',               { templateUrl: '/app/views/workshops/lac.html',            label:'Workshops',            resolveController: true, resolveUser: true}).
            when('/workshops/caribbean',         { templateUrl: '/app/views/workshops/caribbean.html',      label:'Workshops',        resolveController: true, resolveUser: true}).

            //when('/searchforum.shtml',           { templateUrl:'/app/views/about.html#iac'}).
            when('/oauth2/callback',             { templateUrl: '/app/views/oauth2/callback.html',          resolveController: true, resolveUser: true}).
            when('/certificate/:documentNumber', { templateUrl: '/app/views/forms/view/records-id.html',    resolveController: true, resolveUser: true}).

            when('/commonformat', {templateUrl: '/app/views/about/about.html',resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/about/common-formats.html',ignoreSubController: true,}).
            when('/commonformat',           { redirectTo:'/about/common-formats' }).

            // when('/help/presentations/:folder/:document_type', {templateUrl: '/app/views/help/presentations/presentation.html',resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/help/presentations/:folder/-',ignoreSubController: true,}).
            // when('/help/presentations/:folder', { redirectTo: '/help/presentations/:folder/start' }).

             when('/help/presentations', {templateUrl: '/app/views/help/presentations.html',   label:'Presentations and Workshops',   resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/register/contacts.html',}).

            when('/contacts', {templateUrl: '/app/views/register/register.html',resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/register/contacts.html',}).

            when('/searchforum.shtml',      { redirectTo:'/about/portal10' }).
            when('/commonformat',           { redirectTo:'/about/common-formats' }).

            when('/help/manage/:term?', {templateUrl: '/app/views/help/forms/edit-help.html',resolveController: true,resolveUser: true, label:'Forms Help'}).

            //when('/help/glossary', {templateUrl: '/app/views/help/forms/glossary.html',resolveController: true,resolveUser: true, label:'Glossary'}).
            when('/help/glossary/tags/:tag', {templateUrl: '/app/views/help/forms/glossary-term.html',resolveController: true,resolveUser: true, schema:'help-glossarys', label:'Tags'}).
            when('/help/glossary/:term?', {templateUrl: '/app/views/help/forms/glossary-term.html',resolveController: true,resolveUser: true, schema:'help-glossarys', label:'lableText'}).

            //when('/help/faq', {templateUrl: '/app/views/help/forms/faq.html',resolveController: true,resolveUser: true, label:'FAQ'}).
            when('/help/faq/:term?', {templateUrl: '/app/views/help/faq.html',resolveController: true,resolveUser: true, schema:'help-faqs', label:'FAQs'}).
            when('/help/edit/faq/:term?', {templateUrl: '/app/views/help/forms/glossary-term.html',resolveController: true,resolveUser: true, schema:'help-faqs', label:'FAQs'}).
            when('/help/faq/tags/:tag', {templateUrl: '/app/views/help/forms/glossary-term.html',resolveController: true,resolveUser: true, schema:'help-faqs', label:'Tags'}).

            otherwise({templateUrl: '/app/404.html', label:'404 Error'});

    }]);
});
<commit_msg>allow national/refernce record route schema param optional<commit_after>'use strict';

define(['app', 'extended-route-provider','scbd-angularjs-services', 'services', 'filters', 'realm-configuration'], function (app) {

    app.value("realm", {value:"ABS"});
    app.value("schemaTypes", [ "absNationalReport", "absPermit", "absCheckpoint", "absCheckpointCommunique", "authority", "measure", "database", "resource", "modelContractualClause", "communityProtocol" ]);
    app.value("showHelp", {value:{ 'show':true, 'glossary':true, 'showTour':false, 'hasTour':false}});

    app.config(['extendedRouteProvider', '$locationProvider', function ($routeProvider, $locationProvider) {

        $locationProvider.html5Mode(true);
        $locationProvider.hashPrefix('!');

        $routeProvider.
            when('/',                            { templateUrl: '/app/views/home/index.html',                       label:'ABSCH',                              resolveController: true, resolveUser: true}).
            when('/commonformat',                { templateUrl: '/app/views/common-formats.html',                   label:'Common Formats',                     resolveController: true, resolveUser: true}).
            when('/help',                        { templateUrl: '/app/views/help/help.html',                        label:'Help',                               resolveController: true, resolveUser: true}).
            when('/help/about',                  { templateUrl: '/app/views/help/about/about.html',                 label:'About the ABSCH',                    resolveController: true, resolveUser: true}).
            when('/about', { redirectTo: '/help/about/absch' }).
            when('/help/presentations/',         { templateUrl: '/app/views/help/presentations/home.html',          label:'Presentations',                      resolveController: true, resolveUser: true}).
            when('/help/accounts',               { templateUrl: '/app/views/help/accounts/accounts.html',           label:'CBD Accounts',                       resolveController: true, resolveUser: true}).
            when('/help/search',                 { templateUrl: '/app/views/help/search/search.html',               label:'Finding Information',                resolveController: true, resolveUser: true}).
            when('/help/tours',                  { templateUrl: '/app/views/help/tours/tours.html',                 label:'Tours',                              resolveController: true, resolveUser: true}).
            when('/help/register',               { templateUrl: '/app/views/help/register/register.html',           label:'Submitting Information',             resolveController: true, resolveUser: true}).

            when('/forums',                        { templateUrl: '/app/views/forums/forum-list-view.html',         label:'Forums',       resolveController: true, resolveUser: true }).

            when('/forums/iac-trg',          { redirectTo:'/forums/iac'}).
            when('/forums/iac',              { templateUrl: '/app/views/forums/thread-list-view.html'   ,label:'IAC', resolveController: true, resolveUser: true, forumId:17433, postUrl:'/forums/iac', text:'IAC' }).
            when('/forums/iac/:threadId',    { templateUrl: '/app/views/forums/post-list-view.html'     ,label:'Thread-Subject', resolveController: true, resolveUser: true, forumId:17433, forumListUrl:'/forums/iac/', text:'IAC'}).

            when('/forums/vlr',                    { templateUrl: '/app/views/forums/thread-list-view.html'  ,label:'VLR'  ,resolveController: true, resolveUser: true, forumId:17384, postUrl:'/forums/vlr', text:'VLR' }).
            when('/forums/vlr/:threadId',          { templateUrl: '/app/views/forums/post-list-view.html'    ,label:'Thread-Subject'  ,resolveController: true, resolveUser: true, forumId:17384, forumListUrl:'/forums/vlr/', text:'VLR'}).
            when('/forums/caribbean',              { templateUrl: '/app/views/forums/thread-list-view.html'  ,label:'Caribbean'  ,resolveController: true, resolveUser: true, forumId:17378, postUrl:'/forums/caribbean', text:'Caribbean Region Forum' }).
            when('/forums/caribbean/:threadId',    { templateUrl: '/app/views/forums/post-list-view.html'    ,label:'Thread-Subject'  ,resolveController: true, resolveUser: true, forumId:17378, forumListUrl:'/forums/caribbean/', text:'Caribbean Region Forum'}).
            //when('/forums/caribbean region',              { templateUrl: '/app/views/forums/thread-list-view.html'   ,resolveController: true, resolveUser: true, forumId:17378, postUrl:'/forums/caribbean region' }).
            //when('/forums/caribbean region/:threadId',    { templateUrl: '/app/views/forums/post-list-view.html'     ,resolveController: true, resolveUser: true, forumId:17378, forumListUrl:'/forums/caribbean region/'}).
            when('/forums/art10_groups',              { templateUrl: '/app/views/forums/thread-list-view.html' ,label:'Art 10 Groups'  ,resolveController: true, resolveUser: true, forumId:17316, postUrl:'/forums/art10_groups', text:'Forum on Article 10' }).
            when('/forums/art10_groups/:threadId',    { templateUrl: '/app/views/forums/post-list-view.html'   ,label:'Thread-Subject'  ,resolveController: true, resolveUser: true, forumId:17316, forumListUrl:'/forums/art10_groups/', text:'Forum on Article 10' }).

            when('/mailbox',                        { templateUrl: '/app/views/mailbox/inbox.html',         label:'Mailbox',       resolveController: true, resolveUser: true }).
            when('/mailbox/:mailId',                { templateUrl: '/app/views/mailbox/inbox.html',         label:'Mailbox',       resolveController: true, resolveUser: true }).

            when('/search/new',                             { templateUrl: '/app/views/search/search.html',   label:'Search',         resolveController: true, resolveUser: true}).
            when('/search/new/byCountry',                   { templateUrl: '/app/views/search/country-search.html',   label:'Search',         resolveController: true, resolveUser: true}).

            // when('/search/new/measurematrix',                   { templateUrl: '/app/views/search/measure-matrix.html',   label:'Matrix',         resolveController: true, resolveUser: true}).
            // when('/search/new/measurematrix/:uniqueId',         { templateUrl: '/app/views/search/measure-matrix.html',   label:'Matrix',         resolveController: true, resolveUser: true}).
            when('/measurematrix/:code',            { templateUrl: '/app/views/search/measure-matrix-countries.html',   label:'Measures Matrix',         resolveController: true, resolveUser: true}).

            when('/find',                                 { templateUrl: '/app/views/search/find.html',   label:'Find Information',         resolveController: true, resolveUser: true}).
            when('/search',                                 { templateUrl: '/app/views/search/find.html',   label:'Find Information',         resolveController: true, resolveUser: true}).
            // when('/search/:documentSchema',                 { templateUrl: '/app/views/search/search.html',   label:'Search',         resolveController: true, resolveUser: true}).
            // when('/search/:documentSchema/:countryCode',    { templateUrl: '/app/views/search/search.html',   label:'Search',         resolveController: true, resolveUser: true}).
            // when('/find/simple',                            { templateUrl: '/app/views/find/simple.html',   label:'Simple Search',  resolveController: true, resolveUser: true}).
            when('/search/national-records/:documentSchema?',              { templateUrl: '/app/views/search/search.html',   label:'Search',         resolveController: true, resolveUser: true, type:'national'}).
            when('/search/countries/:countryCode?',                       { templateUrl: '/app/views/search/search.html',   label:'Search',         resolveController: true, resolveUser: true, type:'countryProfile'}).
            when('/search/reference-records/:documentSchema?',             { templateUrl: '/app/views/search/search.html',   label:'Search',         resolveController: true, resolveUser: true, type:'reference'}).
            // when('/find',                                   { redirectTo:'/search'}).

            when('/countries',                   { templateUrl: '/app/views/countries/index.html',       label:'Country Information',      resolveController: true, resolveUser: true}).
            when('/countries/:code',             { templateUrl: '/app/views/countries/profiles.html',       label:'Country Profile', param:'true',      resolveController: true, resolveUser: true}).
            when('/countries/:code/:schema',     { templateUrl: '/app/views/countries/profiles.html',       label:'Country Profile', param:'true',      resolveController: true, resolveUser: true}).

            when('/database/record',             { templateUrl: '/app/views/forms/view/records-id.html'     ,resolveController: true, resolveUser: true}).
            when('/database/record/:documentID',  { templateUrl: '/app/views/forms/view/records-id.html'     ,resolveController: true, resolveUser: true}).
            when('/database/record/:documentID/:revision', { templateUrl: '/app/views/forms/view/records-id.html'     ,resolveController: true, resolveUser: true}).
            when('/database/:documentID',                           { templateUrl: '/app/views/forms/view/records-id.html', label:'Record',  param:'true',  resolveController: true, resolveUser: true}).
            when('/database/:documentSchema/:documentID',           { templateUrl: '/app/views/forms/view/records-id.html', label:'Record',  param:'true',  resolveController: true, resolveUser: true}).
            when('/database/:documentSchema/:documentID/:revision', { templateUrl: '/app/views/forms/view/records-id.html', label:'Record',  param:'true',  resolveController: true, resolveUser: true}).

            when('/register/tasks/:id',                                 {templateUrl: '/app/views/tasks/tasks-id.html',             label:'Management Center',  param:'true', resolveController: true, resolveUser: true}).
            when('/register/tasks/:id/:activity',                       {templateUrl: '/app/views/tasks/tasks-id-activity.html',    label:'Management Center',  param:'true', resolveController: true, resolveUser: true}).
            when('/register/dashboard',                                 {templateUrl: '/app/views/register/register.html',          label:'Management Center',  param:'true', resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/register/dashboard.html',}).
            when('/dashboard',                                          {redirectTo:  '/register/dashboard'}).

            when('/register',                                           {templateUrl: '/app/views/register/register.html',          label:'Management Center',  param:'true', resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/register/dashboard.html',}).
            when('/register/requests',                                  {templateUrl: '/app/views/register/register.html',          label:'Requests',  param:'true', resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/tasks/my-tasks.directive.html',    type : 'all'}).
            when('/register/requests/:workflowId',                      {templateUrl: '/app/views/register/register.html',          label:'Requests',  param:'true', resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/tasks/my-tasks.directive.html',type : 'all'}).
            when('/register/requests/:type/:status',                    {templateUrl: '/app/views/register/register.html',          label:'Requests',  param:'true', resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/tasks/my-tasks.directive.html',}).
            when('/register/:document_type',                            {templateUrl: '/app/views/register/register.html',          label:'document_type',  param:'true', resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/register/type_document_list.html',}).
            when('/register/:document_type/new',                        {templateUrl: '/app/views/register/register.html',          label:'New',  param:'true', resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/forms/edit/edit--', }).
            when('/register/:document_type/help',                       {templateUrl: '/app/views/register/register.html',          label:'document_type',  param:'true', resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/register/type_document_list.html',}).
            when('/register/:document_type/:identifier/edit',           {templateUrl: '/app/views/register/register.html',          label:'Edit',  param:'true', resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/forms/edit/edit--', }).
            when('/register/:document_type/:identifier/edit/:tour',     {templateUrl: '/app/views/register/register.html',          label:'Edit',  param:'true', resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/forms/edit/edit--',  }).

            when('/workshops/lac',               { templateUrl: '/app/views/workshops/lac.html',            label:'Workshops',            resolveController: true, resolveUser: true}).
            when('/workshops/caribbean',         { templateUrl: '/app/views/workshops/caribbean.html',      label:'Workshops',        resolveController: true, resolveUser: true}).

            //when('/searchforum.shtml',           { templateUrl:'/app/views/about.html#iac'}).
            when('/oauth2/callback',             { templateUrl: '/app/views/oauth2/callback.html',          resolveController: true, resolveUser: true}).
            when('/certificate/:documentNumber', { templateUrl: '/app/views/forms/view/records-id.html',    resolveController: true, resolveUser: true}).

            when('/commonformat', {templateUrl: '/app/views/about/about.html',resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/about/common-formats.html',ignoreSubController: true,}).
            when('/commonformat',           { redirectTo:'/about/common-formats' }).

            // when('/help/presentations/:folder/:document_type', {templateUrl: '/app/views/help/presentations/presentation.html',resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/help/presentations/:folder/-',ignoreSubController: true,}).
            // when('/help/presentations/:folder', { redirectTo: '/help/presentations/:folder/start' }).

             when('/help/presentations', {templateUrl: '/app/views/help/presentations.html',   label:'Presentations and Workshops',   resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/register/contacts.html',}).

            when('/contacts', {templateUrl: '/app/views/register/register.html',resolveController: true,resolveUser: true,subTemplateUrl: '/app/views/register/contacts.html',}).

            when('/searchforum.shtml',      { redirectTo:'/about/portal10' }).
            when('/commonformat',           { redirectTo:'/about/common-formats' }).

            when('/help/manage/:term?', {templateUrl: '/app/views/help/forms/edit-help.html',resolveController: true,resolveUser: true, label:'Forms Help'}).

            //when('/help/glossary', {templateUrl: '/app/views/help/forms/glossary.html',resolveController: true,resolveUser: true, label:'Glossary'}).
            when('/help/glossary/tags/:tag', {templateUrl: '/app/views/help/forms/glossary-term.html',resolveController: true,resolveUser: true, schema:'help-glossarys', label:'Tags'}).
            when('/help/glossary/:term?', {templateUrl: '/app/views/help/forms/glossary-term.html',resolveController: true,resolveUser: true, schema:'help-glossarys', label:'lableText'}).

            //when('/help/faq', {templateUrl: '/app/views/help/forms/faq.html',resolveController: true,resolveUser: true, label:'FAQ'}).
            when('/help/faq/:term?', {templateUrl: '/app/views/help/faq.html',resolveController: true,resolveUser: true, schema:'help-faqs', label:'FAQs'}).
            when('/help/edit/faq/:term?', {templateUrl: '/app/views/help/forms/glossary-term.html',resolveController: true,resolveUser: true, schema:'help-faqs', label:'FAQs'}).
            when('/help/faq/tags/:tag', {templateUrl: '/app/views/help/forms/glossary-term.html',resolveController: true,resolveUser: true, schema:'help-faqs', label:'Tags'}).

            otherwise({templateUrl: '/app/404.html', label:'404 Error'});

    }]);
});
<|endoftext|>


<commit_before>/**
 * Copyright reelyActive 2019
 * We believe in an open Internet of Things
 */

// Constants
const ELASTICSEARCH_INTERFACE_ROUTE = '/interfaces/elasticsearch';
const QUERY_TEMPLATE_NAMES = [
    'All raddecs',
    'Specific transmitterId',
    'Prefix transmitterId',
    'Aggregate receiverId',
    'Aggregate rec/dec/pac',
    'Auto-date histogram'
];

// DOM elements
let queryTemplates = document.querySelector('#queryTemplates');
let displayCount = document.querySelector('#displayCount');
let queryBox = document.querySelector('#queryBox');
let queryButton = document.querySelector('#queryButton');
let queryResults = document.querySelector('#queryResults');
let responseHits = document.querySelector('#responseHits');
let responseTime = document.querySelector('#responseTime');
let hitsBox = document.querySelector('#hitsBox');
let aggregationsBox = document.querySelector('#aggregationsBox');

// Create query template options
QUERY_TEMPLATE_NAMES.forEach(function(element, index) {
  let option = document.createElement("option");
  option.value = index;
  option.text = element;
  queryTemplates.add(option, null);
});

// Other variables

// Other initialisation
hide(queryButton);
hide(queryResults);

// Update the query JSON based on the selected template
function updateQuery() {
  let query = {};

  switch(queryTemplates.value) {
    case '0': // All raddecs
      query = {
          "size": 10,
          "query": { "match_all": {} },
          "_source": [ "transmitterId", "transmitterIdType", "receiverId",
                       "receiverIdType", "rssi", "timestamp",
                       "numberOfDecodings", "numberOfReceivers",
                       "numberOfPackets" ]
      };
      queryBox.value = JSON.stringify(query, null, 2);
      break;
    case '1': // Specific transmitterId
      query = {
          "size": 10,
          "query": { "term": { "transmitterId": "" } },
          "_source": [ "receiverId", "receiverIdType", "rssi", "timestamp",
                       "numberOfDecodings", "numberOfReceivers",
                       "numberOfPackets", "packets" ]
      };
      queryBox.value = JSON.stringify(query, null, 2);
      break;
    case '2': // Prefix transmitterId
      query = {
          "size": 10,
          "query": { "prefix": { "transmitterId": "" } },
          "_source": [ "transmitterId", "transmitterIdType", "receiverId",
                       "receiverIdType", "rssi", "timestamp",
                       "numberOfDecodings", "numberOfReceivers",
                       "numberOfPackets" ]
      };
      queryBox.value = JSON.stringify(query, null, 2);
      break;
    case '3': // Aggregate receiverId
      query = {
          "size": 0,
          "aggs" : {
            "receivers" : {
              "terms" : {
                "field" : "receiverId.keyword",
                "order" : { "_count" : "desc" },
                "size": 12
              }
            }
          }
      };
      queryBox.value = JSON.stringify(query, null, 2);
      break;
    case '4': // Aggregate rec/dec/pac
      query = {
          "size": 0,
          "aggs" : {
            "numberOfReceivers" : {
              "histogram" : {
                "field" : "numberOfReceivers",
                "interval" : 1
              }
            },
            "numberOfDecodings" : {
              "histogram" : {
                "field" : "numberOfDecodings",
                "interval" : 1,
                "min_doc_count" : 1
              }
            },
            "numberOfDistinctPackets" : {
              "histogram" : {
                "field" : "numberOfDistinctPackets",
                "interval" : 1
              }
            }
          }
      };
      queryBox.value = JSON.stringify(query, null, 2);
      break;
    case '5': // Auto-date histogram
      query = {
          "size": 0,
          "aggs" : {
            "periods" : {
              "auto_date_histogram" : {
                "field" : "timestamp",
                "buckets" : 12
              }
            }
          }
      };
      queryBox.value = JSON.stringify(query, null, 2);
      break;
  }
  queryBox.rows = countNumberOfLines(queryBox.value);
  parseQuery();
}

// Parse the query as typed in the box and confirm it is valid JSON
function parseQuery() {
  let query = {};

  try { query = JSON.parse(queryBox.value); }
  catch(error) {
    queryError.textContent = 'Query must be valid JSON';
    hide(queryButton);
    hide(queryResults);
    show(queryError);
    return null;
  }

  hide(queryError);
  show(queryButton);
  return query;
}

// Handle the current Elasticsearch query
function handleQuery() {
  let query = parseQuery();
  let url = window.location.protocol + '//' + window.location.hostname + ':' +
            window.location.port + ELASTICSEARCH_INTERFACE_ROUTE;
  let httpRequest = new XMLHttpRequest();

  httpRequest.onreadystatechange = function() {
    if(httpRequest.readyState === XMLHttpRequest.DONE) {
      if(httpRequest.status === 200) {
        let response = JSON.parse(httpRequest.responseText);
        updateResults(response);
        updateHits(response);
        updateAggregations(response);
        show(queryResults);
      }
      else {
        queryError.textContent = 'Query returned status ' +
                                 httpRequest.status +
                                 '. Is Elasticsearch connected and running?';
        hide(queryResults);
        hide(queryButton);
        show(queryError);
      }
    }
  };
  httpRequest.open('POST', url);
  httpRequest.setRequestHeader('Content-Type', 'application/json');
  httpRequest.setRequestHeader('Accept', 'application/json');
  httpRequest.send(JSON.stringify(query));
}

// Update the results
function updateResults(response) {
  responseHits.textContent = response.hits.total;
  responseTime.textContent = response.took;
}

// Update the hits
function updateHits(response) {
  if(!response.hits.hasOwnProperty('hits') ||
     (response.hits.hits.length === 0)) {
    hide(hitsCard);
  }
  else {
    show(hitsCard);
    hitsBox.textContent = JSON.stringify(response.hits.hits, null, 2);
  }
}

// Update the aggregations
function updateAggregations(response) {
  if(response.hasOwnProperty('aggregations')) {
    aggregationsBox.textContent = JSON.stringify(response.aggregations,
                                                 null, 2);
    show(aggregationsCard);
  }
  else {
    hide(aggregationsCard);
  }
}

// Count the number of lines in the given JSON string
function countNumberOfLines(jsonString) {
  return (jsonString.match(/\r?\n/g) || []).length + 1;
}

// Hide the given element
function hide(element) {
  element.style.display = 'none';
}

// Show the given element
function show(element) {
  element.style.display = '';
}

// Event listeners
queryTemplates.addEventListener('change', updateQuery);
queryBox.addEventListener('keyup', parseQuery);
queryButton.addEventListener('click', handleQuery);
<commit_msg>Updated queries<commit_after>/**
 * Copyright reelyActive 2019
 * We believe in an open Internet of Things
 */

// Constants
const ELASTICSEARCH_INTERFACE_ROUTE = '/interfaces/elasticsearch';
const QUERY_TEMPLATE_NAMES = [
    'Most recent raddecs',
    'Specific transmitterId',
    'Prefix transmitterId',
    'Aggregate receiverId',
    'Aggregate rec/dec/pac',
    'Auto-date histogram'
];

// DOM elements
let queryTemplates = document.querySelector('#queryTemplates');
let displayCount = document.querySelector('#displayCount');
let queryBox = document.querySelector('#queryBox');
let queryButton = document.querySelector('#queryButton');
let queryResults = document.querySelector('#queryResults');
let responseHits = document.querySelector('#responseHits');
let responseTime = document.querySelector('#responseTime');
let hitsBox = document.querySelector('#hitsBox');
let aggregationsBox = document.querySelector('#aggregationsBox');

// Create query template options
QUERY_TEMPLATE_NAMES.forEach(function(element, index) {
  let option = document.createElement("option");
  option.value = index;
  option.text = element;
  queryTemplates.add(option, null);
});

// Other variables

// Other initialisation
hide(queryButton);
hide(queryResults);

// Update the query JSON based on the selected template
function updateQuery() {
  let query = {};

  switch(queryTemplates.value) {
    case '0': // Most recent raddecs
      query = {
          "size": 10,
          "query": { "match_all": {} },
          "_source": [ "transmitterId", "transmitterIdType", "receiverId",
                       "receiverIdType", "rssi", "timestamp",
                       "numberOfDecodings", "numberOfReceivers",
                       "numberOfDistinctPackets" ],
          "sort": [ { "timestamp": { "order": "desc" } } ]
      };
      queryBox.value = JSON.stringify(query, null, 2);
      break;
    case '1': // Specific transmitterId
      query = {
          "size": 10,
          "query": { "term": { "transmitterId": "" } },
          "_source": [ "receiverId", "receiverIdType", "rssi", "timestamp",
                       "numberOfDecodings", "numberOfReceivers",
                       "numberOfDistinctPackets", "packets" ]
      };
      queryBox.value = JSON.stringify(query, null, 2);
      break;
    case '2': // Prefix transmitterId
      query = {
          "size": 10,
          "query": { "prefix": { "transmitterId": "" } },
          "_source": [ "transmitterId", "transmitterIdType", "receiverId",
                       "receiverIdType", "rssi", "timestamp",
                       "numberOfDecodings", "numberOfReceivers",
                       "numberOfDistinctPackets" ]
      };
      queryBox.value = JSON.stringify(query, null, 2);
      break;
    case '3': // Aggregate receiverId
      query = {
          "size": 0,
          "aggs" : {
            "receivers" : {
              "terms" : {
                "field" : "receiverId.keyword",
                "order" : { "_count" : "desc" },
                "size": 12
              }
            }
          }
      };
      queryBox.value = JSON.stringify(query, null, 2);
      break;
    case '4': // Aggregate rec/dec/pac
      query = {
          "size": 0,
          "aggs" : {
            "numberOfReceivers" : {
              "histogram" : {
                "field" : "numberOfReceivers",
                "interval" : 1
              }
            },
            "numberOfDecodings" : {
              "histogram" : {
                "field" : "numberOfDecodings",
                "interval" : 1,
                "min_doc_count" : 1
              }
            },
            "numberOfDistinctPackets" : {
              "histogram" : {
                "field" : "numberOfDistinctPackets",
                "interval" : 1
              }
            }
          }
      };
      queryBox.value = JSON.stringify(query, null, 2);
      break;
    case '5': // Auto-date histogram
      query = {
          "size": 0,
          "aggs" : {
            "periods" : {
              "auto_date_histogram" : {
                "field" : "timestamp",
                "buckets" : 12
              }
            }
          }
      };
      queryBox.value = JSON.stringify(query, null, 2);
      break;
  }
  queryBox.rows = countNumberOfLines(queryBox.value);
  parseQuery();
}

// Parse the query as typed in the box and confirm it is valid JSON
function parseQuery() {
  let query = {};

  try { query = JSON.parse(queryBox.value); }
  catch(error) {
    queryError.textContent = 'Query must be valid JSON';
    hide(queryButton);
    hide(queryResults);
    show(queryError);
    return null;
  }

  hide(queryError);
  show(queryButton);
  return query;
}

// Handle the current Elasticsearch query
function handleQuery() {
  let query = parseQuery();
  let url = window.location.protocol + '//' + window.location.hostname + ':' +
            window.location.port + ELASTICSEARCH_INTERFACE_ROUTE;
  let httpRequest = new XMLHttpRequest();

  httpRequest.onreadystatechange = function() {
    if(httpRequest.readyState === XMLHttpRequest.DONE) {
      if(httpRequest.status === 200) {
        let response = JSON.parse(httpRequest.responseText);
        updateResults(response);
        updateHits(response);
        updateAggregations(response);
        show(queryResults);
      }
      else {
        queryError.textContent = 'Query returned status ' +
                                 httpRequest.status +
                                 '. Is Elasticsearch connected and running?';
        hide(queryResults);
        hide(queryButton);
        show(queryError);
      }
    }
  };
  httpRequest.open('POST', url);
  httpRequest.setRequestHeader('Content-Type', 'application/json');
  httpRequest.setRequestHeader('Accept', 'application/json');
  httpRequest.send(JSON.stringify(query));
}

// Update the results
function updateResults(response) {
  responseHits.textContent = response.hits.total;
  responseTime.textContent = response.took;
}

// Update the hits
function updateHits(response) {
  if(!response.hits.hasOwnProperty('hits') ||
     (response.hits.hits.length === 0)) {
    hide(hitsCard);
  }
  else {
    show(hitsCard);
    hitsBox.textContent = JSON.stringify(response.hits.hits, null, 2);
  }
}

// Update the aggregations
function updateAggregations(response) {
  if(response.hasOwnProperty('aggregations')) {
    aggregationsBox.textContent = JSON.stringify(response.aggregations,
                                                 null, 2);
    show(aggregationsCard);
  }
  else {
    hide(aggregationsCard);
  }
}

// Count the number of lines in the given JSON string
function countNumberOfLines(jsonString) {
  return (jsonString.match(/\r?\n/g) || []).length + 1;
}

// Hide the given element
function hide(element) {
  element.style.display = 'none';
}

// Show the given element
function show(element) {
  element.style.display = '';
}

// Event listeners
queryTemplates.addEventListener('change', updateQuery);
queryBox.addEventListener('keyup', parseQuery);
queryButton.addEventListener('click', handleQuery);
<|endoftext|>


<commit_before>/* global Vue, Flash, gl */
/* eslint-disable no-param-reassign */
import canceledSvg from 'icons/_icon_status_canceled_borderless.svg';
import createdSvg from 'icons/_icon_status_created_borderless.svg';
import failedSvg from 'icons/_icon_status_failed_borderless.svg';
import manualSvg from 'icons/_icon_status_manual_borderless.svg';
import pendingSvg from 'icons/_icon_status_pending_borderless.svg';
import runningSvg from 'icons/_icon_status_running_borderless.svg';
import skippedSvg from 'icons/_icon_status_skipped_borderless.svg';
import successSvg from 'icons/_icon_status_success_borderless.svg';
import warningSvg from 'icons/_icon_status_warning_borderless.svg';

((gl) => {
  gl.VueStage = Vue.extend({
    data() {
      const svgsDictionary = {
        icon_status_canceled: canceledSvg,
        icon_status_created: createdSvg,
        icon_status_failed: failedSvg,
        icon_status_manual: manualSvg,
        icon_status_pending: pendingSvg,
        icon_status_running: runningSvg,
        icon_status_skipped: skippedSvg,
        icon_status_success: successSvg,
        icon_status_warning: warningSvg,
      };

      return {
        builds: '',
        spinner: '',
        svg: svgsDictionary[this.stage.status.icon],
      };
    },

    props: {
      stage: {
        type: Object,
        required: true,
      },
    },

    updated() {
      if (this.builds) {
        this.stopDropdownClickPropagation();
      }
    },

    methods: {
      fetchBuilds(e) {
        const areaExpanded = e.currentTarget.attributes['aria-expanded'];

        if (areaExpanded && (areaExpanded.textContent === 'true')) return null;

        return this.$http.get(this.stage.dropdown_path)
          .then((response) => {
            this.builds = JSON.parse(response.body).html;
          }, () => {
            const flash = new Flash('Something went wrong on our end.');
            return flash;
          });
      },

      /**
       * When the user right clicks or cmd/ctrl + click in the job name
       * the dropdown should not be closed and the link should open in another tab,
       * so we stop propagation of the click event inside the dropdown.
       *
       * Since this component is rendered multiple times per page we need to guarantee we only
       * target the click event of this component.
       */
      stopDropdownClickPropagation() {
        $(this.$el.querySelectorAll('.js-builds-dropdown-list a.mini-pipeline-graph-dropdown-item')).on('click', (e) => {
          e.stopPropagation();
        });
      },
    },
    computed: {
      buildsOrSpinner() {
        return this.builds ? this.builds : this.spinner;
      },
      dropdownClass() {
        if (this.builds) return 'js-builds-dropdown-container';
        return 'js-builds-dropdown-loading builds-dropdown-loading';
      },
      buildStatus() {
        return `Build: ${this.stage.status.label}`;
      },
      tooltip() {
        return `has-tooltip ci-status-icon ci-status-icon-${this.stage.status.group}`;
      },
      triggerButtonClass() {
        return `mini-pipeline-graph-dropdown-toggle has-tooltip js-builds-dropdown-button ci-status-icon-${this.stage.status.group}`;
      },
    },
    template: `

        <button
          @click="fetchBuilds($event)"
          :class="triggerButtonClass"
          :title="stage.title"
          data-placement="top"
          data-toggle="dropdown"
          type="button"
          :aria-label="stage.title">

        </button>

    `,
  });
})(window.gl || (window.gl = {}));
<commit_msg>Simplify selector<commit_after>/* global Vue, Flash, gl */
/* eslint-disable no-param-reassign */
import canceledSvg from 'icons/_icon_status_canceled_borderless.svg';
import createdSvg from 'icons/_icon_status_created_borderless.svg';
import failedSvg from 'icons/_icon_status_failed_borderless.svg';
import manualSvg from 'icons/_icon_status_manual_borderless.svg';
import pendingSvg from 'icons/_icon_status_pending_borderless.svg';
import runningSvg from 'icons/_icon_status_running_borderless.svg';
import skippedSvg from 'icons/_icon_status_skipped_borderless.svg';
import successSvg from 'icons/_icon_status_success_borderless.svg';
import warningSvg from 'icons/_icon_status_warning_borderless.svg';

((gl) => {
  gl.VueStage = Vue.extend({
    data() {
      const svgsDictionary = {
        icon_status_canceled: canceledSvg,
        icon_status_created: createdSvg,
        icon_status_failed: failedSvg,
        icon_status_manual: manualSvg,
        icon_status_pending: pendingSvg,
        icon_status_running: runningSvg,
        icon_status_skipped: skippedSvg,
        icon_status_success: successSvg,
        icon_status_warning: warningSvg,
      };

      return {
        builds: '',
        spinner: '',
        svg: svgsDictionary[this.stage.status.icon],
      };
    },

    props: {
      stage: {
        type: Object,
        required: true,
      },
    },

    updated() {
      if (this.builds) {
        this.stopDropdownClickPropagation();
      }
    },

    methods: {
      fetchBuilds(e) {
        const areaExpanded = e.currentTarget.attributes['aria-expanded'];

        if (areaExpanded && (areaExpanded.textContent === 'true')) return null;

        return this.$http.get(this.stage.dropdown_path)
          .then((response) => {
            this.builds = JSON.parse(response.body).html;
          }, () => {
            const flash = new Flash('Something went wrong on our end.');
            return flash;
          });
      },

      /**
       * When the user right clicks or cmd/ctrl + click in the job name
       * the dropdown should not be closed and the link should open in another tab,
       * so we stop propagation of the click event inside the dropdown.
       *
       * Since this component is rendered multiple times per page we need to guarantee we only
       * target the click event of this component.
       */
      stopDropdownClickPropagation() {
        $(this.$el).on('click', '.js-builds-dropdown-list a.mini-pipeline-graph-dropdown-item', (e) => {
          e.stopPropagation();
        });
      },
    },
    computed: {
      buildsOrSpinner() {
        return this.builds ? this.builds : this.spinner;
      },
      dropdownClass() {
        if (this.builds) return 'js-builds-dropdown-container';
        return 'js-builds-dropdown-loading builds-dropdown-loading';
      },
      buildStatus() {
        return `Build: ${this.stage.status.label}`;
      },
      tooltip() {
        return `has-tooltip ci-status-icon ci-status-icon-${this.stage.status.group}`;
      },
      triggerButtonClass() {
        return `mini-pipeline-graph-dropdown-toggle has-tooltip js-builds-dropdown-button ci-status-icon-${this.stage.status.group}`;
      },
    },
    template: `

        <button
          @click="fetchBuilds($event)"
          :class="triggerButtonClass"
          :title="stage.title"
          data-placement="top"
          data-toggle="dropdown"
          type="button"
          :aria-label="stage.title">

        </button>

    `,
  });
})(window.gl || (window.gl = {}));
<|endoftext|>


<commit_before>(function($) {
    var routesApp = {
        // All pages
        common: {
            init: function() {
            }
        },
        // Home page
        home: {
            init: function() {
            // JavaScript to be fired on the home page
            }
        }
    };

    // The routing fires all common scripts, followed by the page specific scripts.
    // Add additional events for more control over timing e.g. a finalize event
    var UTIL = {
      fire: function(func, funcname, args) {
        var namespace = routesApp;
        funcname = (funcname === undefined) ? 'init' : funcname;
        if (func !== '' && namespace[func] && typeof namespace[func][funcname] === 'function') {
          namespace[func][funcname](args);
        }
      },
      loadEvents: function() {
        UTIL.fire('common');

        $.each(document.body.className.replace(/-/g, '_').split(/\s+/),function(i,classnm) {
          UTIL.fire(classnm);
        });
      }
    };

    $(document).ready(UTIL.loadEvents);

})(jQuery);
<commit_msg>Fix code style<commit_after>'use strict';

(function($) {
  var routesApp = {
    // All pages
    common: {
      init: function() {
        console.log('oi');
      }
    },
    // Home page
    home: {
      init: function() {
      // JavaScript to be fired on the home page
      }
    }
  };

  // The routing fires all common scripts, followed by the page specific scripts.
  // Add additional events for more control over timing e.g. a finalize event
  var UTIL = {
    fire: function(func, funcname, args) {
      var namespace = routesApp;
      funcname = (funcname === undefined) ? 'init' : funcname;
      if (func !== '' && namespace[func] && typeof namespace[func][funcname] === 'function') {
        namespace[func][funcname](args);
      }
    },
    loadEvents: function() {
      UTIL.fire('common');

      $.each(document.body.className.replace(/-/g, '_').split(/\s+/), function(i, classnm) {
        UTIL.fire(classnm);
      });
    }
  };

  $(document).ready(UTIL.loadEvents);

})(jQuery);
<|endoftext|>