| author | ymh <ymh.work@gmail.com> |
| Mon, 27 Apr 2015 17:22:46 +0200 | |
| changeset 435 | e529b633c339 |
| parent 434 | 0d5998b32a7c |
| child 436 | 4021b3ea388b |
--- a/client/bower.json Sat Apr 25 04:37:06 2015 +0200 +++ b/client/bower.json Mon Apr 27 17:22:46 2015 +0200 @@ -31,9 +31,14 @@ "FileSaver": "*", "backbone-relational": "~0.9.0", "requirejs": null, - "lodash": "2.4.1" + "lodash": "~2.4.1" }, "devDependencies": { "jquery-ui": "~1.11.4" + }, + "exportsOverride": { + "lodash": { + "": "dist/*.js" + } } }
--- a/client/css/renkan.css Sat Apr 25 04:37:06 2015 +0200 +++ b/client/css/renkan.css Mon Apr 27 17:22:46 2015 +0200 @@ -383,7 +383,7 @@ } .Rk-Edit-Image{ - font-size: 12px; width: 230px; + font-size: 12px; width: 220px; } .Rk-Edit-Image-Del{ @@ -398,7 +398,7 @@ } .Rk-Edit-URI { - font-size: 12px; width: 230px; + font-size: 12px; width: 220px; } .Rk-Edit-ImgWrap {
--- a/client/js/header.js Sat Apr 25 04:37:06 2015 +0200 +++ b/client/js/header.js Mon Apr 27 17:22:46 2015 +0200 @@ -1,24 +1,25 @@ -/*! - * _____ _ - * | __ \ | | - * | |__) |___ _ __ | | ____ _ _ __ - * | _ // _ \ '_ \| |/ / _` | '_ \ +/*! + * _____ _ + * | __ \ | | + * | |__) |___ _ __ | | ____ _ _ __ + * | _ // _ \ '_ \| |/ / _` | '_ \ * | | \ \ __/ | | | < (_| | | | | * |_| \_\___|_| |_|_|\_\__,_|_| |_| * - * Copyright 2012-2013 Institut de recherche et d'innovation - * contributor(s) : Yves-Marie Haussonne, Raphael Velt, Samuel Huron - * + * Copyright 2012-2015 Institut de recherche et d'innovation + * contributor(s) : Yves-Marie Haussonne, Raphael Velt, Samuel Huron, + * Thibaut CavaliƩ, Julien Rougeron. + * * contact@iri.centrepompidou.fr - * http://www.iri.centrepompidou.fr - * + * http://www.iri.centrepompidou.fr + * * This software is a computer program whose purpose is to show and add annotations on a video . * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, + * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL-C * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * + * "http://www.cecill.info". + * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. - */ \ No newline at end of file + */
--- a/client/js/models.js Sat Apr 25 04:37:06 2015 +0200 +++ b/client/js/models.js Mon Apr 27 17:22:46 2015 +0200 @@ -100,7 +100,9 @@ .get("_id") : null, size : this.get("size"), clip_path : this.get("clip_path"), - shape : this.get("shape") + shape : this.get("shape"), + type : this.get("type"), + hidden : this.get("hidden") }; } });
--- a/client/js/renderer/baserepresentation.js Sat Apr 25 04:37:06 2015 +0200 +++ b/client/js/renderer/baserepresentation.js Mon Apr 27 17:22:46 2015 +0200 @@ -18,7 +18,7 @@ if (this.model) { var _this = this; this._changeBinding = function() { - _this.redraw(); + _this.redraw({change: true}); }; this._removeBinding = function() { _renderer.removeRepresentation(_this);
--- a/client/js/renderer/nodeeditor.js Sat Apr 25 04:37:06 2015 +0200 +++ b/client/js/renderer/nodeeditor.js Mon Apr 27 17:22:46 2015 +0200 @@ -9,11 +9,11 @@ var NodeEditor = Utils.inherit(BaseEditor); _(NodeEditor.prototype).extend({ - _init: function() { - BaseEditor.prototype._init.apply(this); - this.template = this.options.templates['templates/nodeeditor.html']; - this.readOnlyTemplate = this.options.templates['templates/nodeeditor_readonly.html']; - }, + _init: function() { + BaseEditor.prototype._init.apply(this); + this.template = this.options.templates['templates/nodeeditor.html']; + this.readOnlyTemplate = this.options.templates['templates/nodeeditor_readonly.html']; + }, draw: function() { var _model = this.source_representation.model, _created_by = _model.get("created_by") || Utils._USER_PLACEHOLDER(this.renkan), @@ -44,6 +44,17 @@ this.redraw(); var _this = this, closeEditor = function() { + _this.editor_$.off("keyup"); + _this.editor_$.find("input, textarea, select").off("change keyup paste"); + _this.editor_$.find(".Rk-Edit-Image-File").off('change'); + _this.editor_$.find(".Rk-Edit-ColorPicker-Wrapper").off('hover'); + _this.editor_$.find(".Rk-Edit-Size-Down").off('click'); + _this.editor_$.find(".Rk-Edit-Size-Up").off('click'); + _this.editor_$.find(".Rk-Edit-Image-Del").off('click'); + _this.editor_$.find(".Rk-Edit-ColorPicker").find("li").off('hover click'); + _this.editor_$.find(".Rk-CloseX").off('click'); + _this.editor_$.find(".Rk-Edit-Goto").off('click'); + _this.renderer.removeRepresentation(_this); paper.view.draw(); }; @@ -78,15 +89,10 @@ if (_this.options.change_shapes) { if(_model.get("shape")!==_this.editor_$.find(".Rk-Edit-Shape").val()){ _data.shape = _this.editor_$.find(".Rk-Edit-Shape").val(); - _data.shape_changed = true; } } _model.set(_data); _this.redraw(); - // For an unknown reason, we have to set data twice when we change shape, otherwise the image disappears. - if(_data.shape_changed===true){ - _model.set(_data); - } } else { closeEditor(); } @@ -178,8 +184,8 @@ }); this.editor_$.find(".Rk-Edit-Image-Del").click(function() { - _this.editor_$.find(".Rk-Edit-Image").val(''); - onFieldChange(); + _this.editor_$.find(".Rk-Edit-Image").val(''); + onFieldChange(); return false; }); } else {
--- a/client/js/renderer/noderepr.js Sat Apr 25 04:37:06 2015 +0200 +++ b/client/js/renderer/noderepr.js Mon Apr 27 17:22:46 2015 +0200 @@ -56,8 +56,7 @@ } }, buildShape: function(){ - if(typeof this.model.get("shape_changed")!=="undefined" && this.model.get("shape_changed")===true){ - this.model.set("shape_changed", false); + if( 'shape' in this.model.changed ) { delete this.img; } if(this.circle){ @@ -68,14 +67,16 @@ this.shapeBuilder = new ShapeBuilder(this.model.get("shape")); this.circle = this.shapeBuilder.getShape(); this.circle.__representation = this; + this.circle.sendToBack(); this.last_circle_radius = 1; }, - redraw: function(_dontRedrawEdges) { - if(typeof this.model.get("shape_changed")!=="undefined" && this.model.get("shape_changed")===true){ + redraw: function(options) { + if( 'shape' in this.model.changed && 'change' in options && options.change ) { + //if( 'shape' in this.model.changed ) { this.buildShape(); } var _model_coords = new paper.Point(this.model.get("position")), - _baseRadius = this.options.node_size_base * Math.exp((this.model.get("size") || 0) * Utils._NODE_SIZE_STEP); + _baseRadius = this.options.node_size_base * Math.exp((this.model.get("size") || 0) * Utils._NODE_SIZE_STEP); if (!this.is_dragging || !this.paper_coords) { this.paper_coords = this.renderer.toPaperCoords(_model_coords); } @@ -151,6 +152,9 @@ this.img = this.model.get("image"); if (this.img && this.img !== lastImage) { this.showImage(); + if(this.circle) { + this.circle.sendToBack(); + } } if (this.node_image && !this.img) { this.node_image.remove(); @@ -165,7 +169,7 @@ this.minimap_circle.fitBounds(minipos.subtract(minisize), minisize.multiply(2)); } - if (!_dontRedrawEdges) { + if (typeof options === 'undefined' || !('dontRedrawEdges' in options) || !options.dontRedrawEdges) { var _this = this; _.each( this.project.get("edges").filter( @@ -304,8 +308,7 @@ this.node_image.__representation = _this; this.node_image.scale(this.circle_radius / baseRadius); this.node_image.position = this.paper_coords.subtract(this.image_delta.multiply(this.circle_radius)); - this.redraw(); - this.renderer.throttledPaperDraw(); + this.node_image.insertAbove(this.circle); } else { var _this = this; $(_image).on("load", function() {
--- a/client/js/renderer/scene.js Sat Apr 25 04:37:06 2015 +0200 +++ b/client/js/renderer/scene.js Mon Apr 27 17:22:46 2015 +0200 @@ -833,7 +833,7 @@ return; } _.each(this.representations, function(_representation) { - _representation.redraw(true); + _representation.redraw({ dontRedrawEdges:true }); }); if (this.minimap) { this.redrawMiniframe();
--- a/client/js/renderer/shapebuilder.js Sat Apr 25 04:37:06 2015 +0200 +++ b/client/js/renderer/shapebuilder.js Mon Apr 27 17:22:46 2015 +0200 @@ -39,12 +39,12 @@ }, "diamond":{ getShape: function() { - var d = new paper.Path.Rectangle([-2, -2], [2, 2]); + var d = new paper.Path.Rectangle([-Math.SQRT2, -Math.SQRT2], [Math.SQRT2, Math.SQRT2]); d.rotate(45); return d; }, getImageShape: function(center, radius) { - var d = new paper.Path.Rectangle([-radius, -radius], [radius*2, radius*2]); + var d = new paper.Path.Rectangle([-radius*Math.SQRT2/2, -radius*Math.SQRT2/2], [radius*Math.SQRT2, radius*Math.SQRT2]); d.rotate(45); return d; } @@ -63,15 +63,15 @@ return new paper.Path(path); }, getImageShape: function(center, radius) { - // No calcul for the moment + // No calcul for the moment return new paper.Path(); } }; } }; - + var ShapeBuilder = function (shape){ - if(typeof shape==="undefined"){ + if(shape === null || typeof shape === "undefined"){ shape = "circle"; } if(shape.substr(0,4)==="svg:"){ @@ -82,7 +82,7 @@ } return builders[shape]; }; - + return ShapeBuilder; });
--- a/client/package.json Sat Apr 25 04:37:06 2015 +0200 +++ b/client/package.json Mon Apr 27 17:22:46 2015 +0200 @@ -1,6 +1,6 @@ { "name": "renkan", - "version": "0.8.7", + "version": "0.9.0", "description": "Renkan client application", "repository": { "type": "hg",
--- a/server/java/build.gradle Sat Apr 25 04:37:06 2015 +0200 +++ b/server/java/build.gradle Mon Apr 27 17:22:46 2015 +0200 @@ -2,7 +2,7 @@ apply plugin: 'maven' group = 'org.iri_research.renkan' - version = '0.8.7' + version = '0.9.0' gradle.projectsEvaluated { @@ -17,7 +17,7 @@ junit_version = '4.11' slf4j_log4j12_version = '1.7.5' - spring_version = '3.2.6.RELEASE' + spring_version = '3.2.9.RELEASE' javax_servlet_version = '3.0.1' java_inject_version = '1' commons_codec_version = '1.8'
--- a/server/java/pom.xml Sat Apr 25 04:37:06 2015 +0200 +++ b/server/java/pom.xml Mon Apr 27 17:22:46 2015 +0200 @@ -5,7 +5,7 @@ <groupId>org.iri_research.renkan</groupId> <artifactId>renkan</artifactId> <packaging>pom</packaging> - <version>0.8.7</version> + <version>0.9.0</version> <name>Renkan project</name> <modules>
--- a/server/java/renkan-core/pom.xml Sat Apr 25 04:37:06 2015 +0200 +++ b/server/java/renkan-core/pom.xml Mon Apr 27 17:22:46 2015 +0200 @@ -12,7 +12,7 @@ <name>renkan-core</name> <url>http://maven.apache.org</url> <properties> - <spring-version>3.2.6.RELEASE</spring-version> + <spring-version>3.2.9.RELEASE</spring-version> <spring-data-mongodb-version>1.3.3.RELEASE</spring-data-mongodb-version> <spring-data-commons-version>1.6.3.RELEASE</spring-data-commons-version> <spring-data-jpa-version>1.4.3.RELEASE</spring-data-jpa-version>
--- a/server/java/renkan-core/src/main/java/org/iri_research/renkan/models/Node.java Sat Apr 25 04:37:06 2015 +0200 +++ b/server/java/renkan-core/src/main/java/org/iri_research/renkan/models/Node.java Mon Apr 27 17:22:46 2015 +0200 @@ -19,7 +19,8 @@ public Node(Node node, String projectId) { this(Constants.UUID_GENERATOR.generate().toString(), node.title, node.description, node.uri, node.color, node.createdBy, - node.position, node.image, node.size, projectId); + node.position, node.image, node.size, node.shape, node.type, + node.hidden, projectId); } public Node(Node node) { @@ -33,7 +34,8 @@ @Autowired(required = true) public Node(String id, String title, String description, String uri, String color, String createdBy, Point position, String image, - Integer size, String projectId) { + Integer size, String shape, String type, Boolean hidden, + String projectId) { super(id, title, description, uri, color); this.projectId = projectId; @@ -41,6 +43,9 @@ this.position = position; this.image = image; this.size = (size == null) ? 0 : size.intValue(); + this.shape = shape; + this.type = type; + this.hidden = (hidden == null) ? false : hidden.booleanValue(); } @Field("project_id") @@ -57,6 +62,12 @@ private int size; + private String shape; + + private String type; + + private boolean hidden; + public Point getPosition() { return position; } @@ -69,7 +80,7 @@ public String getProjectId() { return projectId; } - + public void setProjectId(String projectId) { this.projectId = projectId; } @@ -83,6 +94,18 @@ return size; } + public String getShape() { + return shape; + } + + public String getType() { + return type; + } + + public boolean isHidden() { + return hidden; + } + @Override protected String getRawKeyPart() { return this.createdBy;
--- a/server/java/renkan-core/src/test/java/org/iri_research/renkan/test/repositories/ProjectsRepositoryTest.java Sat Apr 25 04:37:06 2015 +0200 +++ b/server/java/renkan-core/src/test/java/org/iri_research/renkan/test/repositories/ProjectsRepositoryTest.java Mon Apr 27 17:22:46 2015 +0200 @@ -144,7 +144,8 @@ Node node = new Node("Node" + i, "Node" + i, "Node " + i, "http://renkan.org/nodes/node" + i, "#ffff0" + i, "test_user", new Point(0, i), - "http://renkan.org/images/node" + i, i, copyProject.getId()); + "http://renkan.org/images/node" + i, i, "circle", "Node", + false, copyProject.getId()); node = this.nodesRepository.save(node); copyProject.getNodes().add(node); this.testNodes.add(node);
--- a/server/java/renkan-web/src/main/java/org/iri_research/renkan/coweb/event/NodeSyncEventManager.java Sat Apr 25 04:37:06 2015 +0200 +++ b/server/java/renkan-web/src/main/java/org/iri_research/renkan/coweb/event/NodeSyncEventManager.java Mon Apr 27 17:22:46 2015 +0200 @@ -72,20 +72,25 @@ String image = (String) values.get("image"); String node_id = (String) values.get("id"); - + //check that node id is unique if(this.getNodesRepository().exists(node_id)) { throw new CowebException("node insert: node exists", String.format("node %s already exists", node_id)); } - + Integer size = (Integer) values.get("size"); + String shape = (String) values.get("shape"); + String type = (String) values.get("type"); + Boolean hidden = (Boolean) values.get("hidden"); + + Node node = new Node(node_id, (String) values.get("title"), (String) values.get("description"), (String) values.get("uri"), (String) values.get("color"), creator_id, nodePosition, image, - size, project_id); + size, shape, type, hidden, project_id); Integer position = (Integer) data.get("position"); @@ -123,9 +128,9 @@ String project_id = (String) values.get("_project_id"); String node_id = (String) values.get("id"); - + Node node = this.getNodesRepository().findOne(node_id); - + if(node==null) { return true; } @@ -136,7 +141,7 @@ return false; } } - + @Override protected void checkUpdate(String clientId, Map<String, Object> data) { @@ -152,5 +157,5 @@ } } - + }
--- a/server/java/renkan-web/src/main/webapp/WEB-INF/templates/projectIndex.html Sat Apr 25 04:37:06 2015 +0200 +++ b/server/java/renkan-web/src/main/webapp/WEB-INF/templates/projectIndex.html Mon Apr 27 17:22:46 2015 +0200 @@ -8,10 +8,10 @@ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/> <link rel="shortcut icon" href="../../static/img/favicon.ico" th:href="@{/static/img/favicon.ico}"/> - + <script th:remove="all" type="text/javascript" src="../../static/lib/jquery/jquery.js"></script> <script th:remove="all" type="text/javascript" src="../../static/js/thymol.js"></script> - + <script src="../../static/lib/jquery/jquery.js" th:src="@{/static/lib/jquery/jquery.js}" ></script> <script src="../../static/lib/jquery-ui/jquery-ui.min.js" th:src="@{/static/lib/jquery-ui/jquery-ui.min.js}" ></script> <script src="../../static/lib/underscore/underscore.js" th:src="@{/static/lib/underscore/underscore.js}" ></script> @@ -30,11 +30,11 @@ <div id="headerNav" th:include="fragment/pageFragment :: headerNavFragment"></div> </header> <div id="inner"> - <div id="label" class="translate" th:text="#{renkanIndex.renkan_exp}">Create a Renkan</div> + <div id="label" class="translate" th:text="#{renkanIndex.renkan_exp}">Create a Renkan</div> <form action="#" id="new-renkan-form"> <fieldset id="form-fields"> <div id="title-field"><label th:text="#{renkanIndex.renkan_title}" for="renkantitle">title</label><input type="text" id="renkantitle" autofocus="autofocus" x-webkit-speech="x-webkit-speech"/></div> - <div id="file-field"><label th:text="#{renkanIndex.renkan_file}" for="renkanfile">file</label><input type="file" id="renkanfile"/></div> + <div id="file-field"><label th:text="#{renkanIndex.renkan_file}" for="renkanfile">file</label><input type="file" id="renkanfile"/></div> </fieldset> <div id="form-submit"><button type="submit">OK</button></div> </form> @@ -42,8 +42,8 @@ <div id="project-list-container"> <h2 th:text="#{renkanIndex.project_list}">Project list</h2> <div id="project-filter-container"> - <form method="get"> - <input type="text" id="project-filter" name="filter" placeholder="filter title" th:placeholder="#{renkanIndex.project_filter}" th:value="${param['filter']}?${param['filter'][0]}:''" /> + <form method="get"> + <input type="text" id="project-filter" name="filter" placeholder="filter title" th:placeholder="#{renkanIndex.project_filter}" th:value="${param['filter']}?${param['filter'][0]}:''" /> <button type="submit">OK</button> </form> </div> @@ -59,7 +59,7 @@ <a href="#?p.page=6">6</a> <span>...</span> <a href="#?p.page=5">></a> - <a href="#?p.page=7">>></a> + <a href="#?p.page=7">>></a> </div> </div> <table th:with="columnSort=${param['p.sort']}?${param['p.sort'][0]}:'updated',sortDir=${param['p.sort.dir']}?${param['p.sort.dir'][0]}:'desc'"> @@ -91,12 +91,12 @@ <li><a href="#" th:href="@{'/p/pub/'+${project.id}(cowebkey=${project.getKey(1)})}"><span class=" ui-icon renkan-icon-eye"></span><span th:text="#{renkanIndex.project_render_link}">View project</span></a></li> <li><a href="#" th:href="@{'/p/exp/'+${project.id}}"><span class="ui-icon ui-icon-arrowthickstop-1-s"></span><span th:text="#{renkanIndex.project_export_link}">Export project</span></a></li> </ul> - + </div> </div> <footer id="footer" th:include="fragment/pageFragment :: footerFragment"> <div id="version">Ā© <span class="version-date">2014</span> <a href="http://www.iri.centrepompidou.fr" target="_blanck">IRI</a> - Version <span class="version-version">0.0</span></div> - </footer> + </footer> </div> <script th:inline="javascript" > /*<![CDATA[*/ @@ -105,15 +105,15 @@ { var renkantitle = $("#renkantitle").val(), renkanfiles = $("#renkanfile").prop("files"); - + if(renkantitle.length === 0 && renkanfiles.length === 0) { - var alert_message = /*[[#{renkanIndex.js.empty_form_error}]]*/"Please enter a title or a file"; + var alert_message = /*[[#{renkanIndex.js.empty_form_error}]]*/"Please enter a title or a file"; alert(alert_message); return false; } var post_url = /*[[@{/rest/projects/}]]*/"/rest/projects/", deferred = $.Deferred(); - + deferred.done(function(new_renkan) { new_renkan.space_id = /*[[${space.id}]]*/"_"; $.ajax(post_url, { @@ -161,20 +161,20 @@ window.location.reload(); }); } - + function deleteProject(project_id, project_title) { var message = /*[[#{renkanIndex.project_delete_confirm}]]*/"Delete project \"<%= title %>\""; - if(confirm(_.template(message, {title: project_title}))) { + if(confirm(_.template(message)({title: project_title}))) { var delete_url = /*[[@{/rest/projects}]]*/"#"; $.ajax(delete_url+"/"+project_id, { - type: "DELETE" + type: "DELETE" }).done(function(){ window.location.reload(); }); } } - + function createMenuHandler(menu, timeoutCallback) { return function(e) { menu.toggle(); @@ -192,12 +192,12 @@ }); if(menu.is(":visible")) { menu.data('blurtimeout', setTimeout( timeoutCallback,5000)); - } + } } } - + $(function(){ - + $(".copy-project").click(function(event) { var project_id = $(event.currentTarget).data("project_id"); copyProject(project_id); @@ -207,29 +207,29 @@ deleteProject($(event.currentTarget).data("project_id"), $(event.currentTarget).data("project_title")); }); - + $("#new-renkan-form").submit(function(e) { e.preventDefault(); go2Title(); return false; }); - + $("#import-renkan-form").submit(function(e) { e.preventDefault(); console.log("import form event :", e); }); - + $('.renkan-action-button').each(function() { var projectId = $(this).data('project_id'); var menu = $('#action-menu-'+projectId).menu().position({ my: "left top", at: "right top", of: this }).hide(); var that = this; - + var timeoutCallback = function() { menu.hide(); $(that).removeClass("ui-icon-triangle-1-se").addClass("ui-icon-triangle-1-e"); menu.removeData('blurtimeout'); }; - + menu.on('menufocus', function() { clearTimeout(menu.data('blurtimeout')); menu.removeData('blurtimeout'); @@ -237,7 +237,7 @@ menu.on('menublur',function(e) { menu.data('blurtimeout', setTimeout( timeoutCallback,200)); }); - + $(this).click(createMenuHandler(menu, timeoutCallback)); }); });
--- a/server/java/renkan-web/src/main/webapp/WEB-INF/templates/renkanIndex.html Sat Apr 25 04:37:06 2015 +0200 +++ b/server/java/renkan-web/src/main/webapp/WEB-INF/templates/renkanIndex.html Mon Apr 27 17:22:46 2015 +0200 @@ -8,15 +8,15 @@ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/> <link rel="shortcut icon" href="../../static/img/favicon.ico" th:href="@{/static/img/favicon.ico}" /> - + <script th:remove="all" type="text/javascript" src="../../static/lib/jquery/jquery.js"></script> - <script th:remove="all" type="text/javascript" src="../../static/js/thymol.js"></script> + <script th:remove="all" type="text/javascript" src="../../static/js/thymol.js"></script> <script src="../../lib/jquery/jquery.js" th:src="@{/static/lib/jquery/jquery.js}" ></script> <script src="../../lib/underscore/underscore.js" th:src="@{/static/lib/underscore/underscore.js}" ></script> <link href="../../static/css/style.css" rel="stylesheet" th:href="@{/static/css/style.css}"/> - <link href="../../static/css/index.css" rel="stylesheet" th:href="@{/static/css/index.css}"/> + <link href="../../static/css/index.css" rel="stylesheet" th:href="@{/static/css/index.css}"/> </head> <body> <div id="container"> @@ -25,7 +25,7 @@ <h1 th:text="#{renkanIndex.renkan_spaces}">Renkan Spaces</h1> </header> <div id="inner"> - <div id="label" class="translate" th:text="#{renkanIndex.space_exp}">Create a Space</div> + <div id="label" class="translate" th:text="#{renkanIndex.space_exp}">Create a Space</div> <form action="#" onsubmit="go2Title();return false;"> <fieldset id="form-fields"> <div id="title-field"><label th:text="#{renkanIndex.renkan_title}" for="renkantitle">title</label><input type="text" id="renkantitle" autofocus="autofocus" x-webkit-speech="x-webkit-speech"/></div> @@ -35,7 +35,7 @@ </div> <h2 th:text="#{renkanIndex.space_list}">Space list</h2> <div th:include="fragment/paginationFragment :: paginationFragment" class="pagination-container"> - <div> + <div> <a href="#?p.page=1"><<</a> <a href="#?p.page=3"><</a> <span>...</span> @@ -46,7 +46,7 @@ <a href="#?p.page=6">6</a> <span>...</span> <a href="#?p.page=5">></a> - <a href="#?p.page=7">>></a> + <a href="#?p.page=7">>></a> </div> </div> <table> @@ -66,7 +66,7 @@ <td><a href="#" th:href="@{'/s/'+${space.id}}" th:text="#{renkanIndex.space_open_link}">Open space</a></td> </tr> </tbody> - </table> + </table> </div> <footer id="footer" th:include="fragment/pageFragment :: footerFragment"> <div id="version">Ā© <span class="version-date">2014</span> <a href="http://www.iri.centrepompidou.fr" target="_blanck">IRI</a> - Version <span class="version-version">0.0</span></div> @@ -74,23 +74,23 @@ </div> <script th:inline="javascript" > /*<![CDATA[*/ - + function go2Title() { var renkantitle = $("#renkantitle").val(); if(renkantitle.length == 0) { - var alert_message = /*[[#{renkanIndex.js.empty_name_error}]]*/"Please enter a title"; + var alert_message = /*[[#{renkanIndex.js.empty_name_error}]]*/"Please enter a title"; alert(alert_message); return false; } - + new_space = { title: renkantitle, description: "(empty description)", uri: null }; - - var post_url = /*[[@{/rest/spaces/}]]*/"/rest/spaces/"; + + var post_url = /*[[@{/rest/spaces/}]]*/"/rest/spaces/"; $.ajax(post_url, { data:JSON.stringify(new_space), type: "POST", @@ -98,9 +98,9 @@ contentType: "application/json; charset=UTF-8" }).done(function(space){ var template_url = /*[[@{'/s/<%=space_id%>'}]]*/"s/<%=space_id%>"; - window.location = _.template(template_url, {space_id: space.id}); + window.location = _.template(template_url)({space_id: space.id}); }); - + //? window.location = "p/" + renkantitle : alert(/*[[#{renkanIndex.js.empty_name_error}]]*/"Please enter a name"); }
--- a/server/java/renkan-web/src/main/webapp/WEB-INF/templates/renkanProjectEdit.html Sat Apr 25 04:37:06 2015 +0200 +++ b/server/java/renkan-web/src/main/webapp/WEB-INF/templates/renkanProjectEdit.html Mon Apr 27 17:22:46 2015 +0200 @@ -4,14 +4,14 @@ <meta charset="utf-8" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> - + <title>RENKAN</title> <meta name="description" content="" /> <meta name="author" content="Institut de Recherche et d'Innovation" /> <link rel="icon" href="../../static/img/favicon.ico" th:href="@{/static/img/favicon.ico}" type="image/x-icon" /> <script src="lib/jquery/jquery.js" th:src="@{/static/lib/jquery/jquery.js}" ></script> <script src="lib/jquery-mousewheel/jquery.mousewheel.js" th:src="@{/static/lib/jquery-mousewheel/jquery.mousewheel.js}"></script> - <script src="lib/underscore/underscore.js" th:src="@{/static/lib/underscore/underscore.js}"></script> + <script src="lib/lodash/lodash.js" th:src="@{/static/lib/lodash/lodash.js}"></script> <script src="lib/backbone/backbone.js" th:src="@{/static/lib/backbone/backbone.js}"></script> <script src="lib/backbone-relational/backbone-relational.js" th:src="@{/static/lib/backbone-relational/backbone-relational.js}"></script> <script src="lib/paper/paper-full.js" th:src="@{/static/lib/paper/paper-full.js}"></script> @@ -31,14 +31,14 @@ useWebSockets: /*[[${coweb_websockets}]]*/false }; </script> - <script type="text/javascript" src="lib/dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true" th:src="@{/static/lib/dojo/dojo.js}"></script> + <script type="text/javascript" src="lib/dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true" th:src="@{/static/lib/dojo/dojo.js}"></script> <script type="text/javascript" th:inline="javascript"> /*<![CDATA[*/ function startRenkan() { var renkan_config = { static_url : /*[[@{/static/}]]*/ "", read_only: true, - change_shapes: false, + change_shapes: true, allow_image_upload : false, bins: [ { @@ -63,11 +63,11 @@ { type: "Wikipedia", lang: "fr" - }, + }, { type: "Wikipedia", lang: "en" - }, + }, { type: "Wikipedia", lang: "ja"
--- a/server/java/renkan-web/src/main/webapp/WEB-INF/templates/renkanProjectPublish.html Sat Apr 25 04:37:06 2015 +0200 +++ b/server/java/renkan-web/src/main/webapp/WEB-INF/templates/renkanProjectPublish.html Mon Apr 27 17:22:46 2015 +0200 @@ -9,7 +9,7 @@ <meta name="author" content="Institut de Recherche et d'Innovation" /> <script src="lib/jquery/jquery.js" th:src="@{/static/lib/jquery/jquery.js}" ></script> <script src="lib/jquery-mousewheel/jquery.mousewheel.js" th:src="@{/static/lib/jquery-mousewheel/jquery.mousewheel.js}"></script> - <script src="lib/underscore/underscore.js" th:src="@{/static/lib/underscore/underscore.js}"></script> + <script src="lib/lodash/lodash.js" th:src="@{/static/lib/lodash/lodash.js}"></script> <script src="lib/backbone/backbone.js" th:src="@{/static/lib/backbone/backbone.js}"></script> <script src="lib/backbone-relational/backbone-relational.js" th:src="@{/static/lib/backbone-relational/backbone-relational.js}"></script> <script src="lib/paper/paper-full.js" th:src="@{/static/lib/paper/paper-full.js}"></script>
--- a/server/java/renkan-web/src/main/webapp/static/js/config.js Sat Apr 25 04:37:06 2015 +0200 +++ b/server/java/renkan-web/src/main/webapp/static/js/config.js Mon Apr 27 17:22:46 2015 +0200 @@ -13,7 +13,7 @@ org : 'lib/org', corenkan: 'static/js/corenkan', rcolor: 'static/lib/rcolor', - underscore: 'static/lib/underscore/underscore', + underscore: 'static/lib/lodash/lodash', jquery: 'static/lib/jquery/jquery', filesaver: 'static/lib/FileSaver/FileSaver', }, @@ -21,6 +21,5 @@ name: 'dojo', location:'static/lib/dojo', main:'main' - }], + }], }; -
--- a/server/java/renkan-web/src/main/webapp/static/js/corenkan.js Sat Apr 25 04:37:06 2015 +0200 +++ b/server/java/renkan-web/src/main/webapp/static/js/corenkan.js Mon Apr 27 17:22:46 2015 +0200 @@ -111,7 +111,7 @@ console.log("Users State response", user_list); _.each(user_list, function(user, i, l) { user._id = user.id; - }); + }); this.renkan.current_user_list.reset(user_list, {silent: true}); }; @@ -139,7 +139,7 @@ for(var fieldname in c.changes) { if(c.changes[fieldname]) { values[fieldname] = obj.get(fieldname); - } + } } return values; } @@ -175,7 +175,7 @@ _project_id : obj.get("project").id, _user_id : (this.project.current_user!==null)?this.project.current_user.id:null }; - collab.sendSync(type, values, "delete", options.index); + collab.sendSync(type, values, "delete", options.index); }; proto.updateObjectBind = function(type, obj, options, collab) { @@ -187,14 +187,14 @@ _project_id : obj.get("project").id, _user_id : (this.project.current_user!==null)?this.project.current_user.id:null }; - _.extend(values,obj.changed); + _.extend(values,obj.changed); collab.sendSync(type, values); } }; /** * Called when an abject is changed - * + * */ proto.objectChange = function(event, model, collection, options) { @@ -231,17 +231,17 @@ var that = this; - renkan.current_user_list.bind("add", function(obj, c, options) { + renkan.current_user_list.on("add", function(obj, c, options) { that.addObjectBind("roster", obj, c, options, that.users_collab); }); //renkan.current_user_list.bind("remove", function(obj, c, options) { // that.removeObjectBind("_roster", obj, c, options, that.users_collab); //}); - renkan.current_user_list.bind("change", function(obj, options) { + renkan.current_user_list.on("change", function(obj, options) { that.updateObjectBind("roster", obj, options, that.users_collab); }); - renkan.current_user_list.bind("change", function(obj, options) { + renkan.current_user_list.on("change", function(obj, options) { console.log("update roster",obj, options); // get user in project var project = obj.get("project"); @@ -339,55 +339,55 @@ } - project.get("nodes").bind("add", function(obj, c, options) { + project.get("nodes").on("add", function(obj, c, options) { that.addObjectBind("node", obj, c, options, that.collab); }); - project.get("nodes").bind("remove", function(obj, c, options) { + project.get("nodes").on("remove", function(obj, c, options) { that.removeObjectBind("node", obj, c, options, that.collab); }); - project.get("nodes").bind("change", function(obj, options) { + project.get("nodes").on("change", function(obj, options) { that.updateObjectBind("node", obj, options, that.collab); }); - project.get("users").bind("add", function(obj, c, options) { + project.get("users").on("add", function(obj, c, options) { that.addObjectBind("user", obj, c, options, that.collab); }); - project.get("users").bind("remove", function(obj, c, options) { + project.get("users").on("remove", function(obj, c, options) { that.removeObjectBind("user", obj, c, options, that.collab); }); - project.get("users").bind("change", function(obj, options) { + project.get("users").on("change", function(obj, options) { that.updateObjectBind("user", obj, options, that.collab); }); - project.get("edges").bind("add", function(obj, c, options) { + project.get("edges").on("add", function(obj, c, options) { that.addObjectBind("edge", obj, c, options, that.collab); }); - project.get("edges").bind("remove", function(obj, c, options) { + project.get("edges").on("remove", function(obj, c, options) { that.removeObjectBind("edge", obj, c, options, that.collab); }); - project.get("edges").bind("change", function(obj, options) { + project.get("edges").on("change", function(obj, options) { that.updateObjectBind("edge", obj, options, that.collab); }); - project.get("views").bind("add", function(obj, c, options) { + project.get("views").on("add", function(obj, c, options) { that.addObjectBind("view", obj, c, options, that.collab); }); - project.get("views").bind("remove", function(obj, c, options) { + project.get("views").on("remove", function(obj, c, options) { that.removeObjectBind("view", obj, c, options, that.collab); }); - project.get("views").bind("change", function(obj, options) { + project.get("views").on("change", function(obj, options) { that.updateObjectBind("view", obj, options, that.collab); }); - + }; @@ -397,7 +397,7 @@ * TODO: manage project list change on server * @param args Cooperative web event */ - proto.onRemoteProjectChange = function(args) { + proto.onRemoteProjectChange = function(args) { console.log("Remote project change", args); if (args.type === "update") { this.onRemoteProjectUpdate(args.value, args.position); @@ -460,13 +460,13 @@ this.onRemoteObjectChange("views", args); }; - + /** * Called when a remote data store for nodes changes in some manner. Dispatches to * local methods for insert, update, delete handling. * @param args Cooperative web event */ - proto.onRemoteRosterChange = function(args) { + proto.onRemoteRosterChange = function(args) { this.onRemoteObjectChange(this.renkan.current_user_list, args); }; @@ -492,7 +492,7 @@ } } - }; + }; /** * Called when an object is inserted in a remote data store. @@ -505,7 +505,7 @@ console.log("Remote ", field_coll ," insert values ", values, "position", position); - var coll = null; + var coll = null; if(typeof field_coll === "string") { coll = this.project.get(field_coll); } @@ -513,7 +513,7 @@ coll = field_coll; } - var object_id = values.id; + var object_id = values.id; var obj = coll.get(object_id); @@ -563,7 +563,7 @@ console.log("Remote ", field_coll ," update values ", values, "position", position); - var coll = null; + var coll = null; if(typeof field_coll === "string") { coll = this.project.get(field_coll); } @@ -595,7 +595,7 @@ */ proto.onRemoteObjectDelete = function(field_coll, position) { console.log("Remote ", field_coll," delete position", position); - var coll = null; + var coll = null; if(typeof field_coll === "string") { coll = this.project.get(field); } @@ -616,4 +616,4 @@ return { app: app }; -}); \ No newline at end of file +});
--- a/server/java/renkan-web/src/test/java/org/iri_research/renkan/test/controller/RenkanControllerTest.java Sat Apr 25 04:37:06 2015 +0200 +++ b/server/java/renkan-web/src/test/java/org/iri_research/renkan/test/controller/RenkanControllerTest.java Mon Apr 27 17:22:46 2015 +0200 @@ -72,7 +72,7 @@ projectsRepository.deleteAll(); spacesRepository.deleteAll(); } - + @Before public void setup() { @@ -104,14 +104,15 @@ e.printStackTrace(); } } - + Project testProject = pl.get(0); - + for (int i = 0; i < 3; i++) { Node node = new Node("Node" + i, "Node" + i, "Node " + i, "http://renkan.org/nodes/node" + i, "#ffff0" + i, "test_user", new Point(0, i), - "http://renkan.org/images/node" + i, i, testProject.getId()); + "http://renkan.org/images/node" + i, i, "circle", "Node", + false, testProject.getId()); node = this.nodesRepository.save(node); testProject.getNodes().add(node); this.testNodes.add(node); @@ -135,12 +136,12 @@ this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build(); } - + @After public void teardown() { this.clean(); } - + @Test public void testExportProject() throws Exception { MockHttpServletRequestBuilder get = MockMvcRequestBuilders.get("/p/exp/"+this.testProjects.get(0).getId()); @@ -148,11 +149,11 @@ .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) .andReturn(); - + logger.debug("testExportProject resp : " + res.getResponse().getContentAsString()); } - + @Test public void testExportProjectContent() throws Exception { MockHttpServletRequestBuilder get = MockMvcRequestBuilders.get("/p/exp/"+this.testProjects.get(0).getId()); @@ -166,12 +167,12 @@ .andExpect(MockMvcResultMatchers.jsonPath("nodes").isArray()) .andExpect(MockMvcResultMatchers.jsonPath("edges").isArray()) .andReturn(); - + logger.debug("testExportProjectContent resp : " + res.getResponse().getContentAsString()); } - - + + @Test public void testExportProjectExclude() throws Exception { MockHttpServletRequestBuilder get = MockMvcRequestBuilders.get("/p/exp/"+this.testProjects.get(0).getId()); @@ -183,9 +184,9 @@ .andExpect(MockMvcResultMatchers.jsonPath("nodes[*].@id").exists()) .andExpect(MockMvcResultMatchers.jsonPath("edges[*].id").doesNotExist()) .andReturn(); - + logger.debug("testExportProjectContentExclude resp : " + res.getResponse().getContentAsString()); } - + }
--- a/server/java/renkan-web/src/test/java/org/iri_research/renkan/test/rest/ProjectRestTest.java Sat Apr 25 04:37:06 2015 +0200 +++ b/server/java/renkan-web/src/test/java/org/iri_research/renkan/test/rest/ProjectRestTest.java Mon Apr 27 17:22:46 2015 +0200 @@ -89,9 +89,9 @@ private String spaceId = UUID.randomUUID().toString(); private String projectId = UUID.randomUUID().toString(); - + private File tempFile = null; - + private ObjectMapper getObjectMapper() { ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JodaModule()); @@ -138,7 +138,8 @@ Node node = new Node("Node" + i, "Node" + i, "Node " + i, "http://renkan.org/nodes/node" + i, "#ffff0" + i, "test_user", new Point(0, i), - "http://renkan.org/images/node" + i, i, testProject.getId()); + "http://renkan.org/images/node" + i, i, "circle", "Node", + false, testProject.getId()); node = this.nodesRepository.save(node); testProject.getNodes().add(node); this.testNodes.add(node); @@ -176,7 +177,7 @@ this.tempFile.deleteOnExit(); } } - + @Test public void testGetProject() throws JsonProcessingException, IOException { WebTarget webResource = this.target(); @@ -184,19 +185,19 @@ .path(testProject.getId()).request().acceptEncoding("UTF-8").accept(MediaType.APPLICATION_JSON_TYPE).get(String.class); Assert.assertNotNull("get resp String not empty", respString); Assert.assertFalse("get resp String non empty", respString.isEmpty()); - + PrintWriter writer = new PrintWriter(this.tempFile, "UTF-8"); writer.write(respString); writer.close(); - + logger.debug("Test get Project : respString : " + respString); - + ObjectMapper mapper = this.getObjectMapper(); - + JsonNode projectNode = mapper.readTree(respString); - + Assert.assertNotNull("project node not null", projectNode); - + Assert.assertNotNull("Must have an id", projectNode.get("id")); Assert.assertEquals("id must match", this.projectId, projectNode.get("id").asText()); Assert.assertNotNull("Must have a created date", projectNode.get("created")); @@ -253,31 +254,31 @@ } } - + @Test public void testPostProject() throws IOException { InputStream in = this.getClass().getResourceAsStream("/org/iri_research/renkan/test/rest/test-project.json"); StringWriter sw = new StringWriter(); IOUtils.copy(in, sw, "utf-8"); - + String jsonStr = sw.toString().replaceAll("\\<space_id\\>", this.spaceId); - + WebTarget webResource = this.target(); Response resp = webResource.path("projects").request(MediaType.APPLICATION_JSON).post(Entity.entity(jsonStr, MediaType.APPLICATION_JSON), Response.class); - + Assert.assertEquals("Status must be OK", 201, resp.getStatus()); - + ObjectMapper mapper = new ObjectMapper(); JsonNode node = mapper.readTree(resp.readEntity(String.class)); - + Assert.assertNotNull("Must have a project in response", node); - + JsonNode idNode = node.findValue("id"); Assert.assertNotNull("Project must have an id", idNode); String id = idNode.asText(); Assert.assertNotNull("Project must have an id not null", id); Assert.assertNotEquals("Project must have an id not empty", "", id); - + Iterator<JsonNode> edges = node.get("edges").elements(); int totalEdges = 0; while(edges.hasNext()) {
--- a/server/python/django/renkanmanager/__init__.py Sat Apr 25 04:37:06 2015 +0200 +++ b/server/python/django/renkanmanager/__init__.py Mon Apr 27 17:22:46 2015 +0200 @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -VERSION = (0, 8, 7, "final", 0) +VERSION = (0, 9, 0, "final", 0) def get_version():
--- a/server/python/django/renkanmanager/static/renkanmanager/lib/FileSaver/FileSaver.js Sat Apr 25 04:37:06 2015 +0200 +++ b/server/python/django/renkanmanager/static/renkanmanager/lib/FileSaver/FileSaver.js Mon Apr 27 17:22:46 2015 +0200 @@ -1,6 +1,6 @@ /* FileSaver.js * A saveAs() FileSaver implementation. - * 2014-12-17 + * 2015-03-04 * * By Eli Grey, http://eligrey.com * License: X11/MIT @@ -135,6 +135,10 @@ revoke(object_url); return; } + // prepend BOM for UTF-8 XML and text/plain types + if (/^\s*(?:text\/(?:plain|xml)|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) { + blob = new Blob(["\ufeff", blob], {type: blob.type}); + } // Object and web filesystem URLs have a problem saving in Google Chrome when // viewed in a tab, so I force save with application/octet-stream // http://code.google.com/p/chromium/issues/detail?id=91158 @@ -236,7 +240,7 @@ // with an attribute `content` that corresponds to the window if (typeof module !== "undefined" && module.exports) { - module.exports = saveAs; + module.exports.saveAs = saveAs; } else if ((typeof define !== "undefined" && define !== null) && (define.amd != null)) { define([], function() { return saveAs;
--- a/server/python/django/renkanmanager/static/renkanmanager/lib/FileSaver/FileSaver.min.js Sat Apr 25 04:37:06 2015 +0200 +++ b/server/python/django/renkanmanager/static/renkanmanager/lib/FileSaver/FileSaver.min.js Mon Apr 27 17:22:46 2015 +0200 @@ -1,2 +1,2 @@ /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ -var saveAs=saveAs||typeof navigator!=="undefined"&&navigator.msSaveOrOpenBlob&&navigator.msSaveOrOpenBlob.bind(navigator)||function(view){"use strict";if(typeof navigator!=="undefined"&&/MSIE [1-9]\./.test(navigator.userAgent)){return}var doc=view.document,get_URL=function(){return view.URL||view.webkitURL||view},save_link=doc.createElementNS("http://www.w3.org/1999/xhtml","a"),can_use_save_link="download"in save_link,click=function(node){var event=doc.createEvent("MouseEvents");event.initMouseEvent("click",true,false,view,0,0,0,0,0,false,false,false,false,0,null);node.dispatchEvent(event)},webkit_req_fs=view.webkitRequestFileSystem,req_fs=view.requestFileSystem||webkit_req_fs||view.mozRequestFileSystem,throw_outside=function(ex){(view.setImmediate||view.setTimeout)(function(){throw ex},0)},force_saveable_type="application/octet-stream",fs_min_size=0,arbitrary_revoke_timeout=500,revoke=function(file){var revoker=function(){if(typeof file==="string"){get_URL().revokeObjectURL(file)}else{file.remove()}};if(view.chrome){revoker()}else{setTimeout(revoker,arbitrary_revoke_timeout)}},dispatch=function(filesaver,event_types,event){event_types=[].concat(event_types);var i=event_types.length;while(i--){var listener=filesaver["on"+event_types[i]];if(typeof listener==="function"){try{listener.call(filesaver,event||filesaver)}catch(ex){throw_outside(ex)}}}},FileSaver=function(blob,name){var filesaver=this,type=blob.type,blob_changed=false,object_url,target_view,dispatch_all=function(){dispatch(filesaver,"writestart progress write writeend".split(" "))},fs_error=function(){if(blob_changed||!object_url){object_url=get_URL().createObjectURL(blob)}if(target_view){target_view.location.href=object_url}else{var new_tab=view.open(object_url,"_blank");if(new_tab==undefined&&typeof safari!=="undefined"){view.location.href=object_url}}filesaver.readyState=filesaver.DONE;dispatch_all();revoke(object_url)},abortable=function(func){return function(){if(filesaver.readyState!==filesaver.DONE){return func.apply(this,arguments)}}},create_if_not_found={create:true,exclusive:false},slice;filesaver.readyState=filesaver.INIT;if(!name){name="download"}if(can_use_save_link){object_url=get_URL().createObjectURL(blob);save_link.href=object_url;save_link.download=name;click(save_link);filesaver.readyState=filesaver.DONE;dispatch_all();revoke(object_url);return}if(view.chrome&&type&&type!==force_saveable_type){slice=blob.slice||blob.webkitSlice;blob=slice.call(blob,0,blob.size,force_saveable_type);blob_changed=true}if(webkit_req_fs&&name!=="download"){name+=".download"}if(type===force_saveable_type||webkit_req_fs){target_view=view}if(!req_fs){fs_error();return}fs_min_size+=blob.size;req_fs(view.TEMPORARY,fs_min_size,abortable(function(fs){fs.root.getDirectory("saved",create_if_not_found,abortable(function(dir){var save=function(){dir.getFile(name,create_if_not_found,abortable(function(file){file.createWriter(abortable(function(writer){writer.onwriteend=function(event){target_view.location.href=file.toURL();filesaver.readyState=filesaver.DONE;dispatch(filesaver,"writeend",event);revoke(file)};writer.onerror=function(){var error=writer.error;if(error.code!==error.ABORT_ERR){fs_error()}};"writestart progress write abort".split(" ").forEach(function(event){writer["on"+event]=filesaver["on"+event]});writer.write(blob);filesaver.abort=function(){writer.abort();filesaver.readyState=filesaver.DONE};filesaver.readyState=filesaver.WRITING}),fs_error)}),fs_error)};dir.getFile(name,{create:false},abortable(function(file){file.remove();save()}),abortable(function(ex){if(ex.code===ex.NOT_FOUND_ERR){save()}else{fs_error()}}))}),fs_error)}),fs_error)},FS_proto=FileSaver.prototype,saveAs=function(blob,name){return new FileSaver(blob,name)};FS_proto.abort=function(){var filesaver=this;filesaver.readyState=filesaver.DONE;dispatch(filesaver,"abort")};FS_proto.readyState=FS_proto.INIT=0;FS_proto.WRITING=1;FS_proto.DONE=2;FS_proto.error=FS_proto.onwritestart=FS_proto.onprogress=FS_proto.onwrite=FS_proto.onabort=FS_proto.onerror=FS_proto.onwriteend=null;return saveAs}(typeof self!=="undefined"&&self||typeof window!=="undefined"&&window||this.content);if(typeof module!=="undefined"&&module.exports){module.exports=saveAs}else if(typeof define!=="undefined"&&define!==null&&define.amd!=null){define([],function(){return saveAs})} +var saveAs=saveAs||"undefined"!=typeof navigator&&navigator.msSaveOrOpenBlob&&navigator.msSaveOrOpenBlob.bind(navigator)||function(e){"use strict";if("undefined"==typeof navigator||!/MSIE [1-9]\./.test(navigator.userAgent)){var t=e.document,n=function(){return e.URL||e.webkitURL||e},o=t.createElementNS("http://www.w3.org/1999/xhtml","a"),r="download"in o,i=function(n){var o=t.createEvent("MouseEvents");o.initMouseEvent("click",!0,!1,e,0,0,0,0,0,!1,!1,!1,!1,0,null),n.dispatchEvent(o)},a=e.webkitRequestFileSystem,c=e.requestFileSystem||a||e.mozRequestFileSystem,s=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},u="application/octet-stream",f=0,d=500,l=function(t){var o=function(){"string"==typeof t?n().revokeObjectURL(t):t.remove()};e.chrome?o():setTimeout(o,d)},v=function(e,t,n){t=[].concat(t);for(var o=t.length;o--;){var r=e["on"+t[o]];if("function"==typeof r)try{r.call(e,n||e)}catch(i){s(i)}}},p=function(t,s){var d,p,w,y=this,m=t.type,S=!1,h=function(){v(y,"writestart progress write writeend".split(" "))},O=function(){if((S||!d)&&(d=n().createObjectURL(t)),p)p.location.href=d;else{var o=e.open(d,"_blank");void 0==o&&"undefined"!=typeof safari&&(e.location.href=d)}y.readyState=y.DONE,h(),l(d)},b=function(e){return function(){return y.readyState!==y.DONE?e.apply(this,arguments):void 0}},g={create:!0,exclusive:!1};return y.readyState=y.INIT,s||(s="download"),r?(d=n().createObjectURL(t),o.href=d,o.download=s,i(o),y.readyState=y.DONE,h(),void l(d)):(/^\s*(?:text\/(?:plain|xml)|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(t.type)&&(t=new Blob(["",t],{type:t.type})),e.chrome&&m&&m!==u&&(w=t.slice||t.webkitSlice,t=w.call(t,0,t.size,u),S=!0),a&&"download"!==s&&(s+=".download"),(m===u||a)&&(p=e),c?(f+=t.size,void c(e.TEMPORARY,f,b(function(e){e.root.getDirectory("saved",g,b(function(e){var n=function(){e.getFile(s,g,b(function(e){e.createWriter(b(function(n){n.onwriteend=function(t){p.location.href=e.toURL(),y.readyState=y.DONE,v(y,"writeend",t),l(e)},n.onerror=function(){var e=n.error;e.code!==e.ABORT_ERR&&O()},"writestart progress write abort".split(" ").forEach(function(e){n["on"+e]=y["on"+e]}),n.write(t),y.abort=function(){n.abort(),y.readyState=y.DONE},y.readyState=y.WRITING}),O)}),O)};e.getFile(s,{create:!1},b(function(e){e.remove(),n()}),b(function(e){e.code===e.NOT_FOUND_ERR?n():O()}))}),O)}),O)):void O())},w=p.prototype,y=function(e,t){return new p(e,t)};return w.abort=function(){var e=this;e.readyState=e.DONE,v(e,"abort")},w.readyState=w.INIT=0,w.WRITING=1,w.DONE=2,w.error=w.onwritestart=w.onprogress=w.onwrite=w.onabort=w.onerror=w.onwriteend=null,y}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this.content);"undefined"!=typeof module&&module.exports?module.exports.saveAs=saveAs:"undefined"!=typeof define&&null!==define&&null!=define.amd&&define([],function(){return saveAs}); \ No newline at end of file
--- a/server/python/django/renkanmanager/static/renkanmanager/lib/FileSaver/LICENSE.md Sat Apr 25 04:37:06 2015 +0200 +++ b/server/python/django/renkanmanager/static/renkanmanager/lib/FileSaver/LICENSE.md Mon Apr 27 17:22:46 2015 +0200 @@ -1,4 +1,4 @@ -Copyright Ā© 2014 [Eli Grey][1]. +Copyright Ā© 2015 [Eli Grey][1]. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
--- a/server/python/django/renkanmanager/static/renkanmanager/lib/FileSaver/README.md Sat Apr 25 04:37:06 2015 +0200 +++ b/server/python/django/renkanmanager/static/renkanmanager/lib/FileSaver/README.md Mon Apr 27 17:22:46 2015 +0200 @@ -10,7 +10,7 @@ sent to an external server. Looking for `canvas.toBlob()` for saving canvases? Check out -[canvas-toBlob.js](https://github.com/eligrey/canvas-toBlob.js) for a cross-browser implementation. +[canvas-toBlob.js][2] for a cross-browser implementation. Supported browsers ------------------ @@ -19,10 +19,10 @@ | -------------- | ------------- | ------------ | ------------- | ------------ | | Firefox 20+ | Blob | Yes | 800 MiB | None | | Firefox < 20 | data: URI | No | n/a | [Blob.js](https://github.com/eligrey/Blob.js) | -| Chrome | Blob | Yes | 345 MiB | None | -| Chrome for Android | Blob | Yes | 345 MiB | None | +| Chrome | Blob | Yes | [500 MiB][3] | None | +| Chrome for Android | Blob | Yes | [500 MiB][3] | None | | IE 10+ | Blob | Yes | 600 MiB | None | -| Opera 15+ | Blob | Yes | 345 MiB | None | +| Opera 15+ | Blob | Yes | 500 MiB | None | | Opera < 15 | data: URI | No | n/a | [Blob.js](https://github.com/eligrey/Blob.js) | | Safari 6.1+* | Blob | No | ? | None | | Safari < 6 | data: URI | No | n/a | [Blob.js](https://github.com/eligrey/Blob.js) | @@ -66,8 +66,8 @@ saveAs(blob, "hello world.txt"); ``` -The standard W3C File API [`Blob`][3] interface is not available in all browsers. -[Blob.js][4] is a cross-browser `Blob` implementation that solves this. +The standard W3C File API [`Blob`][4] interface is not available in all browsers. +[Blob.js][5] is a cross-browser `Blob` implementation that solves this. ### Saving a canvas @@ -80,15 +80,17 @@ ``` Note: The standard HTML5 `canvas.toBlob()` method is not available in all browsers. -[canvas-toBlob.js][5] is a cross-browser `canvas.toBlob()` that polyfills this. +[canvas-toBlob.js][6] is a cross-browser `canvas.toBlob()` that polyfills this.  [1]: http://eligrey.com/demos/FileSaver.js/ - [3]: https://developer.mozilla.org/en-US/docs/DOM/Blob - [4]: https://github.com/eligrey/Blob.js - [5]: https://github.com/eligrey/canvas-toBlob.js + [2]: https://github.com/eligrey/canvas-toBlob.js + [3]: https://code.google.com/p/chromium/issues/detail?id=375297 + [4]: https://developer.mozilla.org/en-US/docs/DOM/Blob + [5]: https://github.com/eligrey/Blob.js + [6]: https://github.com/eligrey/canvas-toBlob.js Contributing ------------ @@ -100,3 +102,8 @@ ``` Please make sure you build a production version before submitting a pull request. + +Bower Installation +------------------ + +Please see the [this repo](http://github.com/Teleborder/FileSaver.js) for a bower-compatible fork of FileSaver.js, available under the package name `file-saver.js`.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/python/django/renkanmanager/static/renkanmanager/lib/lodash/lodash.compat.js Mon Apr 27 17:22:46 2015 +0200 @@ -0,0 +1,7157 @@ +/** + * @license + * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/> + * Build: `lodash -o ./dist/lodash.compat.js` + * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/> + * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE> + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license <http://lodash.com/license> + */ +;(function() { + + /** Used as a safe reference for `undefined` in pre ES5 environments */ + var undefined; + + /** Used to pool arrays and objects used internally */ + var arrayPool = [], + objectPool = []; + + /** Used to generate unique IDs */ + var idCounter = 0; + + /** Used internally to indicate various things */ + var indicatorObject = {}; + + /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */ + var keyPrefix = +new Date + ''; + + /** Used as the size when optimizations are enabled for large arrays */ + var largeArraySize = 75; + + /** Used as the max size of the `arrayPool` and `objectPool` */ + var maxPoolSize = 40; + + /** Used to detect and test whitespace */ + var whitespace = ( + // whitespace + ' \t\x0B\f\xA0\ufeff' + + + // line terminators + '\n\r\u2028\u2029' + + + // unicode category "Zs" space separators + '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' + ); + + /** Used to match empty string literals in compiled template source */ + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + + /** + * Used to match ES6 template delimiters + * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals + */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + + /** Used to match regexp flags from their coerced string values */ + var reFlags = /\w*$/; + + /** Used to detected named functions */ + var reFuncName = /^\s*function[ \n\r\t]+\w/; + + /** Used to match "interpolate" template delimiters */ + var reInterpolate = /<%=([\s\S]+?)%>/g; + + /** Used to match leading whitespace and zeros to be removed */ + var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)'); + + /** Used to ensure capturing order of template delimiters */ + var reNoMatch = /($^)/; + + /** Used to detect functions containing a `this` reference */ + var reThis = /\bthis\b/; + + /** Used to match unescaped characters in compiled string literals */ + var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g; + + /** Used to assign default `context` object properties */ + var contextProps = [ + 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object', + 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN', + 'parseInt', 'setTimeout' + ]; + + /** Used to fix the JScript [[DontEnum]] bug */ + var shadowedProps = [ + 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', + 'toLocaleString', 'toString', 'valueOf' + ]; + + /** Used to make template sourceURLs easier to identify */ + var templateCounter = 0; + + /** `Object#toString` result shortcuts */ + var argsClass = '[object Arguments]', + arrayClass = '[object Array]', + boolClass = '[object Boolean]', + dateClass = '[object Date]', + errorClass = '[object Error]', + funcClass = '[object Function]', + numberClass = '[object Number]', + objectClass = '[object Object]', + regexpClass = '[object RegExp]', + stringClass = '[object String]'; + + /** Used to identify object classifications that `_.clone` supports */ + var cloneableClasses = {}; + cloneableClasses[funcClass] = false; + cloneableClasses[argsClass] = cloneableClasses[arrayClass] = + cloneableClasses[boolClass] = cloneableClasses[dateClass] = + cloneableClasses[numberClass] = cloneableClasses[objectClass] = + cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true; + + /** Used as an internal `_.debounce` options object */ + var debounceOptions = { + 'leading': false, + 'maxWait': 0, + 'trailing': false + }; + + /** Used as the property descriptor for `__bindData__` */ + var descriptor = { + 'configurable': false, + 'enumerable': false, + 'value': null, + 'writable': false + }; + + /** Used as the data object for `iteratorTemplate` */ + var iteratorData = { + 'args': '', + 'array': null, + 'bottom': '', + 'firstArg': '', + 'init': '', + 'keys': null, + 'loop': '', + 'shadowedProps': null, + 'support': null, + 'top': '', + 'useHas': false + }; + + /** Used to determine if values are of the language type Object */ + var objectTypes = { + 'boolean': false, + 'function': true, + 'object': true, + 'number': false, + 'string': false, + 'undefined': false + }; + + /** Used to escape characters for inclusion in compiled string literals */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\t': 't', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + /** Used as a reference to the global object */ + var root = (objectTypes[typeof window] && window) || this; + + /** Detect free variable `exports` */ + var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; + + /** Detect free variable `module` */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports` */ + var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; + + /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */ + var freeGlobal = objectTypes[typeof global] && global; + if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { + root = freeGlobal; + } + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `_.indexOf` without support for binary searches + * or `fromIndex` constraints. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value or `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + var index = (fromIndex || 0) - 1, + length = array ? array.length : 0; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * An implementation of `_.contains` for cache objects that mimics the return + * signature of `_.indexOf` by returning `0` if the value is found, else `-1`. + * + * @private + * @param {Object} cache The cache object to inspect. + * @param {*} value The value to search for. + * @returns {number} Returns `0` if `value` is found, else `-1`. + */ + function cacheIndexOf(cache, value) { + var type = typeof value; + cache = cache.cache; + + if (type == 'boolean' || value == null) { + return cache[value] ? 0 : -1; + } + if (type != 'number' && type != 'string') { + type = 'object'; + } + var key = type == 'number' ? value : keyPrefix + value; + cache = (cache = cache[type]) && cache[key]; + + return type == 'object' + ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1) + : (cache ? 0 : -1); + } + + /** + * Adds a given value to the corresponding cache object. + * + * @private + * @param {*} value The value to add to the cache. + */ + function cachePush(value) { + var cache = this.cache, + type = typeof value; + + if (type == 'boolean' || value == null) { + cache[value] = true; + } else { + if (type != 'number' && type != 'string') { + type = 'object'; + } + var key = type == 'number' ? value : keyPrefix + value, + typeCache = cache[type] || (cache[type] = {}); + + if (type == 'object') { + (typeCache[key] || (typeCache[key] = [])).push(value); + } else { + typeCache[key] = true; + } + } + } + + /** + * Used by `_.max` and `_.min` as the default callback when a given + * collection is a string value. + * + * @private + * @param {string} value The character to inspect. + * @returns {number} Returns the code unit of given character. + */ + function charAtCallback(value) { + return value.charCodeAt(0); + } + + /** + * Used by `sortBy` to compare transformed `collection` elements, stable sorting + * them in ascending order. + * + * @private + * @param {Object} a The object to compare to `b`. + * @param {Object} b The object to compare to `a`. + * @returns {number} Returns the sort order indicator of `1` or `-1`. + */ + function compareAscending(a, b) { + var ac = a.criteria, + bc = b.criteria, + index = -1, + length = ac.length; + + while (++index < length) { + var value = ac[index], + other = bc[index]; + + if (value !== other) { + if (value > other || typeof value == 'undefined') { + return 1; + } + if (value < other || typeof other == 'undefined') { + return -1; + } + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to return the same value for + // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247 + // + // This also ensures a stable sort in V8 and other engines. + // See http://code.google.com/p/v8/issues/detail?id=90 + return a.index - b.index; + } + + /** + * Creates a cache object to optimize linear searches of large arrays. + * + * @private + * @param {Array} [array=[]] The array to search. + * @returns {null|Object} Returns the cache object or `null` if caching should not be used. + */ + function createCache(array) { + var index = -1, + length = array.length, + first = array[0], + mid = array[(length / 2) | 0], + last = array[length - 1]; + + if (first && typeof first == 'object' && + mid && typeof mid == 'object' && last && typeof last == 'object') { + return false; + } + var cache = getObject(); + cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false; + + var result = getObject(); + result.array = array; + result.cache = cache; + result.push = cachePush; + + while (++index < length) { + result.push(array[index]); + } + return result; + } + + /** + * Used by `template` to escape characters for inclusion in compiled + * string literals. + * + * @private + * @param {string} match The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeStringChar(match) { + return '\\' + stringEscapes[match]; + } + + /** + * Gets an array from the array pool or creates a new one if the pool is empty. + * + * @private + * @returns {Array} The array from the pool. + */ + function getArray() { + return arrayPool.pop() || []; + } + + /** + * Gets an object from the object pool or creates a new one if the pool is empty. + * + * @private + * @returns {Object} The object from the pool. + */ + function getObject() { + return objectPool.pop() || { + 'array': null, + 'cache': null, + 'criteria': null, + 'false': false, + 'index': 0, + 'null': false, + 'number': null, + 'object': null, + 'push': null, + 'string': null, + 'true': false, + 'undefined': false, + 'value': null + }; + } + + /** + * Checks if `value` is a DOM node in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`. + */ + function isNode(value) { + // IE < 9 presents DOM nodes as `Object` objects except they have `toString` + // methods that are `typeof` "string" and still can coerce nodes to strings + return typeof value.toString != 'function' && typeof (value + '') == 'string'; + } + + /** + * Releases the given array back to the array pool. + * + * @private + * @param {Array} [array] The array to release. + */ + function releaseArray(array) { + array.length = 0; + if (arrayPool.length < maxPoolSize) { + arrayPool.push(array); + } + } + + /** + * Releases the given object back to the object pool. + * + * @private + * @param {Object} [object] The object to release. + */ + function releaseObject(object) { + var cache = object.cache; + if (cache) { + releaseObject(cache); + } + object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null; + if (objectPool.length < maxPoolSize) { + objectPool.push(object); + } + } + + /** + * Slices the `collection` from the `start` index up to, but not including, + * the `end` index. + * + * Note: This function is used instead of `Array#slice` to support node lists + * in IE < 9 and to ensure dense arrays are returned. + * + * @private + * @param {Array|Object|string} collection The collection to slice. + * @param {number} start The start index. + * @param {number} end The end index. + * @returns {Array} Returns the new array. + */ + function slice(array, start, end) { + start || (start = 0); + if (typeof end == 'undefined') { + end = array ? array.length : 0; + } + var index = -1, + length = end - start || 0, + result = Array(length < 0 ? 0 : length); + + while (++index < length) { + result[index] = array[start + index]; + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Create a new `lodash` function using the given context object. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Object} [context=root] The context object. + * @returns {Function} Returns the `lodash` function. + */ + function runInContext(context) { + // Avoid issues with some ES3 environments that attempt to use values, named + // after built-in constructors like `Object`, for the creation of literals. + // ES5 clears this up by stating that literals must use built-in constructors. + // See http://es5.github.io/#x11.1.5. + context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; + + /** Native constructor references */ + var Array = context.Array, + Boolean = context.Boolean, + Date = context.Date, + Error = context.Error, + Function = context.Function, + Math = context.Math, + Number = context.Number, + Object = context.Object, + RegExp = context.RegExp, + String = context.String, + TypeError = context.TypeError; + + /** + * Used for `Array` method references. + * + * Normally `Array.prototype` would suffice, however, using an array literal + * avoids issues in Narwhal. + */ + var arrayRef = []; + + /** Used for native method references */ + var errorProto = Error.prototype, + objectProto = Object.prototype, + stringProto = String.prototype; + + /** Used to restore the original `_` reference in `noConflict` */ + var oldDash = context._; + + /** Used to resolve the internal [[Class]] of values */ + var toString = objectProto.toString; + + /** Used to detect if a method is native */ + var reNative = RegExp('^' + + String(toString) + .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + .replace(/toString| for [^\]]+/g, '.*?') + '$' + ); + + /** Native method shortcuts */ + var ceil = Math.ceil, + clearTimeout = context.clearTimeout, + floor = Math.floor, + fnToString = Function.prototype.toString, + getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, + hasOwnProperty = objectProto.hasOwnProperty, + push = arrayRef.push, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + setTimeout = context.setTimeout, + splice = arrayRef.splice, + unshift = arrayRef.unshift; + + /** Used to set meta data on functions */ + var defineProperty = (function() { + // IE 8 only accepts DOM elements + try { + var o = {}, + func = isNative(func = Object.defineProperty) && func, + result = func(o, o, o) && func; + } catch(e) { } + return result; + }()); + + /* Native method shortcuts for methods with the same name as other `lodash` methods */ + var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, + nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, + nativeIsFinite = context.isFinite, + nativeIsNaN = context.isNaN, + nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, + nativeMax = Math.max, + nativeMin = Math.min, + nativeParseInt = context.parseInt, + nativeRandom = Math.random; + + /** Used to lookup a built-in constructor by [[Class]] */ + var ctorByClass = {}; + ctorByClass[arrayClass] = Array; + ctorByClass[boolClass] = Boolean; + ctorByClass[dateClass] = Date; + ctorByClass[funcClass] = Function; + ctorByClass[objectClass] = Object; + ctorByClass[numberClass] = Number; + ctorByClass[regexpClass] = RegExp; + ctorByClass[stringClass] = String; + + /** Used to avoid iterating non-enumerable properties in IE < 9 */ + var nonEnumProps = {}; + nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true }; + nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true }; + nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true }; + nonEnumProps[objectClass] = { 'constructor': true }; + + (function() { + var length = shadowedProps.length; + while (length--) { + var key = shadowedProps[length]; + for (var className in nonEnumProps) { + if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) { + nonEnumProps[className][key] = false; + } + } + } + }()); + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps the given value to enable intuitive + * method chaining. + * + * In addition to Lo-Dash methods, wrappers also have the following `Array` methods: + * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, + * and `unshift` + * + * Chaining is supported in custom builds as long as the `value` method is + * implicitly or explicitly included in the build. + * + * The chainable wrapper functions are: + * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, + * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`, + * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, + * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, + * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`, + * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, + * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, + * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, + * and `zip` + * + * The non-chainable wrapper functions are: + * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`, + * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, + * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, + * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, + * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`, + * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`, + * `template`, `unescape`, `uniqueId`, and `value` + * + * The wrapper functions `first` and `last` return wrapped values when `n` is + * provided, otherwise they return unwrapped values. + * + * Explicit chaining can be enabled by using the `_.chain` method. + * + * @name _ + * @constructor + * @category Chaining + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns a `lodash` instance. + * @example + * + * var wrapped = _([1, 2, 3]); + * + * // returns an unwrapped value + * wrapped.reduce(function(sum, num) { + * return sum + num; + * }); + * // => 6 + * + * // returns a wrapped value + * var squares = wrapped.map(function(num) { + * return num * num; + * }); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor + return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__')) + ? value + : new lodashWrapper(value); + } + + /** + * A fast path for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap in a `lodash` instance. + * @param {boolean} chainAll A flag to enable chaining for all methods + * @returns {Object} Returns a `lodash` instance. + */ + function lodashWrapper(value, chainAll) { + this.__chain__ = !!chainAll; + this.__wrapped__ = value; + } + // ensure `new lodashWrapper` is an instance of `lodash` + lodashWrapper.prototype = lodash.prototype; + + /** + * An object used to flag environments features. + * + * @static + * @memberOf _ + * @type Object + */ + var support = lodash.support = {}; + + (function() { + var ctor = function() { this.x = 1; }, + object = { '0': 1, 'length': 1 }, + props = []; + + ctor.prototype = { 'valueOf': 1, 'y': 1 }; + for (var key in new ctor) { props.push(key); } + for (key in arguments) { } + + /** + * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9). + * + * @memberOf _.support + * @type boolean + */ + support.argsClass = toString.call(arguments) == argsClass; + + /** + * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5). + * + * @memberOf _.support + * @type boolean + */ + support.argsObject = arguments.constructor == Object && !(arguments instanceof Array); + + /** + * Detect if `name` or `message` properties of `Error.prototype` are + * enumerable by default. (IE < 9, Safari < 5.1) + * + * @memberOf _.support + * @type boolean + */ + support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name'); + + /** + * Detect if `prototype` properties are enumerable by default. + * + * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 + * (if the prototype or a property on the prototype has been set) + * incorrectly sets a function's `prototype` property [[Enumerable]] + * value to `true`. + * + * @memberOf _.support + * @type boolean + */ + support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype'); + + /** + * Detect if functions can be decompiled by `Function#toString` + * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps). + * + * @memberOf _.support + * @type boolean + */ + support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext); + + /** + * Detect if `Function#name` is supported (all but IE). + * + * @memberOf _.support + * @type boolean + */ + support.funcNames = typeof Function.name == 'string'; + + /** + * Detect if `arguments` object indexes are non-enumerable + * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1). + * + * @memberOf _.support + * @type boolean + */ + support.nonEnumArgs = key != 0; + + /** + * Detect if properties shadowing those on `Object.prototype` are non-enumerable. + * + * In IE < 9 an objects own properties, shadowing non-enumerable ones, are + * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug). + * + * @memberOf _.support + * @type boolean + */ + support.nonEnumShadows = !/valueOf/.test(props); + + /** + * Detect if own properties are iterated after inherited properties (all but IE < 9). + * + * @memberOf _.support + * @type boolean + */ + support.ownLast = props[0] != 'x'; + + /** + * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly. + * + * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()` + * and `splice()` functions that fail to remove the last element, `value[0]`, + * of array-like objects even though the `length` property is set to `0`. + * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()` + * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9. + * + * @memberOf _.support + * @type boolean + */ + support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]); + + /** + * Detect lack of support for accessing string characters by index. + * + * IE < 8 can't access characters by index and IE 8 can only access + * characters by index on string literals. + * + * @memberOf _.support + * @type boolean + */ + support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx'; + + /** + * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9) + * and that the JS engine errors when attempting to coerce an object to + * a string without a `toString` function. + * + * @memberOf _.support + * @type boolean + */ + try { + support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + '')); + } catch(e) { + support.nodeClass = true; + } + }(1)); + + /** + * By default, the template delimiters used by Lo-Dash are similar to those in + * embedded Ruby (ERB). Change the following template settings to use alternative + * delimiters. + * + * @static + * @memberOf _ + * @type Object + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'escape': /<%-([\s\S]+?)%>/g, + + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'evaluate': /<%([\s\S]+?)%>/g, + + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type string + */ + 'variable': '', + + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type Object + */ + 'imports': { + + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type Function + */ + '_': lodash + } + }; + + /*--------------------------------------------------------------------------*/ + + /** + * The template used to create iterator functions. + * + * @private + * @param {Object} data The data object used to populate the text. + * @returns {string} Returns the interpolated text. + */ + var iteratorTemplate = function(obj) { + + var __p = 'var index, iterable = ' + + (obj.firstArg) + + ', result = ' + + (obj.init) + + ';\nif (!iterable) return result;\n' + + (obj.top) + + ';'; + if (obj.array) { + __p += '\nvar length = iterable.length; index = -1;\nif (' + + (obj.array) + + ') { '; + if (support.unindexedChars) { + __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } '; + } + __p += '\n while (++index < length) {\n ' + + (obj.loop) + + ';\n }\n}\nelse { '; + } else if (support.nonEnumArgs) { + __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' + + (obj.loop) + + ';\n }\n } else { '; + } + + if (support.enumPrototypes) { + __p += '\n var skipProto = typeof iterable == \'function\';\n '; + } + + if (support.enumErrorProps) { + __p += '\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n '; + } + + var conditions = []; if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); } if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); } + + if (obj.useHas && obj.keys) { + __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] && keys(iterable),\n length = ownProps ? ownProps.length : 0;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n'; + if (conditions.length) { + __p += ' if (' + + (conditions.join(' && ')) + + ') {\n '; + } + __p += + (obj.loop) + + '; '; + if (conditions.length) { + __p += '\n }'; + } + __p += '\n } '; + } else { + __p += '\n for (index in iterable) {\n'; + if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); } if (conditions.length) { + __p += ' if (' + + (conditions.join(' && ')) + + ') {\n '; + } + __p += + (obj.loop) + + '; '; + if (conditions.length) { + __p += '\n }'; + } + __p += '\n } '; + if (support.nonEnumShadows) { + __p += '\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n '; + for (k = 0; k < 7; k++) { + __p += '\n index = \'' + + (obj.shadowedProps[k]) + + '\';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))'; + if (!obj.useHas) { + __p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])'; + } + __p += ') {\n ' + + (obj.loop) + + ';\n } '; + } + __p += '\n } '; + } + + } + + if (obj.array || support.nonEnumArgs) { + __p += '\n}'; + } + __p += + (obj.bottom) + + ';\nreturn result'; + + return __p + }; + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `_.bind` that creates the bound function and + * sets its meta data. + * + * @private + * @param {Array} bindData The bind data array. + * @returns {Function} Returns the new bound function. + */ + function baseBind(bindData) { + var func = bindData[0], + partialArgs = bindData[2], + thisArg = bindData[4]; + + function bound() { + // `Function#bind` spec + // http://es5.github.io/#x15.3.4.5 + if (partialArgs) { + // avoid `arguments` object deoptimizations by using `slice` instead + // of `Array.prototype.slice.call` and not assigning `arguments` to a + // variable as a ternary expression + var args = slice(partialArgs); + push.apply(args, arguments); + } + // mimic the constructor's `return` behavior + // http://es5.github.io/#x13.2.2 + if (this instanceof bound) { + // ensure `new bound` is an instance of `func` + var thisBinding = baseCreate(func.prototype), + result = func.apply(thisBinding, args || arguments); + return isObject(result) ? result : thisBinding; + } + return func.apply(thisArg, args || arguments); + } + setBindData(bound, bindData); + return bound; + } + + /** + * The base implementation of `_.clone` without argument juggling or support + * for `thisArg` binding. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep=false] Specify a deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates clones with source counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, callback, stackA, stackB) { + if (callback) { + var result = callback(value); + if (typeof result != 'undefined') { + return result; + } + } + // inspect [[Class]] + var isObj = isObject(value); + if (isObj) { + var className = toString.call(value); + if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) { + return value; + } + var ctor = ctorByClass[className]; + switch (className) { + case boolClass: + case dateClass: + return new ctor(+value); + + case numberClass: + case stringClass: + return new ctor(value); + + case regexpClass: + result = ctor(value.source, reFlags.exec(value)); + result.lastIndex = value.lastIndex; + return result; + } + } else { + return value; + } + var isArr = isArray(value); + if (isDeep) { + // check for circular references and return corresponding clone + var initedStack = !stackA; + stackA || (stackA = getArray()); + stackB || (stackB = getArray()); + + var length = stackA.length; + while (length--) { + if (stackA[length] == value) { + return stackB[length]; + } + } + result = isArr ? ctor(value.length) : {}; + } + else { + result = isArr ? slice(value) : assign({}, value); + } + // add array properties assigned by `RegExp#exec` + if (isArr) { + if (hasOwnProperty.call(value, 'index')) { + result.index = value.index; + } + if (hasOwnProperty.call(value, 'input')) { + result.input = value.input; + } + } + // exit for shallow clone + if (!isDeep) { + return result; + } + // add the source value to the stack of traversed objects + // and associate it with its clone + stackA.push(value); + stackB.push(result); + + // recursively populate clone (susceptible to call stack limits) + (isArr ? baseEach : forOwn)(value, function(objValue, key) { + result[key] = baseClone(objValue, isDeep, callback, stackA, stackB); + }); + + if (initedStack) { + releaseArray(stackA); + releaseArray(stackB); + } + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(prototype, properties) { + return isObject(prototype) ? nativeCreate(prototype) : {}; + } + // fallback for browsers without `Object.create` + if (!nativeCreate) { + baseCreate = (function() { + function Object() {} + return function(prototype) { + if (isObject(prototype)) { + Object.prototype = prototype; + var result = new Object; + Object.prototype = null; + } + return result || context.Object(); + }; + }()); + } + + /** + * The base implementation of `_.createCallback` without support for creating + * "_.pluck" or "_.where" style callbacks. + * + * @private + * @param {*} [func=identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of the created callback. + * @param {number} [argCount] The number of arguments the callback accepts. + * @returns {Function} Returns a callback function. + */ + function baseCreateCallback(func, thisArg, argCount) { + if (typeof func != 'function') { + return identity; + } + // exit early for no `thisArg` or already bound by `Function#bind` + if (typeof thisArg == 'undefined' || !('prototype' in func)) { + return func; + } + var bindData = func.__bindData__; + if (typeof bindData == 'undefined') { + if (support.funcNames) { + bindData = !func.name; + } + bindData = bindData || !support.funcDecomp; + if (!bindData) { + var source = fnToString.call(func); + if (!support.funcNames) { + bindData = !reFuncName.test(source); + } + if (!bindData) { + // checks if `func` references the `this` keyword and stores the result + bindData = reThis.test(source); + setBindData(func, bindData); + } + } + } + // exit early if there are no `this` references or `func` is bound + if (bindData === false || (bindData !== true && bindData[1] & 1)) { + return func; + } + switch (argCount) { + case 1: return function(value) { + return func.call(thisArg, value); + }; + case 2: return function(a, b) { + return func.call(thisArg, a, b); + }; + case 3: return function(value, index, collection) { + return func.call(thisArg, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(thisArg, accumulator, value, index, collection); + }; + } + return bind(func, thisArg); + } + + /** + * The base implementation of `createWrapper` that creates the wrapper and + * sets its meta data. + * + * @private + * @param {Array} bindData The bind data array. + * @returns {Function} Returns the new function. + */ + function baseCreateWrapper(bindData) { + var func = bindData[0], + bitmask = bindData[1], + partialArgs = bindData[2], + partialRightArgs = bindData[3], + thisArg = bindData[4], + arity = bindData[5]; + + var isBind = bitmask & 1, + isBindKey = bitmask & 2, + isCurry = bitmask & 4, + isCurryBound = bitmask & 8, + key = func; + + function bound() { + var thisBinding = isBind ? thisArg : this; + if (partialArgs) { + var args = slice(partialArgs); + push.apply(args, arguments); + } + if (partialRightArgs || isCurry) { + args || (args = slice(arguments)); + if (partialRightArgs) { + push.apply(args, partialRightArgs); + } + if (isCurry && args.length < arity) { + bitmask |= 16 & ~32; + return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]); + } + } + args || (args = arguments); + if (isBindKey) { + func = thisBinding[key]; + } + if (this instanceof bound) { + thisBinding = baseCreate(func.prototype); + var result = func.apply(thisBinding, args); + return isObject(result) ? result : thisBinding; + } + return func.apply(thisBinding, args); + } + setBindData(bound, bindData); + return bound; + } + + /** + * The base implementation of `_.difference` that accepts a single array + * of values to exclude. + * + * @private + * @param {Array} array The array to process. + * @param {Array} [values] The array of values to exclude. + * @returns {Array} Returns a new array of filtered values. + */ + function baseDifference(array, values) { + var index = -1, + indexOf = getIndexOf(), + length = array ? array.length : 0, + isLarge = length >= largeArraySize && indexOf === baseIndexOf, + result = []; + + if (isLarge) { + var cache = createCache(values); + if (cache) { + indexOf = cacheIndexOf; + values = cache; + } else { + isLarge = false; + } + } + while (++index < length) { + var value = array[index]; + if (indexOf(values, value) < 0) { + result.push(value); + } + } + if (isLarge) { + releaseObject(values); + } + return result; + } + + /** + * The base implementation of `_.flatten` without support for callback + * shorthands or `thisArg` binding. + * + * @private + * @param {Array} array The array to flatten. + * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. + * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects. + * @param {number} [fromIndex=0] The index to start from. + * @returns {Array} Returns a new flattened array. + */ + function baseFlatten(array, isShallow, isStrict, fromIndex) { + var index = (fromIndex || 0) - 1, + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + + if (value && typeof value == 'object' && typeof value.length == 'number' + && (isArray(value) || isArguments(value))) { + // recursively flatten arrays (susceptible to call stack limits) + if (!isShallow) { + value = baseFlatten(value, isShallow, isStrict); + } + var valIndex = -1, + valLength = value.length, + resIndex = result.length; + + result.length += valLength; + while (++valIndex < valLength) { + result[resIndex++] = value[valIndex]; + } + } else if (!isStrict) { + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.isEqual`, without support for `thisArg` binding, + * that allows partial "_.where" style comparisons. + * + * @private + * @param {*} a The value to compare. + * @param {*} b The other value to compare. + * @param {Function} [callback] The function to customize comparing values. + * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons. + * @param {Array} [stackA=[]] Tracks traversed `a` objects. + * @param {Array} [stackB=[]] Tracks traversed `b` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(a, b, callback, isWhere, stackA, stackB) { + // used to indicate that when comparing objects, `a` has at least the properties of `b` + if (callback) { + var result = callback(a, b); + if (typeof result != 'undefined') { + return !!result; + } + } + // exit early for identical values + if (a === b) { + // treat `+0` vs. `-0` as not equal + return a !== 0 || (1 / a == 1 / b); + } + var type = typeof a, + otherType = typeof b; + + // exit early for unlike primitive values + if (a === a && + !(a && objectTypes[type]) && + !(b && objectTypes[otherType])) { + return false; + } + // exit early for `null` and `undefined` avoiding ES3's Function#call behavior + // http://es5.github.io/#x15.3.4.4 + if (a == null || b == null) { + return a === b; + } + // compare [[Class]] names + var className = toString.call(a), + otherClass = toString.call(b); + + if (className == argsClass) { + className = objectClass; + } + if (otherClass == argsClass) { + otherClass = objectClass; + } + if (className != otherClass) { + return false; + } + switch (className) { + case boolClass: + case dateClass: + // coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal + return +a == +b; + + case numberClass: + // treat `NaN` vs. `NaN` as equal + return (a != +a) + ? b != +b + // but treat `+0` vs. `-0` as not equal + : (a == 0 ? (1 / a == 1 / b) : a == +b); + + case regexpClass: + case stringClass: + // coerce regexes to strings (http://es5.github.io/#x15.10.6.4) + // treat string primitives and their corresponding object instances as equal + return a == String(b); + } + var isArr = className == arrayClass; + if (!isArr) { + // unwrap any `lodash` wrapped values + var aWrapped = hasOwnProperty.call(a, '__wrapped__'), + bWrapped = hasOwnProperty.call(b, '__wrapped__'); + + if (aWrapped || bWrapped) { + return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB); + } + // exit for functions and DOM nodes + if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) { + return false; + } + // in older versions of Opera, `arguments` objects have `Array` constructors + var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor, + ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor; + + // non `Object` object instances with different constructors are not equal + if (ctorA != ctorB && + !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && + ('constructor' in a && 'constructor' in b) + ) { + return false; + } + } + // assume cyclic structures are equal + // the algorithm for detecting cyclic structures is adapted from ES 5.1 + // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3) + var initedStack = !stackA; + stackA || (stackA = getArray()); + stackB || (stackB = getArray()); + + var length = stackA.length; + while (length--) { + if (stackA[length] == a) { + return stackB[length] == b; + } + } + var size = 0; + result = true; + + // add `a` and `b` to the stack of traversed objects + stackA.push(a); + stackB.push(b); + + // recursively compare objects and arrays (susceptible to call stack limits) + if (isArr) { + // compare lengths to determine if a deep comparison is necessary + length = a.length; + size = b.length; + result = size == length; + + if (result || isWhere) { + // deep compare the contents, ignoring non-numeric properties + while (size--) { + var index = length, + value = b[size]; + + if (isWhere) { + while (index--) { + if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) { + break; + } + } + } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) { + break; + } + } + } + } + else { + // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` + // which, in this case, is more costly + forIn(b, function(value, key, b) { + if (hasOwnProperty.call(b, key)) { + // count the number of properties. + size++; + // deep compare each property value. + return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB)); + } + }); + + if (result && !isWhere) { + // ensure both objects have the same number of properties + forIn(a, function(value, key, a) { + if (hasOwnProperty.call(a, key)) { + // `size` will be `-1` if `a` has more properties than `b` + return (result = --size > -1); + } + }); + } + } + stackA.pop(); + stackB.pop(); + + if (initedStack) { + releaseArray(stackA); + releaseArray(stackB); + } + return result; + } + + /** + * The base implementation of `_.merge` without argument juggling or support + * for `thisArg` binding. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} [callback] The function to customize merging properties. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + */ + function baseMerge(object, source, callback, stackA, stackB) { + (isArray(source) ? forEach : forOwn)(source, function(source, key) { + var found, + isArr, + result = source, + value = object[key]; + + if (source && ((isArr = isArray(source)) || isPlainObject(source))) { + // avoid merging previously merged cyclic sources + var stackLength = stackA.length; + while (stackLength--) { + if ((found = stackA[stackLength] == source)) { + value = stackB[stackLength]; + break; + } + } + if (!found) { + var isShallow; + if (callback) { + result = callback(value, source); + if ((isShallow = typeof result != 'undefined')) { + value = result; + } + } + if (!isShallow) { + value = isArr + ? (isArray(value) ? value : []) + : (isPlainObject(value) ? value : {}); + } + // add `source` and associated `value` to the stack of traversed objects + stackA.push(source); + stackB.push(value); + + // recursively merge objects and arrays (susceptible to call stack limits) + if (!isShallow) { + baseMerge(value, source, callback, stackA, stackB); + } + } + } + else { + if (callback) { + result = callback(value, source); + if (typeof result == 'undefined') { + result = source; + } + } + if (typeof result != 'undefined') { + value = result; + } + } + object[key] = value; + }); + } + + /** + * The base implementation of `_.random` without argument juggling or support + * for returning floating-point numbers. + * + * @private + * @param {number} min The minimum possible value. + * @param {number} max The maximum possible value. + * @returns {number} Returns a random number. + */ + function baseRandom(min, max) { + return min + floor(nativeRandom() * (max - min + 1)); + } + + /** + * The base implementation of `_.uniq` without support for callback shorthands + * or `thisArg` binding. + * + * @private + * @param {Array} array The array to process. + * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. + * @param {Function} [callback] The function called per iteration. + * @returns {Array} Returns a duplicate-value-free array. + */ + function baseUniq(array, isSorted, callback) { + var index = -1, + indexOf = getIndexOf(), + length = array ? array.length : 0, + result = []; + + var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf, + seen = (callback || isLarge) ? getArray() : result; + + if (isLarge) { + var cache = createCache(seen); + indexOf = cacheIndexOf; + seen = cache; + } + while (++index < length) { + var value = array[index], + computed = callback ? callback(value, index, array) : value; + + if (isSorted + ? !index || seen[seen.length - 1] !== computed + : indexOf(seen, computed) < 0 + ) { + if (callback || isLarge) { + seen.push(computed); + } + result.push(value); + } + } + if (isLarge) { + releaseArray(seen.array); + releaseObject(seen); + } else if (callback) { + releaseArray(seen); + } + return result; + } + + /** + * Creates a function that aggregates a collection, creating an object composed + * of keys generated from the results of running each element of the collection + * through a callback. The given `setter` function sets the keys and values + * of the composed object. + * + * @private + * @param {Function} setter The setter function. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter) { + return function(collection, callback, thisArg) { + var result = {}; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + setter(result, value, callback(value, index, collection), collection); + } + } else { + baseEach(collection, function(value, key, collection) { + setter(result, value, callback(value, key, collection), collection); + }); + } + return result; + }; + } + + /** + * Creates a function that, when called, either curries or invokes `func` + * with an optional `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of method flags to compose. + * The bitmask may be composed of the following flags: + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` + * 8 - `_.curry` (bound) + * 16 - `_.partial` + * 32 - `_.partialRight` + * @param {Array} [partialArgs] An array of arguments to prepend to those + * provided to the new function. + * @param {Array} [partialRightArgs] An array of arguments to append to those + * provided to the new function. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new function. + */ + function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) { + var isBind = bitmask & 1, + isBindKey = bitmask & 2, + isCurry = bitmask & 4, + isCurryBound = bitmask & 8, + isPartial = bitmask & 16, + isPartialRight = bitmask & 32; + + if (!isBindKey && !isFunction(func)) { + throw new TypeError; + } + if (isPartial && !partialArgs.length) { + bitmask &= ~16; + isPartial = partialArgs = false; + } + if (isPartialRight && !partialRightArgs.length) { + bitmask &= ~32; + isPartialRight = partialRightArgs = false; + } + var bindData = func && func.__bindData__; + if (bindData && bindData !== true) { + // clone `bindData` + bindData = slice(bindData); + if (bindData[2]) { + bindData[2] = slice(bindData[2]); + } + if (bindData[3]) { + bindData[3] = slice(bindData[3]); + } + // set `thisBinding` is not previously bound + if (isBind && !(bindData[1] & 1)) { + bindData[4] = thisArg; + } + // set if previously bound but not currently (subsequent curried functions) + if (!isBind && bindData[1] & 1) { + bitmask |= 8; + } + // set curried arity if not yet set + if (isCurry && !(bindData[1] & 4)) { + bindData[5] = arity; + } + // append partial left arguments + if (isPartial) { + push.apply(bindData[2] || (bindData[2] = []), partialArgs); + } + // append partial right arguments + if (isPartialRight) { + unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs); + } + // merge flags + bindData[1] |= bitmask; + return createWrapper.apply(null, bindData); + } + // fast path for `_.bind` + var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper; + return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]); + } + + /** + * Creates compiled iteration functions. + * + * @private + * @param {...Object} [options] The compile options object(s). + * @param {string} [options.array] Code to determine if the iterable is an array or array-like. + * @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop. + * @param {Function} [options.keys] A reference to `_.keys` for use in own property iteration. + * @param {string} [options.args] A comma separated string of iteration function arguments. + * @param {string} [options.top] Code to execute before the iteration branches. + * @param {string} [options.loop] Code to execute in the object loop. + * @param {string} [options.bottom] Code to execute after the iteration branches. + * @returns {Function} Returns the compiled function. + */ + function createIterator() { + // data properties + iteratorData.shadowedProps = shadowedProps; + + // iterator options + iteratorData.array = iteratorData.bottom = iteratorData.loop = iteratorData.top = ''; + iteratorData.init = 'iterable'; + iteratorData.useHas = true; + + // merge options into a template data object + for (var object, index = 0; object = arguments[index]; index++) { + for (var key in object) { + iteratorData[key] = object[key]; + } + } + var args = iteratorData.args; + iteratorData.firstArg = /^[^,]+/.exec(args)[0]; + + // create the function factory + var factory = Function( + 'baseCreateCallback, errorClass, errorProto, hasOwnProperty, ' + + 'indicatorObject, isArguments, isArray, isString, keys, objectProto, ' + + 'objectTypes, nonEnumProps, stringClass, stringProto, toString', + 'return function(' + args + ') {\n' + iteratorTemplate(iteratorData) + '\n}' + ); + + // return the compiled function + return factory( + baseCreateCallback, errorClass, errorProto, hasOwnProperty, + indicatorObject, isArguments, isArray, isString, iteratorData.keys, objectProto, + objectTypes, nonEnumProps, stringClass, stringProto, toString + ); + } + + /** + * Used by `escape` to convert characters to HTML entities. + * + * @private + * @param {string} match The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeHtmlChar(match) { + return htmlEscapes[match]; + } + + /** + * Gets the appropriate "indexOf" function. If the `_.indexOf` method is + * customized, this method returns the custom method, otherwise it returns + * the `baseIndexOf` function. + * + * @private + * @returns {Function} Returns the "indexOf" function. + */ + function getIndexOf() { + var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result; + return result; + } + + /** + * Checks if `value` is a native function. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a native function, else `false`. + */ + function isNative(value) { + return typeof value == 'function' && reNative.test(value); + } + + /** + * Sets `this` binding data on a given function. + * + * @private + * @param {Function} func The function to set data on. + * @param {Array} value The data array to set. + */ + var setBindData = !defineProperty ? noop : function(func, value) { + descriptor.value = value; + defineProperty(func, '__bindData__', descriptor); + }; + + /** + * A fallback implementation of `isPlainObject` which checks if a given value + * is an object created by the `Object` constructor, assuming objects created + * by the `Object` constructor have no inherited enumerable properties and that + * there are no `Object.prototype` extensions. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + */ + function shimIsPlainObject(value) { + var ctor, + result; + + // avoid non Object objects, `arguments` objects, and DOM elements + if (!(value && toString.call(value) == objectClass) || + (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) || + (!support.argsClass && isArguments(value)) || + (!support.nodeClass && isNode(value))) { + return false; + } + // IE < 9 iterates inherited properties before own properties. If the first + // iterated property is an object's own property then there are no inherited + // enumerable properties. + if (support.ownLast) { + forIn(value, function(value, key, object) { + result = hasOwnProperty.call(object, key); + return false; + }); + return result !== false; + } + // In most environments an object's own properties are iterated before + // its inherited properties. If the last iterated property is an object's + // own property then there are no inherited enumerable properties. + forIn(value, function(value, key) { + result = key; + }); + return typeof result == 'undefined' || hasOwnProperty.call(value, result); + } + + /** + * Used by `unescape` to convert HTML entities to characters. + * + * @private + * @param {string} match The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + function unescapeHtmlChar(match) { + return htmlUnescapes[match]; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Checks if `value` is an `arguments` object. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`. + * @example + * + * (function() { return _.isArguments(arguments); })(1, 2, 3); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + toString.call(value) == argsClass || false; + } + // fallback for browsers that can't detect `arguments` objects by [[Class]] + if (!support.argsClass) { + isArguments = function(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false; + }; + } + + /** + * Checks if `value` is an array. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an array, else `false`. + * @example + * + * (function() { return _.isArray(arguments); })(); + * // => false + * + * _.isArray([1, 2, 3]); + * // => true + */ + var isArray = nativeIsArray || function(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + toString.call(value) == arrayClass || false; + }; + + /** + * A fallback implementation of `Object.keys` which produces an array of the + * given object's own enumerable property names. + * + * @private + * @type Function + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names. + */ + var shimKeys = createIterator({ + 'args': 'object', + 'init': '[]', + 'top': 'if (!(objectTypes[typeof object])) return result', + 'loop': 'result.push(index)' + }); + + /** + * Creates an array composed of the own enumerable property names of an object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names. + * @example + * + * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); + * // => ['one', 'two', 'three'] (property order is not guaranteed across environments) + */ + var keys = !nativeKeys ? shimKeys : function(object) { + if (!isObject(object)) { + return []; + } + if ((support.enumPrototypes && typeof object == 'function') || + (support.nonEnumArgs && object.length && isArguments(object))) { + return shimKeys(object); + } + return nativeKeys(object); + }; + + /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */ + var eachIteratorOptions = { + 'args': 'collection, callback, thisArg', + 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)", + 'array': "typeof length == 'number'", + 'keys': keys, + 'loop': 'if (callback(iterable[index], index, collection) === false) return result' + }; + + /** Reusable iterator options for `assign` and `defaults` */ + var defaultsIteratorOptions = { + 'args': 'object, source, guard', + 'top': + 'var args = arguments,\n' + + ' argsIndex = 0,\n' + + " argsLength = typeof guard == 'number' ? 2 : args.length;\n" + + 'while (++argsIndex < argsLength) {\n' + + ' iterable = args[argsIndex];\n' + + ' if (iterable && objectTypes[typeof iterable]) {', + 'keys': keys, + 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]", + 'bottom': ' }\n}' + }; + + /** Reusable iterator options for `forIn` and `forOwn` */ + var forOwnIteratorOptions = { + 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top, + 'array': false + }; + + /** + * Used to convert characters to HTML entities: + * + * Though the `>` character is escaped for symmetry, characters like `>` and `/` + * don't require escaping in HTML and have no special meaning unless they're part + * of a tag or an unquoted attribute value. + * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact") + */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + + /** Used to convert HTML entities to characters */ + var htmlUnescapes = invert(htmlEscapes); + + /** Used to match HTML entities and HTML characters */ + var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'), + reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g'); + + /** + * A function compiled to iterate `arguments` objects, arrays, objects, and + * strings consistenly across environments, executing the callback for each + * element in the collection. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index|key, collection). Callbacks may exit + * iteration early by explicitly returning `false`. + * + * @private + * @type Function + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + */ + var baseEach = createIterator(eachIteratorOptions); + + /*--------------------------------------------------------------------------*/ + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object. Subsequent sources will overwrite property assignments of previous + * sources. If a callback is provided it will be executed to produce the + * assigned values. The callback is bound to `thisArg` and invoked with two + * arguments; (objectValue, sourceValue). + * + * @static + * @memberOf _ + * @type Function + * @alias extend + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param {Function} [callback] The function to customize assigning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the destination object. + * @example + * + * _.assign({ 'name': 'fred' }, { 'employer': 'slate' }); + * // => { 'name': 'fred', 'employer': 'slate' } + * + * var defaults = _.partialRight(_.assign, function(a, b) { + * return typeof a == 'undefined' ? b : a; + * }); + * + * var object = { 'name': 'barney' }; + * defaults(object, { 'name': 'fred', 'employer': 'slate' }); + * // => { 'name': 'barney', 'employer': 'slate' } + */ + var assign = createIterator(defaultsIteratorOptions, { + 'top': + defaultsIteratorOptions.top.replace(';', + ';\n' + + "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" + + ' var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);\n' + + "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" + + ' callback = args[--argsLength];\n' + + '}' + ), + 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]' + }); + + /** + * Creates a clone of `value`. If `isDeep` is `true` nested objects will also + * be cloned, otherwise they will be assigned by reference. If a callback + * is provided it will be executed to produce the cloned values. If the + * callback returns `undefined` cloning will be handled by the method instead. + * The callback is bound to `thisArg` and invoked with one argument; (value). + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to clone. + * @param {boolean} [isDeep=false] Specify a deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the cloned value. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * var shallow = _.clone(characters); + * shallow[0] === characters[0]; + * // => true + * + * var deep = _.clone(characters, true); + * deep[0] === characters[0]; + * // => false + * + * _.mixin({ + * 'clone': _.partialRight(_.clone, function(value) { + * return _.isElement(value) ? value.cloneNode(false) : undefined; + * }) + * }); + * + * var clone = _.clone(document.body); + * clone.childNodes.length; + * // => 0 + */ + function clone(value, isDeep, callback, thisArg) { + // allows working with "Collections" methods without using their `index` + // and `collection` arguments for `isDeep` and `callback` + if (typeof isDeep != 'boolean' && isDeep != null) { + thisArg = callback; + callback = isDeep; + isDeep = false; + } + return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); + } + + /** + * Creates a deep clone of `value`. If a callback is provided it will be + * executed to produce the cloned values. If the callback returns `undefined` + * cloning will be handled by the method instead. The callback is bound to + * `thisArg` and invoked with one argument; (value). + * + * Note: This method is loosely based on the structured clone algorithm. Functions + * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and + * objects created by constructors other than `Object` are cloned to plain `Object` objects. + * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the deep cloned value. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * var deep = _.cloneDeep(characters); + * deep[0] === characters[0]; + * // => false + * + * var view = { + * 'label': 'docs', + * 'node': element + * }; + * + * var clone = _.cloneDeep(view, function(value) { + * return _.isElement(value) ? value.cloneNode(true) : undefined; + * }); + * + * clone.node == view.node; + * // => false + */ + function cloneDeep(value, callback, thisArg) { + return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); + } + + /** + * Creates an object that inherits from the given `prototype` object. If a + * `properties` object is provided its own enumerable properties are assigned + * to the created object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties) { + var result = baseCreate(prototype); + return properties ? assign(result, properties) : result; + } + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object for all destination properties that resolve to `undefined`. Once a + * property is set, additional defaults of the same property will be ignored. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param- {Object} [guard] Allows working with `_.reduce` without using its + * `key` and `object` arguments as sources. + * @returns {Object} Returns the destination object. + * @example + * + * var object = { 'name': 'barney' }; + * _.defaults(object, { 'name': 'fred', 'employer': 'slate' }); + * // => { 'name': 'barney', 'employer': 'slate' } + */ + var defaults = createIterator(defaultsIteratorOptions); + + /** + * This method is like `_.findIndex` except that it returns the key of the + * first element that passes the callback check, instead of the element itself. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to search. + * @param {Function|Object|string} [callback=identity] The function called per + * iteration. If a property name or object is provided it will be used to + * create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {string|undefined} Returns the key of the found element, else `undefined`. + * @example + * + * var characters = { + * 'barney': { 'age': 36, 'blocked': false }, + * 'fred': { 'age': 40, 'blocked': true }, + * 'pebbles': { 'age': 1, 'blocked': false } + * }; + * + * _.findKey(characters, function(chr) { + * return chr.age < 40; + * }); + * // => 'barney' (property order is not guaranteed across environments) + * + * // using "_.where" callback shorthand + * _.findKey(characters, { 'age': 1 }); + * // => 'pebbles' + * + * // using "_.pluck" callback shorthand + * _.findKey(characters, 'blocked'); + * // => 'fred' + */ + function findKey(object, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forOwn(object, function(value, key, object) { + if (callback(value, key, object)) { + result = key; + return false; + } + }); + return result; + } + + /** + * This method is like `_.findKey` except that it iterates over elements + * of a `collection` in the opposite order. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to search. + * @param {Function|Object|string} [callback=identity] The function called per + * iteration. If a property name or object is provided it will be used to + * create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {string|undefined} Returns the key of the found element, else `undefined`. + * @example + * + * var characters = { + * 'barney': { 'age': 36, 'blocked': true }, + * 'fred': { 'age': 40, 'blocked': false }, + * 'pebbles': { 'age': 1, 'blocked': true } + * }; + * + * _.findLastKey(characters, function(chr) { + * return chr.age < 40; + * }); + * // => returns `pebbles`, assuming `_.findKey` returns `barney` + * + * // using "_.where" callback shorthand + * _.findLastKey(characters, { 'age': 40 }); + * // => 'fred' + * + * // using "_.pluck" callback shorthand + * _.findLastKey(characters, 'blocked'); + * // => 'pebbles' + */ + function findLastKey(object, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forOwnRight(object, function(value, key, object) { + if (callback(value, key, object)) { + result = key; + return false; + } + }); + return result; + } + + /** + * Iterates over own and inherited enumerable properties of an object, + * executing the callback for each property. The callback is bound to `thisArg` + * and invoked with three arguments; (value, key, object). Callbacks may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * Shape.prototype.move = function(x, y) { + * this.x += x; + * this.y += y; + * }; + * + * _.forIn(new Shape, function(value, key) { + * console.log(key); + * }); + * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments) + */ + var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, { + 'useHas': false + }); + + /** + * This method is like `_.forIn` except that it iterates over elements + * of a `collection` in the opposite order. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * Shape.prototype.move = function(x, y) { + * this.x += x; + * this.y += y; + * }; + * + * _.forInRight(new Shape, function(value, key) { + * console.log(key); + * }); + * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move' + */ + function forInRight(object, callback, thisArg) { + var pairs = []; + + forIn(object, function(value, key) { + pairs.push(key, value); + }); + + var length = pairs.length; + callback = baseCreateCallback(callback, thisArg, 3); + while (length--) { + if (callback(pairs[length--], pairs[length], object) === false) { + break; + } + } + return object; + } + + /** + * Iterates over own enumerable properties of an object, executing the callback + * for each property. The callback is bound to `thisArg` and invoked with three + * arguments; (value, key, object). Callbacks may exit iteration early by + * explicitly returning `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { + * console.log(key); + * }); + * // => logs '0', '1', and 'length' (property order is not guaranteed across environments) + */ + var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions); + + /** + * This method is like `_.forOwn` except that it iterates over elements + * of a `collection` in the opposite order. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { + * console.log(key); + * }); + * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length' + */ + function forOwnRight(object, callback, thisArg) { + var props = keys(object), + length = props.length; + + callback = baseCreateCallback(callback, thisArg, 3); + while (length--) { + var key = props[length]; + if (callback(object[key], key, object) === false) { + break; + } + } + return object; + } + + /** + * Creates a sorted array of property names of all enumerable properties, + * own and inherited, of `object` that have function values. + * + * @static + * @memberOf _ + * @alias methods + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names that have function values. + * @example + * + * _.functions(_); + * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] + */ + function functions(object) { + var result = []; + forIn(object, function(value, key) { + if (isFunction(value)) { + result.push(key); + } + }); + return result.sort(); + } + + /** + * Checks if the specified property name exists as a direct property of `object`, + * instead of an inherited property. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @param {string} key The name of the property to check. + * @returns {boolean} Returns `true` if key is a direct property, else `false`. + * @example + * + * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); + * // => true + */ + function has(object, key) { + return object ? hasOwnProperty.call(object, key) : false; + } + + /** + * Creates an object composed of the inverted keys and values of the given object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to invert. + * @returns {Object} Returns the created inverted object. + * @example + * + * _.invert({ 'first': 'fred', 'second': 'barney' }); + * // => { 'fred': 'first', 'barney': 'second' } + */ + function invert(object) { + var index = -1, + props = keys(object), + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index]; + result[object[key]] = key; + } + return result; + } + + /** + * Checks if `value` is a boolean value. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`. + * @example + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + value && typeof value == 'object' && toString.call(value) == boolClass || false; + } + + /** + * Checks if `value` is a date. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a date, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + */ + function isDate(value) { + return value && typeof value == 'object' && toString.call(value) == dateClass || false; + } + + /** + * Checks if `value` is a DOM element. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + */ + function isElement(value) { + return value && value.nodeType === 1 || false; + } + + /** + * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a + * length of `0` and objects with no own enumerable properties are considered + * "empty". + * + * @static + * @memberOf _ + * @category Objects + * @param {Array|Object|string} value The value to inspect. + * @returns {boolean} Returns `true` if the `value` is empty, else `false`. + * @example + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({}); + * // => true + * + * _.isEmpty(''); + * // => true + */ + function isEmpty(value) { + var result = true; + if (!value) { + return result; + } + var className = toString.call(value), + length = value.length; + + if ((className == arrayClass || className == stringClass || + (support.argsClass ? className == argsClass : isArguments(value))) || + (className == objectClass && typeof length == 'number' && isFunction(value.splice))) { + return !length; + } + forOwn(value, function() { + return (result = false); + }); + return result; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent to each other. If a callback is provided it will be executed + * to compare values. If the callback returns `undefined` comparisons will + * be handled by the method instead. The callback is bound to `thisArg` and + * invoked with two arguments; (a, b). + * + * @static + * @memberOf _ + * @category Objects + * @param {*} a The value to compare. + * @param {*} b The other value to compare. + * @param {Function} [callback] The function to customize comparing values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'name': 'fred' }; + * var copy = { 'name': 'fred' }; + * + * object == copy; + * // => false + * + * _.isEqual(object, copy); + * // => true + * + * var words = ['hello', 'goodbye']; + * var otherWords = ['hi', 'goodbye']; + * + * _.isEqual(words, otherWords, function(a, b) { + * var reGreet = /^(?:hello|hi)$/i, + * aGreet = _.isString(a) && reGreet.test(a), + * bGreet = _.isString(b) && reGreet.test(b); + * + * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined; + * }); + * // => true + */ + function isEqual(a, b, callback, thisArg) { + return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2)); + } + + /** + * Checks if `value` is, or can be coerced to, a finite number. + * + * Note: This is not the same as native `isFinite` which will return true for + * booleans and empty strings. See http://es5.github.io/#x15.1.2.5. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is finite, else `false`. + * @example + * + * _.isFinite(-101); + * // => true + * + * _.isFinite('10'); + * // => true + * + * _.isFinite(true); + * // => false + * + * _.isFinite(''); + * // => false + * + * _.isFinite(Infinity); + * // => false + */ + function isFinite(value) { + return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); + } + + /** + * Checks if `value` is a function. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + */ + function isFunction(value) { + return typeof value == 'function'; + } + // fallback for older versions of Chrome and Safari + if (isFunction(/x/)) { + isFunction = function(value) { + return typeof value == 'function' && toString.call(value) == funcClass; + }; + } + + /** + * Checks if `value` is the language type of Object. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ + function isObject(value) { + // check if the value is the ECMAScript language type of Object + // http://es5.github.io/#x8 + // and avoid a V8 bug + // http://code.google.com/p/v8/issues/detail?id=2291 + return !!(value && objectTypes[typeof value]); + } + + /** + * Checks if `value` is `NaN`. + * + * Note: This is not the same as native `isNaN` which will return `true` for + * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // `NaN` as a primitive is the only value that is not equal to itself + // (perform the [[Class]] check first to avoid errors with some host objects in IE) + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(undefined); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is a number. + * + * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a number, else `false`. + * @example + * + * _.isNumber(8.4 * 5); + * // => true + */ + function isNumber(value) { + return typeof value == 'number' || + value && typeof value == 'object' && toString.call(value) == numberClass || false; + } + + /** + * Checks if `value` is an object created by the `Object` constructor. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * _.isPlainObject(new Shape); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + */ + var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { + if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) { + return false; + } + var valueOf = value.valueOf, + objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); + + return objProto + ? (value == objProto || getPrototypeOf(value) == objProto) + : shimIsPlainObject(value); + }; + + /** + * Checks if `value` is a regular expression. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`. + * @example + * + * _.isRegExp(/fred/); + * // => true + */ + function isRegExp(value) { + return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false; + } + + /** + * Checks if `value` is a string. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a string, else `false`. + * @example + * + * _.isString('fred'); + * // => true + */ + function isString(value) { + return typeof value == 'string' || + value && typeof value == 'object' && toString.call(value) == stringClass || false; + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + */ + function isUndefined(value) { + return typeof value == 'undefined'; + } + + /** + * Creates an object with the same keys as `object` and values generated by + * running each own enumerable property of `object` through the callback. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new object with values of the results of each `callback` execution. + * @example + * + * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; }); + * // => { 'a': 3, 'b': 6, 'c': 9 } + * + * var characters = { + * 'fred': { 'name': 'fred', 'age': 40 }, + * 'pebbles': { 'name': 'pebbles', 'age': 1 } + * }; + * + * // using "_.pluck" callback shorthand + * _.mapValues(characters, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } + */ + function mapValues(object, callback, thisArg) { + var result = {}; + callback = lodash.createCallback(callback, thisArg, 3); + + forOwn(object, function(value, key, object) { + result[key] = callback(value, key, object); + }); + return result; + } + + /** + * Recursively merges own enumerable properties of the source object(s), that + * don't resolve to `undefined` into the destination object. Subsequent sources + * will overwrite property assignments of previous sources. If a callback is + * provided it will be executed to produce the merged values of the destination + * and source properties. If the callback returns `undefined` merging will + * be handled by the method instead. The callback is bound to `thisArg` and + * invoked with two arguments; (objectValue, sourceValue). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param {Function} [callback] The function to customize merging properties. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the destination object. + * @example + * + * var names = { + * 'characters': [ + * { 'name': 'barney' }, + * { 'name': 'fred' } + * ] + * }; + * + * var ages = { + * 'characters': [ + * { 'age': 36 }, + * { 'age': 40 } + * ] + * }; + * + * _.merge(names, ages); + * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] } + * + * var food = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var otherFood = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.merge(food, otherFood, function(a, b) { + * return _.isArray(a) ? a.concat(b) : undefined; + * }); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] } + */ + function merge(object) { + var args = arguments, + length = 2; + + if (!isObject(object)) { + return object; + } + // allows working with `_.reduce` and `_.reduceRight` without using + // their `index` and `collection` arguments + if (typeof args[2] != 'number') { + length = args.length; + } + if (length > 3 && typeof args[length - 2] == 'function') { + var callback = baseCreateCallback(args[--length - 1], args[length--], 2); + } else if (length > 2 && typeof args[length - 1] == 'function') { + callback = args[--length]; + } + var sources = slice(arguments, 1, length), + index = -1, + stackA = getArray(), + stackB = getArray(); + + while (++index < length) { + baseMerge(object, sources[index], callback, stackA, stackB); + } + releaseArray(stackA); + releaseArray(stackB); + return object; + } + + /** + * Creates a shallow clone of `object` excluding the specified properties. + * Property names may be specified as individual arguments or as arrays of + * property names. If a callback is provided it will be executed for each + * property of `object` omitting the properties the callback returns truey + * for. The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Function|...string|string[]} [callback] The properties to omit or the + * function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object without the omitted properties. + * @example + * + * _.omit({ 'name': 'fred', 'age': 40 }, 'age'); + * // => { 'name': 'fred' } + * + * _.omit({ 'name': 'fred', 'age': 40 }, function(value) { + * return typeof value == 'number'; + * }); + * // => { 'name': 'fred' } + */ + function omit(object, callback, thisArg) { + var result = {}; + if (typeof callback != 'function') { + var props = []; + forIn(object, function(value, key) { + props.push(key); + }); + props = baseDifference(props, baseFlatten(arguments, true, false, 1)); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + result[key] = object[key]; + } + } else { + callback = lodash.createCallback(callback, thisArg, 3); + forIn(object, function(value, key, object) { + if (!callback(value, key, object)) { + result[key] = value; + } + }); + } + return result; + } + + /** + * Creates a two dimensional array of an object's key-value pairs, + * i.e. `[[key1, value1], [key2, value2]]`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns new array of key-value pairs. + * @example + * + * _.pairs({ 'barney': 36, 'fred': 40 }); + * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments) + */ + function pairs(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + var key = props[index]; + result[index] = [key, object[key]]; + } + return result; + } + + /** + * Creates a shallow clone of `object` composed of the specified properties. + * Property names may be specified as individual arguments or as arrays of + * property names. If a callback is provided it will be executed for each + * property of `object` picking the properties the callback returns truey + * for. The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Function|...string|string[]} [callback] The function called per + * iteration or property names to pick, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object composed of the picked properties. + * @example + * + * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); + * // => { 'name': 'fred' } + * + * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { + * return key.charAt(0) != '_'; + * }); + * // => { 'name': 'fred' } + */ + function pick(object, callback, thisArg) { + var result = {}; + if (typeof callback != 'function') { + var index = -1, + props = baseFlatten(arguments, true, false, 1), + length = isObject(object) ? props.length : 0; + + while (++index < length) { + var key = props[index]; + if (key in object) { + result[key] = object[key]; + } + } + } else { + callback = lodash.createCallback(callback, thisArg, 3); + forIn(object, function(value, key, object) { + if (callback(value, key, object)) { + result[key] = value; + } + }); + } + return result; + } + + /** + * An alternative to `_.reduce` this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own + * enumerable properties through a callback, with each callback execution + * potentially mutating the `accumulator` object. The callback is bound to + * `thisArg` and invoked with four arguments; (accumulator, value, key, object). + * Callbacks may exit iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Array|Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) { + * num *= num; + * if (num % 2) { + * return result.push(num) < 3; + * } + * }); + * // => [1, 9, 25] + * + * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { + * result[key] = num * 3; + * }); + * // => { 'a': 3, 'b': 6, 'c': 9 } + */ + function transform(object, callback, accumulator, thisArg) { + var isArr = isArray(object); + if (accumulator == null) { + if (isArr) { + accumulator = []; + } else { + var ctor = object && object.constructor, + proto = ctor && ctor.prototype; + + accumulator = baseCreate(proto); + } + } + if (callback) { + callback = lodash.createCallback(callback, thisArg, 4); + (isArr ? baseEach : forOwn)(object, function(value, index, object) { + return callback(accumulator, value, index, object); + }); + } + return accumulator; + } + + /** + * Creates an array composed of the own enumerable property values of `object`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property values. + * @example + * + * _.values({ 'one': 1, 'two': 2, 'three': 3 }); + * // => [1, 2, 3] (property order is not guaranteed across environments) + */ + function values(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + result[index] = object[props[index]]; + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates an array of elements from the specified indexes, or keys, of the + * `collection`. Indexes may be specified as individual arguments or as arrays + * of indexes. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(number|number[]|string|string[])} [index] The indexes of `collection` + * to retrieve, specified as individual indexes or arrays of indexes. + * @returns {Array} Returns a new array of elements corresponding to the + * provided indexes. + * @example + * + * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]); + * // => ['a', 'c', 'e'] + * + * _.at(['fred', 'barney', 'pebbles'], 0, 2); + * // => ['fred', 'pebbles'] + */ + function at(collection) { + var args = arguments, + index = -1, + props = baseFlatten(args, true, false, 1), + length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length, + result = Array(length); + + if (support.unindexedChars && isString(collection)) { + collection = collection.split(''); + } + while(++index < length) { + result[index] = collection[props[index]]; + } + return result; + } + + /** + * Checks if a given value is present in a collection using strict equality + * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the + * offset from the end of the collection. + * + * @static + * @memberOf _ + * @alias include + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {*} target The value to check for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {boolean} Returns `true` if the `target` element is found, else `false`. + * @example + * + * _.contains([1, 2, 3], 1); + * // => true + * + * _.contains([1, 2, 3], 1, 2); + * // => false + * + * _.contains({ 'name': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.contains('pebbles', 'eb'); + * // => true + */ + function contains(collection, target, fromIndex) { + var index = -1, + indexOf = getIndexOf(), + length = collection ? collection.length : 0, + result = false; + + fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0; + if (isArray(collection)) { + result = indexOf(collection, target, fromIndex) > -1; + } else if (typeof length == 'number') { + result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1; + } else { + baseEach(collection, function(value) { + if (++index >= fromIndex) { + return !(result = value === target); + } + }); + } + return result; + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through the callback. The corresponding value + * of each key is the number of times the key was returned by the callback. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); }); + * // => { '4': 1, '6': 2 } + * + * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + var countBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); + }); + + /** + * Checks if the given callback returns truey value for **all** elements of + * a collection. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias all + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if all elements passed the callback check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes']); + * // => false + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.every(characters, 'age'); + * // => true + * + * // using "_.where" callback shorthand + * _.every(characters, { 'age': 36 }); + * // => false + */ + function every(collection, callback, thisArg) { + var result = true; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if (!(result = !!callback(collection[index], index, collection))) { + break; + } + } + } else { + baseEach(collection, function(value, index, collection) { + return (result = !!callback(value, index, collection)); + }); + } + return result; + } + + /** + * Iterates over elements of a collection, returning an array of all elements + * the callback returns truey for. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias select + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of elements that passed the callback check. + * @example + * + * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => [2, 4, 6] + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.filter(characters, 'blocked'); + * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + * + * // using "_.where" callback shorthand + * _.filter(characters, { 'age': 36 }); + * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] + */ + function filter(collection, callback, thisArg) { + var result = []; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (callback(value, index, collection)) { + result.push(value); + } + } + } else { + baseEach(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result.push(value); + } + }); + } + return result; + } + + /** + * Iterates over elements of a collection, returning the first element that + * the callback returns truey for. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias detect, findWhere + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the found element, else `undefined`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true }, + * { 'name': 'pebbles', 'age': 1, 'blocked': false } + * ]; + * + * _.find(characters, function(chr) { + * return chr.age < 40; + * }); + * // => { 'name': 'barney', 'age': 36, 'blocked': false } + * + * // using "_.where" callback shorthand + * _.find(characters, { 'age': 1 }); + * // => { 'name': 'pebbles', 'age': 1, 'blocked': false } + * + * // using "_.pluck" callback shorthand + * _.find(characters, 'blocked'); + * // => { 'name': 'fred', 'age': 40, 'blocked': true } + */ + function find(collection, callback, thisArg) { + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (callback(value, index, collection)) { + return value; + } + } + } else { + var result; + baseEach(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result = value; + return false; + } + }); + return result; + } + } + + /** + * This method is like `_.find` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the found element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(num) { + * return num % 2 == 1; + * }); + * // => 3 + */ + function findLast(collection, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forEachRight(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result = value; + return false; + } + }); + return result; + } + + /** + * Iterates over elements of a collection, executing the callback for each + * element. The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). Callbacks may exit iteration early by + * explicitly returning `false`. + * + * Note: As with other "Collections" methods, objects with a `length` property + * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` + * may be used for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(','); + * // => logs each number and returns '1,2,3' + * + * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); }); + * // => logs each number and returns the object (property order is not guaranteed across environments) + */ + function forEach(collection, callback, thisArg) { + if (callback && typeof thisArg == 'undefined' && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if (callback(collection[index], index, collection) === false) { + break; + } + } + } else { + baseEach(collection, callback, thisArg); + } + return collection; + } + + /** + * This method is like `_.forEach` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @alias eachRight + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(','); + * // => logs each number from right to left and returns '3,2,1' + */ + function forEachRight(collection, callback, thisArg) { + var iterable = collection, + length = collection ? collection.length : 0; + + callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); + if (isArray(collection)) { + while (length--) { + if (callback(collection[length], length, collection) === false) { + break; + } + } + } else { + if (typeof length != 'number') { + var props = keys(collection); + length = props.length; + } else if (support.unindexedChars && isString(collection)) { + iterable = collection.split(''); + } + baseEach(collection, function(value, key, collection) { + key = props ? props[--length] : --length; + return callback(iterable[key], key, collection); + }); + } + return collection; + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of a collection through the callback. The corresponding value + * of each key is an array of the elements responsible for generating the key. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false` + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); }); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * // using "_.pluck" callback shorthand + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + var groupBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); + }); + + /** + * Creates an object composed of keys generated from the results of running + * each element of the collection through the given callback. The corresponding + * value of each key is the last element responsible for generating the key. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var keys = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.indexBy(keys, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + */ + var indexBy = createAggregator(function(result, value, key) { + result[key] = value; + }); + + /** + * Invokes the method named by `methodName` on each element in the `collection` + * returning an array of the results of each invoked method. Additional arguments + * will be provided to each invoked method. If `methodName` is a function it + * will be invoked for, and `this` bound to, each element in the `collection`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|string} methodName The name of the method to invoke or + * the function invoked per iteration. + * @param {...*} [arg] Arguments to invoke the method with. + * @returns {Array} Returns a new array of the results of each invoked method. + * @example + * + * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invoke([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ + function invoke(collection, methodName) { + var args = slice(arguments, 2), + index = -1, + isFunc = typeof methodName == 'function', + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + forEach(collection, function(value) { + result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args); + }); + return result; + } + + /** + * Creates an array of values by running each element in the collection + * through the callback. The callback is bound to `thisArg` and invoked with + * three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias collect + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of the results of each `callback` execution. + * @example + * + * _.map([1, 2, 3], function(num) { return num * 3; }); + * // => [3, 6, 9] + * + * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); + * // => [3, 6, 9] (property order is not guaranteed across environments) + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.map(characters, 'name'); + * // => ['barney', 'fred'] + */ + function map(collection, callback, thisArg) { + var index = -1, + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + callback = lodash.createCallback(callback, thisArg, 3); + if (isArray(collection)) { + while (++index < length) { + result[index] = callback(collection[index], index, collection); + } + } else { + baseEach(collection, function(value, key, collection) { + result[++index] = callback(value, key, collection); + }); + } + return result; + } + + /** + * Retrieves the maximum value of a collection. If the collection is empty or + * falsey `-Infinity` is returned. If a callback is provided it will be executed + * for each value in the collection to generate the criterion by which the value + * is ranked. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.max(characters, function(chr) { return chr.age; }); + * // => { 'name': 'fred', 'age': 40 }; + * + * // using "_.pluck" callback shorthand + * _.max(characters, 'age'); + * // => { 'name': 'fred', 'age': 40 }; + */ + function max(collection, callback, thisArg) { + var computed = -Infinity, + result = computed; + + // allows working with functions like `_.map` without using + // their `index` argument as a callback + if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { + callback = null; + } + if (callback == null && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (value > result) { + result = value; + } + } + } else { + callback = (callback == null && isString(collection)) + ? charAtCallback + : lodash.createCallback(callback, thisArg, 3); + + baseEach(collection, function(value, index, collection) { + var current = callback(value, index, collection); + if (current > computed) { + computed = current; + result = value; + } + }); + } + return result; + } + + /** + * Retrieves the minimum value of a collection. If the collection is empty or + * falsey `Infinity` is returned. If a callback is provided it will be executed + * for each value in the collection to generate the criterion by which the value + * is ranked. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.min(characters, function(chr) { return chr.age; }); + * // => { 'name': 'barney', 'age': 36 }; + * + * // using "_.pluck" callback shorthand + * _.min(characters, 'age'); + * // => { 'name': 'barney', 'age': 36 }; + */ + function min(collection, callback, thisArg) { + var computed = Infinity, + result = computed; + + // allows working with functions like `_.map` without using + // their `index` argument as a callback + if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { + callback = null; + } + if (callback == null && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (value < result) { + result = value; + } + } + } else { + callback = (callback == null && isString(collection)) + ? charAtCallback + : lodash.createCallback(callback, thisArg, 3); + + baseEach(collection, function(value, index, collection) { + var current = callback(value, index, collection); + if (current < computed) { + computed = current; + result = value; + } + }); + } + return result; + } + + /** + * Retrieves the value of a specified property from all elements in the collection. + * + * @static + * @memberOf _ + * @type Function + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {string} property The name of the property to pluck. + * @returns {Array} Returns a new array of property values. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.pluck(characters, 'name'); + * // => ['barney', 'fred'] + */ + var pluck = map; + + /** + * Reduces a collection to a value which is the accumulated result of running + * each element in the collection through the callback, where each successive + * callback execution consumes the return value of the previous execution. If + * `accumulator` is not provided the first element of the collection will be + * used as the initial `accumulator` value. The callback is bound to `thisArg` + * and invoked with four arguments; (accumulator, value, index|key, collection). + * + * @static + * @memberOf _ + * @alias foldl, inject + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] Initial value of the accumulator. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var sum = _.reduce([1, 2, 3], function(sum, num) { + * return sum + num; + * }); + * // => 6 + * + * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { + * result[key] = num * 3; + * return result; + * }, {}); + * // => { 'a': 3, 'b': 6, 'c': 9 } + */ + function reduce(collection, callback, accumulator, thisArg) { + var noaccum = arguments.length < 3; + callback = lodash.createCallback(callback, thisArg, 4); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + if (noaccum) { + accumulator = collection[++index]; + } + while (++index < length) { + accumulator = callback(accumulator, collection[index], index, collection); + } + } else { + baseEach(collection, function(value, index, collection) { + accumulator = noaccum + ? (noaccum = false, value) + : callback(accumulator, value, index, collection) + }); + } + return accumulator; + } + + /** + * This method is like `_.reduce` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @alias foldr + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] Initial value of the accumulator. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var list = [[0, 1], [2, 3], [4, 5]]; + * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + function reduceRight(collection, callback, accumulator, thisArg) { + var noaccum = arguments.length < 3; + callback = lodash.createCallback(callback, thisArg, 4); + forEachRight(collection, function(value, index, collection) { + accumulator = noaccum + ? (noaccum = false, value) + : callback(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The opposite of `_.filter` this method returns the elements of a + * collection that the callback does **not** return truey for. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of elements that failed the callback check. + * @example + * + * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => [1, 3, 5] + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.reject(characters, 'blocked'); + * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] + * + * // using "_.where" callback shorthand + * _.reject(characters, { 'age': 36 }); + * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + */ + function reject(collection, callback, thisArg) { + callback = lodash.createCallback(callback, thisArg, 3); + return filter(collection, function(value, index, collection) { + return !callback(value, index, collection); + }); + } + + /** + * Retrieves a random element or `n` random elements from a collection. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to sample. + * @param {number} [n] The number of elements to sample. + * @param- {Object} [guard] Allows working with functions like `_.map` + * without using their `index` arguments as `n`. + * @returns {Array} Returns the random sample(s) of `collection`. + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + * + * _.sample([1, 2, 3, 4], 2); + * // => [3, 1] + */ + function sample(collection, n, guard) { + if (collection && typeof collection.length != 'number') { + collection = values(collection); + } else if (support.unindexedChars && isString(collection)) { + collection = collection.split(''); + } + if (n == null || guard) { + return collection ? collection[baseRandom(0, collection.length - 1)] : undefined; + } + var result = shuffle(collection); + result.length = nativeMin(nativeMax(0, n), result.length); + return result; + } + + /** + * Creates an array of shuffled values, using a version of the Fisher-Yates + * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to shuffle. + * @returns {Array} Returns a new shuffled collection. + * @example + * + * _.shuffle([1, 2, 3, 4, 5, 6]); + * // => [4, 1, 6, 3, 5, 2] + */ + function shuffle(collection) { + var index = -1, + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + forEach(collection, function(value) { + var rand = baseRandom(0, ++index); + result[index] = result[rand]; + result[rand] = value; + }); + return result; + } + + /** + * Gets the size of the `collection` by returning `collection.length` for arrays + * and array-like objects or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns `collection.length` or number of own enumerable properties. + * @example + * + * _.size([1, 2]); + * // => 2 + * + * _.size({ 'one': 1, 'two': 2, 'three': 3 }); + * // => 3 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + var length = collection ? collection.length : 0; + return typeof length == 'number' ? length : keys(collection).length; + } + + /** + * Checks if the callback returns a truey value for **any** element of a + * collection. The function returns as soon as it finds a passing value and + * does not iterate over the entire collection. The callback is bound to + * `thisArg` and invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias any + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if any element passed the callback check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.some(characters, 'blocked'); + * // => true + * + * // using "_.where" callback shorthand + * _.some(characters, { 'age': 1 }); + * // => false + */ + function some(collection, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if ((result = callback(collection[index], index, collection))) { + break; + } + } + } else { + baseEach(collection, function(value, index, collection) { + return !(result = callback(value, index, collection)); + }); + } + return !!result; + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through the callback. This method + * performs a stable sort, that is, it will preserve the original sort order + * of equal elements. The callback is bound to `thisArg` and invoked with + * three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an array of property names is provided for `callback` the collection + * will be sorted by each property value. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of sorted elements. + * @example + * + * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); }); + * // => [3, 1, 2] + * + * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math); + * // => [3, 1, 2] + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 }, + * { 'name': 'barney', 'age': 26 }, + * { 'name': 'fred', 'age': 30 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.map(_.sortBy(characters, 'age'), _.values); + * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]] + * + * // sorting by multiple properties + * _.map(_.sortBy(characters, ['name', 'age']), _.values); + * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] + */ + function sortBy(collection, callback, thisArg) { + var index = -1, + isArr = isArray(callback), + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + if (!isArr) { + callback = lodash.createCallback(callback, thisArg, 3); + } + forEach(collection, function(value, key, collection) { + var object = result[++index] = getObject(); + if (isArr) { + object.criteria = map(callback, function(key) { return value[key]; }); + } else { + (object.criteria = getArray())[0] = callback(value, key, collection); + } + object.index = index; + object.value = value; + }); + + length = result.length; + result.sort(compareAscending); + while (length--) { + var object = result[length]; + result[length] = object.value; + if (!isArr) { + releaseArray(object.criteria); + } + releaseObject(object); + } + return result; + } + + /** + * Converts the `collection` to an array. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to convert. + * @returns {Array} Returns the new converted array. + * @example + * + * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4); + * // => [2, 3, 4] + */ + function toArray(collection) { + if (collection && typeof collection.length == 'number') { + return (support.unindexedChars && isString(collection)) + ? collection.split('') + : slice(collection); + } + return values(collection); + } + + /** + * Performs a deep comparison of each element in a `collection` to the given + * `properties` object, returning an array of all elements that have equivalent + * property values. + * + * @static + * @memberOf _ + * @type Function + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Object} props The object of property values to filter by. + * @returns {Array} Returns a new array of elements that have the given properties. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }, + * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } + * ]; + * + * _.where(characters, { 'age': 36 }); + * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }] + * + * _.where(characters, { 'pets': ['dino'] }); + * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }] + */ + var where = filter; + + /*--------------------------------------------------------------------------*/ + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are all falsey. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to compact. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result.push(value); + } + } + return result; + } + + /** + * Creates an array excluding all values of the provided arrays using strict + * equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to process. + * @param {...Array} [values] The arrays of values to exclude. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.difference([1, 2, 3, 4, 5], [5, 2, 10]); + * // => [1, 3, 4] + */ + function difference(array) { + return baseDifference(array, baseFlatten(arguments, true, true, 1)); + } + + /** + * This method is like `_.find` except that it returns the index of the first + * element that passes the callback check, instead of the element itself. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true }, + * { 'name': 'pebbles', 'age': 1, 'blocked': false } + * ]; + * + * _.findIndex(characters, function(chr) { + * return chr.age < 20; + * }); + * // => 2 + * + * // using "_.where" callback shorthand + * _.findIndex(characters, { 'age': 36 }); + * // => 0 + * + * // using "_.pluck" callback shorthand + * _.findIndex(characters, 'blocked'); + * // => 1 + */ + function findIndex(array, callback, thisArg) { + var index = -1, + length = array ? array.length : 0; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length) { + if (callback(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * This method is like `_.findIndex` except that it iterates over elements + * of a `collection` from right to left. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': true }, + * { 'name': 'fred', 'age': 40, 'blocked': false }, + * { 'name': 'pebbles', 'age': 1, 'blocked': true } + * ]; + * + * _.findLastIndex(characters, function(chr) { + * return chr.age > 30; + * }); + * // => 1 + * + * // using "_.where" callback shorthand + * _.findLastIndex(characters, { 'age': 36 }); + * // => 0 + * + * // using "_.pluck" callback shorthand + * _.findLastIndex(characters, 'blocked'); + * // => 2 + */ + function findLastIndex(array, callback, thisArg) { + var length = array ? array.length : 0; + callback = lodash.createCallback(callback, thisArg, 3); + while (length--) { + if (callback(array[length], length, array)) { + return length; + } + } + return -1; + } + + /** + * Gets the first element or first `n` elements of an array. If a callback + * is provided elements at the beginning of the array are returned as long + * as the callback returns truey. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias head, take + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback] The function called + * per element or the number of elements to return. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the first element(s) of `array`. + * @example + * + * _.first([1, 2, 3]); + * // => 1 + * + * _.first([1, 2, 3], 2); + * // => [1, 2] + * + * _.first([1, 2, 3], function(num) { + * return num < 3; + * }); + * // => [1, 2] + * + * var characters = [ + * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.first(characters, 'blocked'); + * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }] + * + * // using "_.where" callback shorthand + * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name'); + * // => ['barney', 'fred'] + */ + function first(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = -1; + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length && callback(array[index], index, array)) { + n++; + } + } else { + n = callback; + if (n == null || thisArg) { + return array ? array[0] : undefined; + } + } + return slice(array, 0, nativeMin(nativeMax(0, n), length)); + } + + /** + * Flattens a nested array (the nesting can be to any depth). If `isShallow` + * is truey, the array will only be flattened a single level. If a callback + * is provided each element of the array is passed through the callback before + * flattening. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to flatten. + * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new flattened array. + * @example + * + * _.flatten([1, [2], [3, [[4]]]]); + * // => [1, 2, 3, 4]; + * + * _.flatten([1, [2], [3, [[4]]]], true); + * // => [1, 2, 3, [[4]]]; + * + * var characters = [ + * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] }, + * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } + * ]; + * + * // using "_.pluck" callback shorthand + * _.flatten(characters, 'pets'); + * // => ['hoppy', 'baby puss', 'dino'] + */ + function flatten(array, isShallow, callback, thisArg) { + // juggle arguments + if (typeof isShallow != 'boolean' && isShallow != null) { + thisArg = callback; + callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow; + isShallow = false; + } + if (callback != null) { + array = map(array, callback, thisArg); + } + return baseFlatten(array, isShallow); + } + + /** + * Gets the index at which the first occurrence of `value` is found using + * strict equality for comparisons, i.e. `===`. If the array is already sorted + * providing `true` for `fromIndex` will run a faster binary search. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=0] The index to search from or `true` + * to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value or `-1`. + * @example + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2); + * // => 1 + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 4 + * + * _.indexOf([1, 1, 2, 2, 3, 3], 2, true); + * // => 2 + */ + function indexOf(array, value, fromIndex) { + if (typeof fromIndex == 'number') { + var length = array ? array.length : 0; + fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0); + } else if (fromIndex) { + var index = sortedIndex(array, value); + return array[index] === value ? index : -1; + } + return baseIndexOf(array, value, fromIndex); + } + + /** + * Gets all but the last element or last `n` elements of an array. If a + * callback is provided elements at the end of the array are excluded from + * the result as long as the callback returns truey. The callback is bound + * to `thisArg` and invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback=1] The function called + * per element or the number of elements to exclude. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + * + * _.initial([1, 2, 3], 2); + * // => [1] + * + * _.initial([1, 2, 3], function(num) { + * return num > 1; + * }); + * // => [1] + * + * var characters = [ + * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.initial(characters, 'blocked'); + * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }] + * + * // using "_.where" callback shorthand + * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name'); + * // => ['barney', 'fred'] + */ + function initial(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = length; + callback = lodash.createCallback(callback, thisArg, 3); + while (index-- && callback(array[index], index, array)) { + n++; + } + } else { + n = (callback == null || thisArg) ? 1 : callback || n; + } + return slice(array, 0, nativeMin(nativeMax(0, length - n), length)); + } + + /** + * Creates an array of unique values present in all provided arrays using + * strict equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of shared values. + * @example + * + * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]); + * // => [1, 2] + */ + function intersection() { + var args = [], + argsIndex = -1, + argsLength = arguments.length, + caches = getArray(), + indexOf = getIndexOf(), + trustIndexOf = indexOf === baseIndexOf, + seen = getArray(); + + while (++argsIndex < argsLength) { + var value = arguments[argsIndex]; + if (isArray(value) || isArguments(value)) { + args.push(value); + caches.push(trustIndexOf && value.length >= largeArraySize && + createCache(argsIndex ? args[argsIndex] : seen)); + } + } + var array = args[0], + index = -1, + length = array ? array.length : 0, + result = []; + + outer: + while (++index < length) { + var cache = caches[0]; + value = array[index]; + + if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) { + argsIndex = argsLength; + (cache || seen).push(value); + while (--argsIndex) { + cache = caches[argsIndex]; + if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) { + continue outer; + } + } + result.push(value); + } + } + while (argsLength--) { + cache = caches[argsLength]; + if (cache) { + releaseObject(cache); + } + } + releaseArray(caches); + releaseArray(seen); + return result; + } + + /** + * Gets the last element or last `n` elements of an array. If a callback is + * provided elements at the end of the array are returned as long as the + * callback returns truey. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback] The function called + * per element or the number of elements to return. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the last element(s) of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + * + * _.last([1, 2, 3], 2); + * // => [2, 3] + * + * _.last([1, 2, 3], function(num) { + * return num > 1; + * }); + * // => [2, 3] + * + * var characters = [ + * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.pluck(_.last(characters, 'blocked'), 'name'); + * // => ['fred', 'pebbles'] + * + * // using "_.where" callback shorthand + * _.last(characters, { 'employer': 'na' }); + * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] + */ + function last(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = length; + callback = lodash.createCallback(callback, thisArg, 3); + while (index-- && callback(array[index], index, array)) { + n++; + } + } else { + n = callback; + if (n == null || thisArg) { + return array ? array[length - 1] : undefined; + } + } + return slice(array, nativeMax(0, length - n)); + } + + /** + * Gets the index at which the last occurrence of `value` is found using strict + * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used + * as the offset from the end of the collection. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the matched value or `-1`. + * @example + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); + * // => 4 + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 1 + */ + function lastIndexOf(array, value, fromIndex) { + var index = array ? array.length : 0; + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1; + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Removes all provided values from the given array using strict equality for + * comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to modify. + * @param {...*} [value] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * _.pull(array, 2, 3); + * console.log(array); + * // => [1, 1] + */ + function pull(array) { + var args = arguments, + argsIndex = 0, + argsLength = args.length, + length = array ? array.length : 0; + + while (++argsIndex < argsLength) { + var index = -1, + value = args[argsIndex]; + while (++index < length) { + if (array[index] === value) { + splice.call(array, index--, 1); + length--; + } + } + } + return array; + } + + /** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to but not including `end`. If `start` is less than `stop` a + * zero-length range is created unless a negative `step` is specified. + * + * @static + * @memberOf _ + * @category Arrays + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns a new range array. + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ + function range(start, end, step) { + start = +start || 0; + step = typeof step == 'number' ? step : (+step || 1); + + if (end == null) { + end = start; + start = 0; + } + // use `Array(length)` so engines like Chakra and V8 avoid slower modes + // http://youtu.be/XAqIpGU8ZZk#t=17m25s + var index = -1, + length = nativeMax(0, ceil((end - start) / (step || 1))), + result = Array(length); + + while (++index < length) { + result[index] = start; + start += step; + } + return result; + } + + /** + * Removes all elements from an array that the callback returns truey for + * and returns an array of removed elements. The callback is bound to `thisArg` + * and invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to modify. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4, 5, 6]; + * var evens = _.remove(array, function(num) { return num % 2 == 0; }); + * + * console.log(array); + * // => [1, 3, 5] + * + * console.log(evens); + * // => [2, 4, 6] + */ + function remove(array, callback, thisArg) { + var index = -1, + length = array ? array.length : 0, + result = []; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length) { + var value = array[index]; + if (callback(value, index, array)) { + result.push(value); + splice.call(array, index--, 1); + length--; + } + } + return result; + } + + /** + * The opposite of `_.initial` this method gets all but the first element or + * first `n` elements of an array. If a callback function is provided elements + * at the beginning of the array are excluded from the result as long as the + * callback returns truey. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias drop, tail + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback=1] The function called + * per element or the number of elements to exclude. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a slice of `array`. + * @example + * + * _.rest([1, 2, 3]); + * // => [2, 3] + * + * _.rest([1, 2, 3], 2); + * // => [3] + * + * _.rest([1, 2, 3], function(num) { + * return num < 3; + * }); + * // => [3] + * + * var characters = [ + * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.pluck(_.rest(characters, 'blocked'), 'name'); + * // => ['fred', 'pebbles'] + * + * // using "_.where" callback shorthand + * _.rest(characters, { 'employer': 'slate' }); + * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] + */ + function rest(array, callback, thisArg) { + if (typeof callback != 'number' && callback != null) { + var n = 0, + index = -1, + length = array ? array.length : 0; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length && callback(array[index], index, array)) { + n++; + } + } else { + n = (callback == null || thisArg) ? 1 : nativeMax(0, callback); + } + return slice(array, n); + } + + /** + * Uses a binary search to determine the smallest index at which a value + * should be inserted into a given sorted array in order to maintain the sort + * order of the array. If a callback is provided it will be executed for + * `value` and each element of `array` to compute their sort ranking. The + * callback is bound to `thisArg` and invoked with one argument; (value). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([20, 30, 50], 40); + * // => 2 + * + * // using "_.pluck" callback shorthand + * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); + * // => 2 + * + * var dict = { + * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 } + * }; + * + * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { + * return dict.wordToNumber[word]; + * }); + * // => 2 + * + * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { + * return this.wordToNumber[word]; + * }, dict); + * // => 2 + */ + function sortedIndex(array, value, callback, thisArg) { + var low = 0, + high = array ? array.length : low; + + // explicitly reference `identity` for better inlining in Firefox + callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity; + value = callback(value); + + while (low < high) { + var mid = (low + high) >>> 1; + (callback(array[mid]) < value) + ? low = mid + 1 + : high = mid; + } + return low; + } + + /** + * Creates an array of unique values, in order, of the provided arrays using + * strict equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of combined values. + * @example + * + * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]); + * // => [1, 2, 3, 5, 4] + */ + function union() { + return baseUniq(baseFlatten(arguments, true, true)); + } + + /** + * Creates a duplicate-value-free version of an array using strict equality + * for comparisons, i.e. `===`. If the array is sorted, providing + * `true` for `isSorted` will use a faster algorithm. If a callback is provided + * each element of `array` is passed through the callback before uniqueness + * is computed. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias unique + * @category Arrays + * @param {Array} array The array to process. + * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a duplicate-value-free array. + * @example + * + * _.uniq([1, 2, 1, 3, 1]); + * // => [1, 2, 3] + * + * _.uniq([1, 1, 2, 2, 3], true); + * // => [1, 2, 3] + * + * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); }); + * // => ['A', 'b', 'C'] + * + * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math); + * // => [1, 2.5, 3] + * + * // using "_.pluck" callback shorthand + * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniq(array, isSorted, callback, thisArg) { + // juggle arguments + if (typeof isSorted != 'boolean' && isSorted != null) { + thisArg = callback; + callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted; + isSorted = false; + } + if (callback != null) { + callback = lodash.createCallback(callback, thisArg, 3); + } + return baseUniq(array, isSorted, callback); + } + + /** + * Creates an array excluding all provided values using strict equality for + * comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to filter. + * @param {...*} [value] The values to exclude. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); + * // => [2, 3, 4] + */ + function without(array) { + return baseDifference(array, slice(arguments, 1)); + } + + /** + * Creates an array that is the symmetric difference of the provided arrays. + * See http://en.wikipedia.org/wiki/Symmetric_difference. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of values. + * @example + * + * _.xor([1, 2, 3], [5, 2, 1, 4]); + * // => [3, 5, 4] + * + * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]); + * // => [1, 4, 5] + */ + function xor() { + var index = -1, + length = arguments.length; + + while (++index < length) { + var array = arguments[index]; + if (isArray(array) || isArguments(array)) { + var result = result + ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result))) + : array; + } + } + return result || []; + } + + /** + * Creates an array of grouped elements, the first of which contains the first + * elements of the given arrays, the second of which contains the second + * elements of the given arrays, and so on. + * + * @static + * @memberOf _ + * @alias unzip + * @category Arrays + * @param {...Array} [array] Arrays to process. + * @returns {Array} Returns a new array of grouped elements. + * @example + * + * _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + */ + function zip() { + var array = arguments.length > 1 ? arguments : arguments[0], + index = -1, + length = array ? max(pluck(array, 'length')) : 0, + result = Array(length < 0 ? 0 : length); + + while (++index < length) { + result[index] = pluck(array, index); + } + return result; + } + + /** + * Creates an object composed from arrays of `keys` and `values`. Provide + * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]` + * or two arrays, one of `keys` and one of corresponding `values`. + * + * @static + * @memberOf _ + * @alias object + * @category Arrays + * @param {Array} keys The array of keys. + * @param {Array} [values=[]] The array of values. + * @returns {Object} Returns an object composed of the given keys and + * corresponding values. + * @example + * + * _.zipObject(['fred', 'barney'], [30, 40]); + * // => { 'fred': 30, 'barney': 40 } + */ + function zipObject(keys, values) { + var index = -1, + length = keys ? keys.length : 0, + result = {}; + + if (!values && length && !isArray(keys[0])) { + values = []; + } + while (++index < length) { + var key = keys[index]; + if (values) { + result[key] = values[index]; + } else if (key) { + result[key[0]] = key[1]; + } + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a function that executes `func`, with the `this` binding and + * arguments of the created function, only after being called `n` times. + * + * @static + * @memberOf _ + * @category Functions + * @param {number} n The number of times the function must be called before + * `func` is executed. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('Done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => logs 'Done saving!', after all saves have completed + */ + function after(n, func) { + if (!isFunction(func)) { + throw new TypeError; + } + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that, when called, invokes `func` with the `this` + * binding of `thisArg` and prepends any additional `bind` arguments to those + * provided to the bound function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to bind. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var func = function(greeting) { + * return greeting + ' ' + this.name; + * }; + * + * func = _.bind(func, { 'name': 'fred' }, 'hi'); + * func(); + * // => 'hi fred' + */ + function bind(func, thisArg) { + return arguments.length > 2 + ? createWrapper(func, 17, slice(arguments, 2), null, thisArg) + : createWrapper(func, 1, null, null, thisArg); + } + + /** + * Binds methods of an object to the object itself, overwriting the existing + * method. Method names may be specified as individual arguments or as arrays + * of method names. If no method names are provided all the function properties + * of `object` will be bound. + * + * @static + * @memberOf _ + * @category Functions + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...string} [methodName] The object method names to + * bind, specified as individual method names or arrays of method names. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { console.log('clicked ' + this.label); } + * }; + * + * _.bindAll(view); + * jQuery('#docs').on('click', view.onClick); + * // => logs 'clicked docs', when the button is clicked + */ + function bindAll(object) { + var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object), + index = -1, + length = funcs.length; + + while (++index < length) { + var key = funcs[index]; + object[key] = createWrapper(object[key], 1, null, null, object); + } + return object; + } + + /** + * Creates a function that, when called, invokes the method at `object[key]` + * and prepends any additional `bindKey` arguments to those provided to the bound + * function. This method differs from `_.bind` by allowing bound functions to + * reference methods that will be redefined or don't yet exist. + * See http://michaux.ca/articles/lazy-function-definition-pattern. + * + * @static + * @memberOf _ + * @category Functions + * @param {Object} object The object the method belongs to. + * @param {string} key The key of the method. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'name': 'fred', + * 'greet': function(greeting) { + * return greeting + ' ' + this.name; + * } + * }; + * + * var func = _.bindKey(object, 'greet', 'hi'); + * func(); + * // => 'hi fred' + * + * object.greet = function(greeting) { + * return greeting + 'ya ' + this.name + '!'; + * }; + * + * func(); + * // => 'hiya fred!' + */ + function bindKey(object, key) { + return arguments.length > 2 + ? createWrapper(key, 19, slice(arguments, 2), null, object) + : createWrapper(key, 3, null, null, object); + } + + /** + * Creates a function that is the composition of the provided functions, + * where each function consumes the return value of the function that follows. + * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. + * Each function is executed with the `this` binding of the composed function. + * + * @static + * @memberOf _ + * @category Functions + * @param {...Function} [func] Functions to compose. + * @returns {Function} Returns the new composed function. + * @example + * + * var realNameMap = { + * 'pebbles': 'penelope' + * }; + * + * var format = function(name) { + * name = realNameMap[name.toLowerCase()] || name; + * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase(); + * }; + * + * var greet = function(formatted) { + * return 'Hiya ' + formatted + '!'; + * }; + * + * var welcome = _.compose(greet, format); + * welcome('pebbles'); + * // => 'Hiya Penelope!' + */ + function compose() { + var funcs = arguments, + length = funcs.length; + + while (length--) { + if (!isFunction(funcs[length])) { + throw new TypeError; + } + } + return function() { + var args = arguments, + length = funcs.length; + + while (length--) { + args = [funcs[length].apply(this, args)]; + } + return args[0]; + }; + } + + /** + * Creates a function which accepts one or more arguments of `func` that when + * invoked either executes `func` returning its result, if all `func` arguments + * have been provided, or returns a function that accepts one or more of the + * remaining `func` arguments, and so on. The arity of `func` can be specified + * if `func.length` is not sufficient. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @returns {Function} Returns the new curried function. + * @example + * + * var curried = _.curry(function(a, b, c) { + * console.log(a + b + c); + * }); + * + * curried(1)(2)(3); + * // => 6 + * + * curried(1, 2)(3); + * // => 6 + * + * curried(1, 2, 3); + * // => 6 + */ + function curry(func, arity) { + arity = typeof arity == 'number' ? arity : (+arity || func.length); + return createWrapper(func, 4, null, null, null, arity); + } + + /** + * Creates a function that will delay the execution of `func` until after + * `wait` milliseconds have elapsed since the last time it was invoked. + * Provide an options object to indicate that `func` should be invoked on + * the leading and/or trailing edge of the `wait` timeout. Subsequent calls + * to the debounced function will return the result of the last `func` call. + * + * Note: If `leading` and `trailing` options are `true` `func` will be called + * on the trailing edge of the timeout only if the the debounced function is + * invoked more than once during the `wait` timeout. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to debounce. + * @param {number} wait The number of milliseconds to delay. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called. + * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // avoid costly calculations while the window size is in flux + * var lazyLayout = _.debounce(calculateLayout, 150); + * jQuery(window).on('resize', lazyLayout); + * + * // execute `sendMail` when the click event is fired, debouncing subsequent calls + * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * }); + * + * // ensure `batchLog` is executed once after 1 second of debounced calls + * var source = new EventSource('/stream'); + * source.addEventListener('message', _.debounce(batchLog, 250, { + * 'maxWait': 1000 + * }, false); + */ + function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + maxWait = false, + trailing = true; + + if (!isFunction(func)) { + throw new TypeError; + } + wait = nativeMax(0, wait) || 0; + if (options === true) { + var leading = true; + trailing = false; + } else if (isObject(options)) { + leading = options.leading; + maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0); + trailing = 'trailing' in options ? options.trailing : trailing; + } + var delayed = function() { + var remaining = wait - (now() - stamp); + if (remaining <= 0) { + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + var isCalled = trailingCall; + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + } else { + timeoutId = setTimeout(delayed, remaining); + } + }; + + var maxDelayed = function() { + if (timeoutId) { + clearTimeout(timeoutId); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (trailing || (maxWait !== wait)) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + }; + + return function() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled), + isCalled = remaining <= 0; + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + return result; + }; + } + + /** + * Defers executing the `func` function until the current call stack has cleared. + * Additional arguments will be provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to defer. + * @param {...*} [arg] Arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { console.log(text); }, 'deferred'); + * // logs 'deferred' after one or more milliseconds + */ + function defer(func) { + if (!isFunction(func)) { + throw new TypeError; + } + var args = slice(arguments, 1); + return setTimeout(function() { func.apply(undefined, args); }, 1); + } + + /** + * Executes the `func` function after `wait` milliseconds. Additional arguments + * will be provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay execution. + * @param {...*} [arg] Arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { console.log(text); }, 1000, 'later'); + * // => logs 'later' after one second + */ + function delay(func, wait) { + if (!isFunction(func)) { + throw new TypeError; + } + var args = slice(arguments, 2); + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided it will be used to determine the cache key for storing the result + * based on the arguments provided to the memoized function. By default, the + * first argument provided to the memoized function is used as the cache key. + * The `func` is executed with the `this` binding of the memoized function. + * The result cache is exposed as the `cache` property on the memoized function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] A function used to resolve the cache key. + * @returns {Function} Returns the new memoizing function. + * @example + * + * var fibonacci = _.memoize(function(n) { + * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); + * }); + * + * fibonacci(9) + * // => 34 + * + * var data = { + * 'fred': { 'name': 'fred', 'age': 40 }, + * 'pebbles': { 'name': 'pebbles', 'age': 1 } + * }; + * + * // modifying the result cache + * var get = _.memoize(function(name) { return data[name]; }, _.identity); + * get('pebbles'); + * // => { 'name': 'pebbles', 'age': 1 } + * + * get.cache.pebbles.name = 'penelope'; + * get('pebbles'); + * // => { 'name': 'penelope', 'age': 1 } + */ + function memoize(func, resolver) { + if (!isFunction(func)) { + throw new TypeError; + } + var memoized = function() { + var cache = memoized.cache, + key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0]; + + return hasOwnProperty.call(cache, key) + ? cache[key] + : (cache[key] = func.apply(this, arguments)); + } + memoized.cache = {}; + return memoized; + } + + /** + * Creates a function that is restricted to execute `func` once. Repeat calls to + * the function will return the value of the first call. The `func` is executed + * with the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` executes `createApplication` once + */ + function once(func) { + var ran, + result; + + if (!isFunction(func)) { + throw new TypeError; + } + return function() { + if (ran) { + return result; + } + ran = true; + result = func.apply(this, arguments); + + // clear the `func` variable so the function may be garbage collected + func = null; + return result; + }; + } + + /** + * Creates a function that, when called, invokes `func` with any additional + * `partial` arguments prepended to those provided to the new function. This + * method is similar to `_.bind` except it does **not** alter the `this` binding. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { return greeting + ' ' + name; }; + * var hi = _.partial(greet, 'hi'); + * hi('fred'); + * // => 'hi fred' + */ + function partial(func) { + return createWrapper(func, 16, slice(arguments, 1)); + } + + /** + * This method is like `_.partial` except that `partial` arguments are + * appended to those provided to the new function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var defaultsDeep = _.partialRight(_.merge, _.defaults); + * + * var options = { + * 'variable': 'data', + * 'imports': { 'jq': $ } + * }; + * + * defaultsDeep(options, _.templateSettings); + * + * options.variable + * // => 'data' + * + * options.imports + * // => { '_': _, 'jq': $ } + */ + function partialRight(func) { + return createWrapper(func, 32, null, slice(arguments, 1)); + } + + /** + * Creates a function that, when executed, will only call the `func` function + * at most once per every `wait` milliseconds. Provide an options object to + * indicate that `func` should be invoked on the leading and/or trailing edge + * of the `wait` timeout. Subsequent calls to the throttled function will + * return the result of the last `func` call. + * + * Note: If `leading` and `trailing` options are `true` `func` will be called + * on the trailing edge of the timeout only if the the throttled function is + * invoked more than once during the `wait` timeout. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to throttle. + * @param {number} wait The number of milliseconds to throttle executions to. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout. + * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // avoid excessively updating the position while scrolling + * var throttled = _.throttle(updatePosition, 100); + * jQuery(window).on('scroll', throttled); + * + * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes + * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { + * 'trailing': false + * })); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (!isFunction(func)) { + throw new TypeError; + } + if (options === false) { + leading = false; + } else if (isObject(options)) { + leading = 'leading' in options ? options.leading : leading; + trailing = 'trailing' in options ? options.trailing : trailing; + } + debounceOptions.leading = leading; + debounceOptions.maxWait = wait; + debounceOptions.trailing = trailing; + + return debounce(func, wait, debounceOptions); + } + + /** + * Creates a function that provides `value` to the wrapper function as its + * first argument. Additional arguments provided to the function are appended + * to those provided to the wrapper function. The wrapper is executed with + * the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {*} value The value to wrap. + * @param {Function} wrapper The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '<p>' + func(text) + '</p>'; + * }); + * + * p('Fred, Wilma, & Pebbles'); + * // => '<p>Fred, Wilma, & Pebbles</p>' + */ + function wrap(value, wrapper) { + return createWrapper(wrapper, 16, [value]); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a function that returns `value`. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} value The value to return from the new function. + * @returns {Function} Returns the new function. + * @example + * + * var object = { 'name': 'fred' }; + * var getter = _.constant(object); + * getter() === object; + * // => true + */ + function constant(value) { + return function() { + return value; + }; + } + + /** + * Produces a callback bound to an optional `thisArg`. If `func` is a property + * name the created callback will return the property value for a given element. + * If `func` is an object the created callback will return `true` for elements + * that contain the equivalent object properties, otherwise it will return `false`. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} [func=identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of the created callback. + * @param {number} [argCount] The number of arguments the callback accepts. + * @returns {Function} Returns a callback function. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // wrap to create custom callback shorthands + * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) { + * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback); + * return !match ? func(callback, thisArg) : function(object) { + * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3]; + * }; + * }); + * + * _.filter(characters, 'age__gt38'); + * // => [{ 'name': 'fred', 'age': 40 }] + */ + function createCallback(func, thisArg, argCount) { + var type = typeof func; + if (func == null || type == 'function') { + return baseCreateCallback(func, thisArg, argCount); + } + // handle "_.pluck" style callback shorthands + if (type != 'object') { + return property(func); + } + var props = keys(func), + key = props[0], + a = func[key]; + + // handle "_.where" style callback shorthands + if (props.length == 1 && a === a && !isObject(a)) { + // fast path the common case of providing an object with a single + // property containing a primitive value + return function(object) { + var b = object[key]; + return a === b && (a !== 0 || (1 / a == 1 / b)); + }; + } + return function(object) { + var length = props.length, + result = false; + + while (length--) { + if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) { + break; + } + } + return result; + }; + } + + /** + * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their + * corresponding HTML entities. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} string The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('Fred, Wilma, & Pebbles'); + * // => 'Fred, Wilma, & Pebbles' + */ + function escape(string) { + return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar); + } + + /** + * This method returns the first argument provided to it. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'name': 'fred' }; + * _.identity(object) === object; + * // => true + */ + function identity(value) { + return value; + } + + /** + * Adds function properties of a source object to the destination object. + * If `object` is a function methods will be added to its prototype as well. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Function|Object} [object=lodash] object The destination object. + * @param {Object} source The object of functions to add. + * @param {Object} [options] The options object. + * @param {boolean} [options.chain=true] Specify whether the functions added are chainable. + * @example + * + * function capitalize(string) { + * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); + * } + * + * _.mixin({ 'capitalize': capitalize }); + * _.capitalize('fred'); + * // => 'Fred' + * + * _('fred').capitalize().value(); + * // => 'Fred' + * + * _.mixin({ 'capitalize': capitalize }, { 'chain': false }); + * _('fred').capitalize(); + * // => 'Fred' + */ + function mixin(object, source, options) { + var chain = true, + methodNames = source && functions(source); + + if (!source || (!options && !methodNames.length)) { + if (options == null) { + options = source; + } + ctor = lodashWrapper; + source = object; + object = lodash; + methodNames = functions(source); + } + if (options === false) { + chain = false; + } else if (isObject(options) && 'chain' in options) { + chain = options.chain; + } + var ctor = object, + isFunc = isFunction(ctor); + + forEach(methodNames, function(methodName) { + var func = object[methodName] = source[methodName]; + if (isFunc) { + ctor.prototype[methodName] = function() { + var chainAll = this.__chain__, + value = this.__wrapped__, + args = [value]; + + push.apply(args, arguments); + var result = func.apply(object, args); + if (chain || chainAll) { + if (value === result && isObject(result)) { + return this; + } + result = new ctor(result); + result.__chain__ = chainAll; + } + return result; + }; + } + }); + } + + /** + * Reverts the '_' variable to its previous value and returns a reference to + * the `lodash` function. + * + * @static + * @memberOf _ + * @category Utilities + * @returns {Function} Returns the `lodash` function. + * @example + * + * var lodash = _.noConflict(); + */ + function noConflict() { + context._ = oldDash; + return this; + } + + /** + * A no-operation function. + * + * @static + * @memberOf _ + * @category Utilities + * @example + * + * var object = { 'name': 'fred' }; + * _.noop(object) === undefined; + * // => true + */ + function noop() { + // no operation performed + } + + /** + * Gets the number of milliseconds that have elapsed since the Unix epoch + * (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @category Utilities + * @example + * + * var stamp = _.now(); + * _.defer(function() { console.log(_.now() - stamp); }); + * // => logs the number of milliseconds it took for the deferred function to be called + */ + var now = isNative(now = Date.now) && now || function() { + return new Date().getTime(); + }; + + /** + * Converts the given value into an integer of the specified radix. + * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the + * `value` is a hexadecimal, in which case a `radix` of `16` is used. + * + * Note: This method avoids differences in native ES3 and ES5 `parseInt` + * implementations. See http://es5.github.io/#E. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} value The value to parse. + * @param {number} [radix] The radix used to interpret the value to parse. + * @returns {number} Returns the new integer value. + * @example + * + * _.parseInt('08'); + * // => 8 + */ + var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) { + // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt` + return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0); + }; + + /** + * Creates a "_.pluck" style function, which returns the `key` value of a + * given object. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} key The name of the property to retrieve. + * @returns {Function} Returns the new function. + * @example + * + * var characters = [ + * { 'name': 'fred', 'age': 40 }, + * { 'name': 'barney', 'age': 36 } + * ]; + * + * var getName = _.property('name'); + * + * _.map(characters, getName); + * // => ['barney', 'fred'] + * + * _.sortBy(characters, getName); + * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] + */ + function property(key) { + return function(object) { + return object[key]; + }; + } + + /** + * Produces a random number between `min` and `max` (inclusive). If only one + * argument is provided a number between `0` and the given number will be + * returned. If `floating` is truey or either `min` or `max` are floats a + * floating-point number will be returned instead of an integer. + * + * @static + * @memberOf _ + * @category Utilities + * @param {number} [min=0] The minimum possible value. + * @param {number} [max=1] The maximum possible value. + * @param {boolean} [floating=false] Specify returning a floating-point number. + * @returns {number} Returns a random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(min, max, floating) { + var noMin = min == null, + noMax = max == null; + + if (floating == null) { + if (typeof min == 'boolean' && noMax) { + floating = min; + min = 1; + } + else if (!noMax && typeof max == 'boolean') { + floating = max; + noMax = true; + } + } + if (noMin && noMax) { + max = 1; + } + min = +min || 0; + if (noMax) { + max = min; + min = 0; + } else { + max = +max || 0; + } + if (floating || min % 1 || max % 1) { + var rand = nativeRandom(); + return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max); + } + return baseRandom(min, max); + } + + /** + * Resolves the value of property `key` on `object`. If `key` is a function + * it will be invoked with the `this` binding of `object` and its result returned, + * else the property value is returned. If `object` is falsey then `undefined` + * is returned. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Object} object The object to inspect. + * @param {string} key The name of the property to resolve. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { + * 'cheese': 'crumpets', + * 'stuff': function() { + * return 'nonsense'; + * } + * }; + * + * _.result(object, 'cheese'); + * // => 'crumpets' + * + * _.result(object, 'stuff'); + * // => 'nonsense' + */ + function result(object, key) { + if (object) { + var value = object[key]; + return isFunction(value) ? object[key]() : value; + } + } + + /** + * A micro-templating method that handles arbitrary delimiters, preserves + * whitespace, and correctly escapes quotes within interpolated code. + * + * Note: In the development build, `_.template` utilizes sourceURLs for easier + * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl + * + * For more information on precompiling templates see: + * http://lodash.com/custom-builds + * + * For more information on Chrome extension sandboxes see: + * http://developer.chrome.com/stable/extensions/sandboxingEval.html + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} text The template text. + * @param {Object} data The data object used to populate the text. + * @param {Object} [options] The options object. + * @param {RegExp} [options.escape] The "escape" delimiter. + * @param {RegExp} [options.evaluate] The "evaluate" delimiter. + * @param {Object} [options.imports] An object to import into the template as local variables. + * @param {RegExp} [options.interpolate] The "interpolate" delimiter. + * @param {string} [sourceURL] The sourceURL of the template's compiled source. + * @param {string} [variable] The data object variable name. + * @returns {Function|string} Returns a compiled function when no `data` object + * is given, else it returns the interpolated text. + * @example + * + * // using the "interpolate" delimiter to create a compiled template + * var compiled = _.template('hello <%= name %>'); + * compiled({ 'name': 'fred' }); + * // => 'hello fred' + * + * // using the "escape" delimiter to escape HTML in data property values + * _.template('<b><%- value %></b>', { 'value': '<script>' }); + * // => '<b><script></b>' + * + * // using the "evaluate" delimiter to generate HTML + * var list = '<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>'; + * _.template(list, { 'people': ['fred', 'barney'] }); + * // => '<li>fred</li><li>barney</li>' + * + * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter + * _.template('hello ${ name }', { 'name': 'pebbles' }); + * // => 'hello pebbles' + * + * // using the internal `print` function in "evaluate" delimiters + * _.template('<% print("hello " + name); %>!', { 'name': 'barney' }); + * // => 'hello barney!' + * + * // using a custom template delimiters + * _.templateSettings = { + * 'interpolate': /{{([\s\S]+?)}}/g + * }; + * + * _.template('hello {{ name }}!', { 'name': 'mustache' }); + * // => 'hello mustache!' + * + * // using the `imports` option to import jQuery + * var list = '<% jq.each(people, function(name) { %><li><%- name %></li><% }); %>'; + * _.template(list, { 'people': ['fred', 'barney'] }, { 'imports': { 'jq': jQuery } }); + * // => '<li>fred</li><li>barney</li>' + * + * // using the `sourceURL` option to specify a custom sourceURL for the template + * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' }); + * compiled(data); + * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector + * + * // using the `variable` option to ensure a with-statement isn't used in the compiled template + * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' }); + * compiled.source; + * // => function(data) { + * var __t, __p = '', __e = _.escape; + * __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!'; + * return __p; + * } + * + * // using the `source` property to inline compiled templates for meaningful + * // line numbers in error messages and a stack trace + * fs.writeFileSync(path.join(cwd, 'jst.js'), '\ + * var JST = {\ + * "main": ' + _.template(mainText).source + '\ + * };\ + * '); + */ + function template(text, data, options) { + // based on John Resig's `tmpl` implementation + // http://ejohn.org/blog/javascript-micro-templating/ + // and Laura Doktorova's doT.js + // https://github.com/olado/doT + var settings = lodash.templateSettings; + text = String(text || ''); + + // avoid missing dependencies when `iteratorTemplate` is not defined + options = defaults({}, options, settings); + + var imports = defaults({}, options.imports, settings.imports), + importsKeys = keys(imports), + importsValues = values(imports); + + var isEvaluating, + index = 0, + interpolate = options.interpolate || reNoMatch, + source = "__p += '"; + + // compile the regexp to match each delimiter + var reDelimiters = RegExp( + (options.escape || reNoMatch).source + '|' + + interpolate.source + '|' + + (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' + + (options.evaluate || reNoMatch).source + '|$' + , 'g'); + + text.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) { + interpolateValue || (interpolateValue = esTemplateValue); + + // escape characters that cannot be included in string literals + source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar); + + // replace delimiters with snippets + if (escapeValue) { + source += "' +\n__e(" + escapeValue + ") +\n'"; + } + if (evaluateValue) { + isEvaluating = true; + source += "';\n" + evaluateValue + ";\n__p += '"; + } + if (interpolateValue) { + source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'"; + } + index = offset + match.length; + + // the JS engine embedded in Adobe products requires returning the `match` + // string in order to produce the correct `offset` value + return match; + }); + + source += "';\n"; + + // if `variable` is not specified, wrap a with-statement around the generated + // code to add the data object to the top of the scope chain + var variable = options.variable, + hasVariable = variable; + + if (!hasVariable) { + variable = 'obj'; + source = 'with (' + variable + ') {\n' + source + '\n}\n'; + } + // cleanup code by stripping empty strings + source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source) + .replace(reEmptyStringMiddle, '$1') + .replace(reEmptyStringTrailing, '$1;'); + + // frame code as the function body + source = 'function(' + variable + ') {\n' + + (hasVariable ? '' : variable + ' || (' + variable + ' = {});\n') + + "var __t, __p = '', __e = _.escape" + + (isEvaluating + ? ', __j = Array.prototype.join;\n' + + "function print() { __p += __j.call(arguments, '') }\n" + : ';\n' + ) + + source + + 'return __p\n}'; + + // Use a sourceURL for easier debugging. + // http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl + var sourceURL = '\n/*\n//# sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']') + '\n*/'; + + try { + var result = Function(importsKeys, 'return ' + source + sourceURL).apply(undefined, importsValues); + } catch(e) { + e.source = source; + throw e; + } + if (data) { + return result(data); + } + // provide the compiled function's source by its `toString` method, in + // supported environments, or the `source` property as a convenience for + // inlining compiled templates during the build process + result.source = source; + return result; + } + + /** + * Executes the callback `n` times, returning an array of the results + * of each callback execution. The callback is bound to `thisArg` and invoked + * with one argument; (index). + * + * @static + * @memberOf _ + * @category Utilities + * @param {number} n The number of times to execute the callback. + * @param {Function} callback The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns an array of the results of each `callback` execution. + * @example + * + * var diceRolls = _.times(3, _.partial(_.random, 1, 6)); + * // => [3, 6, 4] + * + * _.times(3, function(n) { mage.castSpell(n); }); + * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively + * + * _.times(3, function(n) { this.cast(n); }, mage); + * // => also calls `mage.castSpell(n)` three times + */ + function times(n, callback, thisArg) { + n = (n = +n) > -1 ? n : 0; + var index = -1, + result = Array(n); + + callback = baseCreateCallback(callback, thisArg, 1); + while (++index < n) { + result[index] = callback(index); + } + return result; + } + + /** + * The inverse of `_.escape` this method converts the HTML entities + * `&`, `<`, `>`, `"`, and `'` in `string` to their + * corresponding characters. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} string The string to unescape. + * @returns {string} Returns the unescaped string. + * @example + * + * _.unescape('Fred, Barney & Pebbles'); + * // => 'Fred, Barney & Pebbles' + */ + function unescape(string) { + return string == null ? '' : String(string).replace(reEscapedHtml, unescapeHtmlChar); + } + + /** + * Generates a unique ID. If `prefix` is provided the ID will be appended to it. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} [prefix] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ + function uniqueId(prefix) { + var id = ++idCounter; + return String(prefix == null ? '' : prefix) + id; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object that wraps the given value with explicit + * method chaining enabled. + * + * @static + * @memberOf _ + * @category Chaining + * @param {*} value The value to wrap. + * @returns {Object} Returns the wrapper object. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 }, + * { 'name': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _.chain(characters) + * .sortBy('age') + * .map(function(chr) { return chr.name + ' is ' + chr.age; }) + * .first() + * .value(); + * // => 'pebbles is 1' + */ + function chain(value) { + value = new lodashWrapper(value); + value.__chain__ = true; + return value; + } + + /** + * Invokes `interceptor` with the `value` as the first argument and then + * returns `value`. The purpose of this method is to "tap into" a method + * chain in order to perform operations on intermediate results within + * the chain. + * + * @static + * @memberOf _ + * @category Chaining + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3, 4]) + * .tap(function(array) { array.pop(); }) + * .reverse() + * .value(); + * // => [3, 2, 1] + */ + function tap(value, interceptor) { + interceptor(value); + return value; + } + + /** + * Enables explicit method chaining on the wrapper object. + * + * @name chain + * @memberOf _ + * @category Chaining + * @returns {*} Returns the wrapper object. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // without explicit chaining + * _(characters).first(); + * // => { 'name': 'barney', 'age': 36 } + * + * // with explicit chaining + * _(characters).chain() + * .first() + * .pick('age') + * .value(); + * // => { 'age': 36 } + */ + function wrapperChain() { + this.__chain__ = true; + return this; + } + + /** + * Produces the `toString` result of the wrapped value. + * + * @name toString + * @memberOf _ + * @category Chaining + * @returns {string} Returns the string result. + * @example + * + * _([1, 2, 3]).toString(); + * // => '1,2,3' + */ + function wrapperToString() { + return String(this.__wrapped__); + } + + /** + * Extracts the wrapped value. + * + * @name valueOf + * @memberOf _ + * @alias value + * @category Chaining + * @returns {*} Returns the wrapped value. + * @example + * + * _([1, 2, 3]).valueOf(); + * // => [1, 2, 3] + */ + function wrapperValueOf() { + return this.__wrapped__; + } + + /*--------------------------------------------------------------------------*/ + + // add functions that return wrapped values when chaining + lodash.after = after; + lodash.assign = assign; + lodash.at = at; + lodash.bind = bind; + lodash.bindAll = bindAll; + lodash.bindKey = bindKey; + lodash.chain = chain; + lodash.compact = compact; + lodash.compose = compose; + lodash.constant = constant; + lodash.countBy = countBy; + lodash.create = create; + lodash.createCallback = createCallback; + lodash.curry = curry; + lodash.debounce = debounce; + lodash.defaults = defaults; + lodash.defer = defer; + lodash.delay = delay; + lodash.difference = difference; + lodash.filter = filter; + lodash.flatten = flatten; + lodash.forEach = forEach; + lodash.forEachRight = forEachRight; + lodash.forIn = forIn; + lodash.forInRight = forInRight; + lodash.forOwn = forOwn; + lodash.forOwnRight = forOwnRight; + lodash.functions = functions; + lodash.groupBy = groupBy; + lodash.indexBy = indexBy; + lodash.initial = initial; + lodash.intersection = intersection; + lodash.invert = invert; + lodash.invoke = invoke; + lodash.keys = keys; + lodash.map = map; + lodash.mapValues = mapValues; + lodash.max = max; + lodash.memoize = memoize; + lodash.merge = merge; + lodash.min = min; + lodash.omit = omit; + lodash.once = once; + lodash.pairs = pairs; + lodash.partial = partial; + lodash.partialRight = partialRight; + lodash.pick = pick; + lodash.pluck = pluck; + lodash.property = property; + lodash.pull = pull; + lodash.range = range; + lodash.reject = reject; + lodash.remove = remove; + lodash.rest = rest; + lodash.shuffle = shuffle; + lodash.sortBy = sortBy; + lodash.tap = tap; + lodash.throttle = throttle; + lodash.times = times; + lodash.toArray = toArray; + lodash.transform = transform; + lodash.union = union; + lodash.uniq = uniq; + lodash.values = values; + lodash.where = where; + lodash.without = without; + lodash.wrap = wrap; + lodash.xor = xor; + lodash.zip = zip; + lodash.zipObject = zipObject; + + // add aliases + lodash.collect = map; + lodash.drop = rest; + lodash.each = forEach; + lodash.eachRight = forEachRight; + lodash.extend = assign; + lodash.methods = functions; + lodash.object = zipObject; + lodash.select = filter; + lodash.tail = rest; + lodash.unique = uniq; + lodash.unzip = zip; + + // add functions to `lodash.prototype` + mixin(lodash); + + /*--------------------------------------------------------------------------*/ + + // add functions that return unwrapped values when chaining + lodash.clone = clone; + lodash.cloneDeep = cloneDeep; + lodash.contains = contains; + lodash.escape = escape; + lodash.every = every; + lodash.find = find; + lodash.findIndex = findIndex; + lodash.findKey = findKey; + lodash.findLast = findLast; + lodash.findLastIndex = findLastIndex; + lodash.findLastKey = findLastKey; + lodash.has = has; + lodash.identity = identity; + lodash.indexOf = indexOf; + lodash.isArguments = isArguments; + lodash.isArray = isArray; + lodash.isBoolean = isBoolean; + lodash.isDate = isDate; + lodash.isElement = isElement; + lodash.isEmpty = isEmpty; + lodash.isEqual = isEqual; + lodash.isFinite = isFinite; + lodash.isFunction = isFunction; + lodash.isNaN = isNaN; + lodash.isNull = isNull; + lodash.isNumber = isNumber; + lodash.isObject = isObject; + lodash.isPlainObject = isPlainObject; + lodash.isRegExp = isRegExp; + lodash.isString = isString; + lodash.isUndefined = isUndefined; + lodash.lastIndexOf = lastIndexOf; + lodash.mixin = mixin; + lodash.noConflict = noConflict; + lodash.noop = noop; + lodash.now = now; + lodash.parseInt = parseInt; + lodash.random = random; + lodash.reduce = reduce; + lodash.reduceRight = reduceRight; + lodash.result = result; + lodash.runInContext = runInContext; + lodash.size = size; + lodash.some = some; + lodash.sortedIndex = sortedIndex; + lodash.template = template; + lodash.unescape = unescape; + lodash.uniqueId = uniqueId; + + // add aliases + lodash.all = every; + lodash.any = some; + lodash.detect = find; + lodash.findWhere = find; + lodash.foldl = reduce; + lodash.foldr = reduceRight; + lodash.include = contains; + lodash.inject = reduce; + + mixin(function() { + var source = {} + forOwn(lodash, function(func, methodName) { + if (!lodash.prototype[methodName]) { + source[methodName] = func; + } + }); + return source; + }(), false); + + /*--------------------------------------------------------------------------*/ + + // add functions capable of returning wrapped and unwrapped values when chaining + lodash.first = first; + lodash.last = last; + lodash.sample = sample; + + // add aliases + lodash.take = first; + lodash.head = first; + + forOwn(lodash, function(func, methodName) { + var callbackable = methodName !== 'sample'; + if (!lodash.prototype[methodName]) { + lodash.prototype[methodName]= function(n, guard) { + var chainAll = this.__chain__, + result = func(this.__wrapped__, n, guard); + + return !chainAll && (n == null || (guard && !(callbackable && typeof n == 'function'))) + ? result + : new lodashWrapper(result, chainAll); + }; + } + }); + + /*--------------------------------------------------------------------------*/ + + /** + * The semantic version number. + * + * @static + * @memberOf _ + * @type string + */ + lodash.VERSION = '2.4.1'; + + // add "Chaining" functions to the wrapper + lodash.prototype.chain = wrapperChain; + lodash.prototype.toString = wrapperToString; + lodash.prototype.value = wrapperValueOf; + lodash.prototype.valueOf = wrapperValueOf; + + // add `Array` functions that return unwrapped values + baseEach(['join', 'pop', 'shift'], function(methodName) { + var func = arrayRef[methodName]; + lodash.prototype[methodName] = function() { + var chainAll = this.__chain__, + result = func.apply(this.__wrapped__, arguments); + + return chainAll + ? new lodashWrapper(result, chainAll) + : result; + }; + }); + + // add `Array` functions that return the existing wrapped value + baseEach(['push', 'reverse', 'sort', 'unshift'], function(methodName) { + var func = arrayRef[methodName]; + lodash.prototype[methodName] = function() { + func.apply(this.__wrapped__, arguments); + return this; + }; + }); + + // add `Array` functions that return new wrapped values + baseEach(['concat', 'slice', 'splice'], function(methodName) { + var func = arrayRef[methodName]; + lodash.prototype[methodName] = function() { + return new lodashWrapper(func.apply(this.__wrapped__, arguments), this.__chain__); + }; + }); + + // avoid array-like object bugs with `Array#shift` and `Array#splice` + // in IE < 9, Firefox < 10, Narwhal, and RingoJS + if (!support.spliceObjects) { + baseEach(['pop', 'shift', 'splice'], function(methodName) { + var func = arrayRef[methodName], + isSplice = methodName == 'splice'; + + lodash.prototype[methodName] = function() { + var chainAll = this.__chain__, + value = this.__wrapped__, + result = func.apply(value, arguments); + + if (value.length === 0) { + delete value[0]; + } + return (chainAll || isSplice) + ? new lodashWrapper(result, chainAll) + : result; + }; + }); + } + + return lodash; + } + + /*--------------------------------------------------------------------------*/ + + // expose Lo-Dash + var _ = runInContext(); + + // some AMD build optimizers like r.js check for condition patterns like the following: + if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { + // Expose Lo-Dash to the global object even when an AMD loader is present in + // case Lo-Dash is loaded with a RequireJS shim config. + // See http://requirejs.org/docs/api.html#config-shim + root._ = _; + + // define as an anonymous module so, through path mapping, it can be + // referenced as the "underscore" module + define(function() { + return _; + }); + } + // check for `exports` after `define` in case a build optimizer adds an `exports` object + else if (freeExports && freeModule) { + // in Node.js or RingoJS + if (moduleExports) { + (freeModule.exports = _)._ = _; + } + // in Narwhal or Rhino -require + else { + freeExports._ = _; + } + } + else { + // in a browser or Rhino + root._ = _; + } +}.call(this));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/python/django/renkanmanager/static/renkanmanager/lib/lodash/lodash.compat.min.js Mon Apr 27 17:22:46 2015 +0200 @@ -0,0 +1,61 @@ +/** + * @license + * Lo-Dash 2.4.1 (Custom Build) lodash.com/license | Underscore.js 1.5.2 underscorejs.org/LICENSE + * Build: `lodash -o ./dist/lodash.compat.js` + */ +;(function(){function n(n,t,e){e=(e||0)-1;for(var r=n?n.length:0;++e<r;)if(n[e]===t)return e;return-1}function t(t,e){var r=typeof e;if(t=t.l,"boolean"==r||null==e)return t[e]?0:-1;"number"!=r&&"string"!=r&&(r="object");var u="number"==r?e:b+e;return t=(t=t[r])&&t[u],"object"==r?t&&-1<n(t,e)?0:-1:t?0:-1}function e(n){var t=this.l,e=typeof n;if("boolean"==e||null==n)t[n]=true;else{"number"!=e&&"string"!=e&&(e="object");var r="number"==e?n:b+n,t=t[e]||(t[e]={});"object"==e?(t[r]||(t[r]=[])).push(n):t[r]=true +}}function r(n){return n.charCodeAt(0)}function u(n,t){for(var e=n.m,r=t.m,u=-1,o=e.length;++u<o;){var a=e[u],i=r[u];if(a!==i){if(a>i||typeof a=="undefined")return 1;if(a<i||typeof i=="undefined")return-1}}return n.n-t.n}function o(n){var t=-1,r=n.length,u=n[0],o=n[r/2|0],a=n[r-1];if(u&&typeof u=="object"&&o&&typeof o=="object"&&a&&typeof a=="object")return false;for(u=l(),u["false"]=u["null"]=u["true"]=u.undefined=false,o=l(),o.k=n,o.l=u,o.push=e;++t<r;)o.push(n[t]);return o}function a(n){return"\\"+Y[n] +}function i(){return v.pop()||[]}function l(){return y.pop()||{k:null,l:null,m:null,"false":false,n:0,"null":false,number:null,object:null,push:null,string:null,"true":false,undefined:false,o:null}}function f(n){return typeof n.toString!="function"&&typeof(n+"")=="string"}function c(n){n.length=0,v.length<w&&v.push(n)}function p(n){var t=n.l;t&&p(t),n.k=n.l=n.m=n.object=n.number=n.string=n.o=null,y.length<w&&y.push(n)}function s(n,t,e){t||(t=0),typeof e=="undefined"&&(e=n?n.length:0);var r=-1;e=e-t||0;for(var u=Array(0>e?0:e);++r<e;)u[r]=n[t+r]; +return u}function g(e){function v(n){return n&&typeof n=="object"&&!qe(n)&&we.call(n,"__wrapped__")?n:new y(n)}function y(n,t){this.__chain__=!!t,this.__wrapped__=n}function w(n){function t(){if(r){var n=s(r);je.apply(n,arguments)}if(this instanceof t){var o=nt(e.prototype),n=e.apply(o,n||arguments);return xt(n)?n:o}return e.apply(u,n||arguments)}var e=n[0],r=n[2],u=n[4];return ze(t,n),t}function Y(n,t,e,r,u){if(e){var o=e(n);if(typeof o!="undefined")return o}if(!xt(n))return n;var a=he.call(n);if(!V[a]||!Le.nodeClass&&f(n))return n; +var l=Te[a];switch(a){case L:case z:return new l(+n);case W:case M:return new l(n);case J:return o=l(n.source,S.exec(n)),o.lastIndex=n.lastIndex,o}if(a=qe(n),t){var p=!r;r||(r=i()),u||(u=i());for(var g=r.length;g--;)if(r[g]==n)return u[g];o=a?l(n.length):{}}else o=a?s(n):Ye({},n);return a&&(we.call(n,"index")&&(o.index=n.index),we.call(n,"input")&&(o.input=n.input)),t?(r.push(n),u.push(o),(a?Xe:tr)(n,function(n,a){o[a]=Y(n,t,e,r,u)}),p&&(c(r),c(u)),o):o}function nt(n){return xt(n)?Se(n):{}}function tt(n,t,e){if(typeof n!="function")return Ht; +if(typeof t=="undefined"||!("prototype"in n))return n;var r=n.__bindData__;if(typeof r=="undefined"&&(Le.funcNames&&(r=!n.name),r=r||!Le.funcDecomp,!r)){var u=be.call(n);Le.funcNames||(r=!A.test(u)),r||(r=B.test(u),ze(n,r))}if(false===r||true!==r&&1&r[1])return n;switch(e){case 1:return function(e){return n.call(t,e)};case 2:return function(e,r){return n.call(t,e,r)};case 3:return function(e,r,u){return n.call(t,e,r,u)};case 4:return function(e,r,u,o){return n.call(t,e,r,u,o)}}return Mt(n,t)}function et(n){function t(){var n=l?a:this; +if(u){var h=s(u);je.apply(h,arguments)}return(o||c)&&(h||(h=s(arguments)),o&&je.apply(h,o),c&&h.length<i)?(r|=16,et([e,p?r:-4&r,h,null,a,i])):(h||(h=arguments),f&&(e=n[g]),this instanceof t?(n=nt(e.prototype),h=e.apply(n,h),xt(h)?h:n):e.apply(n,h))}var e=n[0],r=n[1],u=n[2],o=n[3],a=n[4],i=n[5],l=1&r,f=2&r,c=4&r,p=8&r,g=e;return ze(t,n),t}function rt(e,r){var u=-1,a=ht(),i=e?e.length:0,l=i>=_&&a===n,f=[];if(l){var c=o(r);c?(a=t,r=c):l=false}for(;++u<i;)c=e[u],0>a(r,c)&&f.push(c);return l&&p(r),f}function ot(n,t,e,r){r=(r||0)-1; +for(var u=n?n.length:0,o=[];++r<u;){var a=n[r];if(a&&typeof a=="object"&&typeof a.length=="number"&&(qe(a)||dt(a))){t||(a=ot(a,t,e));var i=-1,l=a.length,f=o.length;for(o.length+=l;++i<l;)o[f++]=a[i]}else e||o.push(a)}return o}function at(n,t,e,r,u,o){if(e){var a=e(n,t);if(typeof a!="undefined")return!!a}if(n===t)return 0!==n||1/n==1/t;if(n===n&&!(n&&X[typeof n]||t&&X[typeof t]))return false;if(null==n||null==t)return n===t;var l=he.call(n),p=he.call(t);if(l==T&&(l=G),p==T&&(p=G),l!=p)return false;switch(l){case L:case z:return+n==+t; +case W:return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case J:case M:return n==ie(t)}if(p=l==$,!p){var s=we.call(n,"__wrapped__"),g=we.call(t,"__wrapped__");if(s||g)return at(s?n.__wrapped__:n,g?t.__wrapped__:t,e,r,u,o);if(l!=G||!Le.nodeClass&&(f(n)||f(t)))return false;if(l=!Le.argsObject&&dt(n)?oe:n.constructor,s=!Le.argsObject&&dt(t)?oe:t.constructor,l!=s&&!(jt(l)&&l instanceof l&&jt(s)&&s instanceof s)&&"constructor"in n&&"constructor"in t)return false}for(l=!u,u||(u=i()),o||(o=i()),s=u.length;s--;)if(u[s]==n)return o[s]==t; +var h=0,a=true;if(u.push(n),o.push(t),p){if(s=n.length,h=t.length,(a=h==s)||r)for(;h--;)if(p=s,g=t[h],r)for(;p--&&!(a=at(n[p],g,e,r,u,o)););else if(!(a=at(n[h],g,e,r,u,o)))break}else nr(t,function(t,i,l){return we.call(l,i)?(h++,a=we.call(n,i)&&at(n[i],t,e,r,u,o)):void 0}),a&&!r&&nr(n,function(n,t,e){return we.call(e,t)?a=-1<--h:void 0});return u.pop(),o.pop(),l&&(c(u),c(o)),a}function it(n,t,e,r,u){(qe(t)?Dt:tr)(t,function(t,o){var a,i,l=t,f=n[o];if(t&&((i=qe(t))||er(t))){for(l=r.length;l--;)if(a=r[l]==t){f=u[l]; +break}if(!a){var c;e&&(l=e(f,t),c=typeof l!="undefined")&&(f=l),c||(f=i?qe(f)?f:[]:er(f)?f:{}),r.push(t),u.push(f),c||it(f,t,e,r,u)}}else e&&(l=e(f,t),typeof l=="undefined"&&(l=t)),typeof l!="undefined"&&(f=l);n[o]=f})}function lt(n,t){return n+de(Fe()*(t-n+1))}function ft(e,r,u){var a=-1,l=ht(),f=e?e.length:0,s=[],g=!r&&f>=_&&l===n,h=u||g?i():s;for(g&&(h=o(h),l=t);++a<f;){var v=e[a],y=u?u(v,a,e):v;(r?!a||h[h.length-1]!==y:0>l(h,y))&&((u||g)&&h.push(y),s.push(v))}return g?(c(h.k),p(h)):u&&c(h),s}function ct(n){return function(t,e,r){var u={}; +if(e=v.createCallback(e,r,3),qe(t)){r=-1;for(var o=t.length;++r<o;){var a=t[r];n(u,a,e(a,r,t),t)}}else Xe(t,function(t,r,o){n(u,t,e(t,r,o),o)});return u}}function pt(n,t,e,r,u,o){var a=1&t,i=4&t,l=16&t,f=32&t;if(!(2&t||jt(n)))throw new le;l&&!e.length&&(t&=-17,l=e=false),f&&!r.length&&(t&=-33,f=r=false);var c=n&&n.__bindData__;return c&&true!==c?(c=s(c),c[2]&&(c[2]=s(c[2])),c[3]&&(c[3]=s(c[3])),!a||1&c[1]||(c[4]=u),!a&&1&c[1]&&(t|=8),!i||4&c[1]||(c[5]=o),l&&je.apply(c[2]||(c[2]=[]),e),f&&Ee.apply(c[3]||(c[3]=[]),r),c[1]|=t,pt.apply(null,c)):(1==t||17===t?w:et)([n,t,e,r,u,o]) +}function st(){Q.h=F,Q.b=Q.c=Q.g=Q.i="",Q.e="t",Q.j=true;for(var n,t=0;n=arguments[t];t++)for(var e in n)Q[e]=n[e];t=Q.a,Q.d=/^[^,]+/.exec(t)[0],n=ee,t="return function("+t+"){",e=Q;var r="var n,t="+e.d+",E="+e.e+";if(!t)return E;"+e.i+";";e.b?(r+="var u=t.length;n=-1;if("+e.b+"){",Le.unindexedChars&&(r+="if(s(t)){t=t.split('')}"),r+="while(++n<u){"+e.g+";}}else{"):Le.nonEnumArgs&&(r+="var u=t.length;n=-1;if(u&&p(t)){while(++n<u){n+='';"+e.g+";}}else{"),Le.enumPrototypes&&(r+="var G=typeof t=='function';"),Le.enumErrorProps&&(r+="var F=t===k||t instanceof Error;"); +var u=[];if(Le.enumPrototypes&&u.push('!(G&&n=="prototype")'),Le.enumErrorProps&&u.push('!(F&&(n=="message"||n=="name"))'),e.j&&e.f)r+="var C=-1,D=B[typeof t]&&v(t),u=D?D.length:0;while(++C<u){n=D[C];",u.length&&(r+="if("+u.join("&&")+"){"),r+=e.g+";",u.length&&(r+="}"),r+="}";else if(r+="for(n in t){",e.j&&u.push("m.call(t, n)"),u.length&&(r+="if("+u.join("&&")+"){"),r+=e.g+";",u.length&&(r+="}"),r+="}",Le.nonEnumShadows){for(r+="if(t!==A){var i=t.constructor,r=t===(i&&i.prototype),f=t===J?I:t===k?j:L.call(t),x=y[f];",k=0;7>k;k++)r+="n='"+e.h[k]+"';if((!(r&&x[n])&&m.call(t,n))",e.j||(r+="||(!x[n]&&t[n]!==A[n])"),r+="){"+e.g+"}"; +r+="}"}return(e.b||Le.nonEnumArgs)&&(r+="}"),r+=e.c+";return E",n("d,j,k,m,o,p,q,s,v,A,B,y,I,J,L",t+r+"}")(tt,q,ce,we,d,dt,qe,kt,Q.f,pe,X,$e,M,se,he)}function gt(n){return Ve[n]}function ht(){var t=(t=v.indexOf)===zt?n:t;return t}function vt(n){return typeof n=="function"&&ve.test(n)}function yt(n){var t,e;return!n||he.call(n)!=G||(t=n.constructor,jt(t)&&!(t instanceof t))||!Le.argsClass&&dt(n)||!Le.nodeClass&&f(n)?false:Le.ownLast?(nr(n,function(n,t,r){return e=we.call(r,t),false}),false!==e):(nr(n,function(n,t){e=t +}),typeof e=="undefined"||we.call(n,e))}function mt(n){return He[n]}function dt(n){return n&&typeof n=="object"&&typeof n.length=="number"&&he.call(n)==T||false}function bt(n,t,e){var r=We(n),u=r.length;for(t=tt(t,e,3);u--&&(e=r[u],false!==t(n[e],e,n)););return n}function _t(n){var t=[];return nr(n,function(n,e){jt(n)&&t.push(e)}),t.sort()}function wt(n){for(var t=-1,e=We(n),r=e.length,u={};++t<r;){var o=e[t];u[n[o]]=o}return u}function jt(n){return typeof n=="function"}function xt(n){return!(!n||!X[typeof n]) +}function Ct(n){return typeof n=="number"||n&&typeof n=="object"&&he.call(n)==W||false}function kt(n){return typeof n=="string"||n&&typeof n=="object"&&he.call(n)==M||false}function Et(n){for(var t=-1,e=We(n),r=e.length,u=Zt(r);++t<r;)u[t]=n[e[t]];return u}function Ot(n,t,e){var r=-1,u=ht(),o=n?n.length:0,a=false;return e=(0>e?Be(0,o+e):e)||0,qe(n)?a=-1<u(n,t,e):typeof o=="number"?a=-1<(kt(n)?n.indexOf(t,e):u(n,t,e)):Xe(n,function(n){return++r<e?void 0:!(a=n===t)}),a}function St(n,t,e){var r=true;if(t=v.createCallback(t,e,3),qe(n)){e=-1; +for(var u=n.length;++e<u&&(r=!!t(n[e],e,n)););}else Xe(n,function(n,e,u){return r=!!t(n,e,u)});return r}function At(n,t,e){var r=[];if(t=v.createCallback(t,e,3),qe(n)){e=-1;for(var u=n.length;++e<u;){var o=n[e];t(o,e,n)&&r.push(o)}}else Xe(n,function(n,e,u){t(n,e,u)&&r.push(n)});return r}function It(n,t,e){if(t=v.createCallback(t,e,3),!qe(n)){var r;return Xe(n,function(n,e,u){return t(n,e,u)?(r=n,false):void 0}),r}e=-1;for(var u=n.length;++e<u;){var o=n[e];if(t(o,e,n))return o}}function Dt(n,t,e){if(t&&typeof e=="undefined"&&qe(n)){e=-1; +for(var r=n.length;++e<r&&false!==t(n[e],e,n););}else Xe(n,t,e);return n}function Nt(n,t,e){var r=n,u=n?n.length:0;if(t=t&&typeof e=="undefined"?t:tt(t,e,3),qe(n))for(;u--&&false!==t(n[u],u,n););else{if(typeof u!="number")var o=We(n),u=o.length;else Le.unindexedChars&&kt(n)&&(r=n.split(""));Xe(n,function(n,e,a){return e=o?o[--u]:--u,t(r[e],e,a)})}return n}function Bt(n,t,e){var r=-1,u=n?n.length:0,o=Zt(typeof u=="number"?u:0);if(t=v.createCallback(t,e,3),qe(n))for(;++r<u;)o[r]=t(n[r],r,n);else Xe(n,function(n,e,u){o[++r]=t(n,e,u) +});return o}function Pt(n,t,e){var u=-1/0,o=u;if(typeof t!="function"&&e&&e[t]===n&&(t=null),null==t&&qe(n)){e=-1;for(var a=n.length;++e<a;){var i=n[e];i>o&&(o=i)}}else t=null==t&&kt(n)?r:v.createCallback(t,e,3),Xe(n,function(n,e,r){e=t(n,e,r),e>u&&(u=e,o=n)});return o}function Rt(n,t,e,r){var u=3>arguments.length;if(t=v.createCallback(t,r,4),qe(n)){var o=-1,a=n.length;for(u&&(e=n[++o]);++o<a;)e=t(e,n[o],o,n)}else Xe(n,function(n,r,o){e=u?(u=false,n):t(e,n,r,o)});return e}function Ft(n,t,e,r){var u=3>arguments.length; +return t=v.createCallback(t,r,4),Nt(n,function(n,r,o){e=u?(u=false,n):t(e,n,r,o)}),e}function Tt(n){var t=-1,e=n?n.length:0,r=Zt(typeof e=="number"?e:0);return Dt(n,function(n){var e=lt(0,++t);r[t]=r[e],r[e]=n}),r}function $t(n,t,e){var r;if(t=v.createCallback(t,e,3),qe(n)){e=-1;for(var u=n.length;++e<u&&!(r=t(n[e],e,n)););}else Xe(n,function(n,e,u){return!(r=t(n,e,u))});return!!r}function Lt(n,t,e){var r=0,u=n?n.length:0;if(typeof t!="number"&&null!=t){var o=-1;for(t=v.createCallback(t,e,3);++o<u&&t(n[o],o,n);)r++ +}else if(r=t,null==r||e)return n?n[0]:h;return s(n,0,Pe(Be(0,r),u))}function zt(t,e,r){if(typeof r=="number"){var u=t?t.length:0;r=0>r?Be(0,u+r):r||0}else if(r)return r=Kt(t,e),t[r]===e?r:-1;return n(t,e,r)}function qt(n,t,e){if(typeof t!="number"&&null!=t){var r=0,u=-1,o=n?n.length:0;for(t=v.createCallback(t,e,3);++u<o&&t(n[u],u,n);)r++}else r=null==t||e?1:Be(0,t);return s(n,r)}function Kt(n,t,e,r){var u=0,o=n?n.length:u;for(e=e?v.createCallback(e,r,1):Ht,t=e(t);u<o;)r=u+o>>>1,e(n[r])<t?u=r+1:o=r; +return u}function Wt(n,t,e,r){return typeof t!="boolean"&&null!=t&&(r=e,e=typeof t!="function"&&r&&r[t]===n?null:t,t=false),null!=e&&(e=v.createCallback(e,r,3)),ft(n,t,e)}function Gt(){for(var n=1<arguments.length?arguments:arguments[0],t=-1,e=n?Pt(ar(n,"length")):0,r=Zt(0>e?0:e);++t<e;)r[t]=ar(n,t);return r}function Jt(n,t){var e=-1,r=n?n.length:0,u={};for(t||!r||qe(n[0])||(t=[]);++e<r;){var o=n[e];t?u[o]=t[e]:o&&(u[o[0]]=o[1])}return u}function Mt(n,t){return 2<arguments.length?pt(n,17,s(arguments,2),null,t):pt(n,1,null,null,t) +}function Vt(n,t,e){var r,u,o,a,i,l,f,c=0,p=false,s=true;if(!jt(n))throw new le;if(t=Be(0,t)||0,true===e)var g=true,s=false;else xt(e)&&(g=e.leading,p="maxWait"in e&&(Be(t,e.maxWait)||0),s="trailing"in e?e.trailing:s);var v=function(){var e=t-(ir()-a);0<e?l=Ce(v,e):(u&&me(u),e=f,u=l=f=h,e&&(c=ir(),o=n.apply(i,r),l||u||(r=i=null)))},y=function(){l&&me(l),u=l=f=h,(s||p!==t)&&(c=ir(),o=n.apply(i,r),l||u||(r=i=null))};return function(){if(r=arguments,a=ir(),i=this,f=s&&(l||!g),false===p)var e=g&&!l;else{u||g||(c=a); +var h=p-(a-c),m=0>=h;m?(u&&(u=me(u)),c=a,o=n.apply(i,r)):u||(u=Ce(y,h))}return m&&l?l=me(l):l||t===p||(l=Ce(v,t)),e&&(m=true,o=n.apply(i,r)),!m||l||u||(r=i=null),o}}function Ht(n){return n}function Ut(n,t,e){var r=true,u=t&&_t(t);t&&(e||u.length)||(null==e&&(e=t),o=y,t=n,n=v,u=_t(t)),false===e?r=false:xt(e)&&"chain"in e&&(r=e.chain);var o=n,a=jt(o);Dt(u,function(e){var u=n[e]=t[e];a&&(o.prototype[e]=function(){var t=this.__chain__,e=this.__wrapped__,a=[e];if(je.apply(a,arguments),a=u.apply(n,a),r||t){if(e===a&&xt(a))return this; +a=new o(a),a.__chain__=t}return a})})}function Qt(){}function Xt(n){return function(t){return t[n]}}function Yt(){return this.__wrapped__}e=e?ut.defaults(Z.Object(),e,ut.pick(Z,R)):Z;var Zt=e.Array,ne=e.Boolean,te=e.Date,ee=e.Function,re=e.Math,ue=e.Number,oe=e.Object,ae=e.RegExp,ie=e.String,le=e.TypeError,fe=[],ce=e.Error.prototype,pe=oe.prototype,se=ie.prototype,ge=e._,he=pe.toString,ve=ae("^"+ie(he).replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/toString| for [^\]]+/g,".*?")+"$"),ye=re.ceil,me=e.clearTimeout,de=re.floor,be=ee.prototype.toString,_e=vt(_e=oe.getPrototypeOf)&&_e,we=pe.hasOwnProperty,je=fe.push,xe=pe.propertyIsEnumerable,Ce=e.setTimeout,ke=fe.splice,Ee=fe.unshift,Oe=function(){try{var n={},t=vt(t=oe.defineProperty)&&t,e=t(n,n,n)&&t +}catch(r){}return e}(),Se=vt(Se=oe.create)&&Se,Ae=vt(Ae=Zt.isArray)&&Ae,Ie=e.isFinite,De=e.isNaN,Ne=vt(Ne=oe.keys)&&Ne,Be=re.max,Pe=re.min,Re=e.parseInt,Fe=re.random,Te={};Te[$]=Zt,Te[L]=ne,Te[z]=te,Te[K]=ee,Te[G]=oe,Te[W]=ue,Te[J]=ae,Te[M]=ie;var $e={};$e[$]=$e[z]=$e[W]={constructor:true,toLocaleString:true,toString:true,valueOf:true},$e[L]=$e[M]={constructor:true,toString:true,valueOf:true},$e[q]=$e[K]=$e[J]={constructor:true,toString:true},$e[G]={constructor:true},function(){for(var n=F.length;n--;){var t,e=F[n]; +for(t in $e)we.call($e,t)&&!we.call($e[t],e)&&($e[t][e]=false)}}(),y.prototype=v.prototype;var Le=v.support={};!function(){var n=function(){this.x=1},t={0:1,length:1},r=[];n.prototype={valueOf:1,y:1};for(var u in new n)r.push(u);for(u in arguments);Le.argsClass=he.call(arguments)==T,Le.argsObject=arguments.constructor==oe&&!(arguments instanceof Zt),Le.enumErrorProps=xe.call(ce,"message")||xe.call(ce,"name"),Le.enumPrototypes=xe.call(n,"prototype"),Le.funcDecomp=!vt(e.WinRTError)&&B.test(g),Le.funcNames=typeof ee.name=="string",Le.nonEnumArgs=0!=u,Le.nonEnumShadows=!/valueOf/.test(r),Le.ownLast="x"!=r[0],Le.spliceObjects=(fe.splice.call(t,0,1),!t[0]),Le.unindexedChars="xx"!="x"[0]+oe("x")[0]; +try{Le.nodeClass=!(he.call(document)==G&&!({toString:0}+""))}catch(o){Le.nodeClass=true}}(1),v.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:I,variable:"",imports:{_:v}},Se||(nt=function(){function n(){}return function(t){if(xt(t)){n.prototype=t;var r=new n;n.prototype=null}return r||e.Object()}}());var ze=Oe?function(n,t){U.value=t,Oe(n,"__bindData__",U)}:Qt;Le.argsClass||(dt=function(n){return n&&typeof n=="object"&&typeof n.length=="number"&&we.call(n,"callee")&&!xe.call(n,"callee")||false +});var qe=Ae||function(n){return n&&typeof n=="object"&&typeof n.length=="number"&&he.call(n)==$||false},Ke=st({a:"z",e:"[]",i:"if(!(B[typeof z]))return E",g:"E.push(n)"}),We=Ne?function(n){return xt(n)?Le.enumPrototypes&&typeof n=="function"||Le.nonEnumArgs&&n.length&&dt(n)?Ke(n):Ne(n):[]}:Ke,Ge={a:"g,e,K",i:"e=e&&typeof K=='undefined'?e:d(e,K,3)",b:"typeof u=='number'",v:We,g:"if(e(t[n],n,g)===false)return E"},Je={a:"z,H,l",i:"var a=arguments,b=0,c=typeof l=='number'?2:a.length;while(++b<c){t=a[b];if(t&&B[typeof t]){",v:We,g:"if(typeof E[n]=='undefined')E[n]=t[n]",c:"}}"},Me={i:"if(!B[typeof t])return E;"+Ge.i,b:false},Ve={"&":"&","<":"<",">":">",'"':""","'":"'"},He=wt(Ve),Ue=ae("("+We(He).join("|")+")","g"),Qe=ae("["+We(Ve).join("")+"]","g"),Xe=st(Ge),Ye=st(Je,{i:Je.i.replace(";",";if(c>3&&typeof a[c-2]=='function'){var e=d(a[--c-1],a[c--],2)}else if(c>2&&typeof a[c-1]=='function'){e=a[--c]}"),g:"E[n]=e?e(E[n],t[n]):t[n]"}),Ze=st(Je),nr=st(Ge,Me,{j:false}),tr=st(Ge,Me); +jt(/x/)&&(jt=function(n){return typeof n=="function"&&he.call(n)==K});var er=_e?function(n){if(!n||he.call(n)!=G||!Le.argsClass&&dt(n))return false;var t=n.valueOf,e=vt(t)&&(e=_e(t))&&_e(e);return e?n==e||_e(n)==e:yt(n)}:yt,rr=ct(function(n,t,e){we.call(n,e)?n[e]++:n[e]=1}),ur=ct(function(n,t,e){(we.call(n,e)?n[e]:n[e]=[]).push(t)}),or=ct(function(n,t,e){n[e]=t}),ar=Bt,ir=vt(ir=te.now)&&ir||function(){return(new te).getTime()},lr=8==Re(j+"08")?Re:function(n,t){return Re(kt(n)?n.replace(D,""):n,t||0)}; +return v.after=function(n,t){if(!jt(t))throw new le;return function(){return 1>--n?t.apply(this,arguments):void 0}},v.assign=Ye,v.at=function(n){var t=arguments,e=-1,r=ot(t,true,false,1),t=t[2]&&t[2][t[1]]===n?1:r.length,u=Zt(t);for(Le.unindexedChars&&kt(n)&&(n=n.split(""));++e<t;)u[e]=n[r[e]];return u},v.bind=Mt,v.bindAll=function(n){for(var t=1<arguments.length?ot(arguments,true,false,1):_t(n),e=-1,r=t.length;++e<r;){var u=t[e];n[u]=pt(n[u],1,null,null,n)}return n},v.bindKey=function(n,t){return 2<arguments.length?pt(t,19,s(arguments,2),null,n):pt(t,3,null,null,n) +},v.chain=function(n){return n=new y(n),n.__chain__=true,n},v.compact=function(n){for(var t=-1,e=n?n.length:0,r=[];++t<e;){var u=n[t];u&&r.push(u)}return r},v.compose=function(){for(var n=arguments,t=n.length;t--;)if(!jt(n[t]))throw new le;return function(){for(var t=arguments,e=n.length;e--;)t=[n[e].apply(this,t)];return t[0]}},v.constant=function(n){return function(){return n}},v.countBy=rr,v.create=function(n,t){var e=nt(n);return t?Ye(e,t):e},v.createCallback=function(n,t,e){var r=typeof n;if(null==n||"function"==r)return tt(n,t,e); +if("object"!=r)return Xt(n);var u=We(n),o=u[0],a=n[o];return 1!=u.length||a!==a||xt(a)?function(t){for(var e=u.length,r=false;e--&&(r=at(t[u[e]],n[u[e]],null,true)););return r}:function(n){return n=n[o],a===n&&(0!==a||1/a==1/n)}},v.curry=function(n,t){return t=typeof t=="number"?t:+t||n.length,pt(n,4,null,null,null,t)},v.debounce=Vt,v.defaults=Ze,v.defer=function(n){if(!jt(n))throw new le;var t=s(arguments,1);return Ce(function(){n.apply(h,t)},1)},v.delay=function(n,t){if(!jt(n))throw new le;var e=s(arguments,2); +return Ce(function(){n.apply(h,e)},t)},v.difference=function(n){return rt(n,ot(arguments,true,true,1))},v.filter=At,v.flatten=function(n,t,e,r){return typeof t!="boolean"&&null!=t&&(r=e,e=typeof t!="function"&&r&&r[t]===n?null:t,t=false),null!=e&&(n=Bt(n,e,r)),ot(n,t)},v.forEach=Dt,v.forEachRight=Nt,v.forIn=nr,v.forInRight=function(n,t,e){var r=[];nr(n,function(n,t){r.push(t,n)});var u=r.length;for(t=tt(t,e,3);u--&&false!==t(r[u--],r[u],n););return n},v.forOwn=tr,v.forOwnRight=bt,v.functions=_t,v.groupBy=ur,v.indexBy=or,v.initial=function(n,t,e){var r=0,u=n?n.length:0; +if(typeof t!="number"&&null!=t){var o=u;for(t=v.createCallback(t,e,3);o--&&t(n[o],o,n);)r++}else r=null==t||e?1:t||r;return s(n,0,Pe(Be(0,u-r),u))},v.intersection=function(){for(var e=[],r=-1,u=arguments.length,a=i(),l=ht(),f=l===n,s=i();++r<u;){var g=arguments[r];(qe(g)||dt(g))&&(e.push(g),a.push(f&&g.length>=_&&o(r?e[r]:s)))}var f=e[0],h=-1,v=f?f.length:0,y=[];n:for(;++h<v;){var m=a[0],g=f[h];if(0>(m?t(m,g):l(s,g))){for(r=u,(m||s).push(g);--r;)if(m=a[r],0>(m?t(m,g):l(e[r],g)))continue n;y.push(g) +}}for(;u--;)(m=a[u])&&p(m);return c(a),c(s),y},v.invert=wt,v.invoke=function(n,t){var e=s(arguments,2),r=-1,u=typeof t=="function",o=n?n.length:0,a=Zt(typeof o=="number"?o:0);return Dt(n,function(n){a[++r]=(u?t:n[t]).apply(n,e)}),a},v.keys=We,v.map=Bt,v.mapValues=function(n,t,e){var r={};return t=v.createCallback(t,e,3),tr(n,function(n,e,u){r[e]=t(n,e,u)}),r},v.max=Pt,v.memoize=function(n,t){if(!jt(n))throw new le;var e=function(){var r=e.cache,u=t?t.apply(this,arguments):b+arguments[0];return we.call(r,u)?r[u]:r[u]=n.apply(this,arguments) +};return e.cache={},e},v.merge=function(n){var t=arguments,e=2;if(!xt(n))return n;if("number"!=typeof t[2]&&(e=t.length),3<e&&"function"==typeof t[e-2])var r=tt(t[--e-1],t[e--],2);else 2<e&&"function"==typeof t[e-1]&&(r=t[--e]);for(var t=s(arguments,1,e),u=-1,o=i(),a=i();++u<e;)it(n,t[u],r,o,a);return c(o),c(a),n},v.min=function(n,t,e){var u=1/0,o=u;if(typeof t!="function"&&e&&e[t]===n&&(t=null),null==t&&qe(n)){e=-1;for(var a=n.length;++e<a;){var i=n[e];i<o&&(o=i)}}else t=null==t&&kt(n)?r:v.createCallback(t,e,3),Xe(n,function(n,e,r){e=t(n,e,r),e<u&&(u=e,o=n) +});return o},v.omit=function(n,t,e){var r={};if(typeof t!="function"){var u=[];nr(n,function(n,t){u.push(t)});for(var u=rt(u,ot(arguments,true,false,1)),o=-1,a=u.length;++o<a;){var i=u[o];r[i]=n[i]}}else t=v.createCallback(t,e,3),nr(n,function(n,e,u){t(n,e,u)||(r[e]=n)});return r},v.once=function(n){var t,e;if(!jt(n))throw new le;return function(){return t?e:(t=true,e=n.apply(this,arguments),n=null,e)}},v.pairs=function(n){for(var t=-1,e=We(n),r=e.length,u=Zt(r);++t<r;){var o=e[t];u[t]=[o,n[o]]}return u +},v.partial=function(n){return pt(n,16,s(arguments,1))},v.partialRight=function(n){return pt(n,32,null,s(arguments,1))},v.pick=function(n,t,e){var r={};if(typeof t!="function")for(var u=-1,o=ot(arguments,true,false,1),a=xt(n)?o.length:0;++u<a;){var i=o[u];i in n&&(r[i]=n[i])}else t=v.createCallback(t,e,3),nr(n,function(n,e,u){t(n,e,u)&&(r[e]=n)});return r},v.pluck=ar,v.property=Xt,v.pull=function(n){for(var t=arguments,e=0,r=t.length,u=n?n.length:0;++e<r;)for(var o=-1,a=t[e];++o<u;)n[o]===a&&(ke.call(n,o--,1),u--); +return n},v.range=function(n,t,e){n=+n||0,e=typeof e=="number"?e:+e||1,null==t&&(t=n,n=0);var r=-1;t=Be(0,ye((t-n)/(e||1)));for(var u=Zt(t);++r<t;)u[r]=n,n+=e;return u},v.reject=function(n,t,e){return t=v.createCallback(t,e,3),At(n,function(n,e,r){return!t(n,e,r)})},v.remove=function(n,t,e){var r=-1,u=n?n.length:0,o=[];for(t=v.createCallback(t,e,3);++r<u;)e=n[r],t(e,r,n)&&(o.push(e),ke.call(n,r--,1),u--);return o},v.rest=qt,v.shuffle=Tt,v.sortBy=function(n,t,e){var r=-1,o=qe(t),a=n?n.length:0,f=Zt(typeof a=="number"?a:0); +for(o||(t=v.createCallback(t,e,3)),Dt(n,function(n,e,u){var a=f[++r]=l();o?a.m=Bt(t,function(t){return n[t]}):(a.m=i())[0]=t(n,e,u),a.n=r,a.o=n}),a=f.length,f.sort(u);a--;)n=f[a],f[a]=n.o,o||c(n.m),p(n);return f},v.tap=function(n,t){return t(n),n},v.throttle=function(n,t,e){var r=true,u=true;if(!jt(n))throw new le;return false===e?r=false:xt(e)&&(r="leading"in e?e.leading:r,u="trailing"in e?e.trailing:u),H.leading=r,H.maxWait=t,H.trailing=u,Vt(n,t,H)},v.times=function(n,t,e){n=-1<(n=+n)?n:0;var r=-1,u=Zt(n); +for(t=tt(t,e,1);++r<n;)u[r]=t(r);return u},v.toArray=function(n){return n&&typeof n.length=="number"?Le.unindexedChars&&kt(n)?n.split(""):s(n):Et(n)},v.transform=function(n,t,e,r){var u=qe(n);if(null==e)if(u)e=[];else{var o=n&&n.constructor;e=nt(o&&o.prototype)}return t&&(t=v.createCallback(t,r,4),(u?Xe:tr)(n,function(n,r,u){return t(e,n,r,u)})),e},v.union=function(){return ft(ot(arguments,true,true))},v.uniq=Wt,v.values=Et,v.where=At,v.without=function(n){return rt(n,s(arguments,1))},v.wrap=function(n,t){return pt(t,16,[n]) +},v.xor=function(){for(var n=-1,t=arguments.length;++n<t;){var e=arguments[n];if(qe(e)||dt(e))var r=r?ft(rt(r,e).concat(rt(e,r))):e}return r||[]},v.zip=Gt,v.zipObject=Jt,v.collect=Bt,v.drop=qt,v.each=Dt,v.eachRight=Nt,v.extend=Ye,v.methods=_t,v.object=Jt,v.select=At,v.tail=qt,v.unique=Wt,v.unzip=Gt,Ut(v),v.clone=function(n,t,e,r){return typeof t!="boolean"&&null!=t&&(r=e,e=t,t=false),Y(n,t,typeof e=="function"&&tt(e,r,1))},v.cloneDeep=function(n,t,e){return Y(n,true,typeof t=="function"&&tt(t,e,1))},v.contains=Ot,v.escape=function(n){return null==n?"":ie(n).replace(Qe,gt) +},v.every=St,v.find=It,v.findIndex=function(n,t,e){var r=-1,u=n?n.length:0;for(t=v.createCallback(t,e,3);++r<u;)if(t(n[r],r,n))return r;return-1},v.findKey=function(n,t,e){var r;return t=v.createCallback(t,e,3),tr(n,function(n,e,u){return t(n,e,u)?(r=e,false):void 0}),r},v.findLast=function(n,t,e){var r;return t=v.createCallback(t,e,3),Nt(n,function(n,e,u){return t(n,e,u)?(r=n,false):void 0}),r},v.findLastIndex=function(n,t,e){var r=n?n.length:0;for(t=v.createCallback(t,e,3);r--;)if(t(n[r],r,n))return r; +return-1},v.findLastKey=function(n,t,e){var r;return t=v.createCallback(t,e,3),bt(n,function(n,e,u){return t(n,e,u)?(r=e,false):void 0}),r},v.has=function(n,t){return n?we.call(n,t):false},v.identity=Ht,v.indexOf=zt,v.isArguments=dt,v.isArray=qe,v.isBoolean=function(n){return true===n||false===n||n&&typeof n=="object"&&he.call(n)==L||false},v.isDate=function(n){return n&&typeof n=="object"&&he.call(n)==z||false},v.isElement=function(n){return n&&1===n.nodeType||false},v.isEmpty=function(n){var t=true;if(!n)return t;var e=he.call(n),r=n.length; +return e==$||e==M||(Le.argsClass?e==T:dt(n))||e==G&&typeof r=="number"&&jt(n.splice)?!r:(tr(n,function(){return t=false}),t)},v.isEqual=function(n,t,e,r){return at(n,t,typeof e=="function"&&tt(e,r,2))},v.isFinite=function(n){return Ie(n)&&!De(parseFloat(n))},v.isFunction=jt,v.isNaN=function(n){return Ct(n)&&n!=+n},v.isNull=function(n){return null===n},v.isNumber=Ct,v.isObject=xt,v.isPlainObject=er,v.isRegExp=function(n){return n&&X[typeof n]&&he.call(n)==J||false},v.isString=kt,v.isUndefined=function(n){return typeof n=="undefined" +},v.lastIndexOf=function(n,t,e){var r=n?n.length:0;for(typeof e=="number"&&(r=(0>e?Be(0,r+e):Pe(e,r-1))+1);r--;)if(n[r]===t)return r;return-1},v.mixin=Ut,v.noConflict=function(){return e._=ge,this},v.noop=Qt,v.now=ir,v.parseInt=lr,v.random=function(n,t,e){var r=null==n,u=null==t;return null==e&&(typeof n=="boolean"&&u?(e=n,n=1):u||typeof t!="boolean"||(e=t,u=true)),r&&u&&(t=1),n=+n||0,u?(t=n,n=0):t=+t||0,e||n%1||t%1?(e=Fe(),Pe(n+e*(t-n+parseFloat("1e-"+((e+"").length-1))),t)):lt(n,t)},v.reduce=Rt,v.reduceRight=Ft,v.result=function(n,t){if(n){var e=n[t]; +return jt(e)?n[t]():e}},v.runInContext=g,v.size=function(n){var t=n?n.length:0;return typeof t=="number"?t:We(n).length},v.some=$t,v.sortedIndex=Kt,v.template=function(n,t,e){var r=v.templateSettings;n=ie(n||""),e=Ze({},e,r);var u,o=Ze({},e.imports,r.imports),r=We(o),o=Et(o),i=0,l=e.interpolate||N,f="__p+='",l=ae((e.escape||N).source+"|"+l.source+"|"+(l===I?O:N).source+"|"+(e.evaluate||N).source+"|$","g");n.replace(l,function(t,e,r,o,l,c){return r||(r=o),f+=n.slice(i,c).replace(P,a),e&&(f+="'+__e("+e+")+'"),l&&(u=true,f+="';"+l+";\n__p+='"),r&&(f+="'+((__t=("+r+"))==null?'':__t)+'"),i=c+t.length,t +}),f+="';",l=e=e.variable,l||(e="obj",f="with("+e+"){"+f+"}"),f=(u?f.replace(x,""):f).replace(C,"$1").replace(E,"$1;"),f="function("+e+"){"+(l?"":e+"||("+e+"={});")+"var __t,__p='',__e=_.escape"+(u?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+f+"return __p}";try{var c=ee(r,"return "+f).apply(h,o)}catch(p){throw p.source=f,p}return t?c(t):(c.source=f,c)},v.unescape=function(n){return null==n?"":ie(n).replace(Ue,mt)},v.uniqueId=function(n){var t=++m;return ie(null==n?"":n)+t +},v.all=St,v.any=$t,v.detect=It,v.findWhere=It,v.foldl=Rt,v.foldr=Ft,v.include=Ot,v.inject=Rt,Ut(function(){var n={};return tr(v,function(t,e){v.prototype[e]||(n[e]=t)}),n}(),false),v.first=Lt,v.last=function(n,t,e){var r=0,u=n?n.length:0;if(typeof t!="number"&&null!=t){var o=u;for(t=v.createCallback(t,e,3);o--&&t(n[o],o,n);)r++}else if(r=t,null==r||e)return n?n[u-1]:h;return s(n,Be(0,u-r))},v.sample=function(n,t,e){return n&&typeof n.length!="number"?n=Et(n):Le.unindexedChars&&kt(n)&&(n=n.split("")),null==t||e?n?n[lt(0,n.length-1)]:h:(n=Tt(n),n.length=Pe(Be(0,t),n.length),n) +},v.take=Lt,v.head=Lt,tr(v,function(n,t){var e="sample"!==t;v.prototype[t]||(v.prototype[t]=function(t,r){var u=this.__chain__,o=n(this.__wrapped__,t,r);return u||null!=t&&(!r||e&&typeof t=="function")?new y(o,u):o})}),v.VERSION="2.4.1",v.prototype.chain=function(){return this.__chain__=true,this},v.prototype.toString=function(){return ie(this.__wrapped__)},v.prototype.value=Yt,v.prototype.valueOf=Yt,Xe(["join","pop","shift"],function(n){var t=fe[n];v.prototype[n]=function(){var n=this.__chain__,e=t.apply(this.__wrapped__,arguments); +return n?new y(e,n):e}}),Xe(["push","reverse","sort","unshift"],function(n){var t=fe[n];v.prototype[n]=function(){return t.apply(this.__wrapped__,arguments),this}}),Xe(["concat","slice","splice"],function(n){var t=fe[n];v.prototype[n]=function(){return new y(t.apply(this.__wrapped__,arguments),this.__chain__)}}),Le.spliceObjects||Xe(["pop","shift","splice"],function(n){var t=fe[n],e="splice"==n;v.prototype[n]=function(){var n=this.__chain__,r=this.__wrapped__,u=t.apply(r,arguments);return 0===r.length&&delete r[0],n||e?new y(u,n):u +}}),v}var h,v=[],y=[],m=0,d={},b=+new Date+"",_=75,w=40,j=" \t\x0B\f\xa0\ufeff\n\r\u2028\u2029\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000",x=/\b__p\+='';/g,C=/\b(__p\+=)''\+/g,E=/(__e\(.*?\)|\b__t\))\+'';/g,O=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,S=/\w*$/,A=/^\s*function[ \n\r\t]+\w/,I=/<%=([\s\S]+?)%>/g,D=RegExp("^["+j+"]*0+(?=.$)"),N=/($^)/,B=/\bthis\b/,P=/['\n\r\t\u2028\u2029\\]/g,R="Array Boolean Date Error Function Math Number Object RegExp String _ attachEvent clearTimeout isFinite isNaN parseInt setTimeout".split(" "),F="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),T="[object Arguments]",$="[object Array]",L="[object Boolean]",z="[object Date]",q="[object Error]",K="[object Function]",W="[object Number]",G="[object Object]",J="[object RegExp]",M="[object String]",V={}; +V[K]=false,V[T]=V[$]=V[L]=V[z]=V[W]=V[G]=V[J]=V[M]=true;var H={leading:false,maxWait:0,trailing:false},U={configurable:false,enumerable:false,value:null,writable:false},Q={a:"",b:null,c:"",d:"",e:"",v:null,g:"",h:null,support:null,i:"",j:false},X={"boolean":false,"function":true,object:true,number:false,string:false,undefined:false},Y={"\\":"\\","'":"'","\n":"n","\r":"r","\t":"t","\u2028":"u2028","\u2029":"u2029"},Z=X[typeof window]&&window||this,nt=X[typeof exports]&&exports&&!exports.nodeType&&exports,tt=X[typeof module]&&module&&!module.nodeType&&module,et=tt&&tt.exports===nt&&nt,rt=X[typeof global]&&global; +!rt||rt.global!==rt&&rt.window!==rt||(Z=rt);var ut=g();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(Z._=ut, define(function(){return ut})):nt&&tt?et?(tt.exports=ut)._=ut:nt._=ut:Z._=ut}).call(this); \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/python/django/renkanmanager/static/renkanmanager/lib/lodash/lodash.js Mon Apr 27 17:22:46 2015 +0200 @@ -0,0 +1,6785 @@ +/** + * @license + * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/> + * Build: `lodash modern -o ./dist/lodash.js` + * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/> + * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE> + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license <http://lodash.com/license> + */ +;(function() { + + /** Used as a safe reference for `undefined` in pre ES5 environments */ + var undefined; + + /** Used to pool arrays and objects used internally */ + var arrayPool = [], + objectPool = []; + + /** Used to generate unique IDs */ + var idCounter = 0; + + /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */ + var keyPrefix = +new Date + ''; + + /** Used as the size when optimizations are enabled for large arrays */ + var largeArraySize = 75; + + /** Used as the max size of the `arrayPool` and `objectPool` */ + var maxPoolSize = 40; + + /** Used to detect and test whitespace */ + var whitespace = ( + // whitespace + ' \t\x0B\f\xA0\ufeff' + + + // line terminators + '\n\r\u2028\u2029' + + + // unicode category "Zs" space separators + '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' + ); + + /** Used to match empty string literals in compiled template source */ + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + + /** + * Used to match ES6 template delimiters + * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals + */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + + /** Used to match regexp flags from their coerced string values */ + var reFlags = /\w*$/; + + /** Used to detected named functions */ + var reFuncName = /^\s*function[ \n\r\t]+\w/; + + /** Used to match "interpolate" template delimiters */ + var reInterpolate = /<%=([\s\S]+?)%>/g; + + /** Used to match leading whitespace and zeros to be removed */ + var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)'); + + /** Used to ensure capturing order of template delimiters */ + var reNoMatch = /($^)/; + + /** Used to detect functions containing a `this` reference */ + var reThis = /\bthis\b/; + + /** Used to match unescaped characters in compiled string literals */ + var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g; + + /** Used to assign default `context` object properties */ + var contextProps = [ + 'Array', 'Boolean', 'Date', 'Function', 'Math', 'Number', 'Object', + 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN', + 'parseInt', 'setTimeout' + ]; + + /** Used to make template sourceURLs easier to identify */ + var templateCounter = 0; + + /** `Object#toString` result shortcuts */ + var argsClass = '[object Arguments]', + arrayClass = '[object Array]', + boolClass = '[object Boolean]', + dateClass = '[object Date]', + funcClass = '[object Function]', + numberClass = '[object Number]', + objectClass = '[object Object]', + regexpClass = '[object RegExp]', + stringClass = '[object String]'; + + /** Used to identify object classifications that `_.clone` supports */ + var cloneableClasses = {}; + cloneableClasses[funcClass] = false; + cloneableClasses[argsClass] = cloneableClasses[arrayClass] = + cloneableClasses[boolClass] = cloneableClasses[dateClass] = + cloneableClasses[numberClass] = cloneableClasses[objectClass] = + cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true; + + /** Used as an internal `_.debounce` options object */ + var debounceOptions = { + 'leading': false, + 'maxWait': 0, + 'trailing': false + }; + + /** Used as the property descriptor for `__bindData__` */ + var descriptor = { + 'configurable': false, + 'enumerable': false, + 'value': null, + 'writable': false + }; + + /** Used to determine if values are of the language type Object */ + var objectTypes = { + 'boolean': false, + 'function': true, + 'object': true, + 'number': false, + 'string': false, + 'undefined': false + }; + + /** Used to escape characters for inclusion in compiled string literals */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\t': 't', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + /** Used as a reference to the global object */ + var root = (objectTypes[typeof window] && window) || this; + + /** Detect free variable `exports` */ + var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; + + /** Detect free variable `module` */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports` */ + var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; + + /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */ + var freeGlobal = objectTypes[typeof global] && global; + if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { + root = freeGlobal; + } + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `_.indexOf` without support for binary searches + * or `fromIndex` constraints. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value or `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + var index = (fromIndex || 0) - 1, + length = array ? array.length : 0; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * An implementation of `_.contains` for cache objects that mimics the return + * signature of `_.indexOf` by returning `0` if the value is found, else `-1`. + * + * @private + * @param {Object} cache The cache object to inspect. + * @param {*} value The value to search for. + * @returns {number} Returns `0` if `value` is found, else `-1`. + */ + function cacheIndexOf(cache, value) { + var type = typeof value; + cache = cache.cache; + + if (type == 'boolean' || value == null) { + return cache[value] ? 0 : -1; + } + if (type != 'number' && type != 'string') { + type = 'object'; + } + var key = type == 'number' ? value : keyPrefix + value; + cache = (cache = cache[type]) && cache[key]; + + return type == 'object' + ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1) + : (cache ? 0 : -1); + } + + /** + * Adds a given value to the corresponding cache object. + * + * @private + * @param {*} value The value to add to the cache. + */ + function cachePush(value) { + var cache = this.cache, + type = typeof value; + + if (type == 'boolean' || value == null) { + cache[value] = true; + } else { + if (type != 'number' && type != 'string') { + type = 'object'; + } + var key = type == 'number' ? value : keyPrefix + value, + typeCache = cache[type] || (cache[type] = {}); + + if (type == 'object') { + (typeCache[key] || (typeCache[key] = [])).push(value); + } else { + typeCache[key] = true; + } + } + } + + /** + * Used by `_.max` and `_.min` as the default callback when a given + * collection is a string value. + * + * @private + * @param {string} value The character to inspect. + * @returns {number} Returns the code unit of given character. + */ + function charAtCallback(value) { + return value.charCodeAt(0); + } + + /** + * Used by `sortBy` to compare transformed `collection` elements, stable sorting + * them in ascending order. + * + * @private + * @param {Object} a The object to compare to `b`. + * @param {Object} b The object to compare to `a`. + * @returns {number} Returns the sort order indicator of `1` or `-1`. + */ + function compareAscending(a, b) { + var ac = a.criteria, + bc = b.criteria, + index = -1, + length = ac.length; + + while (++index < length) { + var value = ac[index], + other = bc[index]; + + if (value !== other) { + if (value > other || typeof value == 'undefined') { + return 1; + } + if (value < other || typeof other == 'undefined') { + return -1; + } + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to return the same value for + // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247 + // + // This also ensures a stable sort in V8 and other engines. + // See http://code.google.com/p/v8/issues/detail?id=90 + return a.index - b.index; + } + + /** + * Creates a cache object to optimize linear searches of large arrays. + * + * @private + * @param {Array} [array=[]] The array to search. + * @returns {null|Object} Returns the cache object or `null` if caching should not be used. + */ + function createCache(array) { + var index = -1, + length = array.length, + first = array[0], + mid = array[(length / 2) | 0], + last = array[length - 1]; + + if (first && typeof first == 'object' && + mid && typeof mid == 'object' && last && typeof last == 'object') { + return false; + } + var cache = getObject(); + cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false; + + var result = getObject(); + result.array = array; + result.cache = cache; + result.push = cachePush; + + while (++index < length) { + result.push(array[index]); + } + return result; + } + + /** + * Used by `template` to escape characters for inclusion in compiled + * string literals. + * + * @private + * @param {string} match The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeStringChar(match) { + return '\\' + stringEscapes[match]; + } + + /** + * Gets an array from the array pool or creates a new one if the pool is empty. + * + * @private + * @returns {Array} The array from the pool. + */ + function getArray() { + return arrayPool.pop() || []; + } + + /** + * Gets an object from the object pool or creates a new one if the pool is empty. + * + * @private + * @returns {Object} The object from the pool. + */ + function getObject() { + return objectPool.pop() || { + 'array': null, + 'cache': null, + 'criteria': null, + 'false': false, + 'index': 0, + 'null': false, + 'number': null, + 'object': null, + 'push': null, + 'string': null, + 'true': false, + 'undefined': false, + 'value': null + }; + } + + /** + * Releases the given array back to the array pool. + * + * @private + * @param {Array} [array] The array to release. + */ + function releaseArray(array) { + array.length = 0; + if (arrayPool.length < maxPoolSize) { + arrayPool.push(array); + } + } + + /** + * Releases the given object back to the object pool. + * + * @private + * @param {Object} [object] The object to release. + */ + function releaseObject(object) { + var cache = object.cache; + if (cache) { + releaseObject(cache); + } + object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null; + if (objectPool.length < maxPoolSize) { + objectPool.push(object); + } + } + + /** + * Slices the `collection` from the `start` index up to, but not including, + * the `end` index. + * + * Note: This function is used instead of `Array#slice` to support node lists + * in IE < 9 and to ensure dense arrays are returned. + * + * @private + * @param {Array|Object|string} collection The collection to slice. + * @param {number} start The start index. + * @param {number} end The end index. + * @returns {Array} Returns the new array. + */ + function slice(array, start, end) { + start || (start = 0); + if (typeof end == 'undefined') { + end = array ? array.length : 0; + } + var index = -1, + length = end - start || 0, + result = Array(length < 0 ? 0 : length); + + while (++index < length) { + result[index] = array[start + index]; + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Create a new `lodash` function using the given context object. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Object} [context=root] The context object. + * @returns {Function} Returns the `lodash` function. + */ + function runInContext(context) { + // Avoid issues with some ES3 environments that attempt to use values, named + // after built-in constructors like `Object`, for the creation of literals. + // ES5 clears this up by stating that literals must use built-in constructors. + // See http://es5.github.io/#x11.1.5. + context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; + + /** Native constructor references */ + var Array = context.Array, + Boolean = context.Boolean, + Date = context.Date, + Function = context.Function, + Math = context.Math, + Number = context.Number, + Object = context.Object, + RegExp = context.RegExp, + String = context.String, + TypeError = context.TypeError; + + /** + * Used for `Array` method references. + * + * Normally `Array.prototype` would suffice, however, using an array literal + * avoids issues in Narwhal. + */ + var arrayRef = []; + + /** Used for native method references */ + var objectProto = Object.prototype; + + /** Used to restore the original `_` reference in `noConflict` */ + var oldDash = context._; + + /** Used to resolve the internal [[Class]] of values */ + var toString = objectProto.toString; + + /** Used to detect if a method is native */ + var reNative = RegExp('^' + + String(toString) + .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + .replace(/toString| for [^\]]+/g, '.*?') + '$' + ); + + /** Native method shortcuts */ + var ceil = Math.ceil, + clearTimeout = context.clearTimeout, + floor = Math.floor, + fnToString = Function.prototype.toString, + getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, + hasOwnProperty = objectProto.hasOwnProperty, + push = arrayRef.push, + setTimeout = context.setTimeout, + splice = arrayRef.splice, + unshift = arrayRef.unshift; + + /** Used to set meta data on functions */ + var defineProperty = (function() { + // IE 8 only accepts DOM elements + try { + var o = {}, + func = isNative(func = Object.defineProperty) && func, + result = func(o, o, o) && func; + } catch(e) { } + return result; + }()); + + /* Native method shortcuts for methods with the same name as other `lodash` methods */ + var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, + nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, + nativeIsFinite = context.isFinite, + nativeIsNaN = context.isNaN, + nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, + nativeMax = Math.max, + nativeMin = Math.min, + nativeParseInt = context.parseInt, + nativeRandom = Math.random; + + /** Used to lookup a built-in constructor by [[Class]] */ + var ctorByClass = {}; + ctorByClass[arrayClass] = Array; + ctorByClass[boolClass] = Boolean; + ctorByClass[dateClass] = Date; + ctorByClass[funcClass] = Function; + ctorByClass[objectClass] = Object; + ctorByClass[numberClass] = Number; + ctorByClass[regexpClass] = RegExp; + ctorByClass[stringClass] = String; + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps the given value to enable intuitive + * method chaining. + * + * In addition to Lo-Dash methods, wrappers also have the following `Array` methods: + * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, + * and `unshift` + * + * Chaining is supported in custom builds as long as the `value` method is + * implicitly or explicitly included in the build. + * + * The chainable wrapper functions are: + * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, + * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`, + * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, + * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, + * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`, + * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, + * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, + * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, + * and `zip` + * + * The non-chainable wrapper functions are: + * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`, + * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, + * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, + * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, + * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`, + * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`, + * `template`, `unescape`, `uniqueId`, and `value` + * + * The wrapper functions `first` and `last` return wrapped values when `n` is + * provided, otherwise they return unwrapped values. + * + * Explicit chaining can be enabled by using the `_.chain` method. + * + * @name _ + * @constructor + * @category Chaining + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns a `lodash` instance. + * @example + * + * var wrapped = _([1, 2, 3]); + * + * // returns an unwrapped value + * wrapped.reduce(function(sum, num) { + * return sum + num; + * }); + * // => 6 + * + * // returns a wrapped value + * var squares = wrapped.map(function(num) { + * return num * num; + * }); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor + return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__')) + ? value + : new lodashWrapper(value); + } + + /** + * A fast path for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap in a `lodash` instance. + * @param {boolean} chainAll A flag to enable chaining for all methods + * @returns {Object} Returns a `lodash` instance. + */ + function lodashWrapper(value, chainAll) { + this.__chain__ = !!chainAll; + this.__wrapped__ = value; + } + // ensure `new lodashWrapper` is an instance of `lodash` + lodashWrapper.prototype = lodash.prototype; + + /** + * An object used to flag environments features. + * + * @static + * @memberOf _ + * @type Object + */ + var support = lodash.support = {}; + + /** + * Detect if functions can be decompiled by `Function#toString` + * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps). + * + * @memberOf _.support + * @type boolean + */ + support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext); + + /** + * Detect if `Function#name` is supported (all but IE). + * + * @memberOf _.support + * @type boolean + */ + support.funcNames = typeof Function.name == 'string'; + + /** + * By default, the template delimiters used by Lo-Dash are similar to those in + * embedded Ruby (ERB). Change the following template settings to use alternative + * delimiters. + * + * @static + * @memberOf _ + * @type Object + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'escape': /<%-([\s\S]+?)%>/g, + + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'evaluate': /<%([\s\S]+?)%>/g, + + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type string + */ + 'variable': '', + + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type Object + */ + 'imports': { + + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type Function + */ + '_': lodash + } + }; + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `_.bind` that creates the bound function and + * sets its meta data. + * + * @private + * @param {Array} bindData The bind data array. + * @returns {Function} Returns the new bound function. + */ + function baseBind(bindData) { + var func = bindData[0], + partialArgs = bindData[2], + thisArg = bindData[4]; + + function bound() { + // `Function#bind` spec + // http://es5.github.io/#x15.3.4.5 + if (partialArgs) { + // avoid `arguments` object deoptimizations by using `slice` instead + // of `Array.prototype.slice.call` and not assigning `arguments` to a + // variable as a ternary expression + var args = slice(partialArgs); + push.apply(args, arguments); + } + // mimic the constructor's `return` behavior + // http://es5.github.io/#x13.2.2 + if (this instanceof bound) { + // ensure `new bound` is an instance of `func` + var thisBinding = baseCreate(func.prototype), + result = func.apply(thisBinding, args || arguments); + return isObject(result) ? result : thisBinding; + } + return func.apply(thisArg, args || arguments); + } + setBindData(bound, bindData); + return bound; + } + + /** + * The base implementation of `_.clone` without argument juggling or support + * for `thisArg` binding. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep=false] Specify a deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates clones with source counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, callback, stackA, stackB) { + if (callback) { + var result = callback(value); + if (typeof result != 'undefined') { + return result; + } + } + // inspect [[Class]] + var isObj = isObject(value); + if (isObj) { + var className = toString.call(value); + if (!cloneableClasses[className]) { + return value; + } + var ctor = ctorByClass[className]; + switch (className) { + case boolClass: + case dateClass: + return new ctor(+value); + + case numberClass: + case stringClass: + return new ctor(value); + + case regexpClass: + result = ctor(value.source, reFlags.exec(value)); + result.lastIndex = value.lastIndex; + return result; + } + } else { + return value; + } + var isArr = isArray(value); + if (isDeep) { + // check for circular references and return corresponding clone + var initedStack = !stackA; + stackA || (stackA = getArray()); + stackB || (stackB = getArray()); + + var length = stackA.length; + while (length--) { + if (stackA[length] == value) { + return stackB[length]; + } + } + result = isArr ? ctor(value.length) : {}; + } + else { + result = isArr ? slice(value) : assign({}, value); + } + // add array properties assigned by `RegExp#exec` + if (isArr) { + if (hasOwnProperty.call(value, 'index')) { + result.index = value.index; + } + if (hasOwnProperty.call(value, 'input')) { + result.input = value.input; + } + } + // exit for shallow clone + if (!isDeep) { + return result; + } + // add the source value to the stack of traversed objects + // and associate it with its clone + stackA.push(value); + stackB.push(result); + + // recursively populate clone (susceptible to call stack limits) + (isArr ? forEach : forOwn)(value, function(objValue, key) { + result[key] = baseClone(objValue, isDeep, callback, stackA, stackB); + }); + + if (initedStack) { + releaseArray(stackA); + releaseArray(stackB); + } + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(prototype, properties) { + return isObject(prototype) ? nativeCreate(prototype) : {}; + } + // fallback for browsers without `Object.create` + if (!nativeCreate) { + baseCreate = (function() { + function Object() {} + return function(prototype) { + if (isObject(prototype)) { + Object.prototype = prototype; + var result = new Object; + Object.prototype = null; + } + return result || context.Object(); + }; + }()); + } + + /** + * The base implementation of `_.createCallback` without support for creating + * "_.pluck" or "_.where" style callbacks. + * + * @private + * @param {*} [func=identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of the created callback. + * @param {number} [argCount] The number of arguments the callback accepts. + * @returns {Function} Returns a callback function. + */ + function baseCreateCallback(func, thisArg, argCount) { + if (typeof func != 'function') { + return identity; + } + // exit early for no `thisArg` or already bound by `Function#bind` + if (typeof thisArg == 'undefined' || !('prototype' in func)) { + return func; + } + var bindData = func.__bindData__; + if (typeof bindData == 'undefined') { + if (support.funcNames) { + bindData = !func.name; + } + bindData = bindData || !support.funcDecomp; + if (!bindData) { + var source = fnToString.call(func); + if (!support.funcNames) { + bindData = !reFuncName.test(source); + } + if (!bindData) { + // checks if `func` references the `this` keyword and stores the result + bindData = reThis.test(source); + setBindData(func, bindData); + } + } + } + // exit early if there are no `this` references or `func` is bound + if (bindData === false || (bindData !== true && bindData[1] & 1)) { + return func; + } + switch (argCount) { + case 1: return function(value) { + return func.call(thisArg, value); + }; + case 2: return function(a, b) { + return func.call(thisArg, a, b); + }; + case 3: return function(value, index, collection) { + return func.call(thisArg, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(thisArg, accumulator, value, index, collection); + }; + } + return bind(func, thisArg); + } + + /** + * The base implementation of `createWrapper` that creates the wrapper and + * sets its meta data. + * + * @private + * @param {Array} bindData The bind data array. + * @returns {Function} Returns the new function. + */ + function baseCreateWrapper(bindData) { + var func = bindData[0], + bitmask = bindData[1], + partialArgs = bindData[2], + partialRightArgs = bindData[3], + thisArg = bindData[4], + arity = bindData[5]; + + var isBind = bitmask & 1, + isBindKey = bitmask & 2, + isCurry = bitmask & 4, + isCurryBound = bitmask & 8, + key = func; + + function bound() { + var thisBinding = isBind ? thisArg : this; + if (partialArgs) { + var args = slice(partialArgs); + push.apply(args, arguments); + } + if (partialRightArgs || isCurry) { + args || (args = slice(arguments)); + if (partialRightArgs) { + push.apply(args, partialRightArgs); + } + if (isCurry && args.length < arity) { + bitmask |= 16 & ~32; + return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]); + } + } + args || (args = arguments); + if (isBindKey) { + func = thisBinding[key]; + } + if (this instanceof bound) { + thisBinding = baseCreate(func.prototype); + var result = func.apply(thisBinding, args); + return isObject(result) ? result : thisBinding; + } + return func.apply(thisBinding, args); + } + setBindData(bound, bindData); + return bound; + } + + /** + * The base implementation of `_.difference` that accepts a single array + * of values to exclude. + * + * @private + * @param {Array} array The array to process. + * @param {Array} [values] The array of values to exclude. + * @returns {Array} Returns a new array of filtered values. + */ + function baseDifference(array, values) { + var index = -1, + indexOf = getIndexOf(), + length = array ? array.length : 0, + isLarge = length >= largeArraySize && indexOf === baseIndexOf, + result = []; + + if (isLarge) { + var cache = createCache(values); + if (cache) { + indexOf = cacheIndexOf; + values = cache; + } else { + isLarge = false; + } + } + while (++index < length) { + var value = array[index]; + if (indexOf(values, value) < 0) { + result.push(value); + } + } + if (isLarge) { + releaseObject(values); + } + return result; + } + + /** + * The base implementation of `_.flatten` without support for callback + * shorthands or `thisArg` binding. + * + * @private + * @param {Array} array The array to flatten. + * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. + * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects. + * @param {number} [fromIndex=0] The index to start from. + * @returns {Array} Returns a new flattened array. + */ + function baseFlatten(array, isShallow, isStrict, fromIndex) { + var index = (fromIndex || 0) - 1, + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + + if (value && typeof value == 'object' && typeof value.length == 'number' + && (isArray(value) || isArguments(value))) { + // recursively flatten arrays (susceptible to call stack limits) + if (!isShallow) { + value = baseFlatten(value, isShallow, isStrict); + } + var valIndex = -1, + valLength = value.length, + resIndex = result.length; + + result.length += valLength; + while (++valIndex < valLength) { + result[resIndex++] = value[valIndex]; + } + } else if (!isStrict) { + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.isEqual`, without support for `thisArg` binding, + * that allows partial "_.where" style comparisons. + * + * @private + * @param {*} a The value to compare. + * @param {*} b The other value to compare. + * @param {Function} [callback] The function to customize comparing values. + * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons. + * @param {Array} [stackA=[]] Tracks traversed `a` objects. + * @param {Array} [stackB=[]] Tracks traversed `b` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(a, b, callback, isWhere, stackA, stackB) { + // used to indicate that when comparing objects, `a` has at least the properties of `b` + if (callback) { + var result = callback(a, b); + if (typeof result != 'undefined') { + return !!result; + } + } + // exit early for identical values + if (a === b) { + // treat `+0` vs. `-0` as not equal + return a !== 0 || (1 / a == 1 / b); + } + var type = typeof a, + otherType = typeof b; + + // exit early for unlike primitive values + if (a === a && + !(a && objectTypes[type]) && + !(b && objectTypes[otherType])) { + return false; + } + // exit early for `null` and `undefined` avoiding ES3's Function#call behavior + // http://es5.github.io/#x15.3.4.4 + if (a == null || b == null) { + return a === b; + } + // compare [[Class]] names + var className = toString.call(a), + otherClass = toString.call(b); + + if (className == argsClass) { + className = objectClass; + } + if (otherClass == argsClass) { + otherClass = objectClass; + } + if (className != otherClass) { + return false; + } + switch (className) { + case boolClass: + case dateClass: + // coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal + return +a == +b; + + case numberClass: + // treat `NaN` vs. `NaN` as equal + return (a != +a) + ? b != +b + // but treat `+0` vs. `-0` as not equal + : (a == 0 ? (1 / a == 1 / b) : a == +b); + + case regexpClass: + case stringClass: + // coerce regexes to strings (http://es5.github.io/#x15.10.6.4) + // treat string primitives and their corresponding object instances as equal + return a == String(b); + } + var isArr = className == arrayClass; + if (!isArr) { + // unwrap any `lodash` wrapped values + var aWrapped = hasOwnProperty.call(a, '__wrapped__'), + bWrapped = hasOwnProperty.call(b, '__wrapped__'); + + if (aWrapped || bWrapped) { + return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB); + } + // exit for functions and DOM nodes + if (className != objectClass) { + return false; + } + // in older versions of Opera, `arguments` objects have `Array` constructors + var ctorA = a.constructor, + ctorB = b.constructor; + + // non `Object` object instances with different constructors are not equal + if (ctorA != ctorB && + !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && + ('constructor' in a && 'constructor' in b) + ) { + return false; + } + } + // assume cyclic structures are equal + // the algorithm for detecting cyclic structures is adapted from ES 5.1 + // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3) + var initedStack = !stackA; + stackA || (stackA = getArray()); + stackB || (stackB = getArray()); + + var length = stackA.length; + while (length--) { + if (stackA[length] == a) { + return stackB[length] == b; + } + } + var size = 0; + result = true; + + // add `a` and `b` to the stack of traversed objects + stackA.push(a); + stackB.push(b); + + // recursively compare objects and arrays (susceptible to call stack limits) + if (isArr) { + // compare lengths to determine if a deep comparison is necessary + length = a.length; + size = b.length; + result = size == length; + + if (result || isWhere) { + // deep compare the contents, ignoring non-numeric properties + while (size--) { + var index = length, + value = b[size]; + + if (isWhere) { + while (index--) { + if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) { + break; + } + } + } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) { + break; + } + } + } + } + else { + // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` + // which, in this case, is more costly + forIn(b, function(value, key, b) { + if (hasOwnProperty.call(b, key)) { + // count the number of properties. + size++; + // deep compare each property value. + return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB)); + } + }); + + if (result && !isWhere) { + // ensure both objects have the same number of properties + forIn(a, function(value, key, a) { + if (hasOwnProperty.call(a, key)) { + // `size` will be `-1` if `a` has more properties than `b` + return (result = --size > -1); + } + }); + } + } + stackA.pop(); + stackB.pop(); + + if (initedStack) { + releaseArray(stackA); + releaseArray(stackB); + } + return result; + } + + /** + * The base implementation of `_.merge` without argument juggling or support + * for `thisArg` binding. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} [callback] The function to customize merging properties. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + */ + function baseMerge(object, source, callback, stackA, stackB) { + (isArray(source) ? forEach : forOwn)(source, function(source, key) { + var found, + isArr, + result = source, + value = object[key]; + + if (source && ((isArr = isArray(source)) || isPlainObject(source))) { + // avoid merging previously merged cyclic sources + var stackLength = stackA.length; + while (stackLength--) { + if ((found = stackA[stackLength] == source)) { + value = stackB[stackLength]; + break; + } + } + if (!found) { + var isShallow; + if (callback) { + result = callback(value, source); + if ((isShallow = typeof result != 'undefined')) { + value = result; + } + } + if (!isShallow) { + value = isArr + ? (isArray(value) ? value : []) + : (isPlainObject(value) ? value : {}); + } + // add `source` and associated `value` to the stack of traversed objects + stackA.push(source); + stackB.push(value); + + // recursively merge objects and arrays (susceptible to call stack limits) + if (!isShallow) { + baseMerge(value, source, callback, stackA, stackB); + } + } + } + else { + if (callback) { + result = callback(value, source); + if (typeof result == 'undefined') { + result = source; + } + } + if (typeof result != 'undefined') { + value = result; + } + } + object[key] = value; + }); + } + + /** + * The base implementation of `_.random` without argument juggling or support + * for returning floating-point numbers. + * + * @private + * @param {number} min The minimum possible value. + * @param {number} max The maximum possible value. + * @returns {number} Returns a random number. + */ + function baseRandom(min, max) { + return min + floor(nativeRandom() * (max - min + 1)); + } + + /** + * The base implementation of `_.uniq` without support for callback shorthands + * or `thisArg` binding. + * + * @private + * @param {Array} array The array to process. + * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. + * @param {Function} [callback] The function called per iteration. + * @returns {Array} Returns a duplicate-value-free array. + */ + function baseUniq(array, isSorted, callback) { + var index = -1, + indexOf = getIndexOf(), + length = array ? array.length : 0, + result = []; + + var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf, + seen = (callback || isLarge) ? getArray() : result; + + if (isLarge) { + var cache = createCache(seen); + indexOf = cacheIndexOf; + seen = cache; + } + while (++index < length) { + var value = array[index], + computed = callback ? callback(value, index, array) : value; + + if (isSorted + ? !index || seen[seen.length - 1] !== computed + : indexOf(seen, computed) < 0 + ) { + if (callback || isLarge) { + seen.push(computed); + } + result.push(value); + } + } + if (isLarge) { + releaseArray(seen.array); + releaseObject(seen); + } else if (callback) { + releaseArray(seen); + } + return result; + } + + /** + * Creates a function that aggregates a collection, creating an object composed + * of keys generated from the results of running each element of the collection + * through a callback. The given `setter` function sets the keys and values + * of the composed object. + * + * @private + * @param {Function} setter The setter function. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter) { + return function(collection, callback, thisArg) { + var result = {}; + callback = lodash.createCallback(callback, thisArg, 3); + + var index = -1, + length = collection ? collection.length : 0; + + if (typeof length == 'number') { + while (++index < length) { + var value = collection[index]; + setter(result, value, callback(value, index, collection), collection); + } + } else { + forOwn(collection, function(value, key, collection) { + setter(result, value, callback(value, key, collection), collection); + }); + } + return result; + }; + } + + /** + * Creates a function that, when called, either curries or invokes `func` + * with an optional `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of method flags to compose. + * The bitmask may be composed of the following flags: + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` + * 8 - `_.curry` (bound) + * 16 - `_.partial` + * 32 - `_.partialRight` + * @param {Array} [partialArgs] An array of arguments to prepend to those + * provided to the new function. + * @param {Array} [partialRightArgs] An array of arguments to append to those + * provided to the new function. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new function. + */ + function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) { + var isBind = bitmask & 1, + isBindKey = bitmask & 2, + isCurry = bitmask & 4, + isCurryBound = bitmask & 8, + isPartial = bitmask & 16, + isPartialRight = bitmask & 32; + + if (!isBindKey && !isFunction(func)) { + throw new TypeError; + } + if (isPartial && !partialArgs.length) { + bitmask &= ~16; + isPartial = partialArgs = false; + } + if (isPartialRight && !partialRightArgs.length) { + bitmask &= ~32; + isPartialRight = partialRightArgs = false; + } + var bindData = func && func.__bindData__; + if (bindData && bindData !== true) { + // clone `bindData` + bindData = slice(bindData); + if (bindData[2]) { + bindData[2] = slice(bindData[2]); + } + if (bindData[3]) { + bindData[3] = slice(bindData[3]); + } + // set `thisBinding` is not previously bound + if (isBind && !(bindData[1] & 1)) { + bindData[4] = thisArg; + } + // set if previously bound but not currently (subsequent curried functions) + if (!isBind && bindData[1] & 1) { + bitmask |= 8; + } + // set curried arity if not yet set + if (isCurry && !(bindData[1] & 4)) { + bindData[5] = arity; + } + // append partial left arguments + if (isPartial) { + push.apply(bindData[2] || (bindData[2] = []), partialArgs); + } + // append partial right arguments + if (isPartialRight) { + unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs); + } + // merge flags + bindData[1] |= bitmask; + return createWrapper.apply(null, bindData); + } + // fast path for `_.bind` + var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper; + return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]); + } + + /** + * Used by `escape` to convert characters to HTML entities. + * + * @private + * @param {string} match The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeHtmlChar(match) { + return htmlEscapes[match]; + } + + /** + * Gets the appropriate "indexOf" function. If the `_.indexOf` method is + * customized, this method returns the custom method, otherwise it returns + * the `baseIndexOf` function. + * + * @private + * @returns {Function} Returns the "indexOf" function. + */ + function getIndexOf() { + var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result; + return result; + } + + /** + * Checks if `value` is a native function. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a native function, else `false`. + */ + function isNative(value) { + return typeof value == 'function' && reNative.test(value); + } + + /** + * Sets `this` binding data on a given function. + * + * @private + * @param {Function} func The function to set data on. + * @param {Array} value The data array to set. + */ + var setBindData = !defineProperty ? noop : function(func, value) { + descriptor.value = value; + defineProperty(func, '__bindData__', descriptor); + }; + + /** + * A fallback implementation of `isPlainObject` which checks if a given value + * is an object created by the `Object` constructor, assuming objects created + * by the `Object` constructor have no inherited enumerable properties and that + * there are no `Object.prototype` extensions. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + */ + function shimIsPlainObject(value) { + var ctor, + result; + + // avoid non Object objects, `arguments` objects, and DOM elements + if (!(value && toString.call(value) == objectClass) || + (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor))) { + return false; + } + // In most environments an object's own properties are iterated before + // its inherited properties. If the last iterated property is an object's + // own property then there are no inherited enumerable properties. + forIn(value, function(value, key) { + result = key; + }); + return typeof result == 'undefined' || hasOwnProperty.call(value, result); + } + + /** + * Used by `unescape` to convert HTML entities to characters. + * + * @private + * @param {string} match The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + function unescapeHtmlChar(match) { + return htmlUnescapes[match]; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Checks if `value` is an `arguments` object. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`. + * @example + * + * (function() { return _.isArguments(arguments); })(1, 2, 3); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + toString.call(value) == argsClass || false; + } + + /** + * Checks if `value` is an array. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an array, else `false`. + * @example + * + * (function() { return _.isArray(arguments); })(); + * // => false + * + * _.isArray([1, 2, 3]); + * // => true + */ + var isArray = nativeIsArray || function(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + toString.call(value) == arrayClass || false; + }; + + /** + * A fallback implementation of `Object.keys` which produces an array of the + * given object's own enumerable property names. + * + * @private + * @type Function + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names. + */ + var shimKeys = function(object) { + var index, iterable = object, result = []; + if (!iterable) return result; + if (!(objectTypes[typeof object])) return result; + for (index in iterable) { + if (hasOwnProperty.call(iterable, index)) { + result.push(index); + } + } + return result + }; + + /** + * Creates an array composed of the own enumerable property names of an object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names. + * @example + * + * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); + * // => ['one', 'two', 'three'] (property order is not guaranteed across environments) + */ + var keys = !nativeKeys ? shimKeys : function(object) { + if (!isObject(object)) { + return []; + } + return nativeKeys(object); + }; + + /** + * Used to convert characters to HTML entities: + * + * Though the `>` character is escaped for symmetry, characters like `>` and `/` + * don't require escaping in HTML and have no special meaning unless they're part + * of a tag or an unquoted attribute value. + * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact") + */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + + /** Used to convert HTML entities to characters */ + var htmlUnescapes = invert(htmlEscapes); + + /** Used to match HTML entities and HTML characters */ + var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'), + reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g'); + + /*--------------------------------------------------------------------------*/ + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object. Subsequent sources will overwrite property assignments of previous + * sources. If a callback is provided it will be executed to produce the + * assigned values. The callback is bound to `thisArg` and invoked with two + * arguments; (objectValue, sourceValue). + * + * @static + * @memberOf _ + * @type Function + * @alias extend + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param {Function} [callback] The function to customize assigning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the destination object. + * @example + * + * _.assign({ 'name': 'fred' }, { 'employer': 'slate' }); + * // => { 'name': 'fred', 'employer': 'slate' } + * + * var defaults = _.partialRight(_.assign, function(a, b) { + * return typeof a == 'undefined' ? b : a; + * }); + * + * var object = { 'name': 'barney' }; + * defaults(object, { 'name': 'fred', 'employer': 'slate' }); + * // => { 'name': 'barney', 'employer': 'slate' } + */ + var assign = function(object, source, guard) { + var index, iterable = object, result = iterable; + if (!iterable) return result; + var args = arguments, + argsIndex = 0, + argsLength = typeof guard == 'number' ? 2 : args.length; + if (argsLength > 3 && typeof args[argsLength - 2] == 'function') { + var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2); + } else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') { + callback = args[--argsLength]; + } + while (++argsIndex < argsLength) { + iterable = args[argsIndex]; + if (iterable && objectTypes[typeof iterable]) { + var ownIndex = -1, + ownProps = objectTypes[typeof iterable] && keys(iterable), + length = ownProps ? ownProps.length : 0; + + while (++ownIndex < length) { + index = ownProps[ownIndex]; + result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]; + } + } + } + return result + }; + + /** + * Creates a clone of `value`. If `isDeep` is `true` nested objects will also + * be cloned, otherwise they will be assigned by reference. If a callback + * is provided it will be executed to produce the cloned values. If the + * callback returns `undefined` cloning will be handled by the method instead. + * The callback is bound to `thisArg` and invoked with one argument; (value). + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to clone. + * @param {boolean} [isDeep=false] Specify a deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the cloned value. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * var shallow = _.clone(characters); + * shallow[0] === characters[0]; + * // => true + * + * var deep = _.clone(characters, true); + * deep[0] === characters[0]; + * // => false + * + * _.mixin({ + * 'clone': _.partialRight(_.clone, function(value) { + * return _.isElement(value) ? value.cloneNode(false) : undefined; + * }) + * }); + * + * var clone = _.clone(document.body); + * clone.childNodes.length; + * // => 0 + */ + function clone(value, isDeep, callback, thisArg) { + // allows working with "Collections" methods without using their `index` + // and `collection` arguments for `isDeep` and `callback` + if (typeof isDeep != 'boolean' && isDeep != null) { + thisArg = callback; + callback = isDeep; + isDeep = false; + } + return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); + } + + /** + * Creates a deep clone of `value`. If a callback is provided it will be + * executed to produce the cloned values. If the callback returns `undefined` + * cloning will be handled by the method instead. The callback is bound to + * `thisArg` and invoked with one argument; (value). + * + * Note: This method is loosely based on the structured clone algorithm. Functions + * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and + * objects created by constructors other than `Object` are cloned to plain `Object` objects. + * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the deep cloned value. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * var deep = _.cloneDeep(characters); + * deep[0] === characters[0]; + * // => false + * + * var view = { + * 'label': 'docs', + * 'node': element + * }; + * + * var clone = _.cloneDeep(view, function(value) { + * return _.isElement(value) ? value.cloneNode(true) : undefined; + * }); + * + * clone.node == view.node; + * // => false + */ + function cloneDeep(value, callback, thisArg) { + return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); + } + + /** + * Creates an object that inherits from the given `prototype` object. If a + * `properties` object is provided its own enumerable properties are assigned + * to the created object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties) { + var result = baseCreate(prototype); + return properties ? assign(result, properties) : result; + } + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object for all destination properties that resolve to `undefined`. Once a + * property is set, additional defaults of the same property will be ignored. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param- {Object} [guard] Allows working with `_.reduce` without using its + * `key` and `object` arguments as sources. + * @returns {Object} Returns the destination object. + * @example + * + * var object = { 'name': 'barney' }; + * _.defaults(object, { 'name': 'fred', 'employer': 'slate' }); + * // => { 'name': 'barney', 'employer': 'slate' } + */ + var defaults = function(object, source, guard) { + var index, iterable = object, result = iterable; + if (!iterable) return result; + var args = arguments, + argsIndex = 0, + argsLength = typeof guard == 'number' ? 2 : args.length; + while (++argsIndex < argsLength) { + iterable = args[argsIndex]; + if (iterable && objectTypes[typeof iterable]) { + var ownIndex = -1, + ownProps = objectTypes[typeof iterable] && keys(iterable), + length = ownProps ? ownProps.length : 0; + + while (++ownIndex < length) { + index = ownProps[ownIndex]; + if (typeof result[index] == 'undefined') result[index] = iterable[index]; + } + } + } + return result + }; + + /** + * This method is like `_.findIndex` except that it returns the key of the + * first element that passes the callback check, instead of the element itself. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to search. + * @param {Function|Object|string} [callback=identity] The function called per + * iteration. If a property name or object is provided it will be used to + * create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {string|undefined} Returns the key of the found element, else `undefined`. + * @example + * + * var characters = { + * 'barney': { 'age': 36, 'blocked': false }, + * 'fred': { 'age': 40, 'blocked': true }, + * 'pebbles': { 'age': 1, 'blocked': false } + * }; + * + * _.findKey(characters, function(chr) { + * return chr.age < 40; + * }); + * // => 'barney' (property order is not guaranteed across environments) + * + * // using "_.where" callback shorthand + * _.findKey(characters, { 'age': 1 }); + * // => 'pebbles' + * + * // using "_.pluck" callback shorthand + * _.findKey(characters, 'blocked'); + * // => 'fred' + */ + function findKey(object, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forOwn(object, function(value, key, object) { + if (callback(value, key, object)) { + result = key; + return false; + } + }); + return result; + } + + /** + * This method is like `_.findKey` except that it iterates over elements + * of a `collection` in the opposite order. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to search. + * @param {Function|Object|string} [callback=identity] The function called per + * iteration. If a property name or object is provided it will be used to + * create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {string|undefined} Returns the key of the found element, else `undefined`. + * @example + * + * var characters = { + * 'barney': { 'age': 36, 'blocked': true }, + * 'fred': { 'age': 40, 'blocked': false }, + * 'pebbles': { 'age': 1, 'blocked': true } + * }; + * + * _.findLastKey(characters, function(chr) { + * return chr.age < 40; + * }); + * // => returns `pebbles`, assuming `_.findKey` returns `barney` + * + * // using "_.where" callback shorthand + * _.findLastKey(characters, { 'age': 40 }); + * // => 'fred' + * + * // using "_.pluck" callback shorthand + * _.findLastKey(characters, 'blocked'); + * // => 'pebbles' + */ + function findLastKey(object, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forOwnRight(object, function(value, key, object) { + if (callback(value, key, object)) { + result = key; + return false; + } + }); + return result; + } + + /** + * Iterates over own and inherited enumerable properties of an object, + * executing the callback for each property. The callback is bound to `thisArg` + * and invoked with three arguments; (value, key, object). Callbacks may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * Shape.prototype.move = function(x, y) { + * this.x += x; + * this.y += y; + * }; + * + * _.forIn(new Shape, function(value, key) { + * console.log(key); + * }); + * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments) + */ + var forIn = function(collection, callback, thisArg) { + var index, iterable = collection, result = iterable; + if (!iterable) return result; + if (!objectTypes[typeof iterable]) return result; + callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); + for (index in iterable) { + if (callback(iterable[index], index, collection) === false) return result; + } + return result + }; + + /** + * This method is like `_.forIn` except that it iterates over elements + * of a `collection` in the opposite order. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * Shape.prototype.move = function(x, y) { + * this.x += x; + * this.y += y; + * }; + * + * _.forInRight(new Shape, function(value, key) { + * console.log(key); + * }); + * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move' + */ + function forInRight(object, callback, thisArg) { + var pairs = []; + + forIn(object, function(value, key) { + pairs.push(key, value); + }); + + var length = pairs.length; + callback = baseCreateCallback(callback, thisArg, 3); + while (length--) { + if (callback(pairs[length--], pairs[length], object) === false) { + break; + } + } + return object; + } + + /** + * Iterates over own enumerable properties of an object, executing the callback + * for each property. The callback is bound to `thisArg` and invoked with three + * arguments; (value, key, object). Callbacks may exit iteration early by + * explicitly returning `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { + * console.log(key); + * }); + * // => logs '0', '1', and 'length' (property order is not guaranteed across environments) + */ + var forOwn = function(collection, callback, thisArg) { + var index, iterable = collection, result = iterable; + if (!iterable) return result; + if (!objectTypes[typeof iterable]) return result; + callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); + var ownIndex = -1, + ownProps = objectTypes[typeof iterable] && keys(iterable), + length = ownProps ? ownProps.length : 0; + + while (++ownIndex < length) { + index = ownProps[ownIndex]; + if (callback(iterable[index], index, collection) === false) return result; + } + return result + }; + + /** + * This method is like `_.forOwn` except that it iterates over elements + * of a `collection` in the opposite order. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { + * console.log(key); + * }); + * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length' + */ + function forOwnRight(object, callback, thisArg) { + var props = keys(object), + length = props.length; + + callback = baseCreateCallback(callback, thisArg, 3); + while (length--) { + var key = props[length]; + if (callback(object[key], key, object) === false) { + break; + } + } + return object; + } + + /** + * Creates a sorted array of property names of all enumerable properties, + * own and inherited, of `object` that have function values. + * + * @static + * @memberOf _ + * @alias methods + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names that have function values. + * @example + * + * _.functions(_); + * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] + */ + function functions(object) { + var result = []; + forIn(object, function(value, key) { + if (isFunction(value)) { + result.push(key); + } + }); + return result.sort(); + } + + /** + * Checks if the specified property name exists as a direct property of `object`, + * instead of an inherited property. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @param {string} key The name of the property to check. + * @returns {boolean} Returns `true` if key is a direct property, else `false`. + * @example + * + * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); + * // => true + */ + function has(object, key) { + return object ? hasOwnProperty.call(object, key) : false; + } + + /** + * Creates an object composed of the inverted keys and values of the given object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to invert. + * @returns {Object} Returns the created inverted object. + * @example + * + * _.invert({ 'first': 'fred', 'second': 'barney' }); + * // => { 'fred': 'first', 'barney': 'second' } + */ + function invert(object) { + var index = -1, + props = keys(object), + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index]; + result[object[key]] = key; + } + return result; + } + + /** + * Checks if `value` is a boolean value. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`. + * @example + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + value && typeof value == 'object' && toString.call(value) == boolClass || false; + } + + /** + * Checks if `value` is a date. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a date, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + */ + function isDate(value) { + return value && typeof value == 'object' && toString.call(value) == dateClass || false; + } + + /** + * Checks if `value` is a DOM element. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + */ + function isElement(value) { + return value && value.nodeType === 1 || false; + } + + /** + * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a + * length of `0` and objects with no own enumerable properties are considered + * "empty". + * + * @static + * @memberOf _ + * @category Objects + * @param {Array|Object|string} value The value to inspect. + * @returns {boolean} Returns `true` if the `value` is empty, else `false`. + * @example + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({}); + * // => true + * + * _.isEmpty(''); + * // => true + */ + function isEmpty(value) { + var result = true; + if (!value) { + return result; + } + var className = toString.call(value), + length = value.length; + + if ((className == arrayClass || className == stringClass || className == argsClass ) || + (className == objectClass && typeof length == 'number' && isFunction(value.splice))) { + return !length; + } + forOwn(value, function() { + return (result = false); + }); + return result; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent to each other. If a callback is provided it will be executed + * to compare values. If the callback returns `undefined` comparisons will + * be handled by the method instead. The callback is bound to `thisArg` and + * invoked with two arguments; (a, b). + * + * @static + * @memberOf _ + * @category Objects + * @param {*} a The value to compare. + * @param {*} b The other value to compare. + * @param {Function} [callback] The function to customize comparing values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'name': 'fred' }; + * var copy = { 'name': 'fred' }; + * + * object == copy; + * // => false + * + * _.isEqual(object, copy); + * // => true + * + * var words = ['hello', 'goodbye']; + * var otherWords = ['hi', 'goodbye']; + * + * _.isEqual(words, otherWords, function(a, b) { + * var reGreet = /^(?:hello|hi)$/i, + * aGreet = _.isString(a) && reGreet.test(a), + * bGreet = _.isString(b) && reGreet.test(b); + * + * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined; + * }); + * // => true + */ + function isEqual(a, b, callback, thisArg) { + return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2)); + } + + /** + * Checks if `value` is, or can be coerced to, a finite number. + * + * Note: This is not the same as native `isFinite` which will return true for + * booleans and empty strings. See http://es5.github.io/#x15.1.2.5. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is finite, else `false`. + * @example + * + * _.isFinite(-101); + * // => true + * + * _.isFinite('10'); + * // => true + * + * _.isFinite(true); + * // => false + * + * _.isFinite(''); + * // => false + * + * _.isFinite(Infinity); + * // => false + */ + function isFinite(value) { + return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); + } + + /** + * Checks if `value` is a function. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + */ + function isFunction(value) { + return typeof value == 'function'; + } + + /** + * Checks if `value` is the language type of Object. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ + function isObject(value) { + // check if the value is the ECMAScript language type of Object + // http://es5.github.io/#x8 + // and avoid a V8 bug + // http://code.google.com/p/v8/issues/detail?id=2291 + return !!(value && objectTypes[typeof value]); + } + + /** + * Checks if `value` is `NaN`. + * + * Note: This is not the same as native `isNaN` which will return `true` for + * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // `NaN` as a primitive is the only value that is not equal to itself + // (perform the [[Class]] check first to avoid errors with some host objects in IE) + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(undefined); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is a number. + * + * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a number, else `false`. + * @example + * + * _.isNumber(8.4 * 5); + * // => true + */ + function isNumber(value) { + return typeof value == 'number' || + value && typeof value == 'object' && toString.call(value) == numberClass || false; + } + + /** + * Checks if `value` is an object created by the `Object` constructor. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * _.isPlainObject(new Shape); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + */ + var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { + if (!(value && toString.call(value) == objectClass)) { + return false; + } + var valueOf = value.valueOf, + objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); + + return objProto + ? (value == objProto || getPrototypeOf(value) == objProto) + : shimIsPlainObject(value); + }; + + /** + * Checks if `value` is a regular expression. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`. + * @example + * + * _.isRegExp(/fred/); + * // => true + */ + function isRegExp(value) { + return value && typeof value == 'object' && toString.call(value) == regexpClass || false; + } + + /** + * Checks if `value` is a string. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a string, else `false`. + * @example + * + * _.isString('fred'); + * // => true + */ + function isString(value) { + return typeof value == 'string' || + value && typeof value == 'object' && toString.call(value) == stringClass || false; + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + */ + function isUndefined(value) { + return typeof value == 'undefined'; + } + + /** + * Creates an object with the same keys as `object` and values generated by + * running each own enumerable property of `object` through the callback. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new object with values of the results of each `callback` execution. + * @example + * + * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; }); + * // => { 'a': 3, 'b': 6, 'c': 9 } + * + * var characters = { + * 'fred': { 'name': 'fred', 'age': 40 }, + * 'pebbles': { 'name': 'pebbles', 'age': 1 } + * }; + * + * // using "_.pluck" callback shorthand + * _.mapValues(characters, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } + */ + function mapValues(object, callback, thisArg) { + var result = {}; + callback = lodash.createCallback(callback, thisArg, 3); + + forOwn(object, function(value, key, object) { + result[key] = callback(value, key, object); + }); + return result; + } + + /** + * Recursively merges own enumerable properties of the source object(s), that + * don't resolve to `undefined` into the destination object. Subsequent sources + * will overwrite property assignments of previous sources. If a callback is + * provided it will be executed to produce the merged values of the destination + * and source properties. If the callback returns `undefined` merging will + * be handled by the method instead. The callback is bound to `thisArg` and + * invoked with two arguments; (objectValue, sourceValue). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param {Function} [callback] The function to customize merging properties. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the destination object. + * @example + * + * var names = { + * 'characters': [ + * { 'name': 'barney' }, + * { 'name': 'fred' } + * ] + * }; + * + * var ages = { + * 'characters': [ + * { 'age': 36 }, + * { 'age': 40 } + * ] + * }; + * + * _.merge(names, ages); + * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] } + * + * var food = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var otherFood = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.merge(food, otherFood, function(a, b) { + * return _.isArray(a) ? a.concat(b) : undefined; + * }); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] } + */ + function merge(object) { + var args = arguments, + length = 2; + + if (!isObject(object)) { + return object; + } + // allows working with `_.reduce` and `_.reduceRight` without using + // their `index` and `collection` arguments + if (typeof args[2] != 'number') { + length = args.length; + } + if (length > 3 && typeof args[length - 2] == 'function') { + var callback = baseCreateCallback(args[--length - 1], args[length--], 2); + } else if (length > 2 && typeof args[length - 1] == 'function') { + callback = args[--length]; + } + var sources = slice(arguments, 1, length), + index = -1, + stackA = getArray(), + stackB = getArray(); + + while (++index < length) { + baseMerge(object, sources[index], callback, stackA, stackB); + } + releaseArray(stackA); + releaseArray(stackB); + return object; + } + + /** + * Creates a shallow clone of `object` excluding the specified properties. + * Property names may be specified as individual arguments or as arrays of + * property names. If a callback is provided it will be executed for each + * property of `object` omitting the properties the callback returns truey + * for. The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Function|...string|string[]} [callback] The properties to omit or the + * function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object without the omitted properties. + * @example + * + * _.omit({ 'name': 'fred', 'age': 40 }, 'age'); + * // => { 'name': 'fred' } + * + * _.omit({ 'name': 'fred', 'age': 40 }, function(value) { + * return typeof value == 'number'; + * }); + * // => { 'name': 'fred' } + */ + function omit(object, callback, thisArg) { + var result = {}; + if (typeof callback != 'function') { + var props = []; + forIn(object, function(value, key) { + props.push(key); + }); + props = baseDifference(props, baseFlatten(arguments, true, false, 1)); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + result[key] = object[key]; + } + } else { + callback = lodash.createCallback(callback, thisArg, 3); + forIn(object, function(value, key, object) { + if (!callback(value, key, object)) { + result[key] = value; + } + }); + } + return result; + } + + /** + * Creates a two dimensional array of an object's key-value pairs, + * i.e. `[[key1, value1], [key2, value2]]`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns new array of key-value pairs. + * @example + * + * _.pairs({ 'barney': 36, 'fred': 40 }); + * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments) + */ + function pairs(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + var key = props[index]; + result[index] = [key, object[key]]; + } + return result; + } + + /** + * Creates a shallow clone of `object` composed of the specified properties. + * Property names may be specified as individual arguments or as arrays of + * property names. If a callback is provided it will be executed for each + * property of `object` picking the properties the callback returns truey + * for. The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Function|...string|string[]} [callback] The function called per + * iteration or property names to pick, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object composed of the picked properties. + * @example + * + * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); + * // => { 'name': 'fred' } + * + * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { + * return key.charAt(0) != '_'; + * }); + * // => { 'name': 'fred' } + */ + function pick(object, callback, thisArg) { + var result = {}; + if (typeof callback != 'function') { + var index = -1, + props = baseFlatten(arguments, true, false, 1), + length = isObject(object) ? props.length : 0; + + while (++index < length) { + var key = props[index]; + if (key in object) { + result[key] = object[key]; + } + } + } else { + callback = lodash.createCallback(callback, thisArg, 3); + forIn(object, function(value, key, object) { + if (callback(value, key, object)) { + result[key] = value; + } + }); + } + return result; + } + + /** + * An alternative to `_.reduce` this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own + * enumerable properties through a callback, with each callback execution + * potentially mutating the `accumulator` object. The callback is bound to + * `thisArg` and invoked with four arguments; (accumulator, value, key, object). + * Callbacks may exit iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Array|Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) { + * num *= num; + * if (num % 2) { + * return result.push(num) < 3; + * } + * }); + * // => [1, 9, 25] + * + * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { + * result[key] = num * 3; + * }); + * // => { 'a': 3, 'b': 6, 'c': 9 } + */ + function transform(object, callback, accumulator, thisArg) { + var isArr = isArray(object); + if (accumulator == null) { + if (isArr) { + accumulator = []; + } else { + var ctor = object && object.constructor, + proto = ctor && ctor.prototype; + + accumulator = baseCreate(proto); + } + } + if (callback) { + callback = lodash.createCallback(callback, thisArg, 4); + (isArr ? forEach : forOwn)(object, function(value, index, object) { + return callback(accumulator, value, index, object); + }); + } + return accumulator; + } + + /** + * Creates an array composed of the own enumerable property values of `object`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property values. + * @example + * + * _.values({ 'one': 1, 'two': 2, 'three': 3 }); + * // => [1, 2, 3] (property order is not guaranteed across environments) + */ + function values(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + result[index] = object[props[index]]; + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates an array of elements from the specified indexes, or keys, of the + * `collection`. Indexes may be specified as individual arguments or as arrays + * of indexes. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(number|number[]|string|string[])} [index] The indexes of `collection` + * to retrieve, specified as individual indexes or arrays of indexes. + * @returns {Array} Returns a new array of elements corresponding to the + * provided indexes. + * @example + * + * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]); + * // => ['a', 'c', 'e'] + * + * _.at(['fred', 'barney', 'pebbles'], 0, 2); + * // => ['fred', 'pebbles'] + */ + function at(collection) { + var args = arguments, + index = -1, + props = baseFlatten(args, true, false, 1), + length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length, + result = Array(length); + + while(++index < length) { + result[index] = collection[props[index]]; + } + return result; + } + + /** + * Checks if a given value is present in a collection using strict equality + * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the + * offset from the end of the collection. + * + * @static + * @memberOf _ + * @alias include + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {*} target The value to check for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {boolean} Returns `true` if the `target` element is found, else `false`. + * @example + * + * _.contains([1, 2, 3], 1); + * // => true + * + * _.contains([1, 2, 3], 1, 2); + * // => false + * + * _.contains({ 'name': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.contains('pebbles', 'eb'); + * // => true + */ + function contains(collection, target, fromIndex) { + var index = -1, + indexOf = getIndexOf(), + length = collection ? collection.length : 0, + result = false; + + fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0; + if (isArray(collection)) { + result = indexOf(collection, target, fromIndex) > -1; + } else if (typeof length == 'number') { + result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1; + } else { + forOwn(collection, function(value) { + if (++index >= fromIndex) { + return !(result = value === target); + } + }); + } + return result; + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through the callback. The corresponding value + * of each key is the number of times the key was returned by the callback. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); }); + * // => { '4': 1, '6': 2 } + * + * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + var countBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); + }); + + /** + * Checks if the given callback returns truey value for **all** elements of + * a collection. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias all + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if all elements passed the callback check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes']); + * // => false + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.every(characters, 'age'); + * // => true + * + * // using "_.where" callback shorthand + * _.every(characters, { 'age': 36 }); + * // => false + */ + function every(collection, callback, thisArg) { + var result = true; + callback = lodash.createCallback(callback, thisArg, 3); + + var index = -1, + length = collection ? collection.length : 0; + + if (typeof length == 'number') { + while (++index < length) { + if (!(result = !!callback(collection[index], index, collection))) { + break; + } + } + } else { + forOwn(collection, function(value, index, collection) { + return (result = !!callback(value, index, collection)); + }); + } + return result; + } + + /** + * Iterates over elements of a collection, returning an array of all elements + * the callback returns truey for. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias select + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of elements that passed the callback check. + * @example + * + * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => [2, 4, 6] + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.filter(characters, 'blocked'); + * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + * + * // using "_.where" callback shorthand + * _.filter(characters, { 'age': 36 }); + * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] + */ + function filter(collection, callback, thisArg) { + var result = []; + callback = lodash.createCallback(callback, thisArg, 3); + + var index = -1, + length = collection ? collection.length : 0; + + if (typeof length == 'number') { + while (++index < length) { + var value = collection[index]; + if (callback(value, index, collection)) { + result.push(value); + } + } + } else { + forOwn(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result.push(value); + } + }); + } + return result; + } + + /** + * Iterates over elements of a collection, returning the first element that + * the callback returns truey for. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias detect, findWhere + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the found element, else `undefined`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true }, + * { 'name': 'pebbles', 'age': 1, 'blocked': false } + * ]; + * + * _.find(characters, function(chr) { + * return chr.age < 40; + * }); + * // => { 'name': 'barney', 'age': 36, 'blocked': false } + * + * // using "_.where" callback shorthand + * _.find(characters, { 'age': 1 }); + * // => { 'name': 'pebbles', 'age': 1, 'blocked': false } + * + * // using "_.pluck" callback shorthand + * _.find(characters, 'blocked'); + * // => { 'name': 'fred', 'age': 40, 'blocked': true } + */ + function find(collection, callback, thisArg) { + callback = lodash.createCallback(callback, thisArg, 3); + + var index = -1, + length = collection ? collection.length : 0; + + if (typeof length == 'number') { + while (++index < length) { + var value = collection[index]; + if (callback(value, index, collection)) { + return value; + } + } + } else { + var result; + forOwn(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result = value; + return false; + } + }); + return result; + } + } + + /** + * This method is like `_.find` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the found element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(num) { + * return num % 2 == 1; + * }); + * // => 3 + */ + function findLast(collection, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + forEachRight(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result = value; + return false; + } + }); + return result; + } + + /** + * Iterates over elements of a collection, executing the callback for each + * element. The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). Callbacks may exit iteration early by + * explicitly returning `false`. + * + * Note: As with other "Collections" methods, objects with a `length` property + * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` + * may be used for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(','); + * // => logs each number and returns '1,2,3' + * + * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); }); + * // => logs each number and returns the object (property order is not guaranteed across environments) + */ + function forEach(collection, callback, thisArg) { + var index = -1, + length = collection ? collection.length : 0; + + callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); + if (typeof length == 'number') { + while (++index < length) { + if (callback(collection[index], index, collection) === false) { + break; + } + } + } else { + forOwn(collection, callback); + } + return collection; + } + + /** + * This method is like `_.forEach` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @alias eachRight + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(','); + * // => logs each number from right to left and returns '3,2,1' + */ + function forEachRight(collection, callback, thisArg) { + var length = collection ? collection.length : 0; + callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); + if (typeof length == 'number') { + while (length--) { + if (callback(collection[length], length, collection) === false) { + break; + } + } + } else { + var props = keys(collection); + length = props.length; + forOwn(collection, function(value, key, collection) { + key = props ? props[--length] : --length; + return callback(collection[key], key, collection); + }); + } + return collection; + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of a collection through the callback. The corresponding value + * of each key is an array of the elements responsible for generating the key. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false` + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); }); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * // using "_.pluck" callback shorthand + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + var groupBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); + }); + + /** + * Creates an object composed of keys generated from the results of running + * each element of the collection through the given callback. The corresponding + * value of each key is the last element responsible for generating the key. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var keys = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.indexBy(keys, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + */ + var indexBy = createAggregator(function(result, value, key) { + result[key] = value; + }); + + /** + * Invokes the method named by `methodName` on each element in the `collection` + * returning an array of the results of each invoked method. Additional arguments + * will be provided to each invoked method. If `methodName` is a function it + * will be invoked for, and `this` bound to, each element in the `collection`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|string} methodName The name of the method to invoke or + * the function invoked per iteration. + * @param {...*} [arg] Arguments to invoke the method with. + * @returns {Array} Returns a new array of the results of each invoked method. + * @example + * + * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invoke([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ + function invoke(collection, methodName) { + var args = slice(arguments, 2), + index = -1, + isFunc = typeof methodName == 'function', + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + forEach(collection, function(value) { + result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args); + }); + return result; + } + + /** + * Creates an array of values by running each element in the collection + * through the callback. The callback is bound to `thisArg` and invoked with + * three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias collect + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of the results of each `callback` execution. + * @example + * + * _.map([1, 2, 3], function(num) { return num * 3; }); + * // => [3, 6, 9] + * + * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); + * // => [3, 6, 9] (property order is not guaranteed across environments) + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.map(characters, 'name'); + * // => ['barney', 'fred'] + */ + function map(collection, callback, thisArg) { + var index = -1, + length = collection ? collection.length : 0; + + callback = lodash.createCallback(callback, thisArg, 3); + if (typeof length == 'number') { + var result = Array(length); + while (++index < length) { + result[index] = callback(collection[index], index, collection); + } + } else { + result = []; + forOwn(collection, function(value, key, collection) { + result[++index] = callback(value, key, collection); + }); + } + return result; + } + + /** + * Retrieves the maximum value of a collection. If the collection is empty or + * falsey `-Infinity` is returned. If a callback is provided it will be executed + * for each value in the collection to generate the criterion by which the value + * is ranked. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.max(characters, function(chr) { return chr.age; }); + * // => { 'name': 'fred', 'age': 40 }; + * + * // using "_.pluck" callback shorthand + * _.max(characters, 'age'); + * // => { 'name': 'fred', 'age': 40 }; + */ + function max(collection, callback, thisArg) { + var computed = -Infinity, + result = computed; + + // allows working with functions like `_.map` without using + // their `index` argument as a callback + if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { + callback = null; + } + if (callback == null && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (value > result) { + result = value; + } + } + } else { + callback = (callback == null && isString(collection)) + ? charAtCallback + : lodash.createCallback(callback, thisArg, 3); + + forEach(collection, function(value, index, collection) { + var current = callback(value, index, collection); + if (current > computed) { + computed = current; + result = value; + } + }); + } + return result; + } + + /** + * Retrieves the minimum value of a collection. If the collection is empty or + * falsey `Infinity` is returned. If a callback is provided it will be executed + * for each value in the collection to generate the criterion by which the value + * is ranked. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.min(characters, function(chr) { return chr.age; }); + * // => { 'name': 'barney', 'age': 36 }; + * + * // using "_.pluck" callback shorthand + * _.min(characters, 'age'); + * // => { 'name': 'barney', 'age': 36 }; + */ + function min(collection, callback, thisArg) { + var computed = Infinity, + result = computed; + + // allows working with functions like `_.map` without using + // their `index` argument as a callback + if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { + callback = null; + } + if (callback == null && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (value < result) { + result = value; + } + } + } else { + callback = (callback == null && isString(collection)) + ? charAtCallback + : lodash.createCallback(callback, thisArg, 3); + + forEach(collection, function(value, index, collection) { + var current = callback(value, index, collection); + if (current < computed) { + computed = current; + result = value; + } + }); + } + return result; + } + + /** + * Retrieves the value of a specified property from all elements in the collection. + * + * @static + * @memberOf _ + * @type Function + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {string} property The name of the property to pluck. + * @returns {Array} Returns a new array of property values. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.pluck(characters, 'name'); + * // => ['barney', 'fred'] + */ + var pluck = map; + + /** + * Reduces a collection to a value which is the accumulated result of running + * each element in the collection through the callback, where each successive + * callback execution consumes the return value of the previous execution. If + * `accumulator` is not provided the first element of the collection will be + * used as the initial `accumulator` value. The callback is bound to `thisArg` + * and invoked with four arguments; (accumulator, value, index|key, collection). + * + * @static + * @memberOf _ + * @alias foldl, inject + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] Initial value of the accumulator. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var sum = _.reduce([1, 2, 3], function(sum, num) { + * return sum + num; + * }); + * // => 6 + * + * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { + * result[key] = num * 3; + * return result; + * }, {}); + * // => { 'a': 3, 'b': 6, 'c': 9 } + */ + function reduce(collection, callback, accumulator, thisArg) { + if (!collection) return accumulator; + var noaccum = arguments.length < 3; + callback = lodash.createCallback(callback, thisArg, 4); + + var index = -1, + length = collection.length; + + if (typeof length == 'number') { + if (noaccum) { + accumulator = collection[++index]; + } + while (++index < length) { + accumulator = callback(accumulator, collection[index], index, collection); + } + } else { + forOwn(collection, function(value, index, collection) { + accumulator = noaccum + ? (noaccum = false, value) + : callback(accumulator, value, index, collection) + }); + } + return accumulator; + } + + /** + * This method is like `_.reduce` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @alias foldr + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] Initial value of the accumulator. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var list = [[0, 1], [2, 3], [4, 5]]; + * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + function reduceRight(collection, callback, accumulator, thisArg) { + var noaccum = arguments.length < 3; + callback = lodash.createCallback(callback, thisArg, 4); + forEachRight(collection, function(value, index, collection) { + accumulator = noaccum + ? (noaccum = false, value) + : callback(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The opposite of `_.filter` this method returns the elements of a + * collection that the callback does **not** return truey for. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of elements that failed the callback check. + * @example + * + * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => [1, 3, 5] + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.reject(characters, 'blocked'); + * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] + * + * // using "_.where" callback shorthand + * _.reject(characters, { 'age': 36 }); + * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + */ + function reject(collection, callback, thisArg) { + callback = lodash.createCallback(callback, thisArg, 3); + return filter(collection, function(value, index, collection) { + return !callback(value, index, collection); + }); + } + + /** + * Retrieves a random element or `n` random elements from a collection. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to sample. + * @param {number} [n] The number of elements to sample. + * @param- {Object} [guard] Allows working with functions like `_.map` + * without using their `index` arguments as `n`. + * @returns {Array} Returns the random sample(s) of `collection`. + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + * + * _.sample([1, 2, 3, 4], 2); + * // => [3, 1] + */ + function sample(collection, n, guard) { + if (collection && typeof collection.length != 'number') { + collection = values(collection); + } + if (n == null || guard) { + return collection ? collection[baseRandom(0, collection.length - 1)] : undefined; + } + var result = shuffle(collection); + result.length = nativeMin(nativeMax(0, n), result.length); + return result; + } + + /** + * Creates an array of shuffled values, using a version of the Fisher-Yates + * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to shuffle. + * @returns {Array} Returns a new shuffled collection. + * @example + * + * _.shuffle([1, 2, 3, 4, 5, 6]); + * // => [4, 1, 6, 3, 5, 2] + */ + function shuffle(collection) { + var index = -1, + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + forEach(collection, function(value) { + var rand = baseRandom(0, ++index); + result[index] = result[rand]; + result[rand] = value; + }); + return result; + } + + /** + * Gets the size of the `collection` by returning `collection.length` for arrays + * and array-like objects or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns `collection.length` or number of own enumerable properties. + * @example + * + * _.size([1, 2]); + * // => 2 + * + * _.size({ 'one': 1, 'two': 2, 'three': 3 }); + * // => 3 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + var length = collection ? collection.length : 0; + return typeof length == 'number' ? length : keys(collection).length; + } + + /** + * Checks if the callback returns a truey value for **any** element of a + * collection. The function returns as soon as it finds a passing value and + * does not iterate over the entire collection. The callback is bound to + * `thisArg` and invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias any + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if any element passed the callback check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.some(characters, 'blocked'); + * // => true + * + * // using "_.where" callback shorthand + * _.some(characters, { 'age': 1 }); + * // => false + */ + function some(collection, callback, thisArg) { + var result; + callback = lodash.createCallback(callback, thisArg, 3); + + var index = -1, + length = collection ? collection.length : 0; + + if (typeof length == 'number') { + while (++index < length) { + if ((result = callback(collection[index], index, collection))) { + break; + } + } + } else { + forOwn(collection, function(value, index, collection) { + return !(result = callback(value, index, collection)); + }); + } + return !!result; + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through the callback. This method + * performs a stable sort, that is, it will preserve the original sort order + * of equal elements. The callback is bound to `thisArg` and invoked with + * three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an array of property names is provided for `callback` the collection + * will be sorted by each property value. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of sorted elements. + * @example + * + * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); }); + * // => [3, 1, 2] + * + * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math); + * // => [3, 1, 2] + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 }, + * { 'name': 'barney', 'age': 26 }, + * { 'name': 'fred', 'age': 30 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.map(_.sortBy(characters, 'age'), _.values); + * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]] + * + * // sorting by multiple properties + * _.map(_.sortBy(characters, ['name', 'age']), _.values); + * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] + */ + function sortBy(collection, callback, thisArg) { + var index = -1, + isArr = isArray(callback), + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + if (!isArr) { + callback = lodash.createCallback(callback, thisArg, 3); + } + forEach(collection, function(value, key, collection) { + var object = result[++index] = getObject(); + if (isArr) { + object.criteria = map(callback, function(key) { return value[key]; }); + } else { + (object.criteria = getArray())[0] = callback(value, key, collection); + } + object.index = index; + object.value = value; + }); + + length = result.length; + result.sort(compareAscending); + while (length--) { + var object = result[length]; + result[length] = object.value; + if (!isArr) { + releaseArray(object.criteria); + } + releaseObject(object); + } + return result; + } + + /** + * Converts the `collection` to an array. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to convert. + * @returns {Array} Returns the new converted array. + * @example + * + * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4); + * // => [2, 3, 4] + */ + function toArray(collection) { + if (collection && typeof collection.length == 'number') { + return slice(collection); + } + return values(collection); + } + + /** + * Performs a deep comparison of each element in a `collection` to the given + * `properties` object, returning an array of all elements that have equivalent + * property values. + * + * @static + * @memberOf _ + * @type Function + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Object} props The object of property values to filter by. + * @returns {Array} Returns a new array of elements that have the given properties. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }, + * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } + * ]; + * + * _.where(characters, { 'age': 36 }); + * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }] + * + * _.where(characters, { 'pets': ['dino'] }); + * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }] + */ + var where = filter; + + /*--------------------------------------------------------------------------*/ + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are all falsey. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to compact. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result.push(value); + } + } + return result; + } + + /** + * Creates an array excluding all values of the provided arrays using strict + * equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to process. + * @param {...Array} [values] The arrays of values to exclude. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.difference([1, 2, 3, 4, 5], [5, 2, 10]); + * // => [1, 3, 4] + */ + function difference(array) { + return baseDifference(array, baseFlatten(arguments, true, true, 1)); + } + + /** + * This method is like `_.find` except that it returns the index of the first + * element that passes the callback check, instead of the element itself. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true }, + * { 'name': 'pebbles', 'age': 1, 'blocked': false } + * ]; + * + * _.findIndex(characters, function(chr) { + * return chr.age < 20; + * }); + * // => 2 + * + * // using "_.where" callback shorthand + * _.findIndex(characters, { 'age': 36 }); + * // => 0 + * + * // using "_.pluck" callback shorthand + * _.findIndex(characters, 'blocked'); + * // => 1 + */ + function findIndex(array, callback, thisArg) { + var index = -1, + length = array ? array.length : 0; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length) { + if (callback(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * This method is like `_.findIndex` except that it iterates over elements + * of a `collection` from right to left. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': true }, + * { 'name': 'fred', 'age': 40, 'blocked': false }, + * { 'name': 'pebbles', 'age': 1, 'blocked': true } + * ]; + * + * _.findLastIndex(characters, function(chr) { + * return chr.age > 30; + * }); + * // => 1 + * + * // using "_.where" callback shorthand + * _.findLastIndex(characters, { 'age': 36 }); + * // => 0 + * + * // using "_.pluck" callback shorthand + * _.findLastIndex(characters, 'blocked'); + * // => 2 + */ + function findLastIndex(array, callback, thisArg) { + var length = array ? array.length : 0; + callback = lodash.createCallback(callback, thisArg, 3); + while (length--) { + if (callback(array[length], length, array)) { + return length; + } + } + return -1; + } + + /** + * Gets the first element or first `n` elements of an array. If a callback + * is provided elements at the beginning of the array are returned as long + * as the callback returns truey. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias head, take + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback] The function called + * per element or the number of elements to return. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the first element(s) of `array`. + * @example + * + * _.first([1, 2, 3]); + * // => 1 + * + * _.first([1, 2, 3], 2); + * // => [1, 2] + * + * _.first([1, 2, 3], function(num) { + * return num < 3; + * }); + * // => [1, 2] + * + * var characters = [ + * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.first(characters, 'blocked'); + * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }] + * + * // using "_.where" callback shorthand + * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name'); + * // => ['barney', 'fred'] + */ + function first(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = -1; + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length && callback(array[index], index, array)) { + n++; + } + } else { + n = callback; + if (n == null || thisArg) { + return array ? array[0] : undefined; + } + } + return slice(array, 0, nativeMin(nativeMax(0, n), length)); + } + + /** + * Flattens a nested array (the nesting can be to any depth). If `isShallow` + * is truey, the array will only be flattened a single level. If a callback + * is provided each element of the array is passed through the callback before + * flattening. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to flatten. + * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new flattened array. + * @example + * + * _.flatten([1, [2], [3, [[4]]]]); + * // => [1, 2, 3, 4]; + * + * _.flatten([1, [2], [3, [[4]]]], true); + * // => [1, 2, 3, [[4]]]; + * + * var characters = [ + * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] }, + * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } + * ]; + * + * // using "_.pluck" callback shorthand + * _.flatten(characters, 'pets'); + * // => ['hoppy', 'baby puss', 'dino'] + */ + function flatten(array, isShallow, callback, thisArg) { + // juggle arguments + if (typeof isShallow != 'boolean' && isShallow != null) { + thisArg = callback; + callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow; + isShallow = false; + } + if (callback != null) { + array = map(array, callback, thisArg); + } + return baseFlatten(array, isShallow); + } + + /** + * Gets the index at which the first occurrence of `value` is found using + * strict equality for comparisons, i.e. `===`. If the array is already sorted + * providing `true` for `fromIndex` will run a faster binary search. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=0] The index to search from or `true` + * to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value or `-1`. + * @example + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2); + * // => 1 + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 4 + * + * _.indexOf([1, 1, 2, 2, 3, 3], 2, true); + * // => 2 + */ + function indexOf(array, value, fromIndex) { + if (typeof fromIndex == 'number') { + var length = array ? array.length : 0; + fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0); + } else if (fromIndex) { + var index = sortedIndex(array, value); + return array[index] === value ? index : -1; + } + return baseIndexOf(array, value, fromIndex); + } + + /** + * Gets all but the last element or last `n` elements of an array. If a + * callback is provided elements at the end of the array are excluded from + * the result as long as the callback returns truey. The callback is bound + * to `thisArg` and invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback=1] The function called + * per element or the number of elements to exclude. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + * + * _.initial([1, 2, 3], 2); + * // => [1] + * + * _.initial([1, 2, 3], function(num) { + * return num > 1; + * }); + * // => [1] + * + * var characters = [ + * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.initial(characters, 'blocked'); + * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }] + * + * // using "_.where" callback shorthand + * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name'); + * // => ['barney', 'fred'] + */ + function initial(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = length; + callback = lodash.createCallback(callback, thisArg, 3); + while (index-- && callback(array[index], index, array)) { + n++; + } + } else { + n = (callback == null || thisArg) ? 1 : callback || n; + } + return slice(array, 0, nativeMin(nativeMax(0, length - n), length)); + } + + /** + * Creates an array of unique values present in all provided arrays using + * strict equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of shared values. + * @example + * + * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]); + * // => [1, 2] + */ + function intersection() { + var args = [], + argsIndex = -1, + argsLength = arguments.length, + caches = getArray(), + indexOf = getIndexOf(), + trustIndexOf = indexOf === baseIndexOf, + seen = getArray(); + + while (++argsIndex < argsLength) { + var value = arguments[argsIndex]; + if (isArray(value) || isArguments(value)) { + args.push(value); + caches.push(trustIndexOf && value.length >= largeArraySize && + createCache(argsIndex ? args[argsIndex] : seen)); + } + } + var array = args[0], + index = -1, + length = array ? array.length : 0, + result = []; + + outer: + while (++index < length) { + var cache = caches[0]; + value = array[index]; + + if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) { + argsIndex = argsLength; + (cache || seen).push(value); + while (--argsIndex) { + cache = caches[argsIndex]; + if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) { + continue outer; + } + } + result.push(value); + } + } + while (argsLength--) { + cache = caches[argsLength]; + if (cache) { + releaseObject(cache); + } + } + releaseArray(caches); + releaseArray(seen); + return result; + } + + /** + * Gets the last element or last `n` elements of an array. If a callback is + * provided elements at the end of the array are returned as long as the + * callback returns truey. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback] The function called + * per element or the number of elements to return. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the last element(s) of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + * + * _.last([1, 2, 3], 2); + * // => [2, 3] + * + * _.last([1, 2, 3], function(num) { + * return num > 1; + * }); + * // => [2, 3] + * + * var characters = [ + * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.pluck(_.last(characters, 'blocked'), 'name'); + * // => ['fred', 'pebbles'] + * + * // using "_.where" callback shorthand + * _.last(characters, { 'employer': 'na' }); + * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] + */ + function last(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = length; + callback = lodash.createCallback(callback, thisArg, 3); + while (index-- && callback(array[index], index, array)) { + n++; + } + } else { + n = callback; + if (n == null || thisArg) { + return array ? array[length - 1] : undefined; + } + } + return slice(array, nativeMax(0, length - n)); + } + + /** + * Gets the index at which the last occurrence of `value` is found using strict + * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used + * as the offset from the end of the collection. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the matched value or `-1`. + * @example + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); + * // => 4 + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 1 + */ + function lastIndexOf(array, value, fromIndex) { + var index = array ? array.length : 0; + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1; + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Removes all provided values from the given array using strict equality for + * comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to modify. + * @param {...*} [value] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * _.pull(array, 2, 3); + * console.log(array); + * // => [1, 1] + */ + function pull(array) { + var args = arguments, + argsIndex = 0, + argsLength = args.length, + length = array ? array.length : 0; + + while (++argsIndex < argsLength) { + var index = -1, + value = args[argsIndex]; + while (++index < length) { + if (array[index] === value) { + splice.call(array, index--, 1); + length--; + } + } + } + return array; + } + + /** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to but not including `end`. If `start` is less than `stop` a + * zero-length range is created unless a negative `step` is specified. + * + * @static + * @memberOf _ + * @category Arrays + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns a new range array. + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ + function range(start, end, step) { + start = +start || 0; + step = typeof step == 'number' ? step : (+step || 1); + + if (end == null) { + end = start; + start = 0; + } + // use `Array(length)` so engines like Chakra and V8 avoid slower modes + // http://youtu.be/XAqIpGU8ZZk#t=17m25s + var index = -1, + length = nativeMax(0, ceil((end - start) / (step || 1))), + result = Array(length); + + while (++index < length) { + result[index] = start; + start += step; + } + return result; + } + + /** + * Removes all elements from an array that the callback returns truey for + * and returns an array of removed elements. The callback is bound to `thisArg` + * and invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to modify. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4, 5, 6]; + * var evens = _.remove(array, function(num) { return num % 2 == 0; }); + * + * console.log(array); + * // => [1, 3, 5] + * + * console.log(evens); + * // => [2, 4, 6] + */ + function remove(array, callback, thisArg) { + var index = -1, + length = array ? array.length : 0, + result = []; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length) { + var value = array[index]; + if (callback(value, index, array)) { + result.push(value); + splice.call(array, index--, 1); + length--; + } + } + return result; + } + + /** + * The opposite of `_.initial` this method gets all but the first element or + * first `n` elements of an array. If a callback function is provided elements + * at the beginning of the array are excluded from the result as long as the + * callback returns truey. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias drop, tail + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback=1] The function called + * per element or the number of elements to exclude. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a slice of `array`. + * @example + * + * _.rest([1, 2, 3]); + * // => [2, 3] + * + * _.rest([1, 2, 3], 2); + * // => [3] + * + * _.rest([1, 2, 3], function(num) { + * return num < 3; + * }); + * // => [3] + * + * var characters = [ + * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.pluck(_.rest(characters, 'blocked'), 'name'); + * // => ['fred', 'pebbles'] + * + * // using "_.where" callback shorthand + * _.rest(characters, { 'employer': 'slate' }); + * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] + */ + function rest(array, callback, thisArg) { + if (typeof callback != 'number' && callback != null) { + var n = 0, + index = -1, + length = array ? array.length : 0; + + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length && callback(array[index], index, array)) { + n++; + } + } else { + n = (callback == null || thisArg) ? 1 : nativeMax(0, callback); + } + return slice(array, n); + } + + /** + * Uses a binary search to determine the smallest index at which a value + * should be inserted into a given sorted array in order to maintain the sort + * order of the array. If a callback is provided it will be executed for + * `value` and each element of `array` to compute their sort ranking. The + * callback is bound to `thisArg` and invoked with one argument; (value). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([20, 30, 50], 40); + * // => 2 + * + * // using "_.pluck" callback shorthand + * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); + * // => 2 + * + * var dict = { + * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 } + * }; + * + * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { + * return dict.wordToNumber[word]; + * }); + * // => 2 + * + * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { + * return this.wordToNumber[word]; + * }, dict); + * // => 2 + */ + function sortedIndex(array, value, callback, thisArg) { + var low = 0, + high = array ? array.length : low; + + // explicitly reference `identity` for better inlining in Firefox + callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity; + value = callback(value); + + while (low < high) { + var mid = (low + high) >>> 1; + (callback(array[mid]) < value) + ? low = mid + 1 + : high = mid; + } + return low; + } + + /** + * Creates an array of unique values, in order, of the provided arrays using + * strict equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of combined values. + * @example + * + * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]); + * // => [1, 2, 3, 5, 4] + */ + function union() { + return baseUniq(baseFlatten(arguments, true, true)); + } + + /** + * Creates a duplicate-value-free version of an array using strict equality + * for comparisons, i.e. `===`. If the array is sorted, providing + * `true` for `isSorted` will use a faster algorithm. If a callback is provided + * each element of `array` is passed through the callback before uniqueness + * is computed. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias unique + * @category Arrays + * @param {Array} array The array to process. + * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a duplicate-value-free array. + * @example + * + * _.uniq([1, 2, 1, 3, 1]); + * // => [1, 2, 3] + * + * _.uniq([1, 1, 2, 2, 3], true); + * // => [1, 2, 3] + * + * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); }); + * // => ['A', 'b', 'C'] + * + * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math); + * // => [1, 2.5, 3] + * + * // using "_.pluck" callback shorthand + * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniq(array, isSorted, callback, thisArg) { + // juggle arguments + if (typeof isSorted != 'boolean' && isSorted != null) { + thisArg = callback; + callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted; + isSorted = false; + } + if (callback != null) { + callback = lodash.createCallback(callback, thisArg, 3); + } + return baseUniq(array, isSorted, callback); + } + + /** + * Creates an array excluding all provided values using strict equality for + * comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to filter. + * @param {...*} [value] The values to exclude. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); + * // => [2, 3, 4] + */ + function without(array) { + return baseDifference(array, slice(arguments, 1)); + } + + /** + * Creates an array that is the symmetric difference of the provided arrays. + * See http://en.wikipedia.org/wiki/Symmetric_difference. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of values. + * @example + * + * _.xor([1, 2, 3], [5, 2, 1, 4]); + * // => [3, 5, 4] + * + * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]); + * // => [1, 4, 5] + */ + function xor() { + var index = -1, + length = arguments.length; + + while (++index < length) { + var array = arguments[index]; + if (isArray(array) || isArguments(array)) { + var result = result + ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result))) + : array; + } + } + return result || []; + } + + /** + * Creates an array of grouped elements, the first of which contains the first + * elements of the given arrays, the second of which contains the second + * elements of the given arrays, and so on. + * + * @static + * @memberOf _ + * @alias unzip + * @category Arrays + * @param {...Array} [array] Arrays to process. + * @returns {Array} Returns a new array of grouped elements. + * @example + * + * _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + */ + function zip() { + var array = arguments.length > 1 ? arguments : arguments[0], + index = -1, + length = array ? max(pluck(array, 'length')) : 0, + result = Array(length < 0 ? 0 : length); + + while (++index < length) { + result[index] = pluck(array, index); + } + return result; + } + + /** + * Creates an object composed from arrays of `keys` and `values`. Provide + * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]` + * or two arrays, one of `keys` and one of corresponding `values`. + * + * @static + * @memberOf _ + * @alias object + * @category Arrays + * @param {Array} keys The array of keys. + * @param {Array} [values=[]] The array of values. + * @returns {Object} Returns an object composed of the given keys and + * corresponding values. + * @example + * + * _.zipObject(['fred', 'barney'], [30, 40]); + * // => { 'fred': 30, 'barney': 40 } + */ + function zipObject(keys, values) { + var index = -1, + length = keys ? keys.length : 0, + result = {}; + + if (!values && length && !isArray(keys[0])) { + values = []; + } + while (++index < length) { + var key = keys[index]; + if (values) { + result[key] = values[index]; + } else if (key) { + result[key[0]] = key[1]; + } + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a function that executes `func`, with the `this` binding and + * arguments of the created function, only after being called `n` times. + * + * @static + * @memberOf _ + * @category Functions + * @param {number} n The number of times the function must be called before + * `func` is executed. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('Done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => logs 'Done saving!', after all saves have completed + */ + function after(n, func) { + if (!isFunction(func)) { + throw new TypeError; + } + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that, when called, invokes `func` with the `this` + * binding of `thisArg` and prepends any additional `bind` arguments to those + * provided to the bound function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to bind. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var func = function(greeting) { + * return greeting + ' ' + this.name; + * }; + * + * func = _.bind(func, { 'name': 'fred' }, 'hi'); + * func(); + * // => 'hi fred' + */ + function bind(func, thisArg) { + return arguments.length > 2 + ? createWrapper(func, 17, slice(arguments, 2), null, thisArg) + : createWrapper(func, 1, null, null, thisArg); + } + + /** + * Binds methods of an object to the object itself, overwriting the existing + * method. Method names may be specified as individual arguments or as arrays + * of method names. If no method names are provided all the function properties + * of `object` will be bound. + * + * @static + * @memberOf _ + * @category Functions + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...string} [methodName] The object method names to + * bind, specified as individual method names or arrays of method names. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { console.log('clicked ' + this.label); } + * }; + * + * _.bindAll(view); + * jQuery('#docs').on('click', view.onClick); + * // => logs 'clicked docs', when the button is clicked + */ + function bindAll(object) { + var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object), + index = -1, + length = funcs.length; + + while (++index < length) { + var key = funcs[index]; + object[key] = createWrapper(object[key], 1, null, null, object); + } + return object; + } + + /** + * Creates a function that, when called, invokes the method at `object[key]` + * and prepends any additional `bindKey` arguments to those provided to the bound + * function. This method differs from `_.bind` by allowing bound functions to + * reference methods that will be redefined or don't yet exist. + * See http://michaux.ca/articles/lazy-function-definition-pattern. + * + * @static + * @memberOf _ + * @category Functions + * @param {Object} object The object the method belongs to. + * @param {string} key The key of the method. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'name': 'fred', + * 'greet': function(greeting) { + * return greeting + ' ' + this.name; + * } + * }; + * + * var func = _.bindKey(object, 'greet', 'hi'); + * func(); + * // => 'hi fred' + * + * object.greet = function(greeting) { + * return greeting + 'ya ' + this.name + '!'; + * }; + * + * func(); + * // => 'hiya fred!' + */ + function bindKey(object, key) { + return arguments.length > 2 + ? createWrapper(key, 19, slice(arguments, 2), null, object) + : createWrapper(key, 3, null, null, object); + } + + /** + * Creates a function that is the composition of the provided functions, + * where each function consumes the return value of the function that follows. + * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. + * Each function is executed with the `this` binding of the composed function. + * + * @static + * @memberOf _ + * @category Functions + * @param {...Function} [func] Functions to compose. + * @returns {Function} Returns the new composed function. + * @example + * + * var realNameMap = { + * 'pebbles': 'penelope' + * }; + * + * var format = function(name) { + * name = realNameMap[name.toLowerCase()] || name; + * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase(); + * }; + * + * var greet = function(formatted) { + * return 'Hiya ' + formatted + '!'; + * }; + * + * var welcome = _.compose(greet, format); + * welcome('pebbles'); + * // => 'Hiya Penelope!' + */ + function compose() { + var funcs = arguments, + length = funcs.length; + + while (length--) { + if (!isFunction(funcs[length])) { + throw new TypeError; + } + } + return function() { + var args = arguments, + length = funcs.length; + + while (length--) { + args = [funcs[length].apply(this, args)]; + } + return args[0]; + }; + } + + /** + * Creates a function which accepts one or more arguments of `func` that when + * invoked either executes `func` returning its result, if all `func` arguments + * have been provided, or returns a function that accepts one or more of the + * remaining `func` arguments, and so on. The arity of `func` can be specified + * if `func.length` is not sufficient. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @returns {Function} Returns the new curried function. + * @example + * + * var curried = _.curry(function(a, b, c) { + * console.log(a + b + c); + * }); + * + * curried(1)(2)(3); + * // => 6 + * + * curried(1, 2)(3); + * // => 6 + * + * curried(1, 2, 3); + * // => 6 + */ + function curry(func, arity) { + arity = typeof arity == 'number' ? arity : (+arity || func.length); + return createWrapper(func, 4, null, null, null, arity); + } + + /** + * Creates a function that will delay the execution of `func` until after + * `wait` milliseconds have elapsed since the last time it was invoked. + * Provide an options object to indicate that `func` should be invoked on + * the leading and/or trailing edge of the `wait` timeout. Subsequent calls + * to the debounced function will return the result of the last `func` call. + * + * Note: If `leading` and `trailing` options are `true` `func` will be called + * on the trailing edge of the timeout only if the the debounced function is + * invoked more than once during the `wait` timeout. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to debounce. + * @param {number} wait The number of milliseconds to delay. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called. + * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // avoid costly calculations while the window size is in flux + * var lazyLayout = _.debounce(calculateLayout, 150); + * jQuery(window).on('resize', lazyLayout); + * + * // execute `sendMail` when the click event is fired, debouncing subsequent calls + * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * }); + * + * // ensure `batchLog` is executed once after 1 second of debounced calls + * var source = new EventSource('/stream'); + * source.addEventListener('message', _.debounce(batchLog, 250, { + * 'maxWait': 1000 + * }, false); + */ + function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + maxWait = false, + trailing = true; + + if (!isFunction(func)) { + throw new TypeError; + } + wait = nativeMax(0, wait) || 0; + if (options === true) { + var leading = true; + trailing = false; + } else if (isObject(options)) { + leading = options.leading; + maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0); + trailing = 'trailing' in options ? options.trailing : trailing; + } + var delayed = function() { + var remaining = wait - (now() - stamp); + if (remaining <= 0) { + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + var isCalled = trailingCall; + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + } else { + timeoutId = setTimeout(delayed, remaining); + } + }; + + var maxDelayed = function() { + if (timeoutId) { + clearTimeout(timeoutId); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (trailing || (maxWait !== wait)) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + }; + + return function() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled), + isCalled = remaining <= 0; + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + return result; + }; + } + + /** + * Defers executing the `func` function until the current call stack has cleared. + * Additional arguments will be provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to defer. + * @param {...*} [arg] Arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { console.log(text); }, 'deferred'); + * // logs 'deferred' after one or more milliseconds + */ + function defer(func) { + if (!isFunction(func)) { + throw new TypeError; + } + var args = slice(arguments, 1); + return setTimeout(function() { func.apply(undefined, args); }, 1); + } + + /** + * Executes the `func` function after `wait` milliseconds. Additional arguments + * will be provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay execution. + * @param {...*} [arg] Arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { console.log(text); }, 1000, 'later'); + * // => logs 'later' after one second + */ + function delay(func, wait) { + if (!isFunction(func)) { + throw new TypeError; + } + var args = slice(arguments, 2); + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided it will be used to determine the cache key for storing the result + * based on the arguments provided to the memoized function. By default, the + * first argument provided to the memoized function is used as the cache key. + * The `func` is executed with the `this` binding of the memoized function. + * The result cache is exposed as the `cache` property on the memoized function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] A function used to resolve the cache key. + * @returns {Function} Returns the new memoizing function. + * @example + * + * var fibonacci = _.memoize(function(n) { + * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); + * }); + * + * fibonacci(9) + * // => 34 + * + * var data = { + * 'fred': { 'name': 'fred', 'age': 40 }, + * 'pebbles': { 'name': 'pebbles', 'age': 1 } + * }; + * + * // modifying the result cache + * var get = _.memoize(function(name) { return data[name]; }, _.identity); + * get('pebbles'); + * // => { 'name': 'pebbles', 'age': 1 } + * + * get.cache.pebbles.name = 'penelope'; + * get('pebbles'); + * // => { 'name': 'penelope', 'age': 1 } + */ + function memoize(func, resolver) { + if (!isFunction(func)) { + throw new TypeError; + } + var memoized = function() { + var cache = memoized.cache, + key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0]; + + return hasOwnProperty.call(cache, key) + ? cache[key] + : (cache[key] = func.apply(this, arguments)); + } + memoized.cache = {}; + return memoized; + } + + /** + * Creates a function that is restricted to execute `func` once. Repeat calls to + * the function will return the value of the first call. The `func` is executed + * with the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` executes `createApplication` once + */ + function once(func) { + var ran, + result; + + if (!isFunction(func)) { + throw new TypeError; + } + return function() { + if (ran) { + return result; + } + ran = true; + result = func.apply(this, arguments); + + // clear the `func` variable so the function may be garbage collected + func = null; + return result; + }; + } + + /** + * Creates a function that, when called, invokes `func` with any additional + * `partial` arguments prepended to those provided to the new function. This + * method is similar to `_.bind` except it does **not** alter the `this` binding. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { return greeting + ' ' + name; }; + * var hi = _.partial(greet, 'hi'); + * hi('fred'); + * // => 'hi fred' + */ + function partial(func) { + return createWrapper(func, 16, slice(arguments, 1)); + } + + /** + * This method is like `_.partial` except that `partial` arguments are + * appended to those provided to the new function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var defaultsDeep = _.partialRight(_.merge, _.defaults); + * + * var options = { + * 'variable': 'data', + * 'imports': { 'jq': $ } + * }; + * + * defaultsDeep(options, _.templateSettings); + * + * options.variable + * // => 'data' + * + * options.imports + * // => { '_': _, 'jq': $ } + */ + function partialRight(func) { + return createWrapper(func, 32, null, slice(arguments, 1)); + } + + /** + * Creates a function that, when executed, will only call the `func` function + * at most once per every `wait` milliseconds. Provide an options object to + * indicate that `func` should be invoked on the leading and/or trailing edge + * of the `wait` timeout. Subsequent calls to the throttled function will + * return the result of the last `func` call. + * + * Note: If `leading` and `trailing` options are `true` `func` will be called + * on the trailing edge of the timeout only if the the throttled function is + * invoked more than once during the `wait` timeout. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to throttle. + * @param {number} wait The number of milliseconds to throttle executions to. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout. + * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // avoid excessively updating the position while scrolling + * var throttled = _.throttle(updatePosition, 100); + * jQuery(window).on('scroll', throttled); + * + * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes + * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { + * 'trailing': false + * })); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (!isFunction(func)) { + throw new TypeError; + } + if (options === false) { + leading = false; + } else if (isObject(options)) { + leading = 'leading' in options ? options.leading : leading; + trailing = 'trailing' in options ? options.trailing : trailing; + } + debounceOptions.leading = leading; + debounceOptions.maxWait = wait; + debounceOptions.trailing = trailing; + + return debounce(func, wait, debounceOptions); + } + + /** + * Creates a function that provides `value` to the wrapper function as its + * first argument. Additional arguments provided to the function are appended + * to those provided to the wrapper function. The wrapper is executed with + * the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {*} value The value to wrap. + * @param {Function} wrapper The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '<p>' + func(text) + '</p>'; + * }); + * + * p('Fred, Wilma, & Pebbles'); + * // => '<p>Fred, Wilma, & Pebbles</p>' + */ + function wrap(value, wrapper) { + return createWrapper(wrapper, 16, [value]); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a function that returns `value`. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} value The value to return from the new function. + * @returns {Function} Returns the new function. + * @example + * + * var object = { 'name': 'fred' }; + * var getter = _.constant(object); + * getter() === object; + * // => true + */ + function constant(value) { + return function() { + return value; + }; + } + + /** + * Produces a callback bound to an optional `thisArg`. If `func` is a property + * name the created callback will return the property value for a given element. + * If `func` is an object the created callback will return `true` for elements + * that contain the equivalent object properties, otherwise it will return `false`. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} [func=identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of the created callback. + * @param {number} [argCount] The number of arguments the callback accepts. + * @returns {Function} Returns a callback function. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // wrap to create custom callback shorthands + * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) { + * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback); + * return !match ? func(callback, thisArg) : function(object) { + * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3]; + * }; + * }); + * + * _.filter(characters, 'age__gt38'); + * // => [{ 'name': 'fred', 'age': 40 }] + */ + function createCallback(func, thisArg, argCount) { + var type = typeof func; + if (func == null || type == 'function') { + return baseCreateCallback(func, thisArg, argCount); + } + // handle "_.pluck" style callback shorthands + if (type != 'object') { + return property(func); + } + var props = keys(func), + key = props[0], + a = func[key]; + + // handle "_.where" style callback shorthands + if (props.length == 1 && a === a && !isObject(a)) { + // fast path the common case of providing an object with a single + // property containing a primitive value + return function(object) { + var b = object[key]; + return a === b && (a !== 0 || (1 / a == 1 / b)); + }; + } + return function(object) { + var length = props.length, + result = false; + + while (length--) { + if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) { + break; + } + } + return result; + }; + } + + /** + * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their + * corresponding HTML entities. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} string The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('Fred, Wilma, & Pebbles'); + * // => 'Fred, Wilma, & Pebbles' + */ + function escape(string) { + return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar); + } + + /** + * This method returns the first argument provided to it. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'name': 'fred' }; + * _.identity(object) === object; + * // => true + */ + function identity(value) { + return value; + } + + /** + * Adds function properties of a source object to the destination object. + * If `object` is a function methods will be added to its prototype as well. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Function|Object} [object=lodash] object The destination object. + * @param {Object} source The object of functions to add. + * @param {Object} [options] The options object. + * @param {boolean} [options.chain=true] Specify whether the functions added are chainable. + * @example + * + * function capitalize(string) { + * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); + * } + * + * _.mixin({ 'capitalize': capitalize }); + * _.capitalize('fred'); + * // => 'Fred' + * + * _('fred').capitalize().value(); + * // => 'Fred' + * + * _.mixin({ 'capitalize': capitalize }, { 'chain': false }); + * _('fred').capitalize(); + * // => 'Fred' + */ + function mixin(object, source, options) { + var chain = true, + methodNames = source && functions(source); + + if (!source || (!options && !methodNames.length)) { + if (options == null) { + options = source; + } + ctor = lodashWrapper; + source = object; + object = lodash; + methodNames = functions(source); + } + if (options === false) { + chain = false; + } else if (isObject(options) && 'chain' in options) { + chain = options.chain; + } + var ctor = object, + isFunc = isFunction(ctor); + + forEach(methodNames, function(methodName) { + var func = object[methodName] = source[methodName]; + if (isFunc) { + ctor.prototype[methodName] = function() { + var chainAll = this.__chain__, + value = this.__wrapped__, + args = [value]; + + push.apply(args, arguments); + var result = func.apply(object, args); + if (chain || chainAll) { + if (value === result && isObject(result)) { + return this; + } + result = new ctor(result); + result.__chain__ = chainAll; + } + return result; + }; + } + }); + } + + /** + * Reverts the '_' variable to its previous value and returns a reference to + * the `lodash` function. + * + * @static + * @memberOf _ + * @category Utilities + * @returns {Function} Returns the `lodash` function. + * @example + * + * var lodash = _.noConflict(); + */ + function noConflict() { + context._ = oldDash; + return this; + } + + /** + * A no-operation function. + * + * @static + * @memberOf _ + * @category Utilities + * @example + * + * var object = { 'name': 'fred' }; + * _.noop(object) === undefined; + * // => true + */ + function noop() { + // no operation performed + } + + /** + * Gets the number of milliseconds that have elapsed since the Unix epoch + * (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @category Utilities + * @example + * + * var stamp = _.now(); + * _.defer(function() { console.log(_.now() - stamp); }); + * // => logs the number of milliseconds it took for the deferred function to be called + */ + var now = isNative(now = Date.now) && now || function() { + return new Date().getTime(); + }; + + /** + * Converts the given value into an integer of the specified radix. + * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the + * `value` is a hexadecimal, in which case a `radix` of `16` is used. + * + * Note: This method avoids differences in native ES3 and ES5 `parseInt` + * implementations. See http://es5.github.io/#E. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} value The value to parse. + * @param {number} [radix] The radix used to interpret the value to parse. + * @returns {number} Returns the new integer value. + * @example + * + * _.parseInt('08'); + * // => 8 + */ + var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) { + // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt` + return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0); + }; + + /** + * Creates a "_.pluck" style function, which returns the `key` value of a + * given object. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} key The name of the property to retrieve. + * @returns {Function} Returns the new function. + * @example + * + * var characters = [ + * { 'name': 'fred', 'age': 40 }, + * { 'name': 'barney', 'age': 36 } + * ]; + * + * var getName = _.property('name'); + * + * _.map(characters, getName); + * // => ['barney', 'fred'] + * + * _.sortBy(characters, getName); + * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] + */ + function property(key) { + return function(object) { + return object[key]; + }; + } + + /** + * Produces a random number between `min` and `max` (inclusive). If only one + * argument is provided a number between `0` and the given number will be + * returned. If `floating` is truey or either `min` or `max` are floats a + * floating-point number will be returned instead of an integer. + * + * @static + * @memberOf _ + * @category Utilities + * @param {number} [min=0] The minimum possible value. + * @param {number} [max=1] The maximum possible value. + * @param {boolean} [floating=false] Specify returning a floating-point number. + * @returns {number} Returns a random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(min, max, floating) { + var noMin = min == null, + noMax = max == null; + + if (floating == null) { + if (typeof min == 'boolean' && noMax) { + floating = min; + min = 1; + } + else if (!noMax && typeof max == 'boolean') { + floating = max; + noMax = true; + } + } + if (noMin && noMax) { + max = 1; + } + min = +min || 0; + if (noMax) { + max = min; + min = 0; + } else { + max = +max || 0; + } + if (floating || min % 1 || max % 1) { + var rand = nativeRandom(); + return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max); + } + return baseRandom(min, max); + } + + /** + * Resolves the value of property `key` on `object`. If `key` is a function + * it will be invoked with the `this` binding of `object` and its result returned, + * else the property value is returned. If `object` is falsey then `undefined` + * is returned. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Object} object The object to inspect. + * @param {string} key The name of the property to resolve. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { + * 'cheese': 'crumpets', + * 'stuff': function() { + * return 'nonsense'; + * } + * }; + * + * _.result(object, 'cheese'); + * // => 'crumpets' + * + * _.result(object, 'stuff'); + * // => 'nonsense' + */ + function result(object, key) { + if (object) { + var value = object[key]; + return isFunction(value) ? object[key]() : value; + } + } + + /** + * A micro-templating method that handles arbitrary delimiters, preserves + * whitespace, and correctly escapes quotes within interpolated code. + * + * Note: In the development build, `_.template` utilizes sourceURLs for easier + * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl + * + * For more information on precompiling templates see: + * http://lodash.com/custom-builds + * + * For more information on Chrome extension sandboxes see: + * http://developer.chrome.com/stable/extensions/sandboxingEval.html + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} text The template text. + * @param {Object} data The data object used to populate the text. + * @param {Object} [options] The options object. + * @param {RegExp} [options.escape] The "escape" delimiter. + * @param {RegExp} [options.evaluate] The "evaluate" delimiter. + * @param {Object} [options.imports] An object to import into the template as local variables. + * @param {RegExp} [options.interpolate] The "interpolate" delimiter. + * @param {string} [sourceURL] The sourceURL of the template's compiled source. + * @param {string} [variable] The data object variable name. + * @returns {Function|string} Returns a compiled function when no `data` object + * is given, else it returns the interpolated text. + * @example + * + * // using the "interpolate" delimiter to create a compiled template + * var compiled = _.template('hello <%= name %>'); + * compiled({ 'name': 'fred' }); + * // => 'hello fred' + * + * // using the "escape" delimiter to escape HTML in data property values + * _.template('<b><%- value %></b>', { 'value': '<script>' }); + * // => '<b><script></b>' + * + * // using the "evaluate" delimiter to generate HTML + * var list = '<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>'; + * _.template(list, { 'people': ['fred', 'barney'] }); + * // => '<li>fred</li><li>barney</li>' + * + * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter + * _.template('hello ${ name }', { 'name': 'pebbles' }); + * // => 'hello pebbles' + * + * // using the internal `print` function in "evaluate" delimiters + * _.template('<% print("hello " + name); %>!', { 'name': 'barney' }); + * // => 'hello barney!' + * + * // using a custom template delimiters + * _.templateSettings = { + * 'interpolate': /{{([\s\S]+?)}}/g + * }; + * + * _.template('hello {{ name }}!', { 'name': 'mustache' }); + * // => 'hello mustache!' + * + * // using the `imports` option to import jQuery + * var list = '<% jq.each(people, function(name) { %><li><%- name %></li><% }); %>'; + * _.template(list, { 'people': ['fred', 'barney'] }, { 'imports': { 'jq': jQuery } }); + * // => '<li>fred</li><li>barney</li>' + * + * // using the `sourceURL` option to specify a custom sourceURL for the template + * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' }); + * compiled(data); + * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector + * + * // using the `variable` option to ensure a with-statement isn't used in the compiled template + * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' }); + * compiled.source; + * // => function(data) { + * var __t, __p = '', __e = _.escape; + * __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!'; + * return __p; + * } + * + * // using the `source` property to inline compiled templates for meaningful + * // line numbers in error messages and a stack trace + * fs.writeFileSync(path.join(cwd, 'jst.js'), '\ + * var JST = {\ + * "main": ' + _.template(mainText).source + '\ + * };\ + * '); + */ + function template(text, data, options) { + // based on John Resig's `tmpl` implementation + // http://ejohn.org/blog/javascript-micro-templating/ + // and Laura Doktorova's doT.js + // https://github.com/olado/doT + var settings = lodash.templateSettings; + text = String(text || ''); + + // avoid missing dependencies when `iteratorTemplate` is not defined + options = defaults({}, options, settings); + + var imports = defaults({}, options.imports, settings.imports), + importsKeys = keys(imports), + importsValues = values(imports); + + var isEvaluating, + index = 0, + interpolate = options.interpolate || reNoMatch, + source = "__p += '"; + + // compile the regexp to match each delimiter + var reDelimiters = RegExp( + (options.escape || reNoMatch).source + '|' + + interpolate.source + '|' + + (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' + + (options.evaluate || reNoMatch).source + '|$' + , 'g'); + + text.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) { + interpolateValue || (interpolateValue = esTemplateValue); + + // escape characters that cannot be included in string literals + source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar); + + // replace delimiters with snippets + if (escapeValue) { + source += "' +\n__e(" + escapeValue + ") +\n'"; + } + if (evaluateValue) { + isEvaluating = true; + source += "';\n" + evaluateValue + ";\n__p += '"; + } + if (interpolateValue) { + source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'"; + } + index = offset + match.length; + + // the JS engine embedded in Adobe products requires returning the `match` + // string in order to produce the correct `offset` value + return match; + }); + + source += "';\n"; + + // if `variable` is not specified, wrap a with-statement around the generated + // code to add the data object to the top of the scope chain + var variable = options.variable, + hasVariable = variable; + + if (!hasVariable) { + variable = 'obj'; + source = 'with (' + variable + ') {\n' + source + '\n}\n'; + } + // cleanup code by stripping empty strings + source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source) + .replace(reEmptyStringMiddle, '$1') + .replace(reEmptyStringTrailing, '$1;'); + + // frame code as the function body + source = 'function(' + variable + ') {\n' + + (hasVariable ? '' : variable + ' || (' + variable + ' = {});\n') + + "var __t, __p = '', __e = _.escape" + + (isEvaluating + ? ', __j = Array.prototype.join;\n' + + "function print() { __p += __j.call(arguments, '') }\n" + : ';\n' + ) + + source + + 'return __p\n}'; + + // Use a sourceURL for easier debugging. + // http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl + var sourceURL = '\n/*\n//# sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']') + '\n*/'; + + try { + var result = Function(importsKeys, 'return ' + source + sourceURL).apply(undefined, importsValues); + } catch(e) { + e.source = source; + throw e; + } + if (data) { + return result(data); + } + // provide the compiled function's source by its `toString` method, in + // supported environments, or the `source` property as a convenience for + // inlining compiled templates during the build process + result.source = source; + return result; + } + + /** + * Executes the callback `n` times, returning an array of the results + * of each callback execution. The callback is bound to `thisArg` and invoked + * with one argument; (index). + * + * @static + * @memberOf _ + * @category Utilities + * @param {number} n The number of times to execute the callback. + * @param {Function} callback The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns an array of the results of each `callback` execution. + * @example + * + * var diceRolls = _.times(3, _.partial(_.random, 1, 6)); + * // => [3, 6, 4] + * + * _.times(3, function(n) { mage.castSpell(n); }); + * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively + * + * _.times(3, function(n) { this.cast(n); }, mage); + * // => also calls `mage.castSpell(n)` three times + */ + function times(n, callback, thisArg) { + n = (n = +n) > -1 ? n : 0; + var index = -1, + result = Array(n); + + callback = baseCreateCallback(callback, thisArg, 1); + while (++index < n) { + result[index] = callback(index); + } + return result; + } + + /** + * The inverse of `_.escape` this method converts the HTML entities + * `&`, `<`, `>`, `"`, and `'` in `string` to their + * corresponding characters. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} string The string to unescape. + * @returns {string} Returns the unescaped string. + * @example + * + * _.unescape('Fred, Barney & Pebbles'); + * // => 'Fred, Barney & Pebbles' + */ + function unescape(string) { + return string == null ? '' : String(string).replace(reEscapedHtml, unescapeHtmlChar); + } + + /** + * Generates a unique ID. If `prefix` is provided the ID will be appended to it. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} [prefix] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ + function uniqueId(prefix) { + var id = ++idCounter; + return String(prefix == null ? '' : prefix) + id; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object that wraps the given value with explicit + * method chaining enabled. + * + * @static + * @memberOf _ + * @category Chaining + * @param {*} value The value to wrap. + * @returns {Object} Returns the wrapper object. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 }, + * { 'name': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _.chain(characters) + * .sortBy('age') + * .map(function(chr) { return chr.name + ' is ' + chr.age; }) + * .first() + * .value(); + * // => 'pebbles is 1' + */ + function chain(value) { + value = new lodashWrapper(value); + value.__chain__ = true; + return value; + } + + /** + * Invokes `interceptor` with the `value` as the first argument and then + * returns `value`. The purpose of this method is to "tap into" a method + * chain in order to perform operations on intermediate results within + * the chain. + * + * @static + * @memberOf _ + * @category Chaining + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3, 4]) + * .tap(function(array) { array.pop(); }) + * .reverse() + * .value(); + * // => [3, 2, 1] + */ + function tap(value, interceptor) { + interceptor(value); + return value; + } + + /** + * Enables explicit method chaining on the wrapper object. + * + * @name chain + * @memberOf _ + * @category Chaining + * @returns {*} Returns the wrapper object. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // without explicit chaining + * _(characters).first(); + * // => { 'name': 'barney', 'age': 36 } + * + * // with explicit chaining + * _(characters).chain() + * .first() + * .pick('age') + * .value(); + * // => { 'age': 36 } + */ + function wrapperChain() { + this.__chain__ = true; + return this; + } + + /** + * Produces the `toString` result of the wrapped value. + * + * @name toString + * @memberOf _ + * @category Chaining + * @returns {string} Returns the string result. + * @example + * + * _([1, 2, 3]).toString(); + * // => '1,2,3' + */ + function wrapperToString() { + return String(this.__wrapped__); + } + + /** + * Extracts the wrapped value. + * + * @name valueOf + * @memberOf _ + * @alias value + * @category Chaining + * @returns {*} Returns the wrapped value. + * @example + * + * _([1, 2, 3]).valueOf(); + * // => [1, 2, 3] + */ + function wrapperValueOf() { + return this.__wrapped__; + } + + /*--------------------------------------------------------------------------*/ + + // add functions that return wrapped values when chaining + lodash.after = after; + lodash.assign = assign; + lodash.at = at; + lodash.bind = bind; + lodash.bindAll = bindAll; + lodash.bindKey = bindKey; + lodash.chain = chain; + lodash.compact = compact; + lodash.compose = compose; + lodash.constant = constant; + lodash.countBy = countBy; + lodash.create = create; + lodash.createCallback = createCallback; + lodash.curry = curry; + lodash.debounce = debounce; + lodash.defaults = defaults; + lodash.defer = defer; + lodash.delay = delay; + lodash.difference = difference; + lodash.filter = filter; + lodash.flatten = flatten; + lodash.forEach = forEach; + lodash.forEachRight = forEachRight; + lodash.forIn = forIn; + lodash.forInRight = forInRight; + lodash.forOwn = forOwn; + lodash.forOwnRight = forOwnRight; + lodash.functions = functions; + lodash.groupBy = groupBy; + lodash.indexBy = indexBy; + lodash.initial = initial; + lodash.intersection = intersection; + lodash.invert = invert; + lodash.invoke = invoke; + lodash.keys = keys; + lodash.map = map; + lodash.mapValues = mapValues; + lodash.max = max; + lodash.memoize = memoize; + lodash.merge = merge; + lodash.min = min; + lodash.omit = omit; + lodash.once = once; + lodash.pairs = pairs; + lodash.partial = partial; + lodash.partialRight = partialRight; + lodash.pick = pick; + lodash.pluck = pluck; + lodash.property = property; + lodash.pull = pull; + lodash.range = range; + lodash.reject = reject; + lodash.remove = remove; + lodash.rest = rest; + lodash.shuffle = shuffle; + lodash.sortBy = sortBy; + lodash.tap = tap; + lodash.throttle = throttle; + lodash.times = times; + lodash.toArray = toArray; + lodash.transform = transform; + lodash.union = union; + lodash.uniq = uniq; + lodash.values = values; + lodash.where = where; + lodash.without = without; + lodash.wrap = wrap; + lodash.xor = xor; + lodash.zip = zip; + lodash.zipObject = zipObject; + + // add aliases + lodash.collect = map; + lodash.drop = rest; + lodash.each = forEach; + lodash.eachRight = forEachRight; + lodash.extend = assign; + lodash.methods = functions; + lodash.object = zipObject; + lodash.select = filter; + lodash.tail = rest; + lodash.unique = uniq; + lodash.unzip = zip; + + // add functions to `lodash.prototype` + mixin(lodash); + + /*--------------------------------------------------------------------------*/ + + // add functions that return unwrapped values when chaining + lodash.clone = clone; + lodash.cloneDeep = cloneDeep; + lodash.contains = contains; + lodash.escape = escape; + lodash.every = every; + lodash.find = find; + lodash.findIndex = findIndex; + lodash.findKey = findKey; + lodash.findLast = findLast; + lodash.findLastIndex = findLastIndex; + lodash.findLastKey = findLastKey; + lodash.has = has; + lodash.identity = identity; + lodash.indexOf = indexOf; + lodash.isArguments = isArguments; + lodash.isArray = isArray; + lodash.isBoolean = isBoolean; + lodash.isDate = isDate; + lodash.isElement = isElement; + lodash.isEmpty = isEmpty; + lodash.isEqual = isEqual; + lodash.isFinite = isFinite; + lodash.isFunction = isFunction; + lodash.isNaN = isNaN; + lodash.isNull = isNull; + lodash.isNumber = isNumber; + lodash.isObject = isObject; + lodash.isPlainObject = isPlainObject; + lodash.isRegExp = isRegExp; + lodash.isString = isString; + lodash.isUndefined = isUndefined; + lodash.lastIndexOf = lastIndexOf; + lodash.mixin = mixin; + lodash.noConflict = noConflict; + lodash.noop = noop; + lodash.now = now; + lodash.parseInt = parseInt; + lodash.random = random; + lodash.reduce = reduce; + lodash.reduceRight = reduceRight; + lodash.result = result; + lodash.runInContext = runInContext; + lodash.size = size; + lodash.some = some; + lodash.sortedIndex = sortedIndex; + lodash.template = template; + lodash.unescape = unescape; + lodash.uniqueId = uniqueId; + + // add aliases + lodash.all = every; + lodash.any = some; + lodash.detect = find; + lodash.findWhere = find; + lodash.foldl = reduce; + lodash.foldr = reduceRight; + lodash.include = contains; + lodash.inject = reduce; + + mixin(function() { + var source = {} + forOwn(lodash, function(func, methodName) { + if (!lodash.prototype[methodName]) { + source[methodName] = func; + } + }); + return source; + }(), false); + + /*--------------------------------------------------------------------------*/ + + // add functions capable of returning wrapped and unwrapped values when chaining + lodash.first = first; + lodash.last = last; + lodash.sample = sample; + + // add aliases + lodash.take = first; + lodash.head = first; + + forOwn(lodash, function(func, methodName) { + var callbackable = methodName !== 'sample'; + if (!lodash.prototype[methodName]) { + lodash.prototype[methodName]= function(n, guard) { + var chainAll = this.__chain__, + result = func(this.__wrapped__, n, guard); + + return !chainAll && (n == null || (guard && !(callbackable && typeof n == 'function'))) + ? result + : new lodashWrapper(result, chainAll); + }; + } + }); + + /*--------------------------------------------------------------------------*/ + + /** + * The semantic version number. + * + * @static + * @memberOf _ + * @type string + */ + lodash.VERSION = '2.4.1'; + + // add "Chaining" functions to the wrapper + lodash.prototype.chain = wrapperChain; + lodash.prototype.toString = wrapperToString; + lodash.prototype.value = wrapperValueOf; + lodash.prototype.valueOf = wrapperValueOf; + + // add `Array` functions that return unwrapped values + forEach(['join', 'pop', 'shift'], function(methodName) { + var func = arrayRef[methodName]; + lodash.prototype[methodName] = function() { + var chainAll = this.__chain__, + result = func.apply(this.__wrapped__, arguments); + + return chainAll + ? new lodashWrapper(result, chainAll) + : result; + }; + }); + + // add `Array` functions that return the existing wrapped value + forEach(['push', 'reverse', 'sort', 'unshift'], function(methodName) { + var func = arrayRef[methodName]; + lodash.prototype[methodName] = function() { + func.apply(this.__wrapped__, arguments); + return this; + }; + }); + + // add `Array` functions that return new wrapped values + forEach(['concat', 'slice', 'splice'], function(methodName) { + var func = arrayRef[methodName]; + lodash.prototype[methodName] = function() { + return new lodashWrapper(func.apply(this.__wrapped__, arguments), this.__chain__); + }; + }); + + return lodash; + } + + /*--------------------------------------------------------------------------*/ + + // expose Lo-Dash + var _ = runInContext(); + + // some AMD build optimizers like r.js check for condition patterns like the following: + if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { + // Expose Lo-Dash to the global object even when an AMD loader is present in + // case Lo-Dash is loaded with a RequireJS shim config. + // See http://requirejs.org/docs/api.html#config-shim + root._ = _; + + // define as an anonymous module so, through path mapping, it can be + // referenced as the "underscore" module + define(function() { + return _; + }); + } + // check for `exports` after `define` in case a build optimizer adds an `exports` object + else if (freeExports && freeModule) { + // in Node.js or RingoJS + if (moduleExports) { + (freeModule.exports = _)._ = _; + } + // in Narwhal or Rhino -require + else { + freeExports._ = _; + } + } + else { + // in a browser or Rhino + root._ = _; + } +}.call(this));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/python/django/renkanmanager/static/renkanmanager/lib/lodash/lodash.min.js Mon Apr 27 17:22:46 2015 +0200 @@ -0,0 +1,56 @@ +/** + * @license + * Lo-Dash 2.4.1 (Custom Build) lodash.com/license | Underscore.js 1.5.2 underscorejs.org/LICENSE + * Build: `lodash modern -o ./dist/lodash.js` + */ +;(function(){function n(n,t,e){e=(e||0)-1;for(var r=n?n.length:0;++e<r;)if(n[e]===t)return e;return-1}function t(t,e){var r=typeof e;if(t=t.l,"boolean"==r||null==e)return t[e]?0:-1;"number"!=r&&"string"!=r&&(r="object");var u="number"==r?e:m+e;return t=(t=t[r])&&t[u],"object"==r?t&&-1<n(t,e)?0:-1:t?0:-1}function e(n){var t=this.l,e=typeof n;if("boolean"==e||null==n)t[n]=true;else{"number"!=e&&"string"!=e&&(e="object");var r="number"==e?n:m+n,t=t[e]||(t[e]={});"object"==e?(t[r]||(t[r]=[])).push(n):t[r]=true +}}function r(n){return n.charCodeAt(0)}function u(n,t){for(var e=n.m,r=t.m,u=-1,o=e.length;++u<o;){var i=e[u],a=r[u];if(i!==a){if(i>a||typeof i=="undefined")return 1;if(i<a||typeof a=="undefined")return-1}}return n.n-t.n}function o(n){var t=-1,r=n.length,u=n[0],o=n[r/2|0],i=n[r-1];if(u&&typeof u=="object"&&o&&typeof o=="object"&&i&&typeof i=="object")return false;for(u=f(),u["false"]=u["null"]=u["true"]=u.undefined=false,o=f(),o.k=n,o.l=u,o.push=e;++t<r;)o.push(n[t]);return o}function i(n){return"\\"+U[n] +}function a(){return h.pop()||[]}function f(){return g.pop()||{k:null,l:null,m:null,"false":false,n:0,"null":false,number:null,object:null,push:null,string:null,"true":false,undefined:false,o:null}}function l(n){n.length=0,h.length<_&&h.push(n)}function c(n){var t=n.l;t&&c(t),n.k=n.l=n.m=n.object=n.number=n.string=n.o=null,g.length<_&&g.push(n)}function p(n,t,e){t||(t=0),typeof e=="undefined"&&(e=n?n.length:0);var r=-1;e=e-t||0;for(var u=Array(0>e?0:e);++r<e;)u[r]=n[t+r];return u}function s(e){function h(n,t,e){if(!n||!V[typeof n])return n; +t=t&&typeof e=="undefined"?t:tt(t,e,3);for(var r=-1,u=V[typeof n]&&Fe(n),o=u?u.length:0;++r<o&&(e=u[r],false!==t(n[e],e,n)););return n}function g(n,t,e){var r;if(!n||!V[typeof n])return n;t=t&&typeof e=="undefined"?t:tt(t,e,3);for(r in n)if(false===t(n[r],r,n))break;return n}function _(n,t,e){var r,u=n,o=u;if(!u)return o;for(var i=arguments,a=0,f=typeof e=="number"?2:i.length;++a<f;)if((u=i[a])&&V[typeof u])for(var l=-1,c=V[typeof u]&&Fe(u),p=c?c.length:0;++l<p;)r=c[l],"undefined"==typeof o[r]&&(o[r]=u[r]); +return o}function U(n,t,e){var r,u=n,o=u;if(!u)return o;var i=arguments,a=0,f=typeof e=="number"?2:i.length;if(3<f&&"function"==typeof i[f-2])var l=tt(i[--f-1],i[f--],2);else 2<f&&"function"==typeof i[f-1]&&(l=i[--f]);for(;++a<f;)if((u=i[a])&&V[typeof u])for(var c=-1,p=V[typeof u]&&Fe(u),s=p?p.length:0;++c<s;)r=p[c],o[r]=l?l(o[r],u[r]):u[r];return o}function H(n){var t,e=[];if(!n||!V[typeof n])return e;for(t in n)me.call(n,t)&&e.push(t);return e}function J(n){return n&&typeof n=="object"&&!Te(n)&&me.call(n,"__wrapped__")?n:new Q(n) +}function Q(n,t){this.__chain__=!!t,this.__wrapped__=n}function X(n){function t(){if(r){var n=p(r);be.apply(n,arguments)}if(this instanceof t){var o=nt(e.prototype),n=e.apply(o,n||arguments);return wt(n)?n:o}return e.apply(u,n||arguments)}var e=n[0],r=n[2],u=n[4];return $e(t,n),t}function Z(n,t,e,r,u){if(e){var o=e(n);if(typeof o!="undefined")return o}if(!wt(n))return n;var i=ce.call(n);if(!K[i])return n;var f=Ae[i];switch(i){case T:case F:return new f(+n);case W:case P:return new f(n);case z:return o=f(n.source,C.exec(n)),o.lastIndex=n.lastIndex,o +}if(i=Te(n),t){var c=!r;r||(r=a()),u||(u=a());for(var s=r.length;s--;)if(r[s]==n)return u[s];o=i?f(n.length):{}}else o=i?p(n):U({},n);return i&&(me.call(n,"index")&&(o.index=n.index),me.call(n,"input")&&(o.input=n.input)),t?(r.push(n),u.push(o),(i?St:h)(n,function(n,i){o[i]=Z(n,t,e,r,u)}),c&&(l(r),l(u)),o):o}function nt(n){return wt(n)?ke(n):{}}function tt(n,t,e){if(typeof n!="function")return Ut;if(typeof t=="undefined"||!("prototype"in n))return n;var r=n.__bindData__;if(typeof r=="undefined"&&(De.funcNames&&(r=!n.name),r=r||!De.funcDecomp,!r)){var u=ge.call(n); +De.funcNames||(r=!O.test(u)),r||(r=E.test(u),$e(n,r))}if(false===r||true!==r&&1&r[1])return n;switch(e){case 1:return function(e){return n.call(t,e)};case 2:return function(e,r){return n.call(t,e,r)};case 3:return function(e,r,u){return n.call(t,e,r,u)};case 4:return function(e,r,u,o){return n.call(t,e,r,u,o)}}return Mt(n,t)}function et(n){function t(){var n=f?i:this;if(u){var h=p(u);be.apply(h,arguments)}return(o||c)&&(h||(h=p(arguments)),o&&be.apply(h,o),c&&h.length<a)?(r|=16,et([e,s?r:-4&r,h,null,i,a])):(h||(h=arguments),l&&(e=n[v]),this instanceof t?(n=nt(e.prototype),h=e.apply(n,h),wt(h)?h:n):e.apply(n,h)) +}var e=n[0],r=n[1],u=n[2],o=n[3],i=n[4],a=n[5],f=1&r,l=2&r,c=4&r,s=8&r,v=e;return $e(t,n),t}function rt(e,r){var u=-1,i=st(),a=e?e.length:0,f=a>=b&&i===n,l=[];if(f){var p=o(r);p?(i=t,r=p):f=false}for(;++u<a;)p=e[u],0>i(r,p)&&l.push(p);return f&&c(r),l}function ut(n,t,e,r){r=(r||0)-1;for(var u=n?n.length:0,o=[];++r<u;){var i=n[r];if(i&&typeof i=="object"&&typeof i.length=="number"&&(Te(i)||yt(i))){t||(i=ut(i,t,e));var a=-1,f=i.length,l=o.length;for(o.length+=f;++a<f;)o[l++]=i[a]}else e||o.push(i)}return o +}function ot(n,t,e,r,u,o){if(e){var i=e(n,t);if(typeof i!="undefined")return!!i}if(n===t)return 0!==n||1/n==1/t;if(n===n&&!(n&&V[typeof n]||t&&V[typeof t]))return false;if(null==n||null==t)return n===t;var f=ce.call(n),c=ce.call(t);if(f==D&&(f=q),c==D&&(c=q),f!=c)return false;switch(f){case T:case F:return+n==+t;case W:return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case z:case P:return n==oe(t)}if(c=f==$,!c){var p=me.call(n,"__wrapped__"),s=me.call(t,"__wrapped__");if(p||s)return ot(p?n.__wrapped__:n,s?t.__wrapped__:t,e,r,u,o); +if(f!=q)return false;if(f=n.constructor,p=t.constructor,f!=p&&!(dt(f)&&f instanceof f&&dt(p)&&p instanceof p)&&"constructor"in n&&"constructor"in t)return false}for(f=!u,u||(u=a()),o||(o=a()),p=u.length;p--;)if(u[p]==n)return o[p]==t;var v=0,i=true;if(u.push(n),o.push(t),c){if(p=n.length,v=t.length,(i=v==p)||r)for(;v--;)if(c=p,s=t[v],r)for(;c--&&!(i=ot(n[c],s,e,r,u,o)););else if(!(i=ot(n[v],s,e,r,u,o)))break}else g(t,function(t,a,f){return me.call(f,a)?(v++,i=me.call(n,a)&&ot(n[a],t,e,r,u,o)):void 0}),i&&!r&&g(n,function(n,t,e){return me.call(e,t)?i=-1<--v:void 0 +});return u.pop(),o.pop(),f&&(l(u),l(o)),i}function it(n,t,e,r,u){(Te(t)?St:h)(t,function(t,o){var i,a,f=t,l=n[o];if(t&&((a=Te(t))||Pe(t))){for(f=r.length;f--;)if(i=r[f]==t){l=u[f];break}if(!i){var c;e&&(f=e(l,t),c=typeof f!="undefined")&&(l=f),c||(l=a?Te(l)?l:[]:Pe(l)?l:{}),r.push(t),u.push(l),c||it(l,t,e,r,u)}}else e&&(f=e(l,t),typeof f=="undefined"&&(f=t)),typeof f!="undefined"&&(l=f);n[o]=l})}function at(n,t){return n+he(Re()*(t-n+1))}function ft(e,r,u){var i=-1,f=st(),p=e?e.length:0,s=[],v=!r&&p>=b&&f===n,h=u||v?a():s; +for(v&&(h=o(h),f=t);++i<p;){var g=e[i],y=u?u(g,i,e):g;(r?!i||h[h.length-1]!==y:0>f(h,y))&&((u||v)&&h.push(y),s.push(g))}return v?(l(h.k),c(h)):u&&l(h),s}function lt(n){return function(t,e,r){var u={};e=J.createCallback(e,r,3),r=-1;var o=t?t.length:0;if(typeof o=="number")for(;++r<o;){var i=t[r];n(u,i,e(i,r,t),t)}else h(t,function(t,r,o){n(u,t,e(t,r,o),o)});return u}}function ct(n,t,e,r,u,o){var i=1&t,a=4&t,f=16&t,l=32&t;if(!(2&t||dt(n)))throw new ie;f&&!e.length&&(t&=-17,f=e=false),l&&!r.length&&(t&=-33,l=r=false); +var c=n&&n.__bindData__;return c&&true!==c?(c=p(c),c[2]&&(c[2]=p(c[2])),c[3]&&(c[3]=p(c[3])),!i||1&c[1]||(c[4]=u),!i&&1&c[1]&&(t|=8),!a||4&c[1]||(c[5]=o),f&&be.apply(c[2]||(c[2]=[]),e),l&&we.apply(c[3]||(c[3]=[]),r),c[1]|=t,ct.apply(null,c)):(1==t||17===t?X:et)([n,t,e,r,u,o])}function pt(n){return Be[n]}function st(){var t=(t=J.indexOf)===Wt?n:t;return t}function vt(n){return typeof n=="function"&&pe.test(n)}function ht(n){var t,e;return n&&ce.call(n)==q&&(t=n.constructor,!dt(t)||t instanceof t)?(g(n,function(n,t){e=t +}),typeof e=="undefined"||me.call(n,e)):false}function gt(n){return We[n]}function yt(n){return n&&typeof n=="object"&&typeof n.length=="number"&&ce.call(n)==D||false}function mt(n,t,e){var r=Fe(n),u=r.length;for(t=tt(t,e,3);u--&&(e=r[u],false!==t(n[e],e,n)););return n}function bt(n){var t=[];return g(n,function(n,e){dt(n)&&t.push(e)}),t.sort()}function _t(n){for(var t=-1,e=Fe(n),r=e.length,u={};++t<r;){var o=e[t];u[n[o]]=o}return u}function dt(n){return typeof n=="function"}function wt(n){return!(!n||!V[typeof n]) +}function jt(n){return typeof n=="number"||n&&typeof n=="object"&&ce.call(n)==W||false}function kt(n){return typeof n=="string"||n&&typeof n=="object"&&ce.call(n)==P||false}function xt(n){for(var t=-1,e=Fe(n),r=e.length,u=Xt(r);++t<r;)u[t]=n[e[t]];return u}function Ct(n,t,e){var r=-1,u=st(),o=n?n.length:0,i=false;return e=(0>e?Ie(0,o+e):e)||0,Te(n)?i=-1<u(n,t,e):typeof o=="number"?i=-1<(kt(n)?n.indexOf(t,e):u(n,t,e)):h(n,function(n){return++r<e?void 0:!(i=n===t)}),i}function Ot(n,t,e){var r=true;t=J.createCallback(t,e,3),e=-1; +var u=n?n.length:0;if(typeof u=="number")for(;++e<u&&(r=!!t(n[e],e,n)););else h(n,function(n,e,u){return r=!!t(n,e,u)});return r}function Nt(n,t,e){var r=[];t=J.createCallback(t,e,3),e=-1;var u=n?n.length:0;if(typeof u=="number")for(;++e<u;){var o=n[e];t(o,e,n)&&r.push(o)}else h(n,function(n,e,u){t(n,e,u)&&r.push(n)});return r}function It(n,t,e){t=J.createCallback(t,e,3),e=-1;var r=n?n.length:0;if(typeof r!="number"){var u;return h(n,function(n,e,r){return t(n,e,r)?(u=n,false):void 0}),u}for(;++e<r;){var o=n[e]; +if(t(o,e,n))return o}}function St(n,t,e){var r=-1,u=n?n.length:0;if(t=t&&typeof e=="undefined"?t:tt(t,e,3),typeof u=="number")for(;++r<u&&false!==t(n[r],r,n););else h(n,t);return n}function Et(n,t,e){var r=n?n.length:0;if(t=t&&typeof e=="undefined"?t:tt(t,e,3),typeof r=="number")for(;r--&&false!==t(n[r],r,n););else{var u=Fe(n),r=u.length;h(n,function(n,e,o){return e=u?u[--r]:--r,t(o[e],e,o)})}return n}function Rt(n,t,e){var r=-1,u=n?n.length:0;if(t=J.createCallback(t,e,3),typeof u=="number")for(var o=Xt(u);++r<u;)o[r]=t(n[r],r,n); +else o=[],h(n,function(n,e,u){o[++r]=t(n,e,u)});return o}function At(n,t,e){var u=-1/0,o=u;if(typeof t!="function"&&e&&e[t]===n&&(t=null),null==t&&Te(n)){e=-1;for(var i=n.length;++e<i;){var a=n[e];a>o&&(o=a)}}else t=null==t&&kt(n)?r:J.createCallback(t,e,3),St(n,function(n,e,r){e=t(n,e,r),e>u&&(u=e,o=n)});return o}function Dt(n,t,e,r){if(!n)return e;var u=3>arguments.length;t=J.createCallback(t,r,4);var o=-1,i=n.length;if(typeof i=="number")for(u&&(e=n[++o]);++o<i;)e=t(e,n[o],o,n);else h(n,function(n,r,o){e=u?(u=false,n):t(e,n,r,o) +});return e}function $t(n,t,e,r){var u=3>arguments.length;return t=J.createCallback(t,r,4),Et(n,function(n,r,o){e=u?(u=false,n):t(e,n,r,o)}),e}function Tt(n){var t=-1,e=n?n.length:0,r=Xt(typeof e=="number"?e:0);return St(n,function(n){var e=at(0,++t);r[t]=r[e],r[e]=n}),r}function Ft(n,t,e){var r;t=J.createCallback(t,e,3),e=-1;var u=n?n.length:0;if(typeof u=="number")for(;++e<u&&!(r=t(n[e],e,n)););else h(n,function(n,e,u){return!(r=t(n,e,u))});return!!r}function Bt(n,t,e){var r=0,u=n?n.length:0;if(typeof t!="number"&&null!=t){var o=-1; +for(t=J.createCallback(t,e,3);++o<u&&t(n[o],o,n);)r++}else if(r=t,null==r||e)return n?n[0]:v;return p(n,0,Se(Ie(0,r),u))}function Wt(t,e,r){if(typeof r=="number"){var u=t?t.length:0;r=0>r?Ie(0,u+r):r||0}else if(r)return r=zt(t,e),t[r]===e?r:-1;return n(t,e,r)}function qt(n,t,e){if(typeof t!="number"&&null!=t){var r=0,u=-1,o=n?n.length:0;for(t=J.createCallback(t,e,3);++u<o&&t(n[u],u,n);)r++}else r=null==t||e?1:Ie(0,t);return p(n,r)}function zt(n,t,e,r){var u=0,o=n?n.length:u;for(e=e?J.createCallback(e,r,1):Ut,t=e(t);u<o;)r=u+o>>>1,e(n[r])<t?u=r+1:o=r; +return u}function Pt(n,t,e,r){return typeof t!="boolean"&&null!=t&&(r=e,e=typeof t!="function"&&r&&r[t]===n?null:t,t=false),null!=e&&(e=J.createCallback(e,r,3)),ft(n,t,e)}function Kt(){for(var n=1<arguments.length?arguments:arguments[0],t=-1,e=n?At(Ve(n,"length")):0,r=Xt(0>e?0:e);++t<e;)r[t]=Ve(n,t);return r}function Lt(n,t){var e=-1,r=n?n.length:0,u={};for(t||!r||Te(n[0])||(t=[]);++e<r;){var o=n[e];t?u[o]=t[e]:o&&(u[o[0]]=o[1])}return u}function Mt(n,t){return 2<arguments.length?ct(n,17,p(arguments,2),null,t):ct(n,1,null,null,t) +}function Vt(n,t,e){function r(){c&&ve(c),i=c=p=v,(g||h!==t)&&(s=Ue(),a=n.apply(l,o),c||i||(o=l=null))}function u(){var e=t-(Ue()-f);0<e?c=_e(u,e):(i&&ve(i),e=p,i=c=p=v,e&&(s=Ue(),a=n.apply(l,o),c||i||(o=l=null)))}var o,i,a,f,l,c,p,s=0,h=false,g=true;if(!dt(n))throw new ie;if(t=Ie(0,t)||0,true===e)var y=true,g=false;else wt(e)&&(y=e.leading,h="maxWait"in e&&(Ie(t,e.maxWait)||0),g="trailing"in e?e.trailing:g);return function(){if(o=arguments,f=Ue(),l=this,p=g&&(c||!y),false===h)var e=y&&!c;else{i||y||(s=f);var v=h-(f-s),m=0>=v; +m?(i&&(i=ve(i)),s=f,a=n.apply(l,o)):i||(i=_e(r,v))}return m&&c?c=ve(c):c||t===h||(c=_e(u,t)),e&&(m=true,a=n.apply(l,o)),!m||c||i||(o=l=null),a}}function Ut(n){return n}function Gt(n,t,e){var r=true,u=t&&bt(t);t&&(e||u.length)||(null==e&&(e=t),o=Q,t=n,n=J,u=bt(t)),false===e?r=false:wt(e)&&"chain"in e&&(r=e.chain);var o=n,i=dt(o);St(u,function(e){var u=n[e]=t[e];i&&(o.prototype[e]=function(){var t=this.__chain__,e=this.__wrapped__,i=[e];if(be.apply(i,arguments),i=u.apply(n,i),r||t){if(e===i&&wt(i))return this; +i=new o(i),i.__chain__=t}return i})})}function Ht(){}function Jt(n){return function(t){return t[n]}}function Qt(){return this.__wrapped__}e=e?Y.defaults(G.Object(),e,Y.pick(G,A)):G;var Xt=e.Array,Yt=e.Boolean,Zt=e.Date,ne=e.Function,te=e.Math,ee=e.Number,re=e.Object,ue=e.RegExp,oe=e.String,ie=e.TypeError,ae=[],fe=re.prototype,le=e._,ce=fe.toString,pe=ue("^"+oe(ce).replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/toString| for [^\]]+/g,".*?")+"$"),se=te.ceil,ve=e.clearTimeout,he=te.floor,ge=ne.prototype.toString,ye=vt(ye=re.getPrototypeOf)&&ye,me=fe.hasOwnProperty,be=ae.push,_e=e.setTimeout,de=ae.splice,we=ae.unshift,je=function(){try{var n={},t=vt(t=re.defineProperty)&&t,e=t(n,n,n)&&t +}catch(r){}return e}(),ke=vt(ke=re.create)&&ke,xe=vt(xe=Xt.isArray)&&xe,Ce=e.isFinite,Oe=e.isNaN,Ne=vt(Ne=re.keys)&&Ne,Ie=te.max,Se=te.min,Ee=e.parseInt,Re=te.random,Ae={};Ae[$]=Xt,Ae[T]=Yt,Ae[F]=Zt,Ae[B]=ne,Ae[q]=re,Ae[W]=ee,Ae[z]=ue,Ae[P]=oe,Q.prototype=J.prototype;var De=J.support={};De.funcDecomp=!vt(e.a)&&E.test(s),De.funcNames=typeof ne.name=="string",J.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:N,variable:"",imports:{_:J}},ke||(nt=function(){function n(){}return function(t){if(wt(t)){n.prototype=t; +var r=new n;n.prototype=null}return r||e.Object()}}());var $e=je?function(n,t){M.value=t,je(n,"__bindData__",M)}:Ht,Te=xe||function(n){return n&&typeof n=="object"&&typeof n.length=="number"&&ce.call(n)==$||false},Fe=Ne?function(n){return wt(n)?Ne(n):[]}:H,Be={"&":"&","<":"<",">":">",'"':""","'":"'"},We=_t(Be),qe=ue("("+Fe(We).join("|")+")","g"),ze=ue("["+Fe(Be).join("")+"]","g"),Pe=ye?function(n){if(!n||ce.call(n)!=q)return false;var t=n.valueOf,e=vt(t)&&(e=ye(t))&&ye(e);return e?n==e||ye(n)==e:ht(n) +}:ht,Ke=lt(function(n,t,e){me.call(n,e)?n[e]++:n[e]=1}),Le=lt(function(n,t,e){(me.call(n,e)?n[e]:n[e]=[]).push(t)}),Me=lt(function(n,t,e){n[e]=t}),Ve=Rt,Ue=vt(Ue=Zt.now)&&Ue||function(){return(new Zt).getTime()},Ge=8==Ee(d+"08")?Ee:function(n,t){return Ee(kt(n)?n.replace(I,""):n,t||0)};return J.after=function(n,t){if(!dt(t))throw new ie;return function(){return 1>--n?t.apply(this,arguments):void 0}},J.assign=U,J.at=function(n){for(var t=arguments,e=-1,r=ut(t,true,false,1),t=t[2]&&t[2][t[1]]===n?1:r.length,u=Xt(t);++e<t;)u[e]=n[r[e]]; +return u},J.bind=Mt,J.bindAll=function(n){for(var t=1<arguments.length?ut(arguments,true,false,1):bt(n),e=-1,r=t.length;++e<r;){var u=t[e];n[u]=ct(n[u],1,null,null,n)}return n},J.bindKey=function(n,t){return 2<arguments.length?ct(t,19,p(arguments,2),null,n):ct(t,3,null,null,n)},J.chain=function(n){return n=new Q(n),n.__chain__=true,n},J.compact=function(n){for(var t=-1,e=n?n.length:0,r=[];++t<e;){var u=n[t];u&&r.push(u)}return r},J.compose=function(){for(var n=arguments,t=n.length;t--;)if(!dt(n[t]))throw new ie; +return function(){for(var t=arguments,e=n.length;e--;)t=[n[e].apply(this,t)];return t[0]}},J.constant=function(n){return function(){return n}},J.countBy=Ke,J.create=function(n,t){var e=nt(n);return t?U(e,t):e},J.createCallback=function(n,t,e){var r=typeof n;if(null==n||"function"==r)return tt(n,t,e);if("object"!=r)return Jt(n);var u=Fe(n),o=u[0],i=n[o];return 1!=u.length||i!==i||wt(i)?function(t){for(var e=u.length,r=false;e--&&(r=ot(t[u[e]],n[u[e]],null,true)););return r}:function(n){return n=n[o],i===n&&(0!==i||1/i==1/n) +}},J.curry=function(n,t){return t=typeof t=="number"?t:+t||n.length,ct(n,4,null,null,null,t)},J.debounce=Vt,J.defaults=_,J.defer=function(n){if(!dt(n))throw new ie;var t=p(arguments,1);return _e(function(){n.apply(v,t)},1)},J.delay=function(n,t){if(!dt(n))throw new ie;var e=p(arguments,2);return _e(function(){n.apply(v,e)},t)},J.difference=function(n){return rt(n,ut(arguments,true,true,1))},J.filter=Nt,J.flatten=function(n,t,e,r){return typeof t!="boolean"&&null!=t&&(r=e,e=typeof t!="function"&&r&&r[t]===n?null:t,t=false),null!=e&&(n=Rt(n,e,r)),ut(n,t) +},J.forEach=St,J.forEachRight=Et,J.forIn=g,J.forInRight=function(n,t,e){var r=[];g(n,function(n,t){r.push(t,n)});var u=r.length;for(t=tt(t,e,3);u--&&false!==t(r[u--],r[u],n););return n},J.forOwn=h,J.forOwnRight=mt,J.functions=bt,J.groupBy=Le,J.indexBy=Me,J.initial=function(n,t,e){var r=0,u=n?n.length:0;if(typeof t!="number"&&null!=t){var o=u;for(t=J.createCallback(t,e,3);o--&&t(n[o],o,n);)r++}else r=null==t||e?1:t||r;return p(n,0,Se(Ie(0,u-r),u))},J.intersection=function(){for(var e=[],r=-1,u=arguments.length,i=a(),f=st(),p=f===n,s=a();++r<u;){var v=arguments[r]; +(Te(v)||yt(v))&&(e.push(v),i.push(p&&v.length>=b&&o(r?e[r]:s)))}var p=e[0],h=-1,g=p?p.length:0,y=[];n:for(;++h<g;){var m=i[0],v=p[h];if(0>(m?t(m,v):f(s,v))){for(r=u,(m||s).push(v);--r;)if(m=i[r],0>(m?t(m,v):f(e[r],v)))continue n;y.push(v)}}for(;u--;)(m=i[u])&&c(m);return l(i),l(s),y},J.invert=_t,J.invoke=function(n,t){var e=p(arguments,2),r=-1,u=typeof t=="function",o=n?n.length:0,i=Xt(typeof o=="number"?o:0);return St(n,function(n){i[++r]=(u?t:n[t]).apply(n,e)}),i},J.keys=Fe,J.map=Rt,J.mapValues=function(n,t,e){var r={}; +return t=J.createCallback(t,e,3),h(n,function(n,e,u){r[e]=t(n,e,u)}),r},J.max=At,J.memoize=function(n,t){function e(){var r=e.cache,u=t?t.apply(this,arguments):m+arguments[0];return me.call(r,u)?r[u]:r[u]=n.apply(this,arguments)}if(!dt(n))throw new ie;return e.cache={},e},J.merge=function(n){var t=arguments,e=2;if(!wt(n))return n;if("number"!=typeof t[2]&&(e=t.length),3<e&&"function"==typeof t[e-2])var r=tt(t[--e-1],t[e--],2);else 2<e&&"function"==typeof t[e-1]&&(r=t[--e]);for(var t=p(arguments,1,e),u=-1,o=a(),i=a();++u<e;)it(n,t[u],r,o,i); +return l(o),l(i),n},J.min=function(n,t,e){var u=1/0,o=u;if(typeof t!="function"&&e&&e[t]===n&&(t=null),null==t&&Te(n)){e=-1;for(var i=n.length;++e<i;){var a=n[e];a<o&&(o=a)}}else t=null==t&&kt(n)?r:J.createCallback(t,e,3),St(n,function(n,e,r){e=t(n,e,r),e<u&&(u=e,o=n)});return o},J.omit=function(n,t,e){var r={};if(typeof t!="function"){var u=[];g(n,function(n,t){u.push(t)});for(var u=rt(u,ut(arguments,true,false,1)),o=-1,i=u.length;++o<i;){var a=u[o];r[a]=n[a]}}else t=J.createCallback(t,e,3),g(n,function(n,e,u){t(n,e,u)||(r[e]=n) +});return r},J.once=function(n){var t,e;if(!dt(n))throw new ie;return function(){return t?e:(t=true,e=n.apply(this,arguments),n=null,e)}},J.pairs=function(n){for(var t=-1,e=Fe(n),r=e.length,u=Xt(r);++t<r;){var o=e[t];u[t]=[o,n[o]]}return u},J.partial=function(n){return ct(n,16,p(arguments,1))},J.partialRight=function(n){return ct(n,32,null,p(arguments,1))},J.pick=function(n,t,e){var r={};if(typeof t!="function")for(var u=-1,o=ut(arguments,true,false,1),i=wt(n)?o.length:0;++u<i;){var a=o[u];a in n&&(r[a]=n[a]) +}else t=J.createCallback(t,e,3),g(n,function(n,e,u){t(n,e,u)&&(r[e]=n)});return r},J.pluck=Ve,J.property=Jt,J.pull=function(n){for(var t=arguments,e=0,r=t.length,u=n?n.length:0;++e<r;)for(var o=-1,i=t[e];++o<u;)n[o]===i&&(de.call(n,o--,1),u--);return n},J.range=function(n,t,e){n=+n||0,e=typeof e=="number"?e:+e||1,null==t&&(t=n,n=0);var r=-1;t=Ie(0,se((t-n)/(e||1)));for(var u=Xt(t);++r<t;)u[r]=n,n+=e;return u},J.reject=function(n,t,e){return t=J.createCallback(t,e,3),Nt(n,function(n,e,r){return!t(n,e,r) +})},J.remove=function(n,t,e){var r=-1,u=n?n.length:0,o=[];for(t=J.createCallback(t,e,3);++r<u;)e=n[r],t(e,r,n)&&(o.push(e),de.call(n,r--,1),u--);return o},J.rest=qt,J.shuffle=Tt,J.sortBy=function(n,t,e){var r=-1,o=Te(t),i=n?n.length:0,p=Xt(typeof i=="number"?i:0);for(o||(t=J.createCallback(t,e,3)),St(n,function(n,e,u){var i=p[++r]=f();o?i.m=Rt(t,function(t){return n[t]}):(i.m=a())[0]=t(n,e,u),i.n=r,i.o=n}),i=p.length,p.sort(u);i--;)n=p[i],p[i]=n.o,o||l(n.m),c(n);return p},J.tap=function(n,t){return t(n),n +},J.throttle=function(n,t,e){var r=true,u=true;if(!dt(n))throw new ie;return false===e?r=false:wt(e)&&(r="leading"in e?e.leading:r,u="trailing"in e?e.trailing:u),L.leading=r,L.maxWait=t,L.trailing=u,Vt(n,t,L)},J.times=function(n,t,e){n=-1<(n=+n)?n:0;var r=-1,u=Xt(n);for(t=tt(t,e,1);++r<n;)u[r]=t(r);return u},J.toArray=function(n){return n&&typeof n.length=="number"?p(n):xt(n)},J.transform=function(n,t,e,r){var u=Te(n);if(null==e)if(u)e=[];else{var o=n&&n.constructor;e=nt(o&&o.prototype)}return t&&(t=J.createCallback(t,r,4),(u?St:h)(n,function(n,r,u){return t(e,n,r,u) +})),e},J.union=function(){return ft(ut(arguments,true,true))},J.uniq=Pt,J.values=xt,J.where=Nt,J.without=function(n){return rt(n,p(arguments,1))},J.wrap=function(n,t){return ct(t,16,[n])},J.xor=function(){for(var n=-1,t=arguments.length;++n<t;){var e=arguments[n];if(Te(e)||yt(e))var r=r?ft(rt(r,e).concat(rt(e,r))):e}return r||[]},J.zip=Kt,J.zipObject=Lt,J.collect=Rt,J.drop=qt,J.each=St,J.eachRight=Et,J.extend=U,J.methods=bt,J.object=Lt,J.select=Nt,J.tail=qt,J.unique=Pt,J.unzip=Kt,Gt(J),J.clone=function(n,t,e,r){return typeof t!="boolean"&&null!=t&&(r=e,e=t,t=false),Z(n,t,typeof e=="function"&&tt(e,r,1)) +},J.cloneDeep=function(n,t,e){return Z(n,true,typeof t=="function"&&tt(t,e,1))},J.contains=Ct,J.escape=function(n){return null==n?"":oe(n).replace(ze,pt)},J.every=Ot,J.find=It,J.findIndex=function(n,t,e){var r=-1,u=n?n.length:0;for(t=J.createCallback(t,e,3);++r<u;)if(t(n[r],r,n))return r;return-1},J.findKey=function(n,t,e){var r;return t=J.createCallback(t,e,3),h(n,function(n,e,u){return t(n,e,u)?(r=e,false):void 0}),r},J.findLast=function(n,t,e){var r;return t=J.createCallback(t,e,3),Et(n,function(n,e,u){return t(n,e,u)?(r=n,false):void 0 +}),r},J.findLastIndex=function(n,t,e){var r=n?n.length:0;for(t=J.createCallback(t,e,3);r--;)if(t(n[r],r,n))return r;return-1},J.findLastKey=function(n,t,e){var r;return t=J.createCallback(t,e,3),mt(n,function(n,e,u){return t(n,e,u)?(r=e,false):void 0}),r},J.has=function(n,t){return n?me.call(n,t):false},J.identity=Ut,J.indexOf=Wt,J.isArguments=yt,J.isArray=Te,J.isBoolean=function(n){return true===n||false===n||n&&typeof n=="object"&&ce.call(n)==T||false},J.isDate=function(n){return n&&typeof n=="object"&&ce.call(n)==F||false +},J.isElement=function(n){return n&&1===n.nodeType||false},J.isEmpty=function(n){var t=true;if(!n)return t;var e=ce.call(n),r=n.length;return e==$||e==P||e==D||e==q&&typeof r=="number"&&dt(n.splice)?!r:(h(n,function(){return t=false}),t)},J.isEqual=function(n,t,e,r){return ot(n,t,typeof e=="function"&&tt(e,r,2))},J.isFinite=function(n){return Ce(n)&&!Oe(parseFloat(n))},J.isFunction=dt,J.isNaN=function(n){return jt(n)&&n!=+n},J.isNull=function(n){return null===n},J.isNumber=jt,J.isObject=wt,J.isPlainObject=Pe,J.isRegExp=function(n){return n&&typeof n=="object"&&ce.call(n)==z||false +},J.isString=kt,J.isUndefined=function(n){return typeof n=="undefined"},J.lastIndexOf=function(n,t,e){var r=n?n.length:0;for(typeof e=="number"&&(r=(0>e?Ie(0,r+e):Se(e,r-1))+1);r--;)if(n[r]===t)return r;return-1},J.mixin=Gt,J.noConflict=function(){return e._=le,this},J.noop=Ht,J.now=Ue,J.parseInt=Ge,J.random=function(n,t,e){var r=null==n,u=null==t;return null==e&&(typeof n=="boolean"&&u?(e=n,n=1):u||typeof t!="boolean"||(e=t,u=true)),r&&u&&(t=1),n=+n||0,u?(t=n,n=0):t=+t||0,e||n%1||t%1?(e=Re(),Se(n+e*(t-n+parseFloat("1e-"+((e+"").length-1))),t)):at(n,t) +},J.reduce=Dt,J.reduceRight=$t,J.result=function(n,t){if(n){var e=n[t];return dt(e)?n[t]():e}},J.runInContext=s,J.size=function(n){var t=n?n.length:0;return typeof t=="number"?t:Fe(n).length},J.some=Ft,J.sortedIndex=zt,J.template=function(n,t,e){var r=J.templateSettings;n=oe(n||""),e=_({},e,r);var u,o=_({},e.imports,r.imports),r=Fe(o),o=xt(o),a=0,f=e.interpolate||S,l="__p+='",f=ue((e.escape||S).source+"|"+f.source+"|"+(f===N?x:S).source+"|"+(e.evaluate||S).source+"|$","g");n.replace(f,function(t,e,r,o,f,c){return r||(r=o),l+=n.slice(a,c).replace(R,i),e&&(l+="'+__e("+e+")+'"),f&&(u=true,l+="';"+f+";\n__p+='"),r&&(l+="'+((__t=("+r+"))==null?'':__t)+'"),a=c+t.length,t +}),l+="';",f=e=e.variable,f||(e="obj",l="with("+e+"){"+l+"}"),l=(u?l.replace(w,""):l).replace(j,"$1").replace(k,"$1;"),l="function("+e+"){"+(f?"":e+"||("+e+"={});")+"var __t,__p='',__e=_.escape"+(u?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+l+"return __p}";try{var c=ne(r,"return "+l).apply(v,o)}catch(p){throw p.source=l,p}return t?c(t):(c.source=l,c)},J.unescape=function(n){return null==n?"":oe(n).replace(qe,gt)},J.uniqueId=function(n){var t=++y;return oe(null==n?"":n)+t +},J.all=Ot,J.any=Ft,J.detect=It,J.findWhere=It,J.foldl=Dt,J.foldr=$t,J.include=Ct,J.inject=Dt,Gt(function(){var n={};return h(J,function(t,e){J.prototype[e]||(n[e]=t)}),n}(),false),J.first=Bt,J.last=function(n,t,e){var r=0,u=n?n.length:0;if(typeof t!="number"&&null!=t){var o=u;for(t=J.createCallback(t,e,3);o--&&t(n[o],o,n);)r++}else if(r=t,null==r||e)return n?n[u-1]:v;return p(n,Ie(0,u-r))},J.sample=function(n,t,e){return n&&typeof n.length!="number"&&(n=xt(n)),null==t||e?n?n[at(0,n.length-1)]:v:(n=Tt(n),n.length=Se(Ie(0,t),n.length),n) +},J.take=Bt,J.head=Bt,h(J,function(n,t){var e="sample"!==t;J.prototype[t]||(J.prototype[t]=function(t,r){var u=this.__chain__,o=n(this.__wrapped__,t,r);return u||null!=t&&(!r||e&&typeof t=="function")?new Q(o,u):o})}),J.VERSION="2.4.1",J.prototype.chain=function(){return this.__chain__=true,this},J.prototype.toString=function(){return oe(this.__wrapped__)},J.prototype.value=Qt,J.prototype.valueOf=Qt,St(["join","pop","shift"],function(n){var t=ae[n];J.prototype[n]=function(){var n=this.__chain__,e=t.apply(this.__wrapped__,arguments); +return n?new Q(e,n):e}}),St(["push","reverse","sort","unshift"],function(n){var t=ae[n];J.prototype[n]=function(){return t.apply(this.__wrapped__,arguments),this}}),St(["concat","slice","splice"],function(n){var t=ae[n];J.prototype[n]=function(){return new Q(t.apply(this.__wrapped__,arguments),this.__chain__)}}),J}var v,h=[],g=[],y=0,m=+new Date+"",b=75,_=40,d=" \t\x0B\f\xa0\ufeff\n\r\u2028\u2029\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000",w=/\b__p\+='';/g,j=/\b(__p\+=)''\+/g,k=/(__e\(.*?\)|\b__t\))\+'';/g,x=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,C=/\w*$/,O=/^\s*function[ \n\r\t]+\w/,N=/<%=([\s\S]+?)%>/g,I=RegExp("^["+d+"]*0+(?=.$)"),S=/($^)/,E=/\bthis\b/,R=/['\n\r\t\u2028\u2029\\]/g,A="Array Boolean Date Function Math Number Object RegExp String _ attachEvent clearTimeout isFinite isNaN parseInt setTimeout".split(" "),D="[object Arguments]",$="[object Array]",T="[object Boolean]",F="[object Date]",B="[object Function]",W="[object Number]",q="[object Object]",z="[object RegExp]",P="[object String]",K={}; +K[B]=false,K[D]=K[$]=K[T]=K[F]=K[W]=K[q]=K[z]=K[P]=true;var L={leading:false,maxWait:0,trailing:false},M={configurable:false,enumerable:false,value:null,writable:false},V={"boolean":false,"function":true,object:true,number:false,string:false,undefined:false},U={"\\":"\\","'":"'","\n":"n","\r":"r","\t":"t","\u2028":"u2028","\u2029":"u2029"},G=V[typeof window]&&window||this,H=V[typeof exports]&&exports&&!exports.nodeType&&exports,J=V[typeof module]&&module&&!module.nodeType&&module,Q=J&&J.exports===H&&H,X=V[typeof global]&&global;!X||X.global!==X&&X.window!==X||(G=X); +var Y=s();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(G._=Y, define(function(){return Y})):H&&J?Q?(J.exports=Y)._=Y:H._=Y:G._=Y}).call(this); \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/python/django/renkanmanager/static/renkanmanager/lib/lodash/lodash.underscore.js Mon Apr 27 17:22:46 2015 +0200 @@ -0,0 +1,4979 @@ +/** + * @license + * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/> + * Build: `lodash underscore exports="amd,commonjs,global,node" -o ./dist/lodash.underscore.js` + * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/> + * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE> + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license <http://lodash.com/license> + */ +;(function() { + + /** Used as a safe reference for `undefined` in pre ES5 environments */ + var undefined; + + /** Used to generate unique IDs */ + var idCounter = 0; + + /** Used internally to indicate various things */ + var indicatorObject = {}; + + /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */ + var keyPrefix = +new Date + ''; + + /** Used to match "interpolate" template delimiters */ + var reInterpolate = /<%=([\s\S]+?)%>/g; + + /** Used to ensure capturing order of template delimiters */ + var reNoMatch = /($^)/; + + /** Used to match unescaped characters in compiled string literals */ + var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g; + + /** `Object#toString` result shortcuts */ + var argsClass = '[object Arguments]', + arrayClass = '[object Array]', + boolClass = '[object Boolean]', + dateClass = '[object Date]', + funcClass = '[object Function]', + numberClass = '[object Number]', + objectClass = '[object Object]', + regexpClass = '[object RegExp]', + stringClass = '[object String]'; + + /** Used to determine if values are of the language type Object */ + var objectTypes = { + 'boolean': false, + 'function': true, + 'object': true, + 'number': false, + 'string': false, + 'undefined': false + }; + + /** Used to escape characters for inclusion in compiled string literals */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\t': 't', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + /** Used as a reference to the global object */ + var root = (objectTypes[typeof window] && window) || this; + + /** Detect free variable `exports` */ + var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; + + /** Detect free variable `module` */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports` */ + var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; + + /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */ + var freeGlobal = objectTypes[typeof global] && global; + if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { + root = freeGlobal; + } + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `_.indexOf` without support for binary searches + * or `fromIndex` constraints. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value or `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + var index = (fromIndex || 0) - 1, + length = array ? array.length : 0; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Used by `sortBy` to compare transformed `collection` elements, stable sorting + * them in ascending order. + * + * @private + * @param {Object} a The object to compare to `b`. + * @param {Object} b The object to compare to `a`. + * @returns {number} Returns the sort order indicator of `1` or `-1`. + */ + function compareAscending(a, b) { + var ac = a.criteria, + bc = b.criteria, + index = -1, + length = ac.length; + + while (++index < length) { + var value = ac[index], + other = bc[index]; + + if (value !== other) { + if (value > other || typeof value == 'undefined') { + return 1; + } + if (value < other || typeof other == 'undefined') { + return -1; + } + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to return the same value for + // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247 + // + // This also ensures a stable sort in V8 and other engines. + // See http://code.google.com/p/v8/issues/detail?id=90 + return a.index - b.index; + } + + /** + * Used by `template` to escape characters for inclusion in compiled + * string literals. + * + * @private + * @param {string} match The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeStringChar(match) { + return '\\' + stringEscapes[match]; + } + + /** + * Slices the `collection` from the `start` index up to, but not including, + * the `end` index. + * + * Note: This function is used instead of `Array#slice` to support node lists + * in IE < 9 and to ensure dense arrays are returned. + * + * @private + * @param {Array|Object|string} collection The collection to slice. + * @param {number} start The start index. + * @param {number} end The end index. + * @returns {Array} Returns the new array. + */ + function slice(array, start, end) { + start || (start = 0); + if (typeof end == 'undefined') { + end = array ? array.length : 0; + } + var index = -1, + length = end - start || 0, + result = Array(length < 0 ? 0 : length); + + while (++index < length) { + result[index] = array[start + index]; + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Used for `Array` method references. + * + * Normally `Array.prototype` would suffice, however, using an array literal + * avoids issues in Narwhal. + */ + var arrayRef = []; + + /** Used for native method references */ + var objectProto = Object.prototype; + + /** Used to restore the original `_` reference in `noConflict` */ + var oldDash = root._; + + /** Used to resolve the internal [[Class]] of values */ + var toString = objectProto.toString; + + /** Used to detect if a method is native */ + var reNative = RegExp('^' + + String(toString) + .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + .replace(/toString| for [^\]]+/g, '.*?') + '$' + ); + + /** Native method shortcuts */ + var ceil = Math.ceil, + floor = Math.floor, + hasOwnProperty = objectProto.hasOwnProperty, + push = arrayRef.push, + propertyIsEnumerable = objectProto.propertyIsEnumerable; + + /* Native method shortcuts for methods with the same name as other `lodash` methods */ + var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, + nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, + nativeIsFinite = root.isFinite, + nativeIsNaN = root.isNaN, + nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, + nativeMax = Math.max, + nativeMin = Math.min, + nativeRandom = Math.random; + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps the given value to enable intuitive + * method chaining. + * + * In addition to Lo-Dash methods, wrappers also have the following `Array` methods: + * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, + * and `unshift` + * + * Chaining is supported in custom builds as long as the `value` method is + * implicitly or explicitly included in the build. + * + * The chainable wrapper functions are: + * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, + * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`, + * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, + * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, + * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`, + * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, + * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, + * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, + * and `zip` + * + * The non-chainable wrapper functions are: + * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`, + * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, + * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, + * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, + * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`, + * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`, + * `template`, `unescape`, `uniqueId`, and `value` + * + * The wrapper functions `first` and `last` return wrapped values when `n` is + * provided, otherwise they return unwrapped values. + * + * Explicit chaining can be enabled by using the `_.chain` method. + * + * @name _ + * @constructor + * @category Chaining + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns a `lodash` instance. + * @example + * + * var wrapped = _([1, 2, 3]); + * + * // returns an unwrapped value + * wrapped.reduce(function(sum, num) { + * return sum + num; + * }); + * // => 6 + * + * // returns a wrapped value + * var squares = wrapped.map(function(num) { + * return num * num; + * }); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + return (value instanceof lodash) + ? value + : new lodashWrapper(value); + } + + /** + * A fast path for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap in a `lodash` instance. + * @param {boolean} chainAll A flag to enable chaining for all methods + * @returns {Object} Returns a `lodash` instance. + */ + function lodashWrapper(value, chainAll) { + this.__chain__ = !!chainAll; + this.__wrapped__ = value; + } + // ensure `new lodashWrapper` is an instance of `lodash` + lodashWrapper.prototype = lodash.prototype; + + /** + * An object used to flag environments features. + * + * @static + * @memberOf _ + * @type Object + */ + var support = {}; + + (function() { + var object = { '0': 1, 'length': 1 }; + + /** + * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly. + * + * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()` + * and `splice()` functions that fail to remove the last element, `value[0]`, + * of array-like objects even though the `length` property is set to `0`. + * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()` + * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9. + * + * @memberOf _.support + * @type boolean + */ + support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]); + }(1)); + + /** + * By default, the template delimiters used by Lo-Dash are similar to those in + * embedded Ruby (ERB). Change the following template settings to use alternative + * delimiters. + * + * @static + * @memberOf _ + * @type Object + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'escape': /<%-([\s\S]+?)%>/g, + + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'evaluate': /<%([\s\S]+?)%>/g, + + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type string + */ + 'variable': '' + }; + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `_.bind` that creates the bound function and + * sets its meta data. + * + * @private + * @param {Array} bindData The bind data array. + * @returns {Function} Returns the new bound function. + */ + function baseBind(bindData) { + var func = bindData[0], + partialArgs = bindData[2], + thisArg = bindData[4]; + + function bound() { + // `Function#bind` spec + // http://es5.github.io/#x15.3.4.5 + if (partialArgs) { + // avoid `arguments` object deoptimizations by using `slice` instead + // of `Array.prototype.slice.call` and not assigning `arguments` to a + // variable as a ternary expression + var args = slice(partialArgs); + push.apply(args, arguments); + } + // mimic the constructor's `return` behavior + // http://es5.github.io/#x13.2.2 + if (this instanceof bound) { + // ensure `new bound` is an instance of `func` + var thisBinding = baseCreate(func.prototype), + result = func.apply(thisBinding, args || arguments); + return isObject(result) ? result : thisBinding; + } + return func.apply(thisArg, args || arguments); + } + return bound; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + function baseCreate(prototype, properties) { + return isObject(prototype) ? nativeCreate(prototype) : {}; + } + // fallback for browsers without `Object.create` + if (!nativeCreate) { + baseCreate = (function() { + function Object() {} + return function(prototype) { + if (isObject(prototype)) { + Object.prototype = prototype; + var result = new Object; + Object.prototype = null; + } + return result || root.Object(); + }; + }()); + } + + /** + * The base implementation of `_.createCallback` without support for creating + * "_.pluck" or "_.where" style callbacks. + * + * @private + * @param {*} [func=identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of the created callback. + * @param {number} [argCount] The number of arguments the callback accepts. + * @returns {Function} Returns a callback function. + */ + function baseCreateCallback(func, thisArg, argCount) { + if (typeof func != 'function') { + return identity; + } + // exit early for no `thisArg` or already bound by `Function#bind` + if (typeof thisArg == 'undefined' || !('prototype' in func)) { + return func; + } + switch (argCount) { + case 1: return function(value) { + return func.call(thisArg, value); + }; + case 2: return function(a, b) { + return func.call(thisArg, a, b); + }; + case 3: return function(value, index, collection) { + return func.call(thisArg, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(thisArg, accumulator, value, index, collection); + }; + } + return bind(func, thisArg); + } + + /** + * The base implementation of `createWrapper` that creates the wrapper and + * sets its meta data. + * + * @private + * @param {Array} bindData The bind data array. + * @returns {Function} Returns the new function. + */ + function baseCreateWrapper(bindData) { + var func = bindData[0], + bitmask = bindData[1], + partialArgs = bindData[2], + partialRightArgs = bindData[3], + thisArg = bindData[4], + arity = bindData[5]; + + var isBind = bitmask & 1, + isBindKey = bitmask & 2, + isCurry = bitmask & 4, + isCurryBound = bitmask & 8, + key = func; + + function bound() { + var thisBinding = isBind ? thisArg : this; + if (partialArgs) { + var args = slice(partialArgs); + push.apply(args, arguments); + } + if (partialRightArgs || isCurry) { + args || (args = slice(arguments)); + if (partialRightArgs) { + push.apply(args, partialRightArgs); + } + if (isCurry && args.length < arity) { + bitmask |= 16 & ~32; + return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]); + } + } + args || (args = arguments); + if (isBindKey) { + func = thisBinding[key]; + } + if (this instanceof bound) { + thisBinding = baseCreate(func.prototype); + var result = func.apply(thisBinding, args); + return isObject(result) ? result : thisBinding; + } + return func.apply(thisBinding, args); + } + return bound; + } + + /** + * The base implementation of `_.difference` that accepts a single array + * of values to exclude. + * + * @private + * @param {Array} array The array to process. + * @param {Array} [values] The array of values to exclude. + * @returns {Array} Returns a new array of filtered values. + */ + function baseDifference(array, values) { + var index = -1, + indexOf = getIndexOf(), + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (indexOf(values, value) < 0) { + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.flatten` without support for callback + * shorthands or `thisArg` binding. + * + * @private + * @param {Array} array The array to flatten. + * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. + * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects. + * @param {number} [fromIndex=0] The index to start from. + * @returns {Array} Returns a new flattened array. + */ + function baseFlatten(array, isShallow, isStrict, fromIndex) { + var index = (fromIndex || 0) - 1, + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + + if (value && typeof value == 'object' && typeof value.length == 'number' + && (isArray(value) || isArguments(value))) { + // recursively flatten arrays (susceptible to call stack limits) + if (!isShallow) { + value = baseFlatten(value, isShallow, isStrict); + } + var valIndex = -1, + valLength = value.length, + resIndex = result.length; + + result.length += valLength; + while (++valIndex < valLength) { + result[resIndex++] = value[valIndex]; + } + } else if (!isStrict) { + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.isEqual`, without support for `thisArg` binding, + * that allows partial "_.where" style comparisons. + * + * @private + * @param {*} a The value to compare. + * @param {*} b The other value to compare. + * @param {Function} [callback] The function to customize comparing values. + * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons. + * @param {Array} [stackA=[]] Tracks traversed `a` objects. + * @param {Array} [stackB=[]] Tracks traversed `b` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(a, b, stackA, stackB) { + if (a === b) { + return a !== 0 || (1 / a == 1 / b); + } + var type = typeof a, + otherType = typeof b; + + if (a === a && + !(a && objectTypes[type]) && + !(b && objectTypes[otherType])) { + return false; + } + if (a == null || b == null) { + return a === b; + } + var className = toString.call(a), + otherClass = toString.call(b); + + if (className != otherClass) { + return false; + } + switch (className) { + case boolClass: + case dateClass: + return +a == +b; + + case numberClass: + return a != +a + ? b != +b + : (a == 0 ? (1 / a == 1 / b) : a == +b); + + case regexpClass: + case stringClass: + return a == String(b); + } + var isArr = className == arrayClass; + if (!isArr) { + var aWrapped = a instanceof lodash, + bWrapped = b instanceof lodash; + + if (aWrapped || bWrapped) { + return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, stackA, stackB); + } + if (className != objectClass) { + return false; + } + var ctorA = a.constructor, + ctorB = b.constructor; + + if (ctorA != ctorB && + !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && + ('constructor' in a && 'constructor' in b) + ) { + return false; + } + } + stackA || (stackA = []); + stackB || (stackB = []); + + var length = stackA.length; + while (length--) { + if (stackA[length] == a) { + return stackB[length] == b; + } + } + var result = true, + size = 0; + + stackA.push(a); + stackB.push(b); + + if (isArr) { + size = b.length; + result = size == a.length; + + if (result) { + while (size--) { + if (!(result = baseIsEqual(a[size], b[size], stackA, stackB))) { + break; + } + } + } + } + else { + forIn(b, function(value, key, b) { + if (hasOwnProperty.call(b, key)) { + size++; + return !(result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, stackA, stackB)) && indicatorObject; + } + }); + + if (result) { + forIn(a, function(value, key, a) { + if (hasOwnProperty.call(a, key)) { + return !(result = --size > -1) && indicatorObject; + } + }); + } + } + stackA.pop(); + stackB.pop(); + return result; + } + + /** + * The base implementation of `_.random` without argument juggling or support + * for returning floating-point numbers. + * + * @private + * @param {number} min The minimum possible value. + * @param {number} max The maximum possible value. + * @returns {number} Returns a random number. + */ + function baseRandom(min, max) { + return min + floor(nativeRandom() * (max - min + 1)); + } + + /** + * The base implementation of `_.uniq` without support for callback shorthands + * or `thisArg` binding. + * + * @private + * @param {Array} array The array to process. + * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. + * @param {Function} [callback] The function called per iteration. + * @returns {Array} Returns a duplicate-value-free array. + */ + function baseUniq(array, isSorted, callback) { + var index = -1, + indexOf = getIndexOf(), + length = array ? array.length : 0, + result = [], + seen = callback ? [] : result; + + while (++index < length) { + var value = array[index], + computed = callback ? callback(value, index, array) : value; + + if (isSorted + ? !index || seen[seen.length - 1] !== computed + : indexOf(seen, computed) < 0 + ) { + if (callback) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + /** + * Creates a function that aggregates a collection, creating an object composed + * of keys generated from the results of running each element of the collection + * through a callback. The given `setter` function sets the keys and values + * of the composed object. + * + * @private + * @param {Function} setter The setter function. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter) { + return function(collection, callback, thisArg) { + var result = {}; + callback = createCallback(callback, thisArg, 3); + + var index = -1, + length = collection ? collection.length : 0; + + if (typeof length == 'number') { + while (++index < length) { + var value = collection[index]; + setter(result, value, callback(value, index, collection), collection); + } + } else { + forOwn(collection, function(value, key, collection) { + setter(result, value, callback(value, key, collection), collection); + }); + } + return result; + }; + } + + /** + * Creates a function that, when called, either curries or invokes `func` + * with an optional `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of method flags to compose. + * The bitmask may be composed of the following flags: + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` + * 8 - `_.curry` (bound) + * 16 - `_.partial` + * 32 - `_.partialRight` + * @param {Array} [partialArgs] An array of arguments to prepend to those + * provided to the new function. + * @param {Array} [partialRightArgs] An array of arguments to append to those + * provided to the new function. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new function. + */ + function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) { + var isBind = bitmask & 1, + isBindKey = bitmask & 2, + isCurry = bitmask & 4, + isCurryBound = bitmask & 8, + isPartial = bitmask & 16, + isPartialRight = bitmask & 32; + + if (!isBindKey && !isFunction(func)) { + throw new TypeError; + } + if (isPartial && !partialArgs.length) { + bitmask &= ~16; + isPartial = partialArgs = false; + } + if (isPartialRight && !partialRightArgs.length) { + bitmask &= ~32; + isPartialRight = partialRightArgs = false; + } + // fast path for `_.bind` + var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper; + return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]); + } + + /** + * Used by `escape` to convert characters to HTML entities. + * + * @private + * @param {string} match The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeHtmlChar(match) { + return htmlEscapes[match]; + } + + /** + * Gets the appropriate "indexOf" function. If the `_.indexOf` method is + * customized, this method returns the custom method, otherwise it returns + * the `baseIndexOf` function. + * + * @private + * @returns {Function} Returns the "indexOf" function. + */ + function getIndexOf() { + var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result; + return result; + } + + /** + * Checks if `value` is a native function. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a native function, else `false`. + */ + function isNative(value) { + return typeof value == 'function' && reNative.test(value); + } + + /** + * Used by `unescape` to convert HTML entities to characters. + * + * @private + * @param {string} match The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + function unescapeHtmlChar(match) { + return htmlUnescapes[match]; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Checks if `value` is an `arguments` object. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`. + * @example + * + * (function() { return _.isArguments(arguments); })(1, 2, 3); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + toString.call(value) == argsClass || false; + } + // fallback for browsers that can't detect `arguments` objects by [[Class]] + if (!isArguments(arguments)) { + isArguments = function(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false; + }; + } + + /** + * Checks if `value` is an array. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an array, else `false`. + * @example + * + * (function() { return _.isArray(arguments); })(); + * // => false + * + * _.isArray([1, 2, 3]); + * // => true + */ + var isArray = nativeIsArray || function(value) { + return value && typeof value == 'object' && typeof value.length == 'number' && + toString.call(value) == arrayClass || false; + }; + + /** + * A fallback implementation of `Object.keys` which produces an array of the + * given object's own enumerable property names. + * + * @private + * @type Function + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names. + */ + var shimKeys = function(object) { + var index, iterable = object, result = []; + if (!iterable) return result; + if (!(objectTypes[typeof object])) return result; + for (index in iterable) { + if (hasOwnProperty.call(iterable, index)) { + result.push(index); + } + } + return result + }; + + /** + * Creates an array composed of the own enumerable property names of an object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names. + * @example + * + * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); + * // => ['one', 'two', 'three'] (property order is not guaranteed across environments) + */ + var keys = !nativeKeys ? shimKeys : function(object) { + if (!isObject(object)) { + return []; + } + return nativeKeys(object); + }; + + /** + * Used to convert characters to HTML entities: + * + * Though the `>` character is escaped for symmetry, characters like `>` and `/` + * don't require escaping in HTML and have no special meaning unless they're part + * of a tag or an unquoted attribute value. + * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact") + */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + + /** Used to convert HTML entities to characters */ + var htmlUnescapes = invert(htmlEscapes); + + /** Used to match HTML entities and HTML characters */ + var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'), + reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g'); + + /*--------------------------------------------------------------------------*/ + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object. Subsequent sources will overwrite property assignments of previous + * sources. If a callback is provided it will be executed to produce the + * assigned values. The callback is bound to `thisArg` and invoked with two + * arguments; (objectValue, sourceValue). + * + * @static + * @memberOf _ + * @type Function + * @alias extend + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param {Function} [callback] The function to customize assigning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the destination object. + * @example + * + * _.assign({ 'name': 'fred' }, { 'employer': 'slate' }); + * // => { 'name': 'fred', 'employer': 'slate' } + * + * var defaults = _.partialRight(_.assign, function(a, b) { + * return typeof a == 'undefined' ? b : a; + * }); + * + * var object = { 'name': 'barney' }; + * defaults(object, { 'name': 'fred', 'employer': 'slate' }); + * // => { 'name': 'barney', 'employer': 'slate' } + */ + function assign(object) { + if (!object) { + return object; + } + for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) { + var iterable = arguments[argsIndex]; + if (iterable) { + for (var key in iterable) { + object[key] = iterable[key]; + } + } + } + return object; + } + + /** + * Creates a clone of `value`. If `isDeep` is `true` nested objects will also + * be cloned, otherwise they will be assigned by reference. If a callback + * is provided it will be executed to produce the cloned values. If the + * callback returns `undefined` cloning will be handled by the method instead. + * The callback is bound to `thisArg` and invoked with one argument; (value). + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to clone. + * @param {boolean} [isDeep=false] Specify a deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the cloned value. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * var shallow = _.clone(characters); + * shallow[0] === characters[0]; + * // => true + * + * var deep = _.clone(characters, true); + * deep[0] === characters[0]; + * // => false + * + * _.mixin({ + * 'clone': _.partialRight(_.clone, function(value) { + * return _.isElement(value) ? value.cloneNode(false) : undefined; + * }) + * }); + * + * var clone = _.clone(document.body); + * clone.childNodes.length; + * // => 0 + */ + function clone(value) { + return isObject(value) + ? (isArray(value) ? slice(value) : assign({}, value)) + : value; + } + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object for all destination properties that resolve to `undefined`. Once a + * property is set, additional defaults of the same property will be ignored. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The destination object. + * @param {...Object} [source] The source objects. + * @param- {Object} [guard] Allows working with `_.reduce` without using its + * `key` and `object` arguments as sources. + * @returns {Object} Returns the destination object. + * @example + * + * var object = { 'name': 'barney' }; + * _.defaults(object, { 'name': 'fred', 'employer': 'slate' }); + * // => { 'name': 'barney', 'employer': 'slate' } + */ + function defaults(object) { + if (!object) { + return object; + } + for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) { + var iterable = arguments[argsIndex]; + if (iterable) { + for (var key in iterable) { + if (typeof object[key] == 'undefined') { + object[key] = iterable[key]; + } + } + } + } + return object; + } + + /** + * Iterates over own and inherited enumerable properties of an object, + * executing the callback for each property. The callback is bound to `thisArg` + * and invoked with three arguments; (value, key, object). Callbacks may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * Shape.prototype.move = function(x, y) { + * this.x += x; + * this.y += y; + * }; + * + * _.forIn(new Shape, function(value, key) { + * console.log(key); + * }); + * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments) + */ + var forIn = function(collection, callback) { + var index, iterable = collection, result = iterable; + if (!iterable) return result; + if (!objectTypes[typeof iterable]) return result; + for (index in iterable) { + if (callback(iterable[index], index, collection) === indicatorObject) return result; + } + return result + }; + + /** + * Iterates over own enumerable properties of an object, executing the callback + * for each property. The callback is bound to `thisArg` and invoked with three + * arguments; (value, key, object). Callbacks may exit iteration early by + * explicitly returning `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { + * console.log(key); + * }); + * // => logs '0', '1', and 'length' (property order is not guaranteed across environments) + */ + var forOwn = function(collection, callback) { + var index, iterable = collection, result = iterable; + if (!iterable) return result; + if (!objectTypes[typeof iterable]) return result; + for (index in iterable) { + if (hasOwnProperty.call(iterable, index)) { + if (callback(iterable[index], index, collection) === indicatorObject) return result; + } + } + return result + }; + + /** + * Creates a sorted array of property names of all enumerable properties, + * own and inherited, of `object` that have function values. + * + * @static + * @memberOf _ + * @alias methods + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property names that have function values. + * @example + * + * _.functions(_); + * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] + */ + function functions(object) { + var result = []; + forIn(object, function(value, key) { + if (isFunction(value)) { + result.push(key); + } + }); + return result.sort(); + } + + /** + * Checks if the specified property name exists as a direct property of `object`, + * instead of an inherited property. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @param {string} key The name of the property to check. + * @returns {boolean} Returns `true` if key is a direct property, else `false`. + * @example + * + * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); + * // => true + */ + function has(object, key) { + return object ? hasOwnProperty.call(object, key) : false; + } + + /** + * Creates an object composed of the inverted keys and values of the given object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to invert. + * @returns {Object} Returns the created inverted object. + * @example + * + * _.invert({ 'first': 'fred', 'second': 'barney' }); + * // => { 'fred': 'first', 'barney': 'second' } + */ + function invert(object) { + var index = -1, + props = keys(object), + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index]; + result[object[key]] = key; + } + return result; + } + + /** + * Checks if `value` is a boolean value. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`. + * @example + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || + value && typeof value == 'object' && toString.call(value) == boolClass || false; + } + + /** + * Checks if `value` is a date. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a date, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + */ + function isDate(value) { + return value && typeof value == 'object' && toString.call(value) == dateClass || false; + } + + /** + * Checks if `value` is a DOM element. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + */ + function isElement(value) { + return value && value.nodeType === 1 || false; + } + + /** + * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a + * length of `0` and objects with no own enumerable properties are considered + * "empty". + * + * @static + * @memberOf _ + * @category Objects + * @param {Array|Object|string} value The value to inspect. + * @returns {boolean} Returns `true` if the `value` is empty, else `false`. + * @example + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({}); + * // => true + * + * _.isEmpty(''); + * // => true + */ + function isEmpty(value) { + if (!value) { + return true; + } + if (isArray(value) || isString(value)) { + return !value.length; + } + for (var key in value) { + if (hasOwnProperty.call(value, key)) { + return false; + } + } + return true; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent to each other. If a callback is provided it will be executed + * to compare values. If the callback returns `undefined` comparisons will + * be handled by the method instead. The callback is bound to `thisArg` and + * invoked with two arguments; (a, b). + * + * @static + * @memberOf _ + * @category Objects + * @param {*} a The value to compare. + * @param {*} b The other value to compare. + * @param {Function} [callback] The function to customize comparing values. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'name': 'fred' }; + * var copy = { 'name': 'fred' }; + * + * object == copy; + * // => false + * + * _.isEqual(object, copy); + * // => true + * + * var words = ['hello', 'goodbye']; + * var otherWords = ['hi', 'goodbye']; + * + * _.isEqual(words, otherWords, function(a, b) { + * var reGreet = /^(?:hello|hi)$/i, + * aGreet = _.isString(a) && reGreet.test(a), + * bGreet = _.isString(b) && reGreet.test(b); + * + * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined; + * }); + * // => true + */ + function isEqual(a, b) { + return baseIsEqual(a, b); + } + + /** + * Checks if `value` is, or can be coerced to, a finite number. + * + * Note: This is not the same as native `isFinite` which will return true for + * booleans and empty strings. See http://es5.github.io/#x15.1.2.5. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is finite, else `false`. + * @example + * + * _.isFinite(-101); + * // => true + * + * _.isFinite('10'); + * // => true + * + * _.isFinite(true); + * // => false + * + * _.isFinite(''); + * // => false + * + * _.isFinite(Infinity); + * // => false + */ + function isFinite(value) { + return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); + } + + /** + * Checks if `value` is a function. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + */ + function isFunction(value) { + return typeof value == 'function'; + } + // fallback for older versions of Chrome and Safari + if (isFunction(/x/)) { + isFunction = function(value) { + return typeof value == 'function' && toString.call(value) == funcClass; + }; + } + + /** + * Checks if `value` is the language type of Object. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ + function isObject(value) { + // check if the value is the ECMAScript language type of Object + // http://es5.github.io/#x8 + // and avoid a V8 bug + // http://code.google.com/p/v8/issues/detail?id=2291 + return !!(value && objectTypes[typeof value]); + } + + /** + * Checks if `value` is `NaN`. + * + * Note: This is not the same as native `isNaN` which will return `true` for + * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // `NaN` as a primitive is the only value that is not equal to itself + // (perform the [[Class]] check first to avoid errors with some host objects in IE) + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(undefined); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is a number. + * + * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a number, else `false`. + * @example + * + * _.isNumber(8.4 * 5); + * // => true + */ + function isNumber(value) { + return typeof value == 'number' || + value && typeof value == 'object' && toString.call(value) == numberClass || false; + } + + /** + * Checks if `value` is a regular expression. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`. + * @example + * + * _.isRegExp(/fred/); + * // => true + */ + function isRegExp(value) { + return value && objectTypes[typeof value] && toString.call(value) == regexpClass || false; + } + + /** + * Checks if `value` is a string. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is a string, else `false`. + * @example + * + * _.isString('fred'); + * // => true + */ + function isString(value) { + return typeof value == 'string' || + value && typeof value == 'object' && toString.call(value) == stringClass || false; + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @memberOf _ + * @category Objects + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + */ + function isUndefined(value) { + return typeof value == 'undefined'; + } + + /** + * Creates a shallow clone of `object` excluding the specified properties. + * Property names may be specified as individual arguments or as arrays of + * property names. If a callback is provided it will be executed for each + * property of `object` omitting the properties the callback returns truey + * for. The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Function|...string|string[]} [callback] The properties to omit or the + * function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object without the omitted properties. + * @example + * + * _.omit({ 'name': 'fred', 'age': 40 }, 'age'); + * // => { 'name': 'fred' } + * + * _.omit({ 'name': 'fred', 'age': 40 }, function(value) { + * return typeof value == 'number'; + * }); + * // => { 'name': 'fred' } + */ + function omit(object) { + var props = []; + forIn(object, function(value, key) { + props.push(key); + }); + props = baseDifference(props, baseFlatten(arguments, true, false, 1)); + + var index = -1, + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index]; + result[key] = object[key]; + } + return result; + } + + /** + * Creates a two dimensional array of an object's key-value pairs, + * i.e. `[[key1, value1], [key2, value2]]`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns new array of key-value pairs. + * @example + * + * _.pairs({ 'barney': 36, 'fred': 40 }); + * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments) + */ + function pairs(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + var key = props[index]; + result[index] = [key, object[key]]; + } + return result; + } + + /** + * Creates a shallow clone of `object` composed of the specified properties. + * Property names may be specified as individual arguments or as arrays of + * property names. If a callback is provided it will be executed for each + * property of `object` picking the properties the callback returns truey + * for. The callback is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Function|...string|string[]} [callback] The function called per + * iteration or property names to pick, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object composed of the picked properties. + * @example + * + * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); + * // => { 'name': 'fred' } + * + * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { + * return key.charAt(0) != '_'; + * }); + * // => { 'name': 'fred' } + */ + function pick(object) { + var index = -1, + props = baseFlatten(arguments, true, false, 1), + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index]; + if (key in object) { + result[key] = object[key]; + } + } + return result; + } + + /** + * Creates an array composed of the own enumerable property values of `object`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns an array of property values. + * @example + * + * _.values({ 'one': 1, 'two': 2, 'three': 3 }); + * // => [1, 2, 3] (property order is not guaranteed across environments) + */ + function values(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + result[index] = object[props[index]]; + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Checks if a given value is present in a collection using strict equality + * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the + * offset from the end of the collection. + * + * @static + * @memberOf _ + * @alias include + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {*} target The value to check for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {boolean} Returns `true` if the `target` element is found, else `false`. + * @example + * + * _.contains([1, 2, 3], 1); + * // => true + * + * _.contains([1, 2, 3], 1, 2); + * // => false + * + * _.contains({ 'name': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.contains('pebbles', 'eb'); + * // => true + */ + function contains(collection, target) { + var indexOf = getIndexOf(), + length = collection ? collection.length : 0, + result = false; + if (length && typeof length == 'number') { + result = indexOf(collection, target) > -1; + } else { + forOwn(collection, function(value) { + return (result = value === target) && indicatorObject; + }); + } + return result; + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through the callback. The corresponding value + * of each key is the number of times the key was returned by the callback. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); }); + * // => { '4': 1, '6': 2 } + * + * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + var countBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); + }); + + /** + * Checks if the given callback returns truey value for **all** elements of + * a collection. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias all + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if all elements passed the callback check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes']); + * // => false + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.every(characters, 'age'); + * // => true + * + * // using "_.where" callback shorthand + * _.every(characters, { 'age': 36 }); + * // => false + */ + function every(collection, callback, thisArg) { + var result = true; + callback = createCallback(callback, thisArg, 3); + + var index = -1, + length = collection ? collection.length : 0; + + if (typeof length == 'number') { + while (++index < length) { + if (!(result = !!callback(collection[index], index, collection))) { + break; + } + } + } else { + forOwn(collection, function(value, index, collection) { + return !(result = !!callback(value, index, collection)) && indicatorObject; + }); + } + return result; + } + + /** + * Iterates over elements of a collection, returning an array of all elements + * the callback returns truey for. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias select + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of elements that passed the callback check. + * @example + * + * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => [2, 4, 6] + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.filter(characters, 'blocked'); + * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + * + * // using "_.where" callback shorthand + * _.filter(characters, { 'age': 36 }); + * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] + */ + function filter(collection, callback, thisArg) { + var result = []; + callback = createCallback(callback, thisArg, 3); + + var index = -1, + length = collection ? collection.length : 0; + + if (typeof length == 'number') { + while (++index < length) { + var value = collection[index]; + if (callback(value, index, collection)) { + result.push(value); + } + } + } else { + forOwn(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result.push(value); + } + }); + } + return result; + } + + /** + * Iterates over elements of a collection, returning the first element that + * the callback returns truey for. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias detect, findWhere + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the found element, else `undefined`. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true }, + * { 'name': 'pebbles', 'age': 1, 'blocked': false } + * ]; + * + * _.find(characters, function(chr) { + * return chr.age < 40; + * }); + * // => { 'name': 'barney', 'age': 36, 'blocked': false } + * + * // using "_.where" callback shorthand + * _.find(characters, { 'age': 1 }); + * // => { 'name': 'pebbles', 'age': 1, 'blocked': false } + * + * // using "_.pluck" callback shorthand + * _.find(characters, 'blocked'); + * // => { 'name': 'fred', 'age': 40, 'blocked': true } + */ + function find(collection, callback, thisArg) { + callback = createCallback(callback, thisArg, 3); + + var index = -1, + length = collection ? collection.length : 0; + + if (typeof length == 'number') { + while (++index < length) { + var value = collection[index]; + if (callback(value, index, collection)) { + return value; + } + } + } else { + var result; + forOwn(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result = value; + return indicatorObject; + } + }); + return result; + } + } + + /** + * Examines each element in a `collection`, returning the first that + * has the given properties. When checking `properties`, this method + * performs a deep comparison between values to determine if they are + * equivalent to each other. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Object} properties The object of property values to filter by. + * @returns {*} Returns the found element, else `undefined`. + * @example + * + * var food = [ + * { 'name': 'apple', 'organic': false, 'type': 'fruit' }, + * { 'name': 'banana', 'organic': true, 'type': 'fruit' }, + * { 'name': 'beet', 'organic': false, 'type': 'vegetable' } + * ]; + * + * _.findWhere(food, { 'type': 'vegetable' }); + * // => { 'name': 'beet', 'organic': false, 'type': 'vegetable' } + */ + function findWhere(object, properties) { + return where(object, properties, true); + } + + /** + * Iterates over elements of a collection, executing the callback for each + * element. The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). Callbacks may exit iteration early by + * explicitly returning `false`. + * + * Note: As with other "Collections" methods, objects with a `length` property + * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` + * may be used for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(','); + * // => logs each number and returns '1,2,3' + * + * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); }); + * // => logs each number and returns the object (property order is not guaranteed across environments) + */ + function forEach(collection, callback, thisArg) { + var index = -1, + length = collection ? collection.length : 0; + + callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); + if (typeof length == 'number') { + while (++index < length) { + if (callback(collection[index], index, collection) === indicatorObject) { + break; + } + } + } else { + forOwn(collection, callback); + } + } + + /** + * This method is like `_.forEach` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @alias eachRight + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(','); + * // => logs each number from right to left and returns '3,2,1' + */ + function forEachRight(collection, callback) { + var length = collection ? collection.length : 0; + if (typeof length == 'number') { + while (length--) { + if (callback(collection[length], length, collection) === false) { + break; + } + } + } else { + var props = keys(collection); + length = props.length; + forOwn(collection, function(value, key, collection) { + key = props ? props[--length] : --length; + return callback(collection[key], key, collection) === false && indicatorObject; + }); + } + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of a collection through the callback. The corresponding value + * of each key is an array of the elements responsible for generating the key. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false` + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); }); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * // using "_.pluck" callback shorthand + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + var groupBy = createAggregator(function(result, value, key) { + (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); + }); + + /** + * Creates an object composed of keys generated from the results of running + * each element of the collection through the given callback. The corresponding + * value of each key is the last element responsible for generating the key. + * The callback is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var keys = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.indexBy(keys, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + */ + var indexBy = createAggregator(function(result, value, key) { + result[key] = value; + }); + + /** + * Invokes the method named by `methodName` on each element in the `collection` + * returning an array of the results of each invoked method. Additional arguments + * will be provided to each invoked method. If `methodName` is a function it + * will be invoked for, and `this` bound to, each element in the `collection`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|string} methodName The name of the method to invoke or + * the function invoked per iteration. + * @param {...*} [arg] Arguments to invoke the method with. + * @returns {Array} Returns a new array of the results of each invoked method. + * @example + * + * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invoke([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ + function invoke(collection, methodName) { + var args = slice(arguments, 2), + index = -1, + isFunc = typeof methodName == 'function', + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + forEach(collection, function(value) { + result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args); + }); + return result; + } + + /** + * Creates an array of values by running each element in the collection + * through the callback. The callback is bound to `thisArg` and invoked with + * three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias collect + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of the results of each `callback` execution. + * @example + * + * _.map([1, 2, 3], function(num) { return num * 3; }); + * // => [3, 6, 9] + * + * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); + * // => [3, 6, 9] (property order is not guaranteed across environments) + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.map(characters, 'name'); + * // => ['barney', 'fred'] + */ + function map(collection, callback, thisArg) { + var index = -1, + length = collection ? collection.length : 0; + + callback = createCallback(callback, thisArg, 3); + if (typeof length == 'number') { + var result = Array(length); + while (++index < length) { + result[index] = callback(collection[index], index, collection); + } + } else { + result = []; + forOwn(collection, function(value, key, collection) { + result[++index] = callback(value, key, collection); + }); + } + return result; + } + + /** + * Retrieves the maximum value of a collection. If the collection is empty or + * falsey `-Infinity` is returned. If a callback is provided it will be executed + * for each value in the collection to generate the criterion by which the value + * is ranked. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.max(characters, function(chr) { return chr.age; }); + * // => { 'name': 'fred', 'age': 40 }; + * + * // using "_.pluck" callback shorthand + * _.max(characters, 'age'); + * // => { 'name': 'fred', 'age': 40 }; + */ + function max(collection, callback, thisArg) { + var computed = -Infinity, + result = computed; + + // allows working with functions like `_.map` without using + // their `index` argument as a callback + if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { + callback = null; + } + var index = -1, + length = collection ? collection.length : 0; + + if (callback == null && typeof length == 'number') { + while (++index < length) { + var value = collection[index]; + if (value > result) { + result = value; + } + } + } else { + callback = createCallback(callback, thisArg, 3); + + forEach(collection, function(value, index, collection) { + var current = callback(value, index, collection); + if (current > computed) { + computed = current; + result = value; + } + }); + } + return result; + } + + /** + * Retrieves the minimum value of a collection. If the collection is empty or + * falsey `Infinity` is returned. If a callback is provided it will be executed + * for each value in the collection to generate the criterion by which the value + * is ranked. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.min(characters, function(chr) { return chr.age; }); + * // => { 'name': 'barney', 'age': 36 }; + * + * // using "_.pluck" callback shorthand + * _.min(characters, 'age'); + * // => { 'name': 'barney', 'age': 36 }; + */ + function min(collection, callback, thisArg) { + var computed = Infinity, + result = computed; + + // allows working with functions like `_.map` without using + // their `index` argument as a callback + if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { + callback = null; + } + var index = -1, + length = collection ? collection.length : 0; + + if (callback == null && typeof length == 'number') { + while (++index < length) { + var value = collection[index]; + if (value < result) { + result = value; + } + } + } else { + callback = createCallback(callback, thisArg, 3); + + forEach(collection, function(value, index, collection) { + var current = callback(value, index, collection); + if (current < computed) { + computed = current; + result = value; + } + }); + } + return result; + } + + /** + * Retrieves the value of a specified property from all elements in the collection. + * + * @static + * @memberOf _ + * @type Function + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {string} property The name of the property to pluck. + * @returns {Array} Returns a new array of property values. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * _.pluck(characters, 'name'); + * // => ['barney', 'fred'] + */ + var pluck = map; + + /** + * Reduces a collection to a value which is the accumulated result of running + * each element in the collection through the callback, where each successive + * callback execution consumes the return value of the previous execution. If + * `accumulator` is not provided the first element of the collection will be + * used as the initial `accumulator` value. The callback is bound to `thisArg` + * and invoked with four arguments; (accumulator, value, index|key, collection). + * + * @static + * @memberOf _ + * @alias foldl, inject + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] Initial value of the accumulator. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var sum = _.reduce([1, 2, 3], function(sum, num) { + * return sum + num; + * }); + * // => 6 + * + * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { + * result[key] = num * 3; + * return result; + * }, {}); + * // => { 'a': 3, 'b': 6, 'c': 9 } + */ + function reduce(collection, callback, accumulator, thisArg) { + if (!collection) return accumulator; + var noaccum = arguments.length < 3; + callback = createCallback(callback, thisArg, 4); + + var index = -1, + length = collection.length; + + if (typeof length == 'number') { + if (noaccum) { + accumulator = collection[++index]; + } + while (++index < length) { + accumulator = callback(accumulator, collection[index], index, collection); + } + } else { + forOwn(collection, function(value, index, collection) { + accumulator = noaccum + ? (noaccum = false, value) + : callback(accumulator, value, index, collection) + }); + } + return accumulator; + } + + /** + * This method is like `_.reduce` except that it iterates over elements + * of a `collection` from right to left. + * + * @static + * @memberOf _ + * @alias foldr + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {*} [accumulator] Initial value of the accumulator. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the accumulated value. + * @example + * + * var list = [[0, 1], [2, 3], [4, 5]]; + * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + function reduceRight(collection, callback, accumulator, thisArg) { + var noaccum = arguments.length < 3; + callback = createCallback(callback, thisArg, 4); + forEachRight(collection, function(value, index, collection) { + accumulator = noaccum + ? (noaccum = false, value) + : callback(accumulator, value, index, collection); + }); + return accumulator; + } + + /** + * The opposite of `_.filter` this method returns the elements of a + * collection that the callback does **not** return truey for. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of elements that failed the callback check. + * @example + * + * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => [1, 3, 5] + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.reject(characters, 'blocked'); + * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] + * + * // using "_.where" callback shorthand + * _.reject(characters, { 'age': 36 }); + * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + */ + function reject(collection, callback, thisArg) { + callback = createCallback(callback, thisArg, 3); + return filter(collection, function(value, index, collection) { + return !callback(value, index, collection); + }); + } + + /** + * Retrieves a random element or `n` random elements from a collection. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to sample. + * @param {number} [n] The number of elements to sample. + * @param- {Object} [guard] Allows working with functions like `_.map` + * without using their `index` arguments as `n`. + * @returns {Array} Returns the random sample(s) of `collection`. + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + * + * _.sample([1, 2, 3, 4], 2); + * // => [3, 1] + */ + function sample(collection, n, guard) { + if (collection && typeof collection.length != 'number') { + collection = values(collection); + } + if (n == null || guard) { + return collection ? collection[baseRandom(0, collection.length - 1)] : undefined; + } + var result = shuffle(collection); + result.length = nativeMin(nativeMax(0, n), result.length); + return result; + } + + /** + * Creates an array of shuffled values, using a version of the Fisher-Yates + * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to shuffle. + * @returns {Array} Returns a new shuffled collection. + * @example + * + * _.shuffle([1, 2, 3, 4, 5, 6]); + * // => [4, 1, 6, 3, 5, 2] + */ + function shuffle(collection) { + var index = -1, + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + forEach(collection, function(value) { + var rand = baseRandom(0, ++index); + result[index] = result[rand]; + result[rand] = value; + }); + return result; + } + + /** + * Gets the size of the `collection` by returning `collection.length` for arrays + * and array-like objects or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns `collection.length` or number of own enumerable properties. + * @example + * + * _.size([1, 2]); + * // => 2 + * + * _.size({ 'one': 1, 'two': 2, 'three': 3 }); + * // => 3 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + var length = collection ? collection.length : 0; + return typeof length == 'number' ? length : keys(collection).length; + } + + /** + * Checks if the callback returns a truey value for **any** element of a + * collection. The function returns as soon as it finds a passing value and + * does not iterate over the entire collection. The callback is bound to + * `thisArg` and invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias any + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {boolean} Returns `true` if any element passed the callback check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'blocked': false }, + * { 'name': 'fred', 'age': 40, 'blocked': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.some(characters, 'blocked'); + * // => true + * + * // using "_.where" callback shorthand + * _.some(characters, { 'age': 1 }); + * // => false + */ + function some(collection, callback, thisArg) { + var result; + callback = createCallback(callback, thisArg, 3); + + var index = -1, + length = collection ? collection.length : 0; + + if (typeof length == 'number') { + while (++index < length) { + if ((result = callback(collection[index], index, collection))) { + break; + } + } + } else { + forOwn(collection, function(value, index, collection) { + return (result = callback(value, index, collection)) && indicatorObject; + }); + } + return !!result; + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through the callback. This method + * performs a stable sort, that is, it will preserve the original sort order + * of equal elements. The callback is bound to `thisArg` and invoked with + * three arguments; (value, index|key, collection). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an array of property names is provided for `callback` the collection + * will be sorted by each property value. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of sorted elements. + * @example + * + * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); }); + * // => [3, 1, 2] + * + * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math); + * // => [3, 1, 2] + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 }, + * { 'name': 'barney', 'age': 26 }, + * { 'name': 'fred', 'age': 30 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.map(_.sortBy(characters, 'age'), _.values); + * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]] + * + * // sorting by multiple properties + * _.map(_.sortBy(characters, ['name', 'age']), _.values); + * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] + */ + function sortBy(collection, callback, thisArg) { + var index = -1, + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + callback = createCallback(callback, thisArg, 3); + forEach(collection, function(value, key, collection) { + result[++index] = { + 'criteria': [callback(value, key, collection)], + 'index': index, + 'value': value + }; + }); + + length = result.length; + result.sort(compareAscending); + while (length--) { + result[length] = result[length].value; + } + return result; + } + + /** + * Converts the `collection` to an array. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|string} collection The collection to convert. + * @returns {Array} Returns the new converted array. + * @example + * + * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4); + * // => [2, 3, 4] + */ + function toArray(collection) { + if (isArray(collection)) { + return slice(collection); + } + if (collection && typeof collection.length == 'number') { + return map(collection); + } + return values(collection); + } + + /** + * Performs a deep comparison of each element in a `collection` to the given + * `properties` object, returning an array of all elements that have equivalent + * property values. + * + * @static + * @memberOf _ + * @type Function + * @category Collections + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Object} props The object of property values to filter by. + * @returns {Array} Returns a new array of elements that have the given properties. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }, + * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } + * ]; + * + * _.where(characters, { 'age': 36 }); + * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }] + * + * _.where(characters, { 'pets': ['dino'] }); + * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }] + */ + function where(collection, properties, first) { + return (first && isEmpty(properties)) + ? undefined + : (first ? find : filter)(collection, properties); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are all falsey. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to compact. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result.push(value); + } + } + return result; + } + + /** + * Creates an array excluding all values of the provided arrays using strict + * equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to process. + * @param {...Array} [values] The arrays of values to exclude. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.difference([1, 2, 3, 4, 5], [5, 2, 10]); + * // => [1, 3, 4] + */ + function difference(array) { + return baseDifference(array, baseFlatten(arguments, true, true, 1)); + } + + /** + * Gets the first element or first `n` elements of an array. If a callback + * is provided elements at the beginning of the array are returned as long + * as the callback returns truey. The callback is bound to `thisArg` and + * invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias head, take + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback] The function called + * per element or the number of elements to return. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the first element(s) of `array`. + * @example + * + * _.first([1, 2, 3]); + * // => 1 + * + * _.first([1, 2, 3], 2); + * // => [1, 2] + * + * _.first([1, 2, 3], function(num) { + * return num < 3; + * }); + * // => [1, 2] + * + * var characters = [ + * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.first(characters, 'blocked'); + * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }] + * + * // using "_.where" callback shorthand + * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name'); + * // => ['barney', 'fred'] + */ + function first(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = -1; + callback = createCallback(callback, thisArg, 3); + while (++index < length && callback(array[index], index, array)) { + n++; + } + } else { + n = callback; + if (n == null || thisArg) { + return array ? array[0] : undefined; + } + } + return slice(array, 0, nativeMin(nativeMax(0, n), length)); + } + + /** + * Flattens a nested array (the nesting can be to any depth). If `isShallow` + * is truey, the array will only be flattened a single level. If a callback + * is provided each element of the array is passed through the callback before + * flattening. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to flatten. + * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new flattened array. + * @example + * + * _.flatten([1, [2], [3, [[4]]]]); + * // => [1, 2, 3, 4]; + * + * _.flatten([1, [2], [3, [[4]]]], true); + * // => [1, 2, 3, [[4]]]; + * + * var characters = [ + * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] }, + * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } + * ]; + * + * // using "_.pluck" callback shorthand + * _.flatten(characters, 'pets'); + * // => ['hoppy', 'baby puss', 'dino'] + */ + function flatten(array, isShallow) { + return baseFlatten(array, isShallow); + } + + /** + * Gets the index at which the first occurrence of `value` is found using + * strict equality for comparisons, i.e. `===`. If the array is already sorted + * providing `true` for `fromIndex` will run a faster binary search. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=0] The index to search from or `true` + * to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value or `-1`. + * @example + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2); + * // => 1 + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 4 + * + * _.indexOf([1, 1, 2, 2, 3, 3], 2, true); + * // => 2 + */ + function indexOf(array, value, fromIndex) { + if (typeof fromIndex == 'number') { + var length = array ? array.length : 0; + fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0); + } else if (fromIndex) { + var index = sortedIndex(array, value); + return array[index] === value ? index : -1; + } + return baseIndexOf(array, value, fromIndex); + } + + /** + * Gets all but the last element or last `n` elements of an array. If a + * callback is provided elements at the end of the array are excluded from + * the result as long as the callback returns truey. The callback is bound + * to `thisArg` and invoked with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback=1] The function called + * per element or the number of elements to exclude. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + * + * _.initial([1, 2, 3], 2); + * // => [1] + * + * _.initial([1, 2, 3], function(num) { + * return num > 1; + * }); + * // => [1] + * + * var characters = [ + * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.initial(characters, 'blocked'); + * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }] + * + * // using "_.where" callback shorthand + * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name'); + * // => ['barney', 'fred'] + */ + function initial(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = length; + callback = createCallback(callback, thisArg, 3); + while (index-- && callback(array[index], index, array)) { + n++; + } + } else { + n = (callback == null || thisArg) ? 1 : callback || n; + } + return slice(array, 0, nativeMin(nativeMax(0, length - n), length)); + } + + /** + * Creates an array of unique values present in all provided arrays using + * strict equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of shared values. + * @example + * + * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]); + * // => [1, 2] + */ + function intersection() { + var args = [], + argsIndex = -1, + argsLength = arguments.length; + + while (++argsIndex < argsLength) { + var value = arguments[argsIndex]; + if (isArray(value) || isArguments(value)) { + args.push(value); + } + } + var array = args[0], + index = -1, + indexOf = getIndexOf(), + length = array ? array.length : 0, + result = []; + + outer: + while (++index < length) { + value = array[index]; + if (indexOf(result, value) < 0) { + var argsIndex = argsLength; + while (--argsIndex) { + if (indexOf(args[argsIndex], value) < 0) { + continue outer; + } + } + result.push(value); + } + } + return result; + } + + /** + * Gets the last element or last `n` elements of an array. If a callback is + * provided elements at the end of the array are returned as long as the + * callback returns truey. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback] The function called + * per element or the number of elements to return. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {*} Returns the last element(s) of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + * + * _.last([1, 2, 3], 2); + * // => [2, 3] + * + * _.last([1, 2, 3], function(num) { + * return num > 1; + * }); + * // => [2, 3] + * + * var characters = [ + * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.pluck(_.last(characters, 'blocked'), 'name'); + * // => ['fred', 'pebbles'] + * + * // using "_.where" callback shorthand + * _.last(characters, { 'employer': 'na' }); + * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] + */ + function last(array, callback, thisArg) { + var n = 0, + length = array ? array.length : 0; + + if (typeof callback != 'number' && callback != null) { + var index = length; + callback = createCallback(callback, thisArg, 3); + while (index-- && callback(array[index], index, array)) { + n++; + } + } else { + n = callback; + if (n == null || thisArg) { + return array ? array[length - 1] : undefined; + } + } + return slice(array, nativeMax(0, length - n)); + } + + /** + * Gets the index at which the last occurrence of `value` is found using strict + * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used + * as the offset from the end of the collection. + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=array.length-1] The index to search from. + * @returns {number} Returns the index of the matched value or `-1`. + * @example + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); + * // => 4 + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 1 + */ + function lastIndexOf(array, value, fromIndex) { + var index = array ? array.length : 0; + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1; + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to but not including `end`. If `start` is less than `stop` a + * zero-length range is created unless a negative `step` is specified. + * + * @static + * @memberOf _ + * @category Arrays + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns a new range array. + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ + function range(start, end, step) { + start = +start || 0; + step = (+step || 1); + + if (end == null) { + end = start; + start = 0; + } + // use `Array(length)` so engines like Chakra and V8 avoid slower modes + // http://youtu.be/XAqIpGU8ZZk#t=17m25s + var index = -1, + length = nativeMax(0, ceil((end - start) / step)), + result = Array(length); + + while (++index < length) { + result[index] = start; + start += step; + } + return result; + } + + /** + * The opposite of `_.initial` this method gets all but the first element or + * first `n` elements of an array. If a callback function is provided elements + * at the beginning of the array are excluded from the result as long as the + * callback returns truey. The callback is bound to `thisArg` and invoked + * with three arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias drop, tail + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|number|string} [callback=1] The function called + * per element or the number of elements to exclude. If a property name or + * object is provided it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a slice of `array`. + * @example + * + * _.rest([1, 2, 3]); + * // => [2, 3] + * + * _.rest([1, 2, 3], 2); + * // => [3] + * + * _.rest([1, 2, 3], function(num) { + * return num < 3; + * }); + * // => [3] + * + * var characters = [ + * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, + * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, + * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.pluck(_.rest(characters, 'blocked'), 'name'); + * // => ['fred', 'pebbles'] + * + * // using "_.where" callback shorthand + * _.rest(characters, { 'employer': 'slate' }); + * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] + */ + function rest(array, callback, thisArg) { + if (typeof callback != 'number' && callback != null) { + var n = 0, + index = -1, + length = array ? array.length : 0; + + callback = createCallback(callback, thisArg, 3); + while (++index < length && callback(array[index], index, array)) { + n++; + } + } else { + n = (callback == null || thisArg) ? 1 : nativeMax(0, callback); + } + return slice(array, n); + } + + /** + * Uses a binary search to determine the smallest index at which a value + * should be inserted into a given sorted array in order to maintain the sort + * order of the array. If a callback is provided it will be executed for + * `value` and each element of `array` to compute their sort ranking. The + * callback is bound to `thisArg` and invoked with one argument; (value). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([20, 30, 50], 40); + * // => 2 + * + * // using "_.pluck" callback shorthand + * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); + * // => 2 + * + * var dict = { + * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 } + * }; + * + * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { + * return dict.wordToNumber[word]; + * }); + * // => 2 + * + * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { + * return this.wordToNumber[word]; + * }, dict); + * // => 2 + */ + function sortedIndex(array, value, callback, thisArg) { + var low = 0, + high = array ? array.length : low; + + // explicitly reference `identity` for better inlining in Firefox + callback = callback ? createCallback(callback, thisArg, 1) : identity; + value = callback(value); + + while (low < high) { + var mid = (low + high) >>> 1; + (callback(array[mid]) < value) + ? low = mid + 1 + : high = mid; + } + return low; + } + + /** + * Creates an array of unique values, in order, of the provided arrays using + * strict equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {...Array} [array] The arrays to inspect. + * @returns {Array} Returns an array of combined values. + * @example + * + * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]); + * // => [1, 2, 3, 5, 4] + */ + function union() { + return baseUniq(baseFlatten(arguments, true, true)); + } + + /** + * Creates a duplicate-value-free version of an array using strict equality + * for comparisons, i.e. `===`. If the array is sorted, providing + * `true` for `isSorted` will use a faster algorithm. If a callback is provided + * each element of `array` is passed through the callback before uniqueness + * is computed. The callback is bound to `thisArg` and invoked with three + * arguments; (value, index, array). + * + * If a property name is provided for `callback` the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is provided for `callback` the created "_.where" style callback + * will return `true` for elements that have the properties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias unique + * @category Arrays + * @param {Array} array The array to process. + * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. + * @param {Function|Object|string} [callback=identity] The function called + * per iteration. If a property name or object is provided it will be used + * to create a "_.pluck" or "_.where" style callback, respectively. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a duplicate-value-free array. + * @example + * + * _.uniq([1, 2, 1, 3, 1]); + * // => [1, 2, 3] + * + * _.uniq([1, 1, 2, 2, 3], true); + * // => [1, 2, 3] + * + * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); }); + * // => ['A', 'b', 'C'] + * + * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math); + * // => [1, 2.5, 3] + * + * // using "_.pluck" callback shorthand + * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniq(array, isSorted, callback, thisArg) { + // juggle arguments + if (typeof isSorted != 'boolean' && isSorted != null) { + thisArg = callback; + callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted; + isSorted = false; + } + if (callback != null) { + callback = createCallback(callback, thisArg, 3); + } + return baseUniq(array, isSorted, callback); + } + + /** + * Creates an array excluding all provided values using strict equality for + * comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to filter. + * @param {...*} [value] The values to exclude. + * @returns {Array} Returns a new array of filtered values. + * @example + * + * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); + * // => [2, 3, 4] + */ + function without(array) { + return baseDifference(array, slice(arguments, 1)); + } + + /** + * Creates an array of grouped elements, the first of which contains the first + * elements of the given arrays, the second of which contains the second + * elements of the given arrays, and so on. + * + * @static + * @memberOf _ + * @alias unzip + * @category Arrays + * @param {...Array} [array] Arrays to process. + * @returns {Array} Returns a new array of grouped elements. + * @example + * + * _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + */ + function zip() { + var index = -1, + length = max(pluck(arguments, 'length')), + result = Array(length < 0 ? 0 : length); + + while (++index < length) { + result[index] = pluck(arguments, index); + } + return result; + } + + /** + * Creates an object composed from arrays of `keys` and `values`. Provide + * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]` + * or two arrays, one of `keys` and one of corresponding `values`. + * + * @static + * @memberOf _ + * @alias object + * @category Arrays + * @param {Array} keys The array of keys. + * @param {Array} [values=[]] The array of values. + * @returns {Object} Returns an object composed of the given keys and + * corresponding values. + * @example + * + * _.zipObject(['fred', 'barney'], [30, 40]); + * // => { 'fred': 30, 'barney': 40 } + */ + function zipObject(keys, values) { + var index = -1, + length = keys ? keys.length : 0, + result = {}; + + if (!values && length && !isArray(keys[0])) { + values = []; + } + while (++index < length) { + var key = keys[index]; + if (values) { + result[key] = values[index]; + } else if (key) { + result[key[0]] = key[1]; + } + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a function that executes `func`, with the `this` binding and + * arguments of the created function, only after being called `n` times. + * + * @static + * @memberOf _ + * @category Functions + * @param {number} n The number of times the function must be called before + * `func` is executed. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('Done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => logs 'Done saving!', after all saves have completed + */ + function after(n, func) { + if (!isFunction(func)) { + throw new TypeError; + } + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that, when called, invokes `func` with the `this` + * binding of `thisArg` and prepends any additional `bind` arguments to those + * provided to the bound function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to bind. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var func = function(greeting) { + * return greeting + ' ' + this.name; + * }; + * + * func = _.bind(func, { 'name': 'fred' }, 'hi'); + * func(); + * // => 'hi fred' + */ + function bind(func, thisArg) { + return arguments.length > 2 + ? createWrapper(func, 17, slice(arguments, 2), null, thisArg) + : createWrapper(func, 1, null, null, thisArg); + } + + /** + * Binds methods of an object to the object itself, overwriting the existing + * method. Method names may be specified as individual arguments or as arrays + * of method names. If no method names are provided all the function properties + * of `object` will be bound. + * + * @static + * @memberOf _ + * @category Functions + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...string} [methodName] The object method names to + * bind, specified as individual method names or arrays of method names. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { console.log('clicked ' + this.label); } + * }; + * + * _.bindAll(view); + * jQuery('#docs').on('click', view.onClick); + * // => logs 'clicked docs', when the button is clicked + */ + function bindAll(object) { + var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object), + index = -1, + length = funcs.length; + + while (++index < length) { + var key = funcs[index]; + object[key] = createWrapper(object[key], 1, null, null, object); + } + return object; + } + + /** + * Creates a function that is the composition of the provided functions, + * where each function consumes the return value of the function that follows. + * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. + * Each function is executed with the `this` binding of the composed function. + * + * @static + * @memberOf _ + * @category Functions + * @param {...Function} [func] Functions to compose. + * @returns {Function} Returns the new composed function. + * @example + * + * var realNameMap = { + * 'pebbles': 'penelope' + * }; + * + * var format = function(name) { + * name = realNameMap[name.toLowerCase()] || name; + * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase(); + * }; + * + * var greet = function(formatted) { + * return 'Hiya ' + formatted + '!'; + * }; + * + * var welcome = _.compose(greet, format); + * welcome('pebbles'); + * // => 'Hiya Penelope!' + */ + function compose() { + var funcs = arguments, + length = funcs.length; + + while (length--) { + if (!isFunction(funcs[length])) { + throw new TypeError; + } + } + return function() { + var args = arguments, + length = funcs.length; + + while (length--) { + args = [funcs[length].apply(this, args)]; + } + return args[0]; + }; + } + + /** + * Creates a function that will delay the execution of `func` until after + * `wait` milliseconds have elapsed since the last time it was invoked. + * Provide an options object to indicate that `func` should be invoked on + * the leading and/or trailing edge of the `wait` timeout. Subsequent calls + * to the debounced function will return the result of the last `func` call. + * + * Note: If `leading` and `trailing` options are `true` `func` will be called + * on the trailing edge of the timeout only if the the debounced function is + * invoked more than once during the `wait` timeout. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to debounce. + * @param {number} wait The number of milliseconds to delay. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called. + * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // avoid costly calculations while the window size is in flux + * var lazyLayout = _.debounce(calculateLayout, 150); + * jQuery(window).on('resize', lazyLayout); + * + * // execute `sendMail` when the click event is fired, debouncing subsequent calls + * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * }); + * + * // ensure `batchLog` is executed once after 1 second of debounced calls + * var source = new EventSource('/stream'); + * source.addEventListener('message', _.debounce(batchLog, 250, { + * 'maxWait': 1000 + * }, false); + */ + function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + maxWait = false, + trailing = true; + + if (!isFunction(func)) { + throw new TypeError; + } + wait = nativeMax(0, wait) || 0; + if (options === true) { + var leading = true; + trailing = false; + } else if (isObject(options)) { + leading = options.leading; + maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0); + trailing = 'trailing' in options ? options.trailing : trailing; + } + var delayed = function() { + var remaining = wait - (now() - stamp); + if (remaining <= 0) { + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + var isCalled = trailingCall; + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + } else { + timeoutId = setTimeout(delayed, remaining); + } + }; + + var maxDelayed = function() { + if (timeoutId) { + clearTimeout(timeoutId); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (trailing || (maxWait !== wait)) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + }; + + return function() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled), + isCalled = remaining <= 0; + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + return result; + }; + } + + /** + * Defers executing the `func` function until the current call stack has cleared. + * Additional arguments will be provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to defer. + * @param {...*} [arg] Arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { console.log(text); }, 'deferred'); + * // logs 'deferred' after one or more milliseconds + */ + function defer(func) { + if (!isFunction(func)) { + throw new TypeError; + } + var args = slice(arguments, 1); + return setTimeout(function() { func.apply(undefined, args); }, 1); + } + + /** + * Executes the `func` function after `wait` milliseconds. Additional arguments + * will be provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay execution. + * @param {...*} [arg] Arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { console.log(text); }, 1000, 'later'); + * // => logs 'later' after one second + */ + function delay(func, wait) { + if (!isFunction(func)) { + throw new TypeError; + } + var args = slice(arguments, 2); + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided it will be used to determine the cache key for storing the result + * based on the arguments provided to the memoized function. By default, the + * first argument provided to the memoized function is used as the cache key. + * The `func` is executed with the `this` binding of the memoized function. + * The result cache is exposed as the `cache` property on the memoized function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] A function used to resolve the cache key. + * @returns {Function} Returns the new memoizing function. + * @example + * + * var fibonacci = _.memoize(function(n) { + * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); + * }); + * + * fibonacci(9) + * // => 34 + * + * var data = { + * 'fred': { 'name': 'fred', 'age': 40 }, + * 'pebbles': { 'name': 'pebbles', 'age': 1 } + * }; + * + * // modifying the result cache + * var get = _.memoize(function(name) { return data[name]; }, _.identity); + * get('pebbles'); + * // => { 'name': 'pebbles', 'age': 1 } + * + * get.cache.pebbles.name = 'penelope'; + * get('pebbles'); + * // => { 'name': 'penelope', 'age': 1 } + */ + function memoize(func, resolver) { + var cache = {}; + return function() { + var key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0]; + return hasOwnProperty.call(cache, key) + ? cache[key] + : (cache[key] = func.apply(this, arguments)); + }; + } + + /** + * Creates a function that is restricted to execute `func` once. Repeat calls to + * the function will return the value of the first call. The `func` is executed + * with the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` executes `createApplication` once + */ + function once(func) { + var ran, + result; + + if (!isFunction(func)) { + throw new TypeError; + } + return function() { + if (ran) { + return result; + } + ran = true; + result = func.apply(this, arguments); + + // clear the `func` variable so the function may be garbage collected + func = null; + return result; + }; + } + + /** + * Creates a function that, when called, invokes `func` with any additional + * `partial` arguments prepended to those provided to the new function. This + * method is similar to `_.bind` except it does **not** alter the `this` binding. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [arg] Arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { return greeting + ' ' + name; }; + * var hi = _.partial(greet, 'hi'); + * hi('fred'); + * // => 'hi fred' + */ + function partial(func) { + return createWrapper(func, 16, slice(arguments, 1)); + } + + /** + * Creates a function that, when executed, will only call the `func` function + * at most once per every `wait` milliseconds. Provide an options object to + * indicate that `func` should be invoked on the leading and/or trailing edge + * of the `wait` timeout. Subsequent calls to the throttled function will + * return the result of the last `func` call. + * + * Note: If `leading` and `trailing` options are `true` `func` will be called + * on the trailing edge of the timeout only if the the throttled function is + * invoked more than once during the `wait` timeout. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to throttle. + * @param {number} wait The number of milliseconds to throttle executions to. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout. + * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // avoid excessively updating the position while scrolling + * var throttled = _.throttle(updatePosition, 100); + * jQuery(window).on('scroll', throttled); + * + * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes + * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { + * 'trailing': false + * })); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (!isFunction(func)) { + throw new TypeError; + } + if (options === false) { + leading = false; + } else if (isObject(options)) { + leading = 'leading' in options ? options.leading : leading; + trailing = 'trailing' in options ? options.trailing : trailing; + } + options = {}; + options.leading = leading; + options.maxWait = wait; + options.trailing = trailing; + + return debounce(func, wait, options); + } + + /** + * Creates a function that provides `value` to the wrapper function as its + * first argument. Additional arguments provided to the function are appended + * to those provided to the wrapper function. The wrapper is executed with + * the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {*} value The value to wrap. + * @param {Function} wrapper The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '<p>' + func(text) + '</p>'; + * }); + * + * p('Fred, Wilma, & Pebbles'); + * // => '<p>Fred, Wilma, & Pebbles</p>' + */ + function wrap(value, wrapper) { + return createWrapper(wrapper, 16, [value]); + } + + /*--------------------------------------------------------------------------*/ + + /** + * Produces a callback bound to an optional `thisArg`. If `func` is a property + * name the created callback will return the property value for a given element. + * If `func` is an object the created callback will return `true` for elements + * that contain the equivalent object properties, otherwise it will return `false`. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} [func=identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of the created callback. + * @param {number} [argCount] The number of arguments the callback accepts. + * @returns {Function} Returns a callback function. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // wrap to create custom callback shorthands + * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) { + * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback); + * return !match ? func(callback, thisArg) : function(object) { + * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3]; + * }; + * }); + * + * _.filter(characters, 'age__gt38'); + * // => [{ 'name': 'fred', 'age': 40 }] + */ + function createCallback(func, thisArg, argCount) { + var type = typeof func; + if (func == null || type == 'function') { + return baseCreateCallback(func, thisArg, argCount); + } + // handle "_.pluck" style callback shorthands + if (type != 'object') { + return property(func); + } + var props = keys(func); + return function(object) { + var length = props.length, + result = false; + + while (length--) { + if (!(result = object[props[length]] === func[props[length]])) { + break; + } + } + return result; + }; + } + + /** + * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their + * corresponding HTML entities. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} string The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('Fred, Wilma, & Pebbles'); + * // => 'Fred, Wilma, & Pebbles' + */ + function escape(string) { + return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar); + } + + /** + * This method returns the first argument provided to it. + * + * @static + * @memberOf _ + * @category Utilities + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'name': 'fred' }; + * _.identity(object) === object; + * // => true + */ + function identity(value) { + return value; + } + + /** + * Adds function properties of a source object to the destination object. + * If `object` is a function methods will be added to its prototype as well. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Function|Object} [object=lodash] object The destination object. + * @param {Object} source The object of functions to add. + * @param {Object} [options] The options object. + * @param {boolean} [options.chain=true] Specify whether the functions added are chainable. + * @example + * + * function capitalize(string) { + * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); + * } + * + * _.mixin({ 'capitalize': capitalize }); + * _.capitalize('fred'); + * // => 'Fred' + * + * _('fred').capitalize().value(); + * // => 'Fred' + * + * _.mixin({ 'capitalize': capitalize }, { 'chain': false }); + * _('fred').capitalize(); + * // => 'Fred' + */ + function mixin(object) { + forEach(functions(object), function(methodName) { + var func = lodash[methodName] = object[methodName]; + + lodash.prototype[methodName] = function() { + var args = [this.__wrapped__]; + push.apply(args, arguments); + + var result = func.apply(lodash, args); + return this.__chain__ + ? new lodashWrapper(result, true) + : result; + }; + }); + } + + /** + * Reverts the '_' variable to its previous value and returns a reference to + * the `lodash` function. + * + * @static + * @memberOf _ + * @category Utilities + * @returns {Function} Returns the `lodash` function. + * @example + * + * var lodash = _.noConflict(); + */ + function noConflict() { + root._ = oldDash; + return this; + } + + /** + * A no-operation function. + * + * @static + * @memberOf _ + * @category Utilities + * @example + * + * var object = { 'name': 'fred' }; + * _.noop(object) === undefined; + * // => true + */ + function noop() { + // no operation performed + } + + /** + * Gets the number of milliseconds that have elapsed since the Unix epoch + * (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @category Utilities + * @example + * + * var stamp = _.now(); + * _.defer(function() { console.log(_.now() - stamp); }); + * // => logs the number of milliseconds it took for the deferred function to be called + */ + var now = isNative(now = Date.now) && now || function() { + return new Date().getTime(); + }; + + /** + * Creates a "_.pluck" style function, which returns the `key` value of a + * given object. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} key The name of the property to retrieve. + * @returns {Function} Returns the new function. + * @example + * + * var characters = [ + * { 'name': 'fred', 'age': 40 }, + * { 'name': 'barney', 'age': 36 } + * ]; + * + * var getName = _.property('name'); + * + * _.map(characters, getName); + * // => ['barney', 'fred'] + * + * _.sortBy(characters, getName); + * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] + */ + function property(key) { + return function(object) { + return object[key]; + }; + } + + /** + * Produces a random number between `min` and `max` (inclusive). If only one + * argument is provided a number between `0` and the given number will be + * returned. If `floating` is truey or either `min` or `max` are floats a + * floating-point number will be returned instead of an integer. + * + * @static + * @memberOf _ + * @category Utilities + * @param {number} [min=0] The minimum possible value. + * @param {number} [max=1] The maximum possible value. + * @param {boolean} [floating=false] Specify returning a floating-point number. + * @returns {number} Returns a random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(min, max) { + if (min == null && max == null) { + max = 1; + } + min = +min || 0; + if (max == null) { + max = min; + min = 0; + } else { + max = +max || 0; + } + return min + floor(nativeRandom() * (max - min + 1)); + } + + /** + * Resolves the value of property `key` on `object`. If `key` is a function + * it will be invoked with the `this` binding of `object` and its result returned, + * else the property value is returned. If `object` is falsey then `undefined` + * is returned. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Object} object The object to inspect. + * @param {string} key The name of the property to resolve. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { + * 'cheese': 'crumpets', + * 'stuff': function() { + * return 'nonsense'; + * } + * }; + * + * _.result(object, 'cheese'); + * // => 'crumpets' + * + * _.result(object, 'stuff'); + * // => 'nonsense' + */ + function result(object, key) { + if (object) { + var value = object[key]; + return isFunction(value) ? object[key]() : value; + } + } + + /** + * A micro-templating method that handles arbitrary delimiters, preserves + * whitespace, and correctly escapes quotes within interpolated code. + * + * Note: In the development build, `_.template` utilizes sourceURLs for easier + * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl + * + * For more information on precompiling templates see: + * http://lodash.com/custom-builds + * + * For more information on Chrome extension sandboxes see: + * http://developer.chrome.com/stable/extensions/sandboxingEval.html + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} text The template text. + * @param {Object} data The data object used to populate the text. + * @param {Object} [options] The options object. + * @param {RegExp} [options.escape] The "escape" delimiter. + * @param {RegExp} [options.evaluate] The "evaluate" delimiter. + * @param {Object} [options.imports] An object to import into the template as local variables. + * @param {RegExp} [options.interpolate] The "interpolate" delimiter. + * @param {string} [sourceURL] The sourceURL of the template's compiled source. + * @param {string} [variable] The data object variable name. + * @returns {Function|string} Returns a compiled function when no `data` object + * is given, else it returns the interpolated text. + * @example + * + * // using the "interpolate" delimiter to create a compiled template + * var compiled = _.template('hello <%= name %>'); + * compiled({ 'name': 'fred' }); + * // => 'hello fred' + * + * // using the "escape" delimiter to escape HTML in data property values + * _.template('<b><%- value %></b>', { 'value': '<script>' }); + * // => '<b><script></b>' + * + * // using the "evaluate" delimiter to generate HTML + * var list = '<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>'; + * _.template(list, { 'people': ['fred', 'barney'] }); + * // => '<li>fred</li><li>barney</li>' + * + * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter + * _.template('hello ${ name }', { 'name': 'pebbles' }); + * // => 'hello pebbles' + * + * // using the internal `print` function in "evaluate" delimiters + * _.template('<% print("hello " + name); %>!', { 'name': 'barney' }); + * // => 'hello barney!' + * + * // using a custom template delimiters + * _.templateSettings = { + * 'interpolate': /{{([\s\S]+?)}}/g + * }; + * + * _.template('hello {{ name }}!', { 'name': 'mustache' }); + * // => 'hello mustache!' + * + * // using the `imports` option to import jQuery + * var list = '<% jq.each(people, function(name) { %><li><%- name %></li><% }); %>'; + * _.template(list, { 'people': ['fred', 'barney'] }, { 'imports': { 'jq': jQuery } }); + * // => '<li>fred</li><li>barney</li>' + * + * // using the `sourceURL` option to specify a custom sourceURL for the template + * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' }); + * compiled(data); + * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector + * + * // using the `variable` option to ensure a with-statement isn't used in the compiled template + * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' }); + * compiled.source; + * // => function(data) { + * var __t, __p = '', __e = _.escape; + * __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!'; + * return __p; + * } + * + * // using the `source` property to inline compiled templates for meaningful + * // line numbers in error messages and a stack trace + * fs.writeFileSync(path.join(cwd, 'jst.js'), '\ + * var JST = {\ + * "main": ' + _.template(mainText).source + '\ + * };\ + * '); + */ + function template(text, data, options) { + var _ = lodash, + settings = _.templateSettings; + + text = String(text || ''); + options = defaults({}, options, settings); + + var index = 0, + source = "__p += '", + variable = options.variable; + + var reDelimiters = RegExp( + (options.escape || reNoMatch).source + '|' + + (options.interpolate || reNoMatch).source + '|' + + (options.evaluate || reNoMatch).source + '|$' + , 'g'); + + text.replace(reDelimiters, function(match, escapeValue, interpolateValue, evaluateValue, offset) { + source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar); + if (escapeValue) { + source += "' +\n_.escape(" + escapeValue + ") +\n'"; + } + if (evaluateValue) { + source += "';\n" + evaluateValue + ";\n__p += '"; + } + if (interpolateValue) { + source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'"; + } + index = offset + match.length; + return match; + }); + + source += "';\n"; + if (!variable) { + variable = 'obj'; + source = 'with (' + variable + ' || {}) {\n' + source + '\n}\n'; + } + source = 'function(' + variable + ') {\n' + + "var __t, __p = '', __j = Array.prototype.join;\n" + + "function print() { __p += __j.call(arguments, '') }\n" + + source + + 'return __p\n}'; + + try { + var result = Function('_', 'return ' + source)(_); + } catch(e) { + e.source = source; + throw e; + } + if (data) { + return result(data); + } + result.source = source; + return result; + } + + /** + * Executes the callback `n` times, returning an array of the results + * of each callback execution. The callback is bound to `thisArg` and invoked + * with one argument; (index). + * + * @static + * @memberOf _ + * @category Utilities + * @param {number} n The number of times to execute the callback. + * @param {Function} callback The function called per iteration. + * @param {*} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns an array of the results of each `callback` execution. + * @example + * + * var diceRolls = _.times(3, _.partial(_.random, 1, 6)); + * // => [3, 6, 4] + * + * _.times(3, function(n) { mage.castSpell(n); }); + * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively + * + * _.times(3, function(n) { this.cast(n); }, mage); + * // => also calls `mage.castSpell(n)` three times + */ + function times(n, callback, thisArg) { + n = (n = +n) > -1 ? n : 0; + var index = -1, + result = Array(n); + + callback = baseCreateCallback(callback, thisArg, 1); + while (++index < n) { + result[index] = callback(index); + } + return result; + } + + /** + * The inverse of `_.escape` this method converts the HTML entities + * `&`, `<`, `>`, `"`, and `'` in `string` to their + * corresponding characters. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} string The string to unescape. + * @returns {string} Returns the unescaped string. + * @example + * + * _.unescape('Fred, Barney & Pebbles'); + * // => 'Fred, Barney & Pebbles' + */ + function unescape(string) { + return string == null ? '' : String(string).replace(reEscapedHtml, unescapeHtmlChar); + } + + /** + * Generates a unique ID. If `prefix` is provided the ID will be appended to it. + * + * @static + * @memberOf _ + * @category Utilities + * @param {string} [prefix] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ + function uniqueId(prefix) { + var id = ++idCounter + ''; + return prefix ? prefix + id : id; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object that wraps the given value with explicit + * method chaining enabled. + * + * @static + * @memberOf _ + * @category Chaining + * @param {*} value The value to wrap. + * @returns {Object} Returns the wrapper object. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 }, + * { 'name': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _.chain(characters) + * .sortBy('age') + * .map(function(chr) { return chr.name + ' is ' + chr.age; }) + * .first() + * .value(); + * // => 'pebbles is 1' + */ + function chain(value) { + value = new lodashWrapper(value); + value.__chain__ = true; + return value; + } + + /** + * Invokes `interceptor` with the `value` as the first argument and then + * returns `value`. The purpose of this method is to "tap into" a method + * chain in order to perform operations on intermediate results within + * the chain. + * + * @static + * @memberOf _ + * @category Chaining + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3, 4]) + * .tap(function(array) { array.pop(); }) + * .reverse() + * .value(); + * // => [3, 2, 1] + */ + function tap(value, interceptor) { + interceptor(value); + return value; + } + + /** + * Enables explicit method chaining on the wrapper object. + * + * @name chain + * @memberOf _ + * @category Chaining + * @returns {*} Returns the wrapper object. + * @example + * + * var characters = [ + * { 'name': 'barney', 'age': 36 }, + * { 'name': 'fred', 'age': 40 } + * ]; + * + * // without explicit chaining + * _(characters).first(); + * // => { 'name': 'barney', 'age': 36 } + * + * // with explicit chaining + * _(characters).chain() + * .first() + * .pick('age') + * .value(); + * // => { 'age': 36 } + */ + function wrapperChain() { + this.__chain__ = true; + return this; + } + + /** + * Extracts the wrapped value. + * + * @name valueOf + * @memberOf _ + * @alias value + * @category Chaining + * @returns {*} Returns the wrapped value. + * @example + * + * _([1, 2, 3]).valueOf(); + * // => [1, 2, 3] + */ + function wrapperValueOf() { + return this.__wrapped__; + } + + /*--------------------------------------------------------------------------*/ + + // add functions that return wrapped values when chaining + lodash.after = after; + lodash.bind = bind; + lodash.bindAll = bindAll; + lodash.chain = chain; + lodash.compact = compact; + lodash.compose = compose; + lodash.countBy = countBy; + lodash.debounce = debounce; + lodash.defaults = defaults; + lodash.defer = defer; + lodash.delay = delay; + lodash.difference = difference; + lodash.filter = filter; + lodash.flatten = flatten; + lodash.forEach = forEach; + lodash.functions = functions; + lodash.groupBy = groupBy; + lodash.indexBy = indexBy; + lodash.initial = initial; + lodash.intersection = intersection; + lodash.invert = invert; + lodash.invoke = invoke; + lodash.keys = keys; + lodash.map = map; + lodash.max = max; + lodash.memoize = memoize; + lodash.min = min; + lodash.omit = omit; + lodash.once = once; + lodash.pairs = pairs; + lodash.partial = partial; + lodash.pick = pick; + lodash.pluck = pluck; + lodash.range = range; + lodash.reject = reject; + lodash.rest = rest; + lodash.shuffle = shuffle; + lodash.sortBy = sortBy; + lodash.tap = tap; + lodash.throttle = throttle; + lodash.times = times; + lodash.toArray = toArray; + lodash.union = union; + lodash.uniq = uniq; + lodash.values = values; + lodash.where = where; + lodash.without = without; + lodash.wrap = wrap; + lodash.zip = zip; + + // add aliases + lodash.collect = map; + lodash.drop = rest; + lodash.each = forEach; + lodash.extend = assign; + lodash.methods = functions; + lodash.object = zipObject; + lodash.select = filter; + lodash.tail = rest; + lodash.unique = uniq; + + /*--------------------------------------------------------------------------*/ + + // add functions that return unwrapped values when chaining + lodash.clone = clone; + lodash.contains = contains; + lodash.escape = escape; + lodash.every = every; + lodash.find = find; + lodash.has = has; + lodash.identity = identity; + lodash.indexOf = indexOf; + lodash.isArguments = isArguments; + lodash.isArray = isArray; + lodash.isBoolean = isBoolean; + lodash.isDate = isDate; + lodash.isElement = isElement; + lodash.isEmpty = isEmpty; + lodash.isEqual = isEqual; + lodash.isFinite = isFinite; + lodash.isFunction = isFunction; + lodash.isNaN = isNaN; + lodash.isNull = isNull; + lodash.isNumber = isNumber; + lodash.isObject = isObject; + lodash.isRegExp = isRegExp; + lodash.isString = isString; + lodash.isUndefined = isUndefined; + lodash.lastIndexOf = lastIndexOf; + lodash.mixin = mixin; + lodash.noConflict = noConflict; + lodash.random = random; + lodash.reduce = reduce; + lodash.reduceRight = reduceRight; + lodash.result = result; + lodash.size = size; + lodash.some = some; + lodash.sortedIndex = sortedIndex; + lodash.template = template; + lodash.unescape = unescape; + lodash.uniqueId = uniqueId; + + // add aliases + lodash.all = every; + lodash.any = some; + lodash.detect = find; + lodash.findWhere = findWhere; + lodash.foldl = reduce; + lodash.foldr = reduceRight; + lodash.include = contains; + lodash.inject = reduce; + + /*--------------------------------------------------------------------------*/ + + // add functions capable of returning wrapped and unwrapped values when chaining + lodash.first = first; + lodash.last = last; + lodash.sample = sample; + + // add aliases + lodash.take = first; + lodash.head = first; + + /*--------------------------------------------------------------------------*/ + + // add functions to `lodash.prototype` + mixin(lodash); + + /** + * The semantic version number. + * + * @static + * @memberOf _ + * @type string + */ + lodash.VERSION = '2.4.1'; + + // add "Chaining" functions to the wrapper + lodash.prototype.chain = wrapperChain; + lodash.prototype.value = wrapperValueOf; + + // add `Array` mutator functions to the wrapper + forEach(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(methodName) { + var func = arrayRef[methodName]; + lodash.prototype[methodName] = function() { + var value = this.__wrapped__; + func.apply(value, arguments); + + // avoid array-like object bugs with `Array#shift` and `Array#splice` + // in Firefox < 10 and IE < 9 + if (!support.spliceObjects && value.length === 0) { + delete value[0]; + } + return this; + }; + }); + + // add `Array` accessor functions to the wrapper + forEach(['concat', 'join', 'slice'], function(methodName) { + var func = arrayRef[methodName]; + lodash.prototype[methodName] = function() { + var value = this.__wrapped__, + result = func.apply(value, arguments); + + if (this.__chain__) { + result = new lodashWrapper(result); + result.__chain__ = true; + } + return result; + }; + }); + + /*--------------------------------------------------------------------------*/ + + // some AMD build optimizers like r.js check for condition patterns like the following: + if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { + // Expose Lo-Dash to the global object even when an AMD loader is present in + // case Lo-Dash is loaded with a RequireJS shim config. + // See http://requirejs.org/docs/api.html#config-shim + root._ = lodash; + + // define as an anonymous module so, through path mapping, it can be + // referenced as the "underscore" module + define(function() { + return lodash; + }); + } + // check for `exports` after `define` in case a build optimizer adds an `exports` object + else if (freeExports && freeModule) { + // in Node.js or RingoJS + if (moduleExports) { + (freeModule.exports = lodash)._ = lodash; + } + // in Narwhal or Rhino -require + else { + freeExports._ = lodash; + } + } + else { + // in a browser or Rhino + root._ = lodash; + } +}.call(this));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/python/django/renkanmanager/static/renkanmanager/lib/lodash/lodash.underscore.min.js Mon Apr 27 17:22:46 2015 +0200 @@ -0,0 +1,39 @@ +/** + * @license + * Lo-Dash 2.4.1 (Custom Build) lodash.com/license | Underscore.js 1.5.2 underscorejs.org/LICENSE + * Build: `lodash underscore exports="amd,commonjs,global,node" -o ./dist/lodash.underscore.js` + */ +;(function(){function n(n,r,t){t=(t||0)-1;for(var e=n?n.length:0;++t<e;)if(n[t]===r)return t;return-1}function r(n,r){for(var t=n.m,e=r.m,u=-1,o=t.length;++u<o;){var i=t[u],f=e[u];if(i!==f){if(i>f||typeof i=="undefined")return 1;if(i<f||typeof f=="undefined")return-1}}return n.n-r.n}function t(n){return"\\"+yr[n]}function e(n,r,t){r||(r=0),typeof t=="undefined"&&(t=n?n.length:0);var e=-1;t=t-r||0;for(var u=Array(0>t?0:t);++e<t;)u[e]=n[r+e];return u}function u(n){return n instanceof u?n:new o(n)}function o(n,r){this.__chain__=!!r,this.__wrapped__=n +}function i(n){function r(){if(u){var n=e(u);Rr.apply(n,arguments)}if(this instanceof r){var i=f(t.prototype),n=t.apply(i,n||arguments);return O(n)?n:i}return t.apply(o,n||arguments)}var t=n[0],u=n[2],o=n[4];return r}function f(n){return O(n)?Br(n):{}}function a(n,r,t){if(typeof n!="function")return Y;if(typeof r=="undefined"||!("prototype"in n))return n;switch(t){case 1:return function(t){return n.call(r,t)};case 2:return function(t,e){return n.call(r,t,e)};case 3:return function(t,e,u){return n.call(r,t,e,u) +};case 4:return function(t,e,u,o){return n.call(r,t,e,u,o)}}return L(n,r)}function l(n){function r(){var n=p?a:this;if(o){var y=e(o);Rr.apply(y,arguments)}return(i||g)&&(y||(y=e(arguments)),i&&Rr.apply(y,i),g&&y.length<c)?(u|=16,l([t,h?u:-4&u,y,null,a,c])):(y||(y=arguments),s&&(t=n[v]),this instanceof r?(n=f(t.prototype),y=t.apply(n,y),O(y)?y:n):t.apply(n,y))}var t=n[0],u=n[1],o=n[2],i=n[3],a=n[4],c=n[5],p=1&u,s=2&u,g=4&u,h=8&u,v=t;return r}function c(n,r){for(var t=-1,e=m(),u=n?n.length:0,o=[];++t<u;){var i=n[t]; +0>e(r,i)&&o.push(i)}return o}function p(n,r,t,e){e=(e||0)-1;for(var u=n?n.length:0,o=[];++e<u;){var i=n[e];if(i&&typeof i=="object"&&typeof i.length=="number"&&(Cr(i)||b(i))){r||(i=p(i,r,t));var f=-1,a=i.length,l=o.length;for(o.length+=a;++f<a;)o[l++]=i[f]}else t||o.push(i)}return o}function s(n,r,t,e){if(n===r)return 0!==n||1/n==1/r;if(n===n&&!(n&&vr[typeof n]||r&&vr[typeof r]))return false;if(null==n||null==r)return n===r;var o=Er.call(n),i=Er.call(r);if(o!=i)return false;switch(o){case lr:case cr:return+n==+r; +case pr:return n!=+n?r!=+r:0==n?1/n==1/r:n==+r;case gr:case hr:return n==r+""}if(i=o==ar,!i){var f=n instanceof u,a=r instanceof u;if(f||a)return s(f?n.__wrapped__:n,a?r.__wrapped__:r,t,e);if(o!=sr)return false;if(o=n.constructor,f=r.constructor,o!=f&&!(A(o)&&o instanceof o&&A(f)&&f instanceof f)&&"constructor"in n&&"constructor"in r)return false}for(t||(t=[]),e||(e=[]),o=t.length;o--;)if(t[o]==n)return e[o]==r;var l=true,c=0;if(t.push(n),e.push(r),i){if(c=r.length,l=c==n.length)for(;c--&&(l=s(n[c],r[c],t,e)););}else Kr(r,function(r,u,o){return Nr.call(o,u)?(c++,!(l=Nr.call(n,u)&&s(n[u],r,t,e))&&er):void 0 +}),l&&Kr(n,function(n,r,t){return Nr.call(t,r)?!(l=-1<--c)&&er:void 0});return t.pop(),e.pop(),l}function g(n,r,t){for(var e=-1,u=m(),o=n?n.length:0,i=[],f=t?[]:i;++e<o;){var a=n[e],l=t?t(a,e,n):a;(r?!e||f[f.length-1]!==l:0>u(f,l))&&(t&&f.push(l),i.push(a))}return i}function h(n){return function(r,t,e){var u={};t=X(t,e,3),e=-1;var o=r?r.length:0;if(typeof o=="number")for(;++e<o;){var i=r[e];n(u,i,t(i,e,r),r)}else Lr(r,function(r,e,o){n(u,r,t(r,e,o),o)});return u}}function v(n,r,t,e,u,o){var f=16&r,a=32&r; +if(!(2&r||A(n)))throw new TypeError;return f&&!t.length&&(r&=-17,t=false),a&&!e.length&&(r&=-33,e=false),(1==r||17===r?i:l)([n,r,t,e,u,o])}function y(n){return Vr[n]}function m(){var r=(r=u.indexOf)===G?n:r;return r}function _(n){return typeof n=="function"&&Ar.test(n)}function d(n){return Gr[n]}function b(n){return n&&typeof n=="object"&&typeof n.length=="number"&&Er.call(n)==fr||false}function w(n){if(!n)return n;for(var r=1,t=arguments.length;r<t;r++){var e=arguments[r];if(e)for(var u in e)n[u]=e[u]}return n +}function j(n){if(!n)return n;for(var r=1,t=arguments.length;r<t;r++){var e=arguments[r];if(e)for(var u in e)"undefined"==typeof n[u]&&(n[u]=e[u])}return n}function x(n){var r=[];return Kr(n,function(n,t){A(n)&&r.push(t)}),r.sort()}function T(n){for(var r=-1,t=Ur(n),e=t.length,u={};++r<e;){var o=t[r];u[n[o]]=o}return u}function E(n){if(!n)return true;if(Cr(n)||N(n))return!n.length;for(var r in n)if(Nr.call(n,r))return false;return true}function A(n){return typeof n=="function"}function O(n){return!(!n||!vr[typeof n]) +}function S(n){return typeof n=="number"||n&&typeof n=="object"&&Er.call(n)==pr||false}function N(n){return typeof n=="string"||n&&typeof n=="object"&&Er.call(n)==hr||false}function R(n){for(var r=-1,t=Ur(n),e=t.length,u=Array(e);++r<e;)u[r]=n[t[r]];return u}function k(n,r){var t=m(),e=n?n.length:0,u=false;return e&&typeof e=="number"?u=-1<t(n,r):Lr(n,function(n){return(u=n===r)&&er}),u}function B(n,r,t){var e=true;r=X(r,t,3),t=-1;var u=n?n.length:0;if(typeof u=="number")for(;++t<u&&(e=!!r(n[t],t,n)););else Lr(n,function(n,t,u){return!(e=!!r(n,t,u))&&er +});return e}function F(n,r,t){var e=[];r=X(r,t,3),t=-1;var u=n?n.length:0;if(typeof u=="number")for(;++t<u;){var o=n[t];r(o,t,n)&&e.push(o)}else Lr(n,function(n,t,u){r(n,t,u)&&e.push(n)});return e}function q(n,r,t){r=X(r,t,3),t=-1;var e=n?n.length:0;if(typeof e!="number"){var u;return Lr(n,function(n,t,e){return r(n,t,e)?(u=n,er):void 0}),u}for(;++t<e;){var o=n[t];if(r(o,t,n))return o}}function D(n,r,t){var e=-1,u=n?n.length:0;if(r=r&&typeof t=="undefined"?r:a(r,t,3),typeof u=="number")for(;++e<u&&r(n[e],e,n)!==er;);else Lr(n,r) +}function I(n,r){var t=n?n.length:0;if(typeof t=="number")for(;t--&&false!==r(n[t],t,n););else{var e=Ur(n),t=e.length;Lr(n,function(n,u,o){return u=e?e[--t]:--t,false===r(o[u],u,o)&&er})}}function M(n,r,t){var e=-1,u=n?n.length:0;if(r=X(r,t,3),typeof u=="number")for(var o=Array(u);++e<u;)o[e]=r(n[e],e,n);else o=[],Lr(n,function(n,t,u){o[++e]=r(n,t,u)});return o}function $(n,r,t){var e=-1/0,u=e;typeof r!="function"&&t&&t[r]===n&&(r=null);var o=-1,i=n?n.length:0;if(null==r&&typeof i=="number")for(;++o<i;)t=n[o],t>u&&(u=t); +else r=X(r,t,3),D(n,function(n,t,o){t=r(n,t,o),t>e&&(e=t,u=n)});return u}function W(n,r,t,e){if(!n)return t;var u=3>arguments.length;r=X(r,e,4);var o=-1,i=n.length;if(typeof i=="number")for(u&&(t=n[++o]);++o<i;)t=r(t,n[o],o,n);else Lr(n,function(n,e,o){t=u?(u=false,n):r(t,n,e,o)});return t}function z(n,r,t,e){var u=3>arguments.length;return r=X(r,e,4),I(n,function(n,e,o){t=u?(u=false,n):r(t,n,e,o)}),t}function C(n){var r=-1,t=n?n.length:0,e=Array(typeof t=="number"?t:0);return D(n,function(n){var t;t=++r,t=0+Sr(Wr()*(t-0+1)),e[r]=e[t],e[t]=n +}),e}function P(n,r,t){var e;r=X(r,t,3),t=-1;var u=n?n.length:0;if(typeof u=="number")for(;++t<u&&!(e=r(n[t],t,n)););else Lr(n,function(n,t,u){return(e=r(n,t,u))&&er});return!!e}function U(n,r,t){return t&&E(r)?rr:(t?q:F)(n,r)}function V(n,r,t){var u=0,o=n?n.length:0;if(typeof r!="number"&&null!=r){var i=-1;for(r=X(r,t,3);++i<o&&r(n[i],i,n);)u++}else if(u=r,null==u||t)return n?n[0]:rr;return e(n,0,$r(Mr(0,u),o))}function G(r,t,e){if(typeof e=="number"){var u=r?r.length:0;e=0>e?Mr(0,u+e):e||0}else if(e)return e=J(r,t),r[e]===t?e:-1; +return n(r,t,e)}function H(n,r,t){if(typeof r!="number"&&null!=r){var u=0,o=-1,i=n?n.length:0;for(r=X(r,t,3);++o<i&&r(n[o],o,n);)u++}else u=null==r||t?1:Mr(0,r);return e(n,u)}function J(n,r,t,e){var u=0,o=n?n.length:u;for(t=t?X(t,e,1):Y,r=t(r);u<o;)e=u+o>>>1,t(n[e])<r?u=e+1:o=e;return u}function K(n,r,t,e){return typeof r!="boolean"&&null!=r&&(e=t,t=typeof r!="function"&&e&&e[r]===n?null:r,r=false),null!=t&&(t=X(t,e,3)),g(n,r,t)}function L(n,r){return 2<arguments.length?v(n,17,e(arguments,2),null,r):v(n,1,null,null,r) +}function Q(n,r,t){var e,u,o,i,f,a,l,c=0,p=false,s=true;if(!A(n))throw new TypeError;if(r=Mr(0,r)||0,true===t)var g=true,s=false;else O(t)&&(g=t.leading,p="maxWait"in t&&(Mr(r,t.maxWait)||0),s="trailing"in t?t.trailing:s);var h=function(){var t=r-(nt()-i);0<t?a=setTimeout(h,t):(u&&clearTimeout(u),t=l,u=a=l=rr,t&&(c=nt(),o=n.apply(f,e),a||u||(e=f=null)))},v=function(){a&&clearTimeout(a),u=a=l=rr,(s||p!==r)&&(c=nt(),o=n.apply(f,e),a||u||(e=f=null))};return function(){if(e=arguments,i=nt(),f=this,l=s&&(a||!g),false===p)var t=g&&!a; +else{u||g||(c=i);var y=p-(i-c),m=0>=y;m?(u&&(u=clearTimeout(u)),c=i,o=n.apply(f,e)):u||(u=setTimeout(v,y))}return m&&a?a=clearTimeout(a):a||r===p||(a=setTimeout(h,r)),t&&(m=true,o=n.apply(f,e)),!m||a||u||(e=f=null),o}}function X(n,r,t){var e=typeof n;if(null==n||"function"==e)return a(n,r,t);if("object"!=e)return nr(n);var u=Ur(n);return function(r){for(var t=u.length,e=false;t--&&(e=r[u[t]]===n[u[t]]););return e}}function Y(n){return n}function Z(n){D(x(n),function(r){var t=u[r]=n[r];u.prototype[r]=function(){var n=[this.__wrapped__]; +return Rr.apply(n,arguments),n=t.apply(u,n),this.__chain__?new o(n,true):n}})}function nr(n){return function(r){return r[n]}}var rr,tr=0,er={},ur=+new Date+"",or=/($^)/,ir=/['\n\r\t\u2028\u2029\\]/g,fr="[object Arguments]",ar="[object Array]",lr="[object Boolean]",cr="[object Date]",pr="[object Number]",sr="[object Object]",gr="[object RegExp]",hr="[object String]",vr={"boolean":false,"function":true,object:true,number:false,string:false,undefined:false},yr={"\\":"\\","'":"'","\n":"n","\r":"r","\t":"t","\u2028":"u2028","\u2029":"u2029"},mr=vr[typeof window]&&window||this,_r=vr[typeof exports]&&exports&&!exports.nodeType&&exports,dr=vr[typeof module]&&module&&!module.nodeType&&module,br=dr&&dr.exports===_r&&_r,wr=vr[typeof global]&&global; +!wr||wr.global!==wr&&wr.window!==wr||(mr=wr);var jr=[],xr=Object.prototype,Tr=mr._,Er=xr.toString,Ar=RegExp("^"+(Er+"").replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/toString| for [^\]]+/g,".*?")+"$"),Or=Math.ceil,Sr=Math.floor,Nr=xr.hasOwnProperty,Rr=jr.push,kr=xr.propertyIsEnumerable,Br=_(Br=Object.create)&&Br,Fr=_(Fr=Array.isArray)&&Fr,qr=mr.isFinite,Dr=mr.isNaN,Ir=_(Ir=Object.keys)&&Ir,Mr=Math.max,$r=Math.min,Wr=Math.random;o.prototype=u.prototype;var zr={};!function(){var n={0:1,length:1};zr.spliceObjects=(jr.splice.call(n,0,1),!n[0]) +}(1),u.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""},Br||(f=function(){function n(){}return function(r){if(O(r)){n.prototype=r;var t=new n;n.prototype=null}return t||mr.Object()}}()),b(arguments)||(b=function(n){return n&&typeof n=="object"&&typeof n.length=="number"&&Nr.call(n,"callee")&&!kr.call(n,"callee")||false});var Cr=Fr||function(n){return n&&typeof n=="object"&&typeof n.length=="number"&&Er.call(n)==ar||false},Pr=function(n){var r,t=[]; +if(!n||!vr[typeof n])return t;for(r in n)Nr.call(n,r)&&t.push(r);return t},Ur=Ir?function(n){return O(n)?Ir(n):[]}:Pr,Vr={"&":"&","<":"<",">":">",'"':""","'":"'"},Gr=T(Vr),Hr=RegExp("("+Ur(Gr).join("|")+")","g"),Jr=RegExp("["+Ur(Vr).join("")+"]","g"),Kr=function(n,r){var t;if(!n||!vr[typeof n])return n;for(t in n)if(r(n[t],t,n)===er)break;return n},Lr=function(n,r){var t;if(!n||!vr[typeof n])return n;for(t in n)if(Nr.call(n,t)&&r(n[t],t,n)===er)break;return n};A(/x/)&&(A=function(n){return typeof n=="function"&&"[object Function]"==Er.call(n) +});var Qr=h(function(n,r,t){Nr.call(n,t)?n[t]++:n[t]=1}),Xr=h(function(n,r,t){(Nr.call(n,t)?n[t]:n[t]=[]).push(r)}),Yr=h(function(n,r,t){n[t]=r}),Zr=M,nt=_(nt=Date.now)&&nt||function(){return(new Date).getTime()};u.after=function(n,r){if(!A(r))throw new TypeError;return function(){return 1>--n?r.apply(this,arguments):void 0}},u.bind=L,u.bindAll=function(n){for(var r=1<arguments.length?p(arguments,true,false,1):x(n),t=-1,e=r.length;++t<e;){var u=r[t];n[u]=v(n[u],1,null,null,n)}return n},u.chain=function(n){return n=new o(n),n.__chain__=true,n +},u.compact=function(n){for(var r=-1,t=n?n.length:0,e=[];++r<t;){var u=n[r];u&&e.push(u)}return e},u.compose=function(){for(var n=arguments,r=n.length;r--;)if(!A(n[r]))throw new TypeError;return function(){for(var r=arguments,t=n.length;t--;)r=[n[t].apply(this,r)];return r[0]}},u.countBy=Qr,u.debounce=Q,u.defaults=j,u.defer=function(n){if(!A(n))throw new TypeError;var r=e(arguments,1);return setTimeout(function(){n.apply(rr,r)},1)},u.delay=function(n,r){if(!A(n))throw new TypeError;var t=e(arguments,2); +return setTimeout(function(){n.apply(rr,t)},r)},u.difference=function(n){return c(n,p(arguments,true,true,1))},u.filter=F,u.flatten=function(n,r){return p(n,r)},u.forEach=D,u.functions=x,u.groupBy=Xr,u.indexBy=Yr,u.initial=function(n,r,t){var u=0,o=n?n.length:0;if(typeof r!="number"&&null!=r){var i=o;for(r=X(r,t,3);i--&&r(n[i],i,n);)u++}else u=null==r||t?1:r||u;return e(n,0,$r(Mr(0,o-u),o))},u.intersection=function(){for(var n=[],r=-1,t=arguments.length;++r<t;){var e=arguments[r];(Cr(e)||b(e))&&n.push(e) +}var u=n[0],o=-1,i=m(),f=u?u.length:0,a=[];n:for(;++o<f;)if(e=u[o],0>i(a,e)){for(r=t;--r;)if(0>i(n[r],e))continue n;a.push(e)}return a},u.invert=T,u.invoke=function(n,r){var t=e(arguments,2),u=-1,o=typeof r=="function",i=n?n.length:0,f=Array(typeof i=="number"?i:0);return D(n,function(n){f[++u]=(o?r:n[r]).apply(n,t)}),f},u.keys=Ur,u.map=M,u.max=$,u.memoize=function(n,r){var t={};return function(){var e=r?r.apply(this,arguments):ur+arguments[0];return Nr.call(t,e)?t[e]:t[e]=n.apply(this,arguments) +}},u.min=function(n,r,t){var e=1/0,u=e;typeof r!="function"&&t&&t[r]===n&&(r=null);var o=-1,i=n?n.length:0;if(null==r&&typeof i=="number")for(;++o<i;)t=n[o],t<u&&(u=t);else r=X(r,t,3),D(n,function(n,t,o){t=r(n,t,o),t<e&&(e=t,u=n)});return u},u.omit=function(n){var r=[];Kr(n,function(n,t){r.push(t)});for(var r=c(r,p(arguments,true,false,1)),t=-1,e=r.length,u={};++t<e;){var o=r[t];u[o]=n[o]}return u},u.once=function(n){var r,t;if(!A(n))throw new TypeError;return function(){return r?t:(r=true,t=n.apply(this,arguments),n=null,t) +}},u.pairs=function(n){for(var r=-1,t=Ur(n),e=t.length,u=Array(e);++r<e;){var o=t[r];u[r]=[o,n[o]]}return u},u.partial=function(n){return v(n,16,e(arguments,1))},u.pick=function(n){for(var r=-1,t=p(arguments,true,false,1),e=t.length,u={};++r<e;){var o=t[r];o in n&&(u[o]=n[o])}return u},u.pluck=Zr,u.range=function(n,r,t){n=+n||0,t=+t||1,null==r&&(r=n,n=0);var e=-1;r=Mr(0,Or((r-n)/t));for(var u=Array(r);++e<r;)u[e]=n,n+=t;return u},u.reject=function(n,r,t){return r=X(r,t,3),F(n,function(n,t,e){return!r(n,t,e) +})},u.rest=H,u.shuffle=C,u.sortBy=function(n,t,e){var u=-1,o=n?n.length:0,i=Array(typeof o=="number"?o:0);for(t=X(t,e,3),D(n,function(n,r,e){i[++u]={m:[t(n,r,e)],n:u,o:n}}),o=i.length,i.sort(r);o--;)i[o]=i[o].o;return i},u.tap=function(n,r){return r(n),n},u.throttle=function(n,r,t){var e=true,u=true;if(!A(n))throw new TypeError;return false===t?e=false:O(t)&&(e="leading"in t?t.leading:e,u="trailing"in t?t.trailing:u),t={},t.leading=e,t.maxWait=r,t.trailing=u,Q(n,r,t)},u.times=function(n,r,t){n=-1<(n=+n)?n:0; +var e=-1,u=Array(n);for(r=a(r,t,1);++e<n;)u[e]=r(e);return u},u.toArray=function(n){return Cr(n)?e(n):n&&typeof n.length=="number"?M(n):R(n)},u.union=function(){return g(p(arguments,true,true))},u.uniq=K,u.values=R,u.where=U,u.without=function(n){return c(n,e(arguments,1))},u.wrap=function(n,r){return v(r,16,[n])},u.zip=function(){for(var n=-1,r=$(Zr(arguments,"length")),t=Array(0>r?0:r);++n<r;)t[n]=Zr(arguments,n);return t},u.collect=M,u.drop=H,u.each=D,u.extend=w,u.methods=x,u.object=function(n,r){var t=-1,e=n?n.length:0,u={}; +for(r||!e||Cr(n[0])||(r=[]);++t<e;){var o=n[t];r?u[o]=r[t]:o&&(u[o[0]]=o[1])}return u},u.select=F,u.tail=H,u.unique=K,u.clone=function(n){return O(n)?Cr(n)?e(n):w({},n):n},u.contains=k,u.escape=function(n){return null==n?"":(n+"").replace(Jr,y)},u.every=B,u.find=q,u.has=function(n,r){return n?Nr.call(n,r):false},u.identity=Y,u.indexOf=G,u.isArguments=b,u.isArray=Cr,u.isBoolean=function(n){return true===n||false===n||n&&typeof n=="object"&&Er.call(n)==lr||false},u.isDate=function(n){return n&&typeof n=="object"&&Er.call(n)==cr||false +},u.isElement=function(n){return n&&1===n.nodeType||false},u.isEmpty=E,u.isEqual=function(n,r){return s(n,r)},u.isFinite=function(n){return qr(n)&&!Dr(parseFloat(n))},u.isFunction=A,u.isNaN=function(n){return S(n)&&n!=+n},u.isNull=function(n){return null===n},u.isNumber=S,u.isObject=O,u.isRegExp=function(n){return n&&vr[typeof n]&&Er.call(n)==gr||false},u.isString=N,u.isUndefined=function(n){return typeof n=="undefined"},u.lastIndexOf=function(n,r,t){var e=n?n.length:0;for(typeof t=="number"&&(e=(0>t?Mr(0,e+t):$r(t,e-1))+1);e--;)if(n[e]===r)return e; +return-1},u.mixin=Z,u.noConflict=function(){return mr._=Tr,this},u.random=function(n,r){return null==n&&null==r&&(r=1),n=+n||0,null==r?(r=n,n=0):r=+r||0,n+Sr(Wr()*(r-n+1))},u.reduce=W,u.reduceRight=z,u.result=function(n,r){if(n){var t=n[r];return A(t)?n[r]():t}},u.size=function(n){var r=n?n.length:0;return typeof r=="number"?r:Ur(n).length},u.some=P,u.sortedIndex=J,u.template=function(n,r,e){var o=u,i=o.templateSettings;n=(n||"")+"",e=j({},e,i);var f=0,a="__p+='",i=e.variable;n.replace(RegExp((e.escape||or).source+"|"+(e.interpolate||or).source+"|"+(e.evaluate||or).source+"|$","g"),function(r,e,u,o,i){return a+=n.slice(f,i).replace(ir,t),e&&(a+="'+_.escape("+e+")+'"),o&&(a+="';"+o+";\n__p+='"),u&&(a+="'+((__t=("+u+"))==null?'':__t)+'"),f=i+r.length,r +}),a+="';",i||(i="obj",a="with("+i+"||{}){"+a+"}"),a="function("+i+"){var __t,__p='',__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}"+a+"return __p}";try{var l=Function("_","return "+a)(o)}catch(c){throw c.source=a,c}return r?l(r):(l.source=a,l)},u.unescape=function(n){return null==n?"":(n+"").replace(Hr,d)},u.uniqueId=function(n){var r=++tr+"";return n?n+r:r},u.all=B,u.any=P,u.detect=q,u.findWhere=function(n,r){return U(n,r,true)},u.foldl=W,u.foldr=z,u.include=k,u.inject=W,u.first=V,u.last=function(n,r,t){var u=0,o=n?n.length:0; +if(typeof r!="number"&&null!=r){var i=o;for(r=X(r,t,3);i--&&r(n[i],i,n);)u++}else if(u=r,null==u||t)return n?n[o-1]:rr;return e(n,Mr(0,o-u))},u.sample=function(n,r,t){return n&&typeof n.length!="number"&&(n=R(n)),null==r||t?n?n[0+Sr(Wr()*(n.length-1-0+1))]:rr:(n=C(n),n.length=$r(Mr(0,r),n.length),n)},u.take=V,u.head=V,Z(u),u.VERSION="2.4.1",u.prototype.chain=function(){return this.__chain__=true,this},u.prototype.value=function(){return this.__wrapped__},D("pop push reverse shift sort splice unshift".split(" "),function(n){var r=jr[n]; +u.prototype[n]=function(){var n=this.__wrapped__;return r.apply(n,arguments),zr.spliceObjects||0!==n.length||delete n[0],this}}),D(["concat","join","slice"],function(n){var r=jr[n];u.prototype[n]=function(){var n=r.apply(this.__wrapped__,arguments);return this.__chain__&&(n=new o(n),n.__chain__=true),n}}),typeof define=="function"&&typeof define.amd=="object"&&define.amd?(mr._=u, define(function(){return u})):_r&&dr?br?(dr.exports=u)._=u:_r._=u:mr._=u}).call(this); \ No newline at end of file
--- a/server/python/django/renkanmanager/static/renkanmanager/lib/renkan/css/renkan.css Sat Apr 25 04:37:06 2015 +0200 +++ b/server/python/django/renkanmanager/static/renkanmanager/lib/renkan/css/renkan.css Mon Apr 27 17:22:46 2015 +0200 @@ -1,28 +1,30 @@ -/*! - * _____ _ - * | __ \ | | - * | |__) |___ _ __ | | ____ _ _ __ - * | _ // _ \ '_ \| |/ / _` | '_ \ +/*! + * _____ _ + * | __ \ | | + * | |__) |___ _ __ | | ____ _ _ __ + * | _ // _ \ '_ \| |/ / _` | '_ \ * | | \ \ __/ | | | < (_| | | | | * |_| \_\___|_| |_|_|\_\__,_|_| |_| * - * Copyright 2012-2013 Institut de recherche et d'innovation - * contributor(s) : Yves-Marie Haussonne, Raphael Velt, Samuel Huron - * + * Copyright 2012-2015 Institut de recherche et d'innovation + * contributor(s) : Yves-Marie Haussonne, Raphael Velt, Samuel Huron, + * Thibaut Cavalié, Julien Rougeron. + * * contact@iri.centrepompidou.fr - * http://www.iri.centrepompidou.fr - * + * http://www.iri.centrepompidou.fr + * * This software is a computer program whose purpose is to show and add annotations on a video . * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, + * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL-C * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * + * "http://www.cecill.info". + * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ -/*! renkan - v0.8.7 - Copyright © IRI 2015 */ + +/*! renkan - v0.9.0 - Copyright © IRI 2015 */ /*! * _____ _ @@ -409,7 +411,7 @@ } .Rk-Edit-Image{ - font-size: 12px; width: 230px; + font-size: 12px; width: 220px; } .Rk-Edit-Image-Del{ @@ -424,7 +426,7 @@ } .Rk-Edit-URI { - font-size: 12px; width: 230px; + font-size: 12px; width: 220px; } .Rk-Edit-ImgWrap {
--- a/server/python/django/renkanmanager/static/renkanmanager/lib/renkan/css/renkan.min.css Sat Apr 25 04:37:06 2015 +0200 +++ b/server/python/django/renkanmanager/static/renkanmanager/lib/renkan/css/renkan.min.css Mon Apr 27 17:22:46 2015 +0200 @@ -1,28 +1,30 @@ -/*! - * _____ _ - * | __ \ | | - * | |__) |___ _ __ | | ____ _ _ __ - * | _ // _ \ '_ \| |/ / _` | '_ \ +/*! + * _____ _ + * | __ \ | | + * | |__) |___ _ __ | | ____ _ _ __ + * | _ // _ \ '_ \| |/ / _` | '_ \ * | | \ \ __/ | | | < (_| | | | | * |_| \_\___|_| |_|_|\_\__,_|_| |_| * - * Copyright 2012-2013 Institut de recherche et d'innovation - * contributor(s) : Yves-Marie Haussonne, Raphael Velt, Samuel Huron - * + * Copyright 2012-2015 Institut de recherche et d'innovation + * contributor(s) : Yves-Marie Haussonne, Raphael Velt, Samuel Huron, + * Thibaut Cavalié, Julien Rougeron. + * * contact@iri.centrepompidou.fr - * http://www.iri.centrepompidou.fr - * + * http://www.iri.centrepompidou.fr + * * This software is a computer program whose purpose is to show and add annotations on a video . * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, + * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL-C * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * + * "http://www.cecill.info". + * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ -/*! renkan - v0.8.7 - Copyright © IRI 2015 */ + +/*! renkan - v0.9.0 - Copyright © IRI 2015 */ /*! @@ -48,4 +50,4 @@ * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. - *//*! renkan - v0.7.11 - Copyright © IRI 2014 */#renkan{overflow:hidden}.Rk-Main h3,.Rk-Main h4,.Rk-Main li,.Rk-Main p,.Rk-Main ul{border:0 none;margin:0;padding:0}.Rk-Main li,.Rk-Main ul{list-style:none}.Rk-Main input::-moz-focus-inner{border:0;padding:0}.Rk-Main table{border-collapse:separate;border-spacing:0}.Rk-Main td,.Rk-Main th{vertical-align:top}.Rk-Main img a{border:none}.Rk-Main{font-size:10px;font-family:Arial,Helvetica,sans-serif;background:#fff;color:#000}.Rk-Main a{color:#6060c0}.Rk-Main{position:absolute;left:0;top:0;right:0;bottom:0}.Rk-Render{position:absolute;top:0;right:0;bottom:0;background:#fff}.Rk-Render-Full{left:0}.Rk-Render-Panel{left:300px}.Rk-TopBar{position:absolute;left:0;top:0;right:0;height:35px;background:#333;background:-moz-linear-gradient(top,#505050 5px,#1e1e1e 30px);background:-webkit-linear-gradient(top,#505050 5px,#1e1e1e 30px);background:-ms-linear-gradient(top,#505050 5px,#1e1e1e 30px);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#505050', endColorstr='#1e1e1e', GradientType=0)}.Rk-TopBar .loader{display:block;background:none repeat red;width:0;height:4px;overflow:hidden;position:absolute;bottom:0;left:0;transition:width 3s linear;z-index:50}.Rk-TopBar .loader.run{width:100%}.Rk-PadTitle{float:left;font-size:14px;height:16px;margin:4px 5px;background:#666;padding:4px;border:1px solid #333;border-radius:3px;box-shadow:0 1px 0 #505050;color:#fff;font-weight:700}input.Rk-PadTitle{width:180px}h2.Rk-PadTitle{min-width:180px;max-width:320px;overflow:hidden}.Rk-Users{float:right;width:130px;margin:4px 5px}.Rk-CurrentUser{font-size:13px;background:#666;padding:4px;border:1px solid #333;border-radius:3px;box-shadow:0 1px 0 #505050;color:#fff;text-align:center}.Rk-CurrentUser-Color{display:inline-block;width:12px;height:12px;border:1px solid #333;margin:-2px 2px;position:relative}.Rk-CurrentUser input{width:95px;padding:1px;border:none;border-radius:2px}.Rk-UserList{box-shadow:0 2px 2px #999;position:relative;z-index:3;display:none;padding-top:8px}.Rk-User{background:#fff;padding:3px;font-size:12px;border-style:solid solid none;border-color:#ccc;border-width:1px}.Rk-TopBar-Button{float:right;background:url(../img/topbarbuttons.png) no-repeat;height:35px;cursor:pointer;position:relative}.Rk-TopBar-Separator{background:#666;background:-moz-linear-gradient(top,#666 20%,#333 80%);background:-webkit-linear-gradient(top,#666 20%,#333 80%);background:-ms-linear-gradient(top,#666 20%,#333 80%);content:"";display:block;height:35px;float:right;width:1px;border-left:1px solid #111;margin:0 3px}.Rk-TopBar-Tooltip{position:absolute;top:31px;left:50%;margin-left:-60px;width:120px;z-index:4;display:none}.Rk-TopBar-Tooltip-Contents{background:#fff;font-size:13px;font-weight:700;color:#6060c0;text-align:center;padding:2px;border-style:none solid solid;border-width:1px;border-color:#ccc;border-bottom-left-radius:2px;border-bottom-right-radius:2px}.Rk-TopBar-Tooltip:before{content:".";display:block;text-indent:-8000px;height:7px;background:url(../img/tooltiparrow.png) center no-repeat;margin:0 1px}.Rk-AddNode-Button{width:30px;background-position:-2px 0}.Rk-AddNode-Button:hover{background-position:-2px -35px}.Rk-FullScreen-Button{width:30px;background-position:-36px 0}.Rk-FullScreen-Button:hover{background-position:-36px -35px}.Rk-AddEdge-Button{width:30px;background-position:-70px 0}.Rk-AddEdge-Button:hover{background-position:-70px -35px}.Rk-Save-Button{width:30px;background-position:-104px 0}.Rk-Save-Button.saving{background-position:-104px 0}.Rk-Save-Button.Rk-Save-Online:hover,.Rk-Save-Button.saved:hover,.Rk-Save-Button:hover{background-position:-104px -35px}.Rk-Save-Button.Rk-Save-Online:active,.Rk-Save-Button.saved:active,.Rk-Save-Button:active{background-position:-104px 0}.Rk-Save-Button.to-save{background-position:-172px -35px}.Rk-Save-Button.Rk-Save-Online,.Rk-Save-Button.saved{background-position:-172px 0}.Rk-Save-Button.Rk-Save-ReadOnly,.Rk-Save-Button.disabled{opacity:.4;cursor:default}.Rk-Export-Button{width:30px;background-position:-274px 0}.Rk-Export-Button.disabled{opacity:.5;cursor:default}.Rk-Export-Button:hover{background-position:-274px -35px}.Rk-Export-Button.disabled:hover{opacity:1;background-position:-274px 0}.Rk-Bookmarklet-Button{width:30px;background-position:-138px 0}.Rk-Bookmarklet-Button.disabled{opacity:.5;cursor:default}.Rk-Bookmarklet-Button:hover{background-position:-138px -35px}.Rk-Bookmarklet-Button.disabled:hover{opacity:1;background-position:-138px 0}.Rk-Home-Button{width:30px;background-position:-206px 0}.Rk-Home-Button:hover{background-position:-206px -35px}.Rk-Open-Button{width:30px;background-position:-240px 0}.Rk-Open-Button:hover{background-position:-240px -35px}.Rk-GraphSearch-Form{float:right;width:185px;position:relative}.Rk-GraphSearch-Form:after,.Rk-GraphSearch-Form:before{position:absolute;display:block;content:".";text-indent:-9999px}.Rk-GraphSearch-Form:before{right:10px;top:20px;width:7px;height:2px;border:none;padding:0;background:#666;transform:rotate(40deg);-webkit-transform:rotate(40deg)}.Rk-GraphSearch-Form:after{right:13px;top:11px;width:6px;height:6px;border-radius:8px;border:2px solid #666}.Rk-GraphSearch-Field{line-height:23px;font-size:14px;height:23px;padding:0 5px;border:none;margin:6px 5px;width:165px;background:#f0f0f0;box-shadow:1px 1px 1px #999 inset;border-radius:5px;-webkit-appearance:none;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.Rk-Editing-Space{position:absolute;left:0;top:35px;right:0;bottom:0;overflow:hidden;background:-moz-radial-gradient(center,circle,#fff 40%,#e0e0e0 90%);background:-webkit-radial-gradient(center,circle,#fff 40%,#e0e0e0 90%);background:-ms-radial-gradient(center,circle,#fff 40%,#e0e0e0 90%)}.Rk-Editing-Space-Full{top:0}.Rk-Canvas{position:absolute;left:0;top:0;right:0;bottom:0;z-index:2}.Rk-Canvas[resize]{width:100%;height:100%}.Rk-Highlighted{background:rgba(255,255,0,.5)}.Rk-Labels{position:absolute;left:0;top:0;z-index:1;font-family:"Segoe UI","Helvetica Neue",Arial,Helvetica,sans-serif}.Rk-Label{position:absolute;width:160px;margin-left:-80px;text-align:center;font-size:13px;line-height:13px}.Rk-Edge-Label{font-size:11px;transform-origin:50% 0;-moz-transform-origin:50% 0;-webkit-transform-origin:50% 0;-ms-transform-origin:50% 0}.Rk-Editor{position:absolute;left:0;top:0;z-index:3}.Rk-Notifications{position:absolute;right:15px;top:15px;width:200px;padding:10px;border-radius:8px;display:none;color:#fff;font-size:13px;text-align:center;font-weight:700;background:rgba(20,20,20,.7);background:-moz-linear-gradient(top,rgba(40,40,40,.7)20%,rgba(0,0,0,.7)80%);background:-webkit-linear-gradient(top,rgba(40,40,40,.7)20%,rgba(0,0,0,.7)80%);background:-ms-linear-gradient(top,rgba(40,40,40,.7)20%,rgba(0,0,0,.7)80%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#202020', endColorstr='#000000', GradientType=0)}.Rk-CloseX{float:right;cursor:pointer}.Rk-Editor h2{font-size:16px;font-weight:700}.Rk-Editor p,.Rk-Editor-p{margin:5px 0;font-size:12px;clear:both}.Rk-Editor-Label{float:left;width:80px}a.Rk-Edit-Goto{display:block;float:right;width:18px;height:17px;margin:1px 0;border:none;background:url(../img/goto.png)}.Rk-Edit-Image-File,.Rk-Edit-Title,.Rk-Edit-URI,.Rk-Edit-Vocabulary{font-size:12px;width:250px}.Rk-Edit-Image{font-size:12px;width:230px}.Rk-Edit-Image-Del{display:inline-block;background:url(../img/remove.png);background-size:15px 20px;background-repeat:no-repeat;vertical-align:top;height:20px;width:15px;margin-right:2px}.Rk-Edit-URI{font-size:12px;width:230px}.Rk-Edit-ImgWrap{text-align:center}.Rk-Edit-ImgPreview{display:inline-block;border:1px solid #666;margin:5px auto;position:relative}.Rk-Edit-ImgPreview img{display:inline-block;max-width:253px!important;max-height:200px!important}.Rk-Edit-ImgPreview svg{height:100%;left:0;position:absolute;top:0;width:100%}.Rk-Editor textarea{width:250px;height:120px;resize:none}.Rk-UserColor{display:inline-block;width:12px;height:12px;border:1px solid #666;margin:-2px 2px}.Rk-Edit-Color{display:inline-block;width:10px;height:10px;border:2px solid #333;margin:-2px 2px;position:relative}.Rk-Edit-ColorTip{display:block;width:3px;height:3px;background:#fff;position:absolute;bottom:0;right:0;cursor:pointer}.Rk-Edit-ColorPicker-Wrapper{display:inline-block;position:relative;float:left}.Rk-Edit-ColorPicker{position:absolute;top:-2px;left:15px;width:96px;height:96px;border:1px solid #CCC;padding:5px 4px 4px 5px;background:#fff;border-radius:5px;display:none;z-index:4}.Rk-CurrentUser .Rk-Edit-ColorPicker{left:-105px;top:2px}.Rk-Edit-ColorPicker-Text{color:#303080;font-weight:700}.Rk-Edit-ColorPicker li{float:left;width:11px;height:11px;margin:0 1px 1px 0;cursor:pointer}.Rk-Edit-Size-Down,.Rk-Edit-Size-Up{font-size:13px;font-weight:700;padding:0 4px;background:#fff;color:#000;border:1px solid #ccc;text-decoration:none}.Rk-Edit-Size-Down:hover,.Rk-Edit-Size-Up:hover{background:#666}.Rk-Edit-Size-Value{display:inline-block;padding:0 5px;text-align:center;width:20px}.Rk-Edit-Vocabulary-Class{color:#999;font-style:italic;font-weight:700}.Rk-Edit-Vocabulary-Property{padding-left:20px}.Rk-Edit-Direction{border:1px solid #666;padding:3px 5px;line-height:20px;border-radius:3px;background:#f0f0f0;cursor:pointer}.Rk-Edit-Direction:hover{background:silver}.Rk-Display-Title a{text-decoration:none;color:#000}.Rk-Display-Title a:hover{text-decoration:underline}.Rk-Display-URI{font-style:italic}.Rk-Display-ImgPreview{margin:5px auto;display:block;max-width:255px!important;max-height:260px!important}.Rk-Fold-Bins{position:absolute;top:5px;width:12px;text-align:center;font-size:16px;cursor:pointer;line-height:16px;padding:4px;color:#fff;background:#666;border-radius:0 6px 6px 0;font-weight:700}.Rk-Fold-Bins:hover{background:#333}.Rk-ZoomButtons{position:absolute;left:0;top:35px;cursor:pointer}.Rk-Editing-Space-Full .Rk-ZoomButtons{top:0}.Rk-ZoomFit,.Rk-ZoomIn,.Rk-ZoomOut,.Rk-ZoomSave,.Rk-ZoomSetSaved{width:21px;height:20px;background:url(../img/zoombuttons.png);margin:5px}.Rk-ZoomIn:hover{background-position:0 -20px}.Rk-ZoomFit{background-position:-42px 0}.Rk-ZoomFit:hover{background-position:-42px -20px}.Rk-ZoomOut{background-position:-21px 0}.Rk-ZoomOut:hover{background-position:-21px -20px}.Rk-ZoomSave{background-position:-63px 0}.Rk-ZoomSave:hover{background-position:-63px -20px}.Rk-ZoomSetSaved{background-position:-84px 0;display:none}.Rk-ZoomSetSaved:hover{background-position:-84px -20px}.Rk-Bins{background:#fff;position:absolute;left:0;top:0;width:299px;bottom:0;overflow:hidden;border-right:1px solid #252525}.Rk-Bins-Title{border:0 none;width:290px;height:15px;line-height:15px;margin:0;padding:15px 0 5px 10px;font-size:14px;color:#F0F0F0;background:-moz-linear-gradient(top,#1e1e1e 5px,#606060 30px);background:-webkit-linear-gradient(top,#1e1e1e 5px,#606060 30px);background:-ms-linear-gradient(top,#1e1e1e 5px,#606060 30px);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#1e1e1e', endColorstr='#606060', GradientType=0)}.Rk-Search-Form{padding:0 10px 8px;height:27px;background:#606060}.Rk-Search-Input,.Rk-Search-Select{float:left;margin:0}.Rk-Search-Input{border-top-left-radius:5px;border-bottom-left-radius:5px;border:1px solid #003050;font-size:13px;background:#fff;height:25px;padding:0 5px;line-height:25px;-webkit-appearance:none;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.Rk-Web-Search-Input{width:190px}.Rk-Bins-Search-Input{width:235px}.Rk-Search-Select{display:inline-block;position:relative;width:45px;border-width:1px;border-color:#003050;border-style:solid none;cursor:pointer;height:25px;background:#fff url(../img/more.png) 30px 10px no-repeat}.Rk-Search-Select:hover{background-color:#3030FF}.Rk-Search-Current{width:40px;height:20px;margin:2px;background-repeat:no-repeat}.Rk-Search-List{width:180px;margin-left:15px;font-size:13px;position:absolute;right:0;top:25px;background:#fff;box-shadow:1px 1px 2px #505050;display:none;border:1px solid #ccc;z-index:2}.Rk-Search-List li{padding:2px 2px 2px 30px;border-top:1px solid #ccc;height:16px;background-color:#fff;background-repeat:no-repeat;cursor:pointer}.Rk-Search-List li:hover{background-color:#3030ff;color:#fff}.Rk-Search-Submit{border:1px solid #003050;height:27px;width:30px;border-top-right-radius:5px;border-bottom-right-radius:5px;background:#333 center no-repeat url(../img/search.png);cursor:pointer}.Rk-Search-Submit:hover{background-color:#999}.Rk-Bin-Title{background:#333;background:-moz-linear-gradient(top,#505050 20%,#1e1e1e 80%);background:-webkit-linear-gradient(top,#505050 20%,#1e1e1e 80%);background:-ms-linear-gradient(top,#505050 20%,#1e1e1e 80%);font-weight:700;font-size:14px;padding:5px;cursor:pointer;color:#f0f0f0;margin:0;border:0 none}.Rk-Bin-Close{float:right;display:block;font-size:16px;font-weight:700;margin:2px 3px 0;color:#f0f0f0;cursor:pointer;text-shadow:-1px -1px 1px #999,1px 1px 1px #000;text-decoration:none}.Rk-Bin-Close:hover{color:#ffff80}.Rk-Bin-Title:hover{color:#ffffe0;background:#505050;background:-moz-linear-gradient(top,#141414 20%,#3c3c3c 80%);background:-webkit-linear-gradient(top,#141414 20%,#3c3c3c 80%);background:-ms-linear-gradient(top,#141414 20%,#3c3c3c 80%)}.Rk-Bin-Refresh{width:18px;height:17px;background:url(../img/refresh.png);display:block;float:right;margin-top:4px}.Rk-Bin-Refresh:hover{background-position:-18px 0}.Rk-Bin-Count{float:right;background:#c000a0;color:#FFF;text-shadow:1px 1px 1px #000;display:none;border-radius:4px;padding:1px 3px;font-size:10px;font-weight:700;margin-top:4px}.Rk-Bin-Title-Icon{float:left;width:25px;margin:2px}.Rk-Bin-Main{overflow:auto;background:#fff;background:-moz-linear-gradient(top,#e0e0e0 0,#FFF 2%,#FFF 98%,#e0e0e0 100%);background:-webkit-linear-gradient(top,#e0e0e0 0,#FFF 2%,#FFF 98%,#e0e0e0 100%);background:-ms-linear-gradient(top,#e0e0e0 0,#FFF 2%,#FFF 98%,#e0e0e0 100%)}.Rk-Bin-Item{cursor:move}.Rk-Bin-Item.hover,.Rk-Bin-Item:hover{background:-moz-linear-gradient(top,rgba(0,0,0,.1)20%,rgba(128,128,128,.1)80%);background:-webkit-linear-gradient(top,rgba(0,0,0,.1)20%,rgba(128,128,128,.1)80%);background:-ms-linear-gradient(top,rgba(0,0,0,.1)20%,rgba(128,128,128,.1)80%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#d0d0d0', endColorstr='#f3f3f3', GradientType=0)}.Rk-Bin-Item.selected{background:#ffffc0}.Rk-Bin-Main li{padding:2px;border-bottom:1px solid #ccc;clear:both;overflow:hidden}.Rk-Bin-Main h3{font-size:14px;font-style:italic;font-weight:700;text-align:center}.Rk-Bin-Main h4{font-size:12px;font-weight:700}.Rk-Bin-Main p{font-size:11px}.Rk-Bin-Main h4 a{color:#303080}.Rk-Bin-Main .searchmatch{background:#ffff80}.Rk-Wikipedia-Search-Icon{background-image:url(../img/search-logos.png)}.Rk-Wikipedia-Icon{float:left;margin:3px;max-height:48px;max-width:48px}.Rk-Wikipedia-Title-Icon{height:20px;background:url(../img/search-logos.png)}.Rk-Wikipedia-Lang-en{background-position:0 -20px}.Rk-Wikipedia-Lang-fr{background-position:0 -40px}.Rk-Wikipedia-Lang-ja{background-position:0 -60px}.Rk-Wikipedia-Result{min-height:51px}.Rk-Wikipedia-Result h4,.Rk-Wikipedia-Result p{margin-left:54px}.Rk-ResourceList-Image{float:left;max-width:100px;max-height:75px;margin-right:2px}.Rk-Ldt-Icon,.Rk-Ldt-Title-Icon{background:url(../img/search-logos.png);background-position:0 -100px;background-repeat:no-repeat}.Rk-Ldt-Title-Icon{height:20px;margin-top:4px}.Rk-Ldt-Tag-Icon{float:left;margin:0 2px 0 0}.Rk-Ldt-Annotation-Icon{float:left;margin:3px}.Rk-Clear{clear:both}h4.Rk-Bin-Loading{margin:10px;text-align:center;font-size:20px;color:#999} \ No newline at end of file + *//*! renkan - v0.7.11 - Copyright © IRI 2014 */#renkan{overflow:hidden}.Rk-Main h3,.Rk-Main h4,.Rk-Main li,.Rk-Main p,.Rk-Main ul{border:0 none;margin:0;padding:0}.Rk-Main li,.Rk-Main ul{list-style:none}.Rk-Main input::-moz-focus-inner{border:0;padding:0}.Rk-Main table{border-collapse:separate;border-spacing:0}.Rk-Main td,.Rk-Main th{vertical-align:top}.Rk-Main img a{border:none}.Rk-Main{font-size:10px;font-family:Arial,Helvetica,sans-serif;background:#fff;color:#000}.Rk-Main a{color:#6060c0}.Rk-Main{position:absolute;left:0;top:0;right:0;bottom:0}.Rk-Render{position:absolute;top:0;right:0;bottom:0;background:#fff}.Rk-Render-Full{left:0}.Rk-Render-Panel{left:300px}.Rk-TopBar{position:absolute;left:0;top:0;right:0;height:35px;background:#333;background:-moz-linear-gradient(top,#505050 5px,#1e1e1e 30px);background:-webkit-linear-gradient(top,#505050 5px,#1e1e1e 30px);background:-ms-linear-gradient(top,#505050 5px,#1e1e1e 30px);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#505050', endColorstr='#1e1e1e', GradientType=0)}.Rk-TopBar .loader{display:block;background:none repeat red;width:0;height:4px;overflow:hidden;position:absolute;bottom:0;left:0;transition:width 3s linear;z-index:50}.Rk-TopBar .loader.run{width:100%}.Rk-PadTitle{float:left;font-size:14px;height:16px;margin:4px 5px;background:#666;padding:4px;border:1px solid #333;border-radius:3px;box-shadow:0 1px 0 #505050;color:#fff;font-weight:700}input.Rk-PadTitle{width:180px}h2.Rk-PadTitle{min-width:180px;max-width:320px;overflow:hidden}.Rk-Users{float:right;width:130px;margin:4px 5px}.Rk-CurrentUser{font-size:13px;background:#666;padding:4px;border:1px solid #333;border-radius:3px;box-shadow:0 1px 0 #505050;color:#fff;text-align:center}.Rk-CurrentUser-Color{display:inline-block;width:12px;height:12px;border:1px solid #333;margin:-2px 2px;position:relative}.Rk-CurrentUser input{width:95px;padding:1px;border:none;border-radius:2px}.Rk-UserList{box-shadow:0 2px 2px #999;position:relative;z-index:3;display:none;padding-top:8px}.Rk-User{background:#fff;padding:3px;font-size:12px;border-style:solid solid none;border-color:#ccc;border-width:1px}.Rk-TopBar-Button{float:right;background:url(../img/topbarbuttons.png) no-repeat;height:35px;cursor:pointer;position:relative}.Rk-TopBar-Separator{background:#666;background:-moz-linear-gradient(top,#666 20%,#333 80%);background:-webkit-linear-gradient(top,#666 20%,#333 80%);background:-ms-linear-gradient(top,#666 20%,#333 80%);content:"";display:block;height:35px;float:right;width:1px;border-left:1px solid #111;margin:0 3px}.Rk-TopBar-Tooltip{position:absolute;top:31px;left:50%;margin-left:-60px;width:120px;z-index:4;display:none}.Rk-TopBar-Tooltip-Contents{background:#fff;font-size:13px;font-weight:700;color:#6060c0;text-align:center;padding:2px;border-style:none solid solid;border-width:1px;border-color:#ccc;border-bottom-left-radius:2px;border-bottom-right-radius:2px}.Rk-TopBar-Tooltip:before{content:".";display:block;text-indent:-8000px;height:7px;background:url(../img/tooltiparrow.png) center no-repeat;margin:0 1px}.Rk-AddNode-Button{width:30px;background-position:-2px 0}.Rk-AddNode-Button:hover{background-position:-2px -35px}.Rk-FullScreen-Button{width:30px;background-position:-36px 0}.Rk-FullScreen-Button:hover{background-position:-36px -35px}.Rk-AddEdge-Button{width:30px;background-position:-70px 0}.Rk-AddEdge-Button:hover{background-position:-70px -35px}.Rk-Save-Button{width:30px;background-position:-104px 0}.Rk-Save-Button.saving{background-position:-104px 0}.Rk-Save-Button.Rk-Save-Online:hover,.Rk-Save-Button.saved:hover,.Rk-Save-Button:hover{background-position:-104px -35px}.Rk-Save-Button.Rk-Save-Online:active,.Rk-Save-Button.saved:active,.Rk-Save-Button:active{background-position:-104px 0}.Rk-Save-Button.to-save{background-position:-172px -35px}.Rk-Save-Button.Rk-Save-Online,.Rk-Save-Button.saved{background-position:-172px 0}.Rk-Save-Button.Rk-Save-ReadOnly,.Rk-Save-Button.disabled{opacity:.4;cursor:default}.Rk-Export-Button{width:30px;background-position:-274px 0}.Rk-Export-Button.disabled{opacity:.5;cursor:default}.Rk-Export-Button:hover{background-position:-274px -35px}.Rk-Export-Button.disabled:hover{opacity:1;background-position:-274px 0}.Rk-Bookmarklet-Button{width:30px;background-position:-138px 0}.Rk-Bookmarklet-Button.disabled{opacity:.5;cursor:default}.Rk-Bookmarklet-Button:hover{background-position:-138px -35px}.Rk-Bookmarklet-Button.disabled:hover{opacity:1;background-position:-138px 0}.Rk-Home-Button{width:30px;background-position:-206px 0}.Rk-Home-Button:hover{background-position:-206px -35px}.Rk-Open-Button{width:30px;background-position:-240px 0}.Rk-Open-Button:hover{background-position:-240px -35px}.Rk-GraphSearch-Form{float:right;width:185px;position:relative}.Rk-GraphSearch-Form:after,.Rk-GraphSearch-Form:before{position:absolute;display:block;content:".";text-indent:-9999px}.Rk-GraphSearch-Form:before{right:10px;top:20px;width:7px;height:2px;border:none;padding:0;background:#666;transform:rotate(40deg);-webkit-transform:rotate(40deg)}.Rk-GraphSearch-Form:after{right:13px;top:11px;width:6px;height:6px;border-radius:8px;border:2px solid #666}.Rk-GraphSearch-Field{line-height:23px;font-size:14px;height:23px;padding:0 5px;border:none;margin:6px 5px;width:165px;background:#f0f0f0;box-shadow:1px 1px 1px #999 inset;border-radius:5px;-webkit-appearance:none;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.Rk-Editing-Space{position:absolute;left:0;top:35px;right:0;bottom:0;overflow:hidden;background:-moz-radial-gradient(center,circle,#fff 40%,#e0e0e0 90%);background:-webkit-radial-gradient(center,circle,#fff 40%,#e0e0e0 90%);background:-ms-radial-gradient(center,circle,#fff 40%,#e0e0e0 90%)}.Rk-Editing-Space-Full{top:0}.Rk-Canvas{position:absolute;left:0;top:0;right:0;bottom:0;z-index:2}.Rk-Canvas[resize]{width:100%;height:100%}.Rk-Highlighted{background:rgba(255,255,0,.5)}.Rk-Labels{position:absolute;left:0;top:0;z-index:1;font-family:"Segoe UI","Helvetica Neue",Arial,Helvetica,sans-serif}.Rk-Label{position:absolute;width:160px;margin-left:-80px;text-align:center;font-size:13px;line-height:13px}.Rk-Edge-Label{font-size:11px;transform-origin:50% 0;-moz-transform-origin:50% 0;-webkit-transform-origin:50% 0;-ms-transform-origin:50% 0}.Rk-Editor{position:absolute;left:0;top:0;z-index:3}.Rk-Notifications{position:absolute;right:15px;top:15px;width:200px;padding:10px;border-radius:8px;display:none;color:#fff;font-size:13px;text-align:center;font-weight:700;background:rgba(20,20,20,.7);background:-moz-linear-gradient(top,rgba(40,40,40,.7)20%,rgba(0,0,0,.7)80%);background:-webkit-linear-gradient(top,rgba(40,40,40,.7)20%,rgba(0,0,0,.7)80%);background:-ms-linear-gradient(top,rgba(40,40,40,.7)20%,rgba(0,0,0,.7)80%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#202020', endColorstr='#000000', GradientType=0)}.Rk-CloseX{float:right;cursor:pointer}.Rk-Editor h2{font-size:16px;font-weight:700}.Rk-Editor p,.Rk-Editor-p{margin:5px 0;font-size:12px;clear:both}.Rk-Editor-Label{float:left;width:80px}a.Rk-Edit-Goto{display:block;float:right;width:18px;height:17px;margin:1px 0;border:none;background:url(../img/goto.png)}.Rk-Edit-Image-File,.Rk-Edit-Title,.Rk-Edit-URI,.Rk-Edit-Vocabulary{font-size:12px;width:250px}.Rk-Edit-Image{font-size:12px;width:220px}.Rk-Edit-Image-Del{display:inline-block;background:url(../img/remove.png);background-size:15px 20px;background-repeat:no-repeat;vertical-align:top;height:20px;width:15px;margin-right:2px}.Rk-Edit-URI{font-size:12px;width:220px}.Rk-Edit-ImgWrap{text-align:center}.Rk-Edit-ImgPreview{display:inline-block;border:1px solid #666;margin:5px auto;position:relative}.Rk-Edit-ImgPreview img{display:inline-block;max-width:253px!important;max-height:200px!important}.Rk-Edit-ImgPreview svg{height:100%;left:0;position:absolute;top:0;width:100%}.Rk-Editor textarea{width:250px;height:120px;resize:none}.Rk-UserColor{display:inline-block;width:12px;height:12px;border:1px solid #666;margin:-2px 2px}.Rk-Edit-Color{display:inline-block;width:10px;height:10px;border:2px solid #333;margin:-2px 2px;position:relative}.Rk-Edit-ColorTip{display:block;width:3px;height:3px;background:#fff;position:absolute;bottom:0;right:0;cursor:pointer}.Rk-Edit-ColorPicker-Wrapper{display:inline-block;position:relative;float:left}.Rk-Edit-ColorPicker{position:absolute;top:-2px;left:15px;width:96px;height:96px;border:1px solid #CCC;padding:5px 4px 4px 5px;background:#fff;border-radius:5px;display:none;z-index:4}.Rk-CurrentUser .Rk-Edit-ColorPicker{left:-105px;top:2px}.Rk-Edit-ColorPicker-Text{color:#303080;font-weight:700}.Rk-Edit-ColorPicker li{float:left;width:11px;height:11px;margin:0 1px 1px 0;cursor:pointer}.Rk-Edit-Size-Down,.Rk-Edit-Size-Up{font-size:13px;font-weight:700;padding:0 4px;background:#fff;color:#000;border:1px solid #ccc;text-decoration:none}.Rk-Edit-Size-Down:hover,.Rk-Edit-Size-Up:hover{background:#666}.Rk-Edit-Size-Value{display:inline-block;padding:0 5px;text-align:center;width:20px}.Rk-Edit-Vocabulary-Class{color:#999;font-style:italic;font-weight:700}.Rk-Edit-Vocabulary-Property{padding-left:20px}.Rk-Edit-Direction{border:1px solid #666;padding:3px 5px;line-height:20px;border-radius:3px;background:#f0f0f0;cursor:pointer}.Rk-Edit-Direction:hover{background:silver}.Rk-Display-Title a{text-decoration:none;color:#000}.Rk-Display-Title a:hover{text-decoration:underline}.Rk-Display-URI{font-style:italic}.Rk-Display-ImgPreview{margin:5px auto;display:block;max-width:255px!important;max-height:260px!important}.Rk-Fold-Bins{position:absolute;top:5px;width:12px;text-align:center;font-size:16px;cursor:pointer;line-height:16px;padding:4px;color:#fff;background:#666;border-radius:0 6px 6px 0;font-weight:700}.Rk-Fold-Bins:hover{background:#333}.Rk-ZoomButtons{position:absolute;left:0;top:35px;cursor:pointer}.Rk-Editing-Space-Full .Rk-ZoomButtons{top:0}.Rk-ZoomFit,.Rk-ZoomIn,.Rk-ZoomOut,.Rk-ZoomSave,.Rk-ZoomSetSaved{width:21px;height:20px;background:url(../img/zoombuttons.png);margin:5px}.Rk-ZoomIn:hover{background-position:0 -20px}.Rk-ZoomFit{background-position:-42px 0}.Rk-ZoomFit:hover{background-position:-42px -20px}.Rk-ZoomOut{background-position:-21px 0}.Rk-ZoomOut:hover{background-position:-21px -20px}.Rk-ZoomSave{background-position:-63px 0}.Rk-ZoomSave:hover{background-position:-63px -20px}.Rk-ZoomSetSaved{background-position:-84px 0;display:none}.Rk-ZoomSetSaved:hover{background-position:-84px -20px}.Rk-Bins{background:#fff;position:absolute;left:0;top:0;width:299px;bottom:0;overflow:hidden;border-right:1px solid #252525}.Rk-Bins-Title{border:0 none;width:290px;height:15px;line-height:15px;margin:0;padding:15px 0 5px 10px;font-size:14px;color:#F0F0F0;background:-moz-linear-gradient(top,#1e1e1e 5px,#606060 30px);background:-webkit-linear-gradient(top,#1e1e1e 5px,#606060 30px);background:-ms-linear-gradient(top,#1e1e1e 5px,#606060 30px);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#1e1e1e', endColorstr='#606060', GradientType=0)}.Rk-Search-Form{padding:0 10px 8px;height:27px;background:#606060}.Rk-Search-Input,.Rk-Search-Select{float:left;margin:0}.Rk-Search-Input{border-top-left-radius:5px;border-bottom-left-radius:5px;border:1px solid #003050;font-size:13px;background:#fff;height:25px;padding:0 5px;line-height:25px;-webkit-appearance:none;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.Rk-Web-Search-Input{width:190px}.Rk-Bins-Search-Input{width:235px}.Rk-Search-Select{display:inline-block;position:relative;width:45px;border-width:1px;border-color:#003050;border-style:solid none;cursor:pointer;height:25px;background:#fff url(../img/more.png) 30px 10px no-repeat}.Rk-Search-Select:hover{background-color:#3030FF}.Rk-Search-Current{width:40px;height:20px;margin:2px;background-repeat:no-repeat}.Rk-Search-List{width:180px;margin-left:15px;font-size:13px;position:absolute;right:0;top:25px;background:#fff;box-shadow:1px 1px 2px #505050;display:none;border:1px solid #ccc;z-index:2}.Rk-Search-List li{padding:2px 2px 2px 30px;border-top:1px solid #ccc;height:16px;background-color:#fff;background-repeat:no-repeat;cursor:pointer}.Rk-Search-List li:hover{background-color:#3030ff;color:#fff}.Rk-Search-Submit{border:1px solid #003050;height:27px;width:30px;border-top-right-radius:5px;border-bottom-right-radius:5px;background:#333 center no-repeat url(../img/search.png);cursor:pointer}.Rk-Search-Submit:hover{background-color:#999}.Rk-Bin-Title{background:#333;background:-moz-linear-gradient(top,#505050 20%,#1e1e1e 80%);background:-webkit-linear-gradient(top,#505050 20%,#1e1e1e 80%);background:-ms-linear-gradient(top,#505050 20%,#1e1e1e 80%);font-weight:700;font-size:14px;padding:5px;cursor:pointer;color:#f0f0f0;margin:0;border:0 none}.Rk-Bin-Close{float:right;display:block;font-size:16px;font-weight:700;margin:2px 3px 0;color:#f0f0f0;cursor:pointer;text-shadow:-1px -1px 1px #999,1px 1px 1px #000;text-decoration:none}.Rk-Bin-Close:hover{color:#ffff80}.Rk-Bin-Title:hover{color:#ffffe0;background:#505050;background:-moz-linear-gradient(top,#141414 20%,#3c3c3c 80%);background:-webkit-linear-gradient(top,#141414 20%,#3c3c3c 80%);background:-ms-linear-gradient(top,#141414 20%,#3c3c3c 80%)}.Rk-Bin-Refresh{width:18px;height:17px;background:url(../img/refresh.png);display:block;float:right;margin-top:4px}.Rk-Bin-Refresh:hover{background-position:-18px 0}.Rk-Bin-Count{float:right;background:#c000a0;color:#FFF;text-shadow:1px 1px 1px #000;display:none;border-radius:4px;padding:1px 3px;font-size:10px;font-weight:700;margin-top:4px}.Rk-Bin-Title-Icon{float:left;width:25px;margin:2px}.Rk-Bin-Main{overflow:auto;background:#fff;background:-moz-linear-gradient(top,#e0e0e0 0,#FFF 2%,#FFF 98%,#e0e0e0 100%);background:-webkit-linear-gradient(top,#e0e0e0 0,#FFF 2%,#FFF 98%,#e0e0e0 100%);background:-ms-linear-gradient(top,#e0e0e0 0,#FFF 2%,#FFF 98%,#e0e0e0 100%)}.Rk-Bin-Item{cursor:move}.Rk-Bin-Item.hover,.Rk-Bin-Item:hover{background:-moz-linear-gradient(top,rgba(0,0,0,.1)20%,rgba(128,128,128,.1)80%);background:-webkit-linear-gradient(top,rgba(0,0,0,.1)20%,rgba(128,128,128,.1)80%);background:-ms-linear-gradient(top,rgba(0,0,0,.1)20%,rgba(128,128,128,.1)80%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#d0d0d0', endColorstr='#f3f3f3', GradientType=0)}.Rk-Bin-Item.selected{background:#ffffc0}.Rk-Bin-Main li{padding:2px;border-bottom:1px solid #ccc;clear:both;overflow:hidden}.Rk-Bin-Main h3{font-size:14px;font-style:italic;font-weight:700;text-align:center}.Rk-Bin-Main h4{font-size:12px;font-weight:700}.Rk-Bin-Main p{font-size:11px}.Rk-Bin-Main h4 a{color:#303080}.Rk-Bin-Main .searchmatch{background:#ffff80}.Rk-Wikipedia-Search-Icon{background-image:url(../img/search-logos.png)}.Rk-Wikipedia-Icon{float:left;margin:3px;max-height:48px;max-width:48px}.Rk-Wikipedia-Title-Icon{height:20px;background:url(../img/search-logos.png)}.Rk-Wikipedia-Lang-en{background-position:0 -20px}.Rk-Wikipedia-Lang-fr{background-position:0 -40px}.Rk-Wikipedia-Lang-ja{background-position:0 -60px}.Rk-Wikipedia-Result{min-height:51px}.Rk-Wikipedia-Result h4,.Rk-Wikipedia-Result p{margin-left:54px}.Rk-ResourceList-Image{float:left;max-width:100px;max-height:75px;margin-right:2px}.Rk-Ldt-Icon,.Rk-Ldt-Title-Icon{background:url(../img/search-logos.png);background-position:0 -100px;background-repeat:no-repeat}.Rk-Ldt-Title-Icon{height:20px;margin-top:4px}.Rk-Ldt-Tag-Icon{float:left;margin:0 2px 0 0}.Rk-Ldt-Annotation-Icon{float:left;margin:3px}.Rk-Clear{clear:both}h4.Rk-Bin-Loading{margin:10px;text-align:center;font-size:20px;color:#999} \ No newline at end of file
--- a/server/python/django/renkanmanager/static/renkanmanager/lib/renkan/css/space-editor.css Sat Apr 25 04:37:06 2015 +0200 +++ b/server/python/django/renkanmanager/static/renkanmanager/lib/renkan/css/space-editor.css Mon Apr 27 17:22:46 2015 +0200 @@ -1,28 +1,30 @@ -/*! - * _____ _ - * | __ \ | | - * | |__) |___ _ __ | | ____ _ _ __ - * | _ // _ \ '_ \| |/ / _` | '_ \ +/*! + * _____ _ + * | __ \ | | + * | |__) |___ _ __ | | ____ _ _ __ + * | _ // _ \ '_ \| |/ / _` | '_ \ * | | \ \ __/ | | | < (_| | | | | * |_| \_\___|_| |_|_|\_\__,_|_| |_| * - * Copyright 2012-2013 Institut de recherche et d'innovation - * contributor(s) : Yves-Marie Haussonne, Raphael Velt, Samuel Huron - * + * Copyright 2012-2015 Institut de recherche et d'innovation + * contributor(s) : Yves-Marie Haussonne, Raphael Velt, Samuel Huron, + * Thibaut Cavalié, Julien Rougeron. + * * contact@iri.centrepompidou.fr - * http://www.iri.centrepompidou.fr - * + * http://www.iri.centrepompidou.fr + * * This software is a computer program whose purpose is to show and add annotations on a video . * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, + * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL-C * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * + * "http://www.cecill.info". + * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ -/*! renkan - v0.8.7 - Copyright © IRI 2015 */ + +/*! renkan - v0.9.0 - Copyright © IRI 2015 */ html { overflow: visible !important;
--- a/server/python/django/renkanmanager/static/renkanmanager/lib/renkan/css/space-editor.min.css Sat Apr 25 04:37:06 2015 +0200 +++ b/server/python/django/renkanmanager/static/renkanmanager/lib/renkan/css/space-editor.min.css Mon Apr 27 17:22:46 2015 +0200 @@ -1,28 +1,30 @@ -/*! - * _____ _ - * | __ \ | | - * | |__) |___ _ __ | | ____ _ _ __ - * | _ // _ \ '_ \| |/ / _` | '_ \ +/*! + * _____ _ + * | __ \ | | + * | |__) |___ _ __ | | ____ _ _ __ + * | _ // _ \ '_ \| |/ / _` | '_ \ * | | \ \ __/ | | | < (_| | | | | * |_| \_\___|_| |_|_|\_\__,_|_| |_| * - * Copyright 2012-2013 Institut de recherche et d'innovation - * contributor(s) : Yves-Marie Haussonne, Raphael Velt, Samuel Huron - * + * Copyright 2012-2015 Institut de recherche et d'innovation + * contributor(s) : Yves-Marie Haussonne, Raphael Velt, Samuel Huron, + * Thibaut Cavalié, Julien Rougeron. + * * contact@iri.centrepompidou.fr - * http://www.iri.centrepompidou.fr - * + * http://www.iri.centrepompidou.fr + * * This software is a computer program whose purpose is to show and add annotations on a video . * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, + * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL-C * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * + * "http://www.cecill.info". + * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ -/*! renkan - v0.8.7 - Copyright © IRI 2015 */ + +/*! renkan - v0.9.0 - Copyright © IRI 2015 */ html{overflow:visible!important}body{font-family:Arial,Helvetica,sans-serif;background:#F6F6F6;color:#333}.clearer{display:block;clear:both;height:1px}h1{margin-bottom:5px;padding:0 15px;background:#333;color:#fff;font-weight:700;font-size:30px;line-height:60px}.right{width:301px;position:absolute;top:10px;right:10px}.main{margin:10px 330px 10px 20px}.blue-button{display:inline-block;padding:4px 6px;color:#fff;text-decoration:none;border-radius:4px;background:-moz-linear-gradient(top,#6080c0,#2040a0);background:-webkit-linear-gradient(top,#6080c0,#2040a0);box-shadow:1px 1px 2px gray}.blue-button:hover{background:-moz-linear-gradient(top,#2040a0,#6080c0);background:-webkit-linear-gradient(top,#2040a0,#6080c0)}.update-preview{text-align:center;display:block;margin-bottom:10px;font-size:24px;font-weight:700;line-height:34px}#preview{position:relative;border-left:1px solid #000;border-bottom:1px solid #000;width:300px;height:800px;border-radius:4px;overflow:hidden;margin-bottom:10px}.section-title{font-size:20px;font-weight:700;margin:20px 0 5px}.first-level-list{margin:5px 0}.add-item{margin:5px 0;font-size:22px;font-weight:700;line-height:18px}.add-item:hover:after{float:right;font-size:14px;font-weight:400;line-height:18px;margin-left:4px}.add-search-engine:hover:after{content:"Add Search Engine"}.add-resource:hover:after{content:"Add Resource"}.add-bin:hover:after{content:"Add Bin"}.item{padding:5px;margin:5px 0;border-radius:4px;font-size:12px;background:-moz-linear-gradient(top,#ffcc8f,#fff0d0);background:-webkit-linear-gradient(top,#ffcc8f,#fff0d0);box-shadow:1px 1px 2px gray}.remove-item{float:right;font-size:22px;line-height:18px;height:18px;margin:0 0 2px -10px;font-weight:700}.setting{float:left;width:260px;margin:2px 15px 2px 2px;line-height:24px;min-height:24px}.setting label{float:left;display:block;width:100px;font-weight:700}.display-value{float:left;display:block;width:160px}.edit-value{width:160px;display:none;border:1px solid #ccc;border-radius:3px}input.edit-value,textarea.edit-value{width:154px;padding:2px}textarea.edit-value{resize:vertical;height:72px}.item-editing .display-value{display:none}.item-editing .edit-value{display:inline-block}.resource-list-title{clear:both;width:100%;font-size:16px;font-weight:700;margin:5px 0 0}.resource{display:block;clear:both;padding:5px;margin:5px;border-radius:4px;background:-moz-linear-gradient(top,#ff8f00,#ffcc8f);background:-webkit-linear-gradient(top,#ff8f00,#ffcc8f);box-shadow:1px 1px 2px gray}.resource .display-value{display:inline-block}.resource .edit-value,.resource.resource-editing .display-value{display:none}.resource.resource-editing .edit-value{display:inline-block} \ No newline at end of file
--- a/server/python/django/renkanmanager/static/renkanmanager/lib/renkan/js/renkan.js Sat Apr 25 04:37:06 2015 +0200 +++ b/server/python/django/renkanmanager/static/renkanmanager/lib/renkan/js/renkan.js Mon Apr 27 17:22:46 2015 +0200 @@ -1,28 +1,30 @@ -/*! - * _____ _ - * | __ \ | | - * | |__) |___ _ __ | | ____ _ _ __ - * | _ // _ \ '_ \| |/ / _` | '_ \ +/*! + * _____ _ + * | __ \ | | + * | |__) |___ _ __ | | ____ _ _ __ + * | _ // _ \ '_ \| |/ / _` | '_ \ * | | \ \ __/ | | | < (_| | | | | * |_| \_\___|_| |_|_|\_\__,_|_| |_| * - * Copyright 2012-2013 Institut de recherche et d'innovation - * contributor(s) : Yves-Marie Haussonne, Raphael Velt, Samuel Huron - * + * Copyright 2012-2015 Institut de recherche et d'innovation + * contributor(s) : Yves-Marie Haussonne, Raphael Velt, Samuel Huron, + * Thibaut CavaliĆ©, Julien Rougeron. + * * contact@iri.centrepompidou.fr - * http://www.iri.centrepompidou.fr - * + * http://www.iri.centrepompidou.fr + * * This software is a computer program whose purpose is to show and add annotations on a video . * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, + * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL-C * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * + * "http://www.cecill.info". + * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ -/*! renkan - v0.8.7 - Copyright Ā© IRI 2015 */ + +/*! renkan - v0.9.0 - Copyright Ā© IRI 2015 */ this["renkanJST"] = this["renkanJST"] || {}; @@ -45,81 +47,81 @@ var __t, __p = '', __e = _.escape, __j = Array.prototype.join; function print() { __p += __j.call(arguments, '') } with (obj) { -__p += '<h2>\n\t<span class="Rk-CloseX">×</span>' + +__p += '<h2>\n <span class="Rk-CloseX">×</span>' + __e(renkan.translate("Edit Edge")) + -'</span>\n</h2>\n<p>\n\t<label>' + +'</span>\n</h2>\n<p>\n <label>' + __e(renkan.translate("Title:")) + -'</label>\n\t<input class="Rk-Edit-Title" type="text" value="' + +'</label>\n <input class="Rk-Edit-Title" type="text" value="' + __e(edge.title) + '" />\n</p>\n'; if (options.show_edge_editor_uri) { ; -__p += '\n\t<p>\n\t\t<label>' + +__p += '\n <p>\n <label>' + __e(renkan.translate("URI:")) + -'</label>\n\t\t<input class="Rk-Edit-URI" type="text" value="' + +'</label>\n <input class="Rk-Edit-URI" type="text" value="' + __e(edge.uri) + -'" />\n\t\t<a class="Rk-Edit-Goto" href="' + +'" />\n <a class="Rk-Edit-Goto" href="' + __e(edge.uri) + -'" target="_blank"></a>\n\t</p>\n\t'; +'" target="_blank"></a>\n </p>\n '; if (options.properties.length) { ; -__p += '\n\t\t<p>\n\t\t\t<label>' + +__p += '\n <p>\n <label>' + __e(renkan.translate("Choose from vocabulary:")) + -'</label>\n\t\t\t<select class="Rk-Edit-Vocabulary">\n\t\t\t\t'; - _(options.properties).each(function(ontology) { ; -__p += '\n\t\t\t\t\t<option class="Rk-Edit-Vocabulary-Class" value="">\n\t\t\t\t\t\t' + +'</label>\n <select class="Rk-Edit-Vocabulary">\n '; + _.each(options.properties, function(ontology) { ; +__p += '\n <option class="Rk-Edit-Vocabulary-Class" value="">\n ' + __e( renkan.translate(ontology.label) ) + -'\n\t\t\t\t\t</option>\n\t\t\t\t\t'; - _(ontology.properties).each(function(property) { var uri = ontology["base-uri"] + property.uri; ; -__p += '\n\t\t\t\t\t\t<option class="Rk-Edit-Vocabulary-Property" value="' + +'\n </option>\n '; + _.each(ontology.properties, function(property) { var uri = ontology["base-uri"] + property.uri; ; +__p += '\n <option class="Rk-Edit-Vocabulary-Property" value="' + __e( uri ) + -'"\n\t\t\t\t\t\t\t'; +'"\n '; if (uri === edge.uri) { ; __p += ' selected'; } ; -__p += '>\n\t\t\t\t\t\t\t' + +__p += '>\n ' + __e( renkan.translate(property.label) ) + -'\n\t\t\t\t\t\t</option>\n\t\t\t\t\t'; +'\n </option>\n '; }) ; -__p += '\n\t\t\t\t'; +__p += '\n '; }) ; -__p += '\n\t\t\t</select>\n\t\t</p>\n'; +__p += '\n </select>\n </p>\n'; } } ; __p += '\n'; if (options.show_edge_editor_color) { ; -__p += '\n\t<div class="Rk-Editor-p">\n\t\t<span class="Rk-Editor-Label">' + +__p += '\n <div class="Rk-Editor-p">\n <span class="Rk-Editor-Label">' + __e(renkan.translate("Edge color:")) + -'</span>\n\t\t<div class="Rk-Edit-ColorPicker-Wrapper">\n\t\t\t<span class="Rk-Edit-Color" style="background: <%-edge.color%>;">\n\t\t\t\t<span class="Rk-Edit-ColorTip"></span>\n\t\t\t</span>\n\t\t\t' + +'</span>\n <div class="Rk-Edit-ColorPicker-Wrapper">\n <span class="Rk-Edit-Color" style="background: <%-edge.color%>;">\n <span class="Rk-Edit-ColorTip"></span>\n </span>\n ' + ((__t = ( renkan.colorPicker )) == null ? '' : __t) + -'\n\t\t\t<span class="Rk-Edit-ColorPicker-Text">' + +'\n <span class="Rk-Edit-ColorPicker-Text">' + __e( renkan.translate("Choose color") ) + -'</span>\n\t\t</div>\n\t</div>\n'; +'</span>\n </div>\n </div>\n'; } ; __p += '\n'; if (options.show_edge_editor_direction) { ; -__p += '\n\t<p>\n\t\t<span class="Rk-Edit-Direction">' + +__p += '\n <p>\n <span class="Rk-Edit-Direction">' + __e( renkan.translate("Change edge direction") ) + -'</span>\n\t</p>\n'; +'</span>\n </p>\n'; } ; __p += '\n'; if (options.show_edge_editor_nodes) { ; -__p += '\n\t<p>\n\t\t<span class="Rk-Editor-Label">' + +__p += '\n <p>\n <span class="Rk-Editor-Label">' + __e(renkan.translate("From:")) + -'</span>\n\t\t<span class="Rk-UserColor" style="background: ' + +'</span>\n <span class="Rk-UserColor" style="background: ' + __e(edge.from_color) + -';"></span>\n\t\t' + +';"></span>\n ' + __e( shortenText(edge.from_title, 25) ) + -'\n\t</p>\n\t<p>\n\t\t<span class="Rk-Editor-Label">' + +'\n </p>\n <p>\n <span class="Rk-Editor-Label">' + __e(renkan.translate("To:")) + -'</span>\n\t\t<span class="Rk-UserColor" style="background: >%-edge.to_color%>;"></span>\n\t\t' + +'</span>\n <span class="Rk-UserColor" style="background: >%-edge.to_color%>;"></span>\n ' + __e( shortenText(edge.to_title, 25) ) + -'\n\t</p>\n'; +'\n </p>\n'; } ; __p += '\n'; if (options.show_edge_editor_creator && edge.has_creator) { ; -__p += '\n\t<p>\n\t\t<span class="Rk-Editor-Label">' + +__p += '\n <p>\n <span class="Rk-Editor-Label">' + __e(renkan.translate("Created by:")) + -'</span>\n\t\t<span class="Rk-UserColor" style="background: <%-edge.created_by_color%>;"></span>\n\t\t' + +'</span>\n <span class="Rk-UserColor" style="background: <%-edge.created_by_color%>;"></span>\n ' + __e( shortenText(edge.created_by_title, 25) ) + -'\n\t</p>\n'; +'\n </p>\n'; } ; __p += '\n'; @@ -132,59 +134,59 @@ var __t, __p = '', __e = _.escape, __j = Array.prototype.join; function print() { __p += __j.call(arguments, '') } with (obj) { -__p += '<h2>\n\t<span class="Rk-CloseX">×</span>\n\t'; +__p += '<h2>\n <span class="Rk-CloseX">×</span>\n '; if (options.show_edge_tooltip_color) { ; -__p += '\n\t\t<span class="Rk-UserColor" style="background: ' + +__p += '\n <span class="Rk-UserColor" style="background: ' + __e( edge.color ) + -';"></span>\n\t'; +';"></span>\n '; } ; -__p += '\n\t<span class="Rk-Display-Title">\n\t\t'; +__p += '\n <span class="Rk-Display-Title">\n '; if (edge.uri) { ; -__p += '\n\t\t\t<a href="' + +__p += '\n <a href="' + __e(edge.uri) + -'" target="_blank">\n\t\t'; +'" target="_blank">\n '; } ; -__p += '\n\t\t' + +__p += '\n ' + __e(edge.title) + -'\n\t\t'; +'\n '; if (edge.uri) { ; __p += ' </a> '; } ; -__p += '\n\t</span>\n</h2>\n'; +__p += '\n </span>\n</h2>\n'; if (options.show_edge_tooltip_uri && edge.uri) { ; -__p += '\n\t<p class="Rk-Display-URI">\n\t\t<a href="' + +__p += '\n <p class="Rk-Display-URI">\n <a href="' + __e(edge.uri) + '" target="_blank">' + __e( edge.short_uri ) + -'</a>\n\t</p>\n'; +'</a>\n </p>\n'; } ; __p += '\n<p>' + __e(edge.description) + '</p>\n'; if (options.show_edge_tooltip_nodes) { ; -__p += '\n\t<p>\n\t\t<span class="Rk-Editor-Label">' + +__p += '\n <p>\n <span class="Rk-Editor-Label">' + __e(renkan.translate("From:")) + -'</span>\n\t\t<span class="Rk-UserColor" style="background: ' + +'</span>\n <span class="Rk-UserColor" style="background: ' + __e( edge.from_color ) + -';"></span>\n\t\t' + +';"></span>\n ' + __e( shortenText(edge.from_title, 25) ) + -'\n\t</p>\n\t<p>\n\t\t<span class="Rk-Editor-Label">' + +'\n </p>\n <p>\n <span class="Rk-Editor-Label">' + __e(renkan.translate("To:")) + -'</span>\n\t\t<span class="Rk-UserColor" style="background: ' + +'</span>\n <span class="Rk-UserColor" style="background: ' + __e( edge.to_color ) + -';"></span>\n\t\t' + +';"></span>\n ' + __e( shortenText(edge.to_title, 25) ) + -'\n\t</p>\n'; +'\n </p>\n'; } ; __p += '\n'; if (options.show_edge_tooltip_creator && edge.has_creator) { ; -__p += '\n\t<p>\n\t\t<span class="Rk-Editor-Label">' + +__p += '\n <p>\n <span class="Rk-Editor-Label">' + __e(renkan.translate("Created by:")) + -'</span>\n\t\t<span class="Rk-UserColor" style="background: ' + +'</span>\n <span class="Rk-UserColor" style="background: ' + __e( edge.created_by_color ) + -';"></span>\n\t\t' + +';"></span>\n ' + __e( shortenText(edge.created_by_title, 25) ) + -'\n\t</p>\n'; +'\n </p>\n'; } ; __p += '\n'; @@ -196,31 +198,31 @@ obj || (obj = {}); var __t, __p = '', __e = _.escape; with (obj) { -__p += '<li class="Rk-Bin-Item" draggable="true"\n\tdata-image="' + +__p += '<li class="Rk-Bin-Item" draggable="true"\n data-image="' + __e( Rkns.Utils.getFullURL(image) ) + -'"\n\tdata-uri="' + +'"\n data-uri="' + ((__t = (ldt_platform)) == null ? '' : __t) + 'ldtplatform/ldt/front/player/' + ((__t = (mediaid)) == null ? '' : __t) + '/#id=' + ((__t = (annotationid)) == null ? '' : __t) + -'"\n\tdata-title="' + +'"\n data-title="' + __e(title) + '" data-description="' + __e(description) + -'">\n\t\n\t<img class="Rk-Ldt-Annotation-Icon" src="' + +'">\n\n <img class="Rk-Ldt-Annotation-Icon" src="' + ((__t = (image)) == null ? '' : __t) + -'" />\n\t<h4>' + +'" />\n <h4>' + ((__t = (htitle)) == null ? '' : __t) + -'</h4>\n\t<p>' + +'</h4>\n <p>' + ((__t = (hdescription)) == null ? '' : __t) + -'</p>\n\t<p>Start: ' + +'</p>\n <p>Start: ' + ((__t = (start)) == null ? '' : __t) + ', End: ' + ((__t = (end)) == null ? '' : __t) + ', Duration: ' + ((__t = (duration)) == null ? '' : __t) + -'</p>\n\t<div class="Rk-Clear"></div>\n</li>'; +'</p>\n <div class="Rk-Clear"></div>\n</li>\n'; } return __p @@ -230,31 +232,31 @@ obj || (obj = {}); var __t, __p = '', __e = _.escape; with (obj) { -__p += '<li class="Rk-Bin-Item" draggable="true"\n\tdata-image="' + +__p += '<li class="Rk-Bin-Item" draggable="true"\n data-image="' + __e( Rkns.Utils.getFullURL(image) ) + -'"\n\tdata-uri="' + +'"\n data-uri="' + ((__t = (ldt_platform)) == null ? '' : __t) + 'ldtplatform/ldt/front/player/' + ((__t = (mediaid)) == null ? '' : __t) + '/#id=' + ((__t = (annotationid)) == null ? '' : __t) + -'"\n\tdata-title="' + +'"\n data-title="' + __e(title) + '" data-description="' + __e(description) + -'">\n\t\n\t<img class="Rk-Ldt-Annotation-Icon" src="' + +'">\n\n <img class="Rk-Ldt-Annotation-Icon" src="' + ((__t = (image)) == null ? '' : __t) + -'" />\n\t<h4>' + +'" />\n <h4>' + ((__t = (htitle)) == null ? '' : __t) + -'</h4>\n\t<p>' + +'</h4>\n <p>' + ((__t = (hdescription)) == null ? '' : __t) + -'</p>\n\t<p>Start: ' + +'</p>\n <p>Start: ' + ((__t = (start)) == null ? '' : __t) + ', End: ' + ((__t = (end)) == null ? '' : __t) + ', Duration: ' + ((__t = (duration)) == null ? '' : __t) + -'</p>\n\t<div class="Rk-Clear"></div>\n</li>'; +'</p>\n <div class="Rk-Clear"></div>\n</li>\n'; } return __p @@ -264,21 +266,21 @@ obj || (obj = {}); var __t, __p = '', __e = _.escape; with (obj) { -__p += '<li class="Rk-Bin-Item" draggable="true"\n\tdata-image="' + +__p += '<li class="Rk-Bin-Item" draggable="true"\n data-image="' + __e( Rkns.Utils.getFullURL(static_url+'img/ldt-tag.png') ) + -'"\n\tdata-uri="' + +'"\n data-uri="' + ((__t = (ldt_platform)) == null ? '' : __t) + 'ldtplatform/ldt/front/search/?search=' + ((__t = (encodedtitle)) == null ? '' : __t) + -'&field=all"\n\tdata-title="' + +'&field=all"\n data-title="' + __e(title) + '" data-description="Tag \'' + __e(title) + -'\'">\n\n\t<img class="Rk-Ldt-Tag-Icon" src="' + +'\'">\n\n <img class="Rk-Ldt-Tag-Icon" src="' + __e(static_url) + -'img/ldt-tag.png" />\n\t<h4>' + +'img/ldt-tag.png" />\n <h4>' + ((__t = (htitle)) == null ? '' : __t) + -'</h4>\n\t<div class="Rk-Clear"></div>\n</li>'; +'</h4>\n <div class="Rk-Clear"></div>\n</li>\n'; } return __p @@ -289,49 +291,49 @@ var __t, __p = '', __e = _.escape, __j = Array.prototype.join; function print() { __p += __j.call(arguments, '') } with (obj) { -__p += '<li class="Rk-Bin-Item Rk-ResourceList-Item" draggable="true"\n\tdata-uri="' + +__p += '<li class="Rk-Bin-Item Rk-ResourceList-Item" draggable="true"\n data-uri="' + __e(url) + '" data-title="' + __e(title) + -'"\n\tdata-description="' + +'"\n data-description="' + __e(description) + -'"\n\t'; +'"\n '; if (image) { ; -__p += '\n\t\tdata-image="' + +__p += '\n data-image="' + __e( Rkns.Utils.getFullURL(image) ) + -'"\n\t'; +'"\n '; } else { ; -__p += '\n\t\tdata-image=""\n\t'; +__p += '\n data-image=""\n '; } ; __p += '\n>'; if (image) { ; -__p += '\n\t<img class="Rk-ResourceList-Image" src="' + +__p += '\n <img class="Rk-ResourceList-Image" src="' + __e(image) + '" />\n'; } ; -__p += '\n<h4 class="Rk-ResourceList-Title">\n\t'; +__p += '\n<h4 class="Rk-ResourceList-Title">\n '; if (url) { ; -__p += '\n\t\t<a href="' + +__p += '\n <a href="' + __e(url) + -'" target="_blank">\n\t'; +'" target="_blank">\n '; } ; -__p += '\n\t' + +__p += '\n ' + ((__t = (htitle)) == null ? '' : __t) + -'\n\t'; +'\n '; if (url) { ; __p += '</a>'; } ; -__p += '\n\t</h4> \n\t'; +__p += '\n </h4>\n '; if (description) { ; -__p += '\n\t\t<p class="Rk-ResourceList-Description">' + +__p += '\n <p class="Rk-ResourceList-Description">' + ((__t = (hdescription)) == null ? '' : __t) + -'</p>\n\t'; +'</p>\n '; } ; -__p += '\n\t'; +__p += '\n '; if (image) { ; -__p += '\n\t\t<div style="clear: both;"></div>\n\t'; +__p += '\n <div style="clear: both;"></div>\n '; } ; -__p += '\n</li>'; +__p += '\n</li>\n'; } return __p @@ -344,21 +346,21 @@ with (obj) { if (options.show_bins) { ; -__p += '\n\t<div class="Rk-Bins">\n\t\t<div class="Rk-Bins-Head">\n\t\t\t<h2 class="Rk-Bins-Title">' + +__p += '\n <div class="Rk-Bins">\n <div class="Rk-Bins-Head">\n <h2 class="Rk-Bins-Title">' + __e( translate("Select contents:")) + -'</h2>\n\t\t\t<form class="Rk-Web-Search-Form Rk-Search-Form">\n\t\t\t\t<input class="Rk-Web-Search-Input Rk-Search-Input" type="search"\n\t\t\t\t\tplaceholder="' + +'</h2>\n <form class="Rk-Web-Search-Form Rk-Search-Form">\n <input class="Rk-Web-Search-Input Rk-Search-Input" type="search"\n placeholder="' + __e( translate('Search the Web') ) + -'" />\n\t\t\t\t<div class="Rk-Search-Select">\n\t\t\t\t\t<div class="Rk-Search-Current"></div>\n\t\t\t\t\t<ul class="Rk-Search-List"></ul>\n\t\t\t\t</div>\n\t\t\t\t<input type="submit" value=""\n\t\t\t\t\tclass="Rk-Web-Search-Submit Rk-Search-Submit" title="' + +'" />\n <div class="Rk-Search-Select">\n <div class="Rk-Search-Current"></div>\n <ul class="Rk-Search-List"></ul>\n </div>\n <input type="submit" value=""\n class="Rk-Web-Search-Submit Rk-Search-Submit" title="' + __e( translate('Search the Web') ) + -'" />\n\t\t\t</form>\n\t\t\t<form class="Rk-Bins-Search-Form Rk-Search-Form">\n\t\t\t\t<input class="Rk-Bins-Search-Input Rk-Search-Input" type="search"\n\t\t\t\t\tplaceholder="' + +'" />\n </form>\n <form class="Rk-Bins-Search-Form Rk-Search-Form">\n <input class="Rk-Bins-Search-Input Rk-Search-Input" type="search"\n placeholder="' + __e( translate('Search in Bins') ) + -'" /> <input\n\t\t\t\t\ttype="submit" value=""\n\t\t\t\t\tclass="Rk-Bins-Search-Submit Rk-Search-Submit"\n\t\t\t\t\ttitle="' + +'" /> <input\n type="submit" value=""\n class="Rk-Bins-Search-Submit Rk-Search-Submit"\n title="' + __e( translate('Search in Bins') ) + -'" />\n\t\t\t</form>\n\t\t</div>\n\t\t<ul class="Rk-Bin-List"></ul>\n\t</div>\n'; +'" />\n </form>\n </div>\n <ul class="Rk-Bin-List"></ul>\n </div>\n'; } ; __p += ' '; if (options.show_editor) { ; -__p += '\n\t<div class="Rk-Render Rk-Render-'; +__p += '\n <div class="Rk-Render Rk-Render-'; if (options.show_bins) { ; __p += 'Panel'; } else { ; @@ -377,123 +379,123 @@ var __t, __p = '', __e = _.escape, __j = Array.prototype.join; function print() { __p += __j.call(arguments, '') } with (obj) { -__p += '<h2>\n\t<span class="Rk-CloseX">×</span>' + +__p += '<h2>\n <span class="Rk-CloseX">×</span>' + __e(renkan.translate("Edit Node")) + -'</span>\n</h2>\n<p>\n\t<label>' + +'</span>\n</h2>\n<p>\n <label>' + __e(renkan.translate("Title:")) + -'</label>\n\t<input class="Rk-Edit-Title" type="text" value="' + +'</label>\n <input class="Rk-Edit-Title" type="text" value="' + __e(node.title) + '" />\n</p>\n'; if (options.show_node_editor_uri) { ; -__p += '\n\t<p>\n\t\t<label>' + +__p += '\n <p>\n <label>' + __e(renkan.translate("URI:")) + -'</label>\n\t\t<input class="Rk-Edit-URI" type="text" value="' + +'</label>\n <input class="Rk-Edit-URI" type="text" value="' + __e(node.uri) + -'" />\n\t\t<a class="Rk-Edit-Goto" href="' + +'" />\n <a class="Rk-Edit-Goto" href="' + __e(node.uri) + -'" target="_blank"></a>\n\t</p>\n'; +'" target="_blank"></a>\n </p>\n'; } ; __p += ' '; if (options.show_node_editor_description) { ; -__p += '\n\t<p>\n\t\t<label>' + +__p += '\n <p>\n <label>' + __e(renkan.translate("Description:")) + -'</label>\n\t\t<textarea class="Rk-Edit-Description">' + +'</label>\n <textarea class="Rk-Edit-Description">' + __e(node.description) + -'</textarea>\n\t</p>\n'; +'</textarea>\n </p>\n'; } ; __p += ' '; if (options.show_node_editor_size) { ; -__p += '\n\t<p>\n\t\t<span class="Rk-Editor-Label">' + +__p += '\n <p>\n <span class="Rk-Editor-Label">' + __e(renkan.translate("Size:")) + -'</span>\n\t\t<a href="#" class="Rk-Edit-Size-Down">-</a>\n\t\t<span class="Rk-Edit-Size-Value">' + +'</span>\n <a href="#" class="Rk-Edit-Size-Down">-</a>\n <span class="Rk-Edit-Size-Value">' + __e(node.size) + -'</span>\n\t\t<a href="#" class="Rk-Edit-Size-Up">+</a>\n\t</p>\n'; +'</span>\n <a href="#" class="Rk-Edit-Size-Up">+</a>\n </p>\n'; } ; __p += ' '; if (options.show_node_editor_color) { ; -__p += '\n\t<div class="Rk-Editor-p">\n\t\t<span class="Rk-Editor-Label">\n\t\t' + +__p += '\n <div class="Rk-Editor-p">\n <span class="Rk-Editor-Label">\n ' + __e(renkan.translate("Node color:")) + -'</span>\n\t\t<div class="Rk-Edit-ColorPicker-Wrapper">\n\t\t\t<span class="Rk-Edit-Color" style="background: ' + +'</span>\n <div class="Rk-Edit-ColorPicker-Wrapper">\n <span class="Rk-Edit-Color" style="background: ' + __e(node.color) + -';">\n\t\t\t\t<span class="Rk-Edit-ColorTip"></span>\n\t\t\t</span>\n\t\t\t' + +';">\n <span class="Rk-Edit-ColorTip"></span>\n </span>\n ' + ((__t = ( renkan.colorPicker )) == null ? '' : __t) + -'\n\t\t\t<span class="Rk-Edit-ColorPicker-Text">' + +'\n <span class="Rk-Edit-ColorPicker-Text">' + __e( renkan.translate("Choose color") ) + -'</span>\n\t\t</div>\n\t</div>\n'; +'</span>\n </div>\n </div>\n'; } ; __p += ' '; if (options.show_node_editor_image) { ; -__p += '\n\t<div class="Rk-Edit-ImgWrap">\n\t\t<div class="Rk-Edit-ImgPreview">\n\t\t\t<img src="' + +__p += '\n <div class="Rk-Edit-ImgWrap">\n <div class="Rk-Edit-ImgPreview">\n <img src="' + __e(node.image || node.image_placeholder) + -'" />\n\t\t\t'; +'" />\n '; if (node.clip_path) { ; -__p += '\n\t\t\t\t<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewbox="0 0 1 1" preserveAspectRatio="none">\n\t\t\t\t\t<path style="stroke-width: .02; stroke:red; fill-opacity:.3; fill:red;" d="' + +__p += '\n <svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewbox="0 0 1 1" preserveAspectRatio="none">\n <path style="stroke-width: .02; stroke:red; fill-opacity:.3; fill:red;" d="' + __e( node.clip_path ) + -'" />\n\t\t\t\t</svg>\n\t\t\t'; +'" />\n </svg>\n '; }; -__p += '\n\t\t</div>\n\t</div>\n\t<p>\n\t\t<label>' + +__p += '\n </div>\n </div>\n <p>\n <label>' + __e(renkan.translate("Image URL:")) + -'</label>\n\t\t<div>\n\t\t\t<a class="Rk-Edit-Image-Del" href="#"></a>\n\t\t\t<input class="Rk-Edit-Image" type="text" value=\'' + +'</label>\n <div>\n <a class="Rk-Edit-Image-Del" href="#"></a>\n <input class="Rk-Edit-Image" type="text" value=\'' + __e(node.image) + -'\' />\n\t\t</div>\n\t</p>\n'; +'\' />\n </div>\n </p>\n'; if (options.allow_image_upload) { ; -__p += '\n\t<p>\n\t\t<label>' + +__p += '\n <p>\n <label>' + __e(renkan.translate("Choose Image File:")) + -'</label>\n\t\t<input class="Rk-Edit-Image-File" type="file" accept="image/*" />\n\t</p>\n'; +'</label>\n <input class="Rk-Edit-Image-File" type="file" accept="image/*" />\n </p>\n'; }; } ; __p += ' '; if (options.show_node_editor_creator && node.has_creator) { ; -__p += '\n\t<p>\n\t\t<span class="Rk-Editor-Label">' + +__p += '\n <p>\n <span class="Rk-Editor-Label">' + __e(renkan.translate("Created by:")) + -'</span>\n\t\t<span class="Rk-UserColor" style="background: ' + +'</span>\n <span class="Rk-UserColor" style="background: ' + __e(node.created_by_color) + -';"></span>\n\t\t' + +';"></span>\n ' + __e( shortenText(node.created_by_title, 25) ) + -'\n\t</p>\n'; +'\n </p>\n'; } ; __p += ' '; if (options.change_shapes) { ; -__p += '\n\t<p>\n\t\t<label>' + +__p += '\n <p>\n <label>' + __e(renkan.translate("Shapes available")) + -':</label>\n\t\t<select class="Rk-Edit-Shape">\n\t\t\t<option class="Rk-Edit-Vocabulary-Property" value="circle"'; +':</label>\n <select class="Rk-Edit-Shape">\n <option class="Rk-Edit-Vocabulary-Property" value="circle"'; if (node.shape === "circle") { ; __p += ' selected'; } ; -__p += '>\n\t\t\t\t' + +__p += '>\n ' + __e( renkan.translate("Circle") ) + -'\n\t\t\t</option>\n\t\t\t<option class="Rk-Edit-Vocabulary-Property" value="rectangle"'; +'\n </option>\n <option class="Rk-Edit-Vocabulary-Property" value="rectangle"'; if (node.shape === "rectangle") { ; __p += ' selected'; } ; -__p += '>\n\t\t\t\t' + +__p += '>\n ' + __e( renkan.translate("Square") ) + -'\n\t\t\t</option>\n\t\t\t<option class="Rk-Edit-Vocabulary-Property" value="diamond"'; +'\n </option>\n <option class="Rk-Edit-Vocabulary-Property" value="diamond"'; if (node.shape === "diamond") { ; __p += ' selected'; } ; -__p += '>\n\t\t\t\t' + +__p += '>\n ' + __e( renkan.translate("Diamond") ) + -'\n\t\t\t</option>\n\t\t\t<option class="Rk-Edit-Vocabulary-Property" value="polygon"'; +'\n </option>\n <option class="Rk-Edit-Vocabulary-Property" value="polygon"'; if (node.shape === "polygon") { ; __p += ' selected'; } ; -__p += '>\n\t\t\t\t' + +__p += '>\n ' + __e( renkan.translate("Hexagone") ) + -'\n\t\t\t</option>\n\t\t\t<option class="Rk-Edit-Vocabulary-Property" value="ellipse"'; +'\n </option>\n <option class="Rk-Edit-Vocabulary-Property" value="ellipse"'; if (node.shape === "ellipse") { ; __p += ' selected'; } ; -__p += '>\n\t\t\t\t' + +__p += '>\n ' + __e( renkan.translate("Ellipse") ) + -'\n\t\t\t</option>\n\t\t\t<option class="Rk-Edit-Vocabulary-Property" value="star"'; +'\n </option>\n <option class="Rk-Edit-Vocabulary-Property" value="star"'; if (node.shape === "star") { ; __p += ' selected'; } ; -__p += '>\n\t\t\t\t' + +__p += '>\n ' + __e( renkan.translate("Star") ) + -'\n\t\t\t</option>\n\t\t</select>\n\t</p>\n'; +'\n </option>\n </select>\n </p>\n'; } ; __p += '\n'; @@ -506,53 +508,53 @@ var __t, __p = '', __e = _.escape, __j = Array.prototype.join; function print() { __p += __j.call(arguments, '') } with (obj) { -__p += '<h2>\n\t<span class="Rk-CloseX">×</span>\n\t'; +__p += '<h2>\n <span class="Rk-CloseX">×</span>\n '; if (options.show_node_tooltip_color) { ; -__p += '\n\t\t<span class="Rk-UserColor" style="background: ' + +__p += '\n <span class="Rk-UserColor" style="background: ' + __e(node.color) + -';"></span>\n\t'; +';"></span>\n '; } ; -__p += '\n\t<span class="Rk-Display-Title">\n\t\t'; +__p += '\n <span class="Rk-Display-Title">\n '; if (node.uri) { ; -__p += '\n\t\t\t<a href="' + +__p += '\n <a href="' + __e(node.uri) + -'" target="_blank">\n\t\t'; +'" target="_blank">\n '; } ; -__p += '\n\t\t' + +__p += '\n ' + __e(node.title) + -'\n\t\t'; +'\n '; if (node.uri) { ; __p += '</a>'; } ; -__p += '\n\t</span>\n</h2>\n'; +__p += '\n </span>\n</h2>\n'; if (node.uri && options.show_node_tooltip_uri) { ; -__p += '\n\t<p class="Rk-Display-URI">\n\t\t<a href="' + +__p += '\n <p class="Rk-Display-URI">\n <a href="' + __e(node.uri) + '" target="_blank">' + __e(node.short_uri) + -'</a>\n\t</p>\n'; +'</a>\n </p>\n'; } ; __p += ' '; if (options.show_node_tooltip_description) { ; -__p += '\n\t<p class="Rk-Display-Description">' + +__p += '\n <p class="Rk-Display-Description">' + __e(node.description) + '</p>\n'; } ; __p += ' '; if (node.image && options.show_node_tooltip_image) { ; -__p += '\n\t<img class="Rk-Display-ImgPreview" src="' + +__p += '\n <img class="Rk-Display-ImgPreview" src="' + __e(node.image) + '" />\n'; } ; __p += ' '; if (node.has_creator && options.show_node_tooltip_creator) { ; -__p += '\n\t<p>\n\t\t<span class="Rk-Editor-Label">' + +__p += '\n <p>\n <span class="Rk-Editor-Label">' + __e(renkan.translate("Created by:")) + -'</span>\n\t\t<span class="Rk-UserColor" style="background: ' + +'</span>\n <span class="Rk-UserColor" style="background: ' + __e(node.created_by_color) + -';"></span>\n\t\t' + +';"></span>\n ' + __e( shortenText(node.created_by_title, 25) ) + -'\n\t</p>\n'; +'\n </p>\n'; } ; __p += '\n'; @@ -567,135 +569,135 @@ with (obj) { if (options.show_top_bar) { ; -__p += '\n\t<div class="Rk-TopBar">\n\t\t<div class="loader"></div>\n\t\t'; +__p += '\n <div class="Rk-TopBar">\n <div class="loader"></div>\n '; if (!options.editor_mode) { ; -__p += '\n\t\t\t<h2 class="Rk-PadTitle">\n\t\t\t\t' + +__p += '\n <h2 class="Rk-PadTitle">\n ' + __e( project.get("title") || translate("Untitled project")) + -'\n\t\t\t</h2>\n\t\t'; +'\n </h2>\n '; } else { ; -__p += '\n\t\t\t<input type="text" class="Rk-PadTitle" value="' + +__p += '\n <input type="text" class="Rk-PadTitle" value="' + __e( project.get('title') || '' ) + '" placeholder="' + __e(translate('Untitled project')) + -'" />\n\t\t'; +'" />\n '; } ; -__p += '\n\t\t'; +__p += '\n '; if (options.show_user_list) { ; -__p += '\n\t\t\t<div class="Rk-Users">\n\t\t\t\t<div class="Rk-CurrentUser">\n\t\t\t\t\t'; +__p += '\n <div class="Rk-Users">\n <div class="Rk-CurrentUser">\n '; if (options.show_user_color) { ; -__p += '\n\t\t\t\t\t\t<div class="Rk-Edit-ColorPicker-Wrapper">\n\t\t\t\t\t\t\t<span class="Rk-CurrentUser-Color">\n\t\t\t\t\t\t\t'; +__p += '\n <div class="Rk-Edit-ColorPicker-Wrapper">\n <span class="Rk-CurrentUser-Color">\n '; if (options.user_color_editable) { ; -__p += '\n\t\t\t\t\t\t\t\t<span class="Rk-Edit-ColorTip"></span>\n\t\t\t\t\t\t\t'; +__p += '\n <span class="Rk-Edit-ColorTip"></span>\n '; } ; -__p += '\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t'; +__p += '\n </span>\n '; if (options.user_color_editable) { print(colorPicker) } ; -__p += '\n\t\t\t\t\t\t</div>\n\t\t\t\t\t'; +__p += '\n </div>\n '; } ; -__p += '\n\t\t\t\t\t<span class="Rk-CurrentUser-Name"><unknown user></span>\n\t\t\t\t</div>\n\t\t\t\t<ul class="Rk-UserList"></ul>\n\t\t\t</div>\n\t\t'; +__p += '\n <span class="Rk-CurrentUser-Name"><unknown user></span>\n </div>\n <ul class="Rk-UserList"></ul>\n </div>\n '; } ; -__p += '\n\t\t'; +__p += '\n '; if (options.home_button_url) {; -__p += '\n\t\t\t<div class="Rk-TopBar-Separator"></div>\n\t\t\t<a class="Rk-TopBar-Button Rk-Home-Button" href="' + +__p += '\n <div class="Rk-TopBar-Separator"></div>\n <a class="Rk-TopBar-Button Rk-Home-Button" href="' + __e( options.home_button_url ) + -'">\n\t\t\t\t<div class="Rk-TopBar-Tooltip">\n\t\t\t\t\t<div class="Rk-TopBar-Tooltip-Contents">\n\t\t\t\t\t\t' + +'">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n ' + __e( translate(options.home_button_title) ) + -'\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</a>\n\t\t'; +'\n </div>\n </div>\n </a>\n '; } ; -__p += '\n\t\t'; +__p += '\n '; if (options.show_fullscreen_button) { ; -__p += '\n\t\t\t<div class="Rk-TopBar-Separator"></div>\n\t\t\t<div class="Rk-TopBar-Button Rk-FullScreen-Button">\n\t\t\t\t<div class="Rk-TopBar-Tooltip">\n\t\t\t\t\t<div class="Rk-TopBar-Tooltip-Contents">\n\t\t\t\t\t\t' + +__p += '\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-FullScreen-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n ' + __e(translate("Full Screen")) + -'\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t'; +'\n </div>\n </div>\n </div>\n '; } ; -__p += '\n\t\t'; +__p += '\n '; if (options.editor_mode) { ; -__p += '\n\t\t\t'; +__p += '\n '; if (options.show_addnode_button) { ; -__p += '\n\t\t\t\t<div class="Rk-TopBar-Separator"></div>\n\t\t\t\t<div class="Rk-TopBar-Button Rk-AddNode-Button">\n\t\t\t\t\t<div class="Rk-TopBar-Tooltip">\n\t\t\t\t\t\t<div class="Rk-TopBar-Tooltip-Contents">\n\t\t\t\t\t\t\t' + +__p += '\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-AddNode-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n ' + __e(translate("Add Node")) + -'\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t'; +'\n </div>\n </div>\n </div>\n '; } ; -__p += '\n\t\t\t'; +__p += '\n '; if (options.show_addedge_button) { ; -__p += '\n\t\t\t\t<div class="Rk-TopBar-Separator"></div>\n\t\t\t\t<div class="Rk-TopBar-Button Rk-AddEdge-Button">\n\t\t\t\t\t<div class="Rk-TopBar-Tooltip">\n\t\t\t\t\t\t<div class="Rk-TopBar-Tooltip-Contents">\n\t\t\t\t\t\t\t' + +__p += '\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-AddEdge-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n ' + __e(translate("Add Edge")) + -'\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t'; +'\n </div>\n </div>\n </div>\n '; } ; -__p += '\n\t\t\t'; +__p += '\n '; if (options.show_export_button) { ; -__p += '\n\t\t\t\t<div class="Rk-TopBar-Separator"></div>\n\t\t\t\t<div class="Rk-TopBar-Button Rk-Export-Button">\n\t\t\t\t\t<div class="Rk-TopBar-Tooltip">\n\t\t\t\t\t\t<div class="Rk-TopBar-Tooltip-Contents">\n\t\t\t\t\t\t\t' + +__p += '\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-Export-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n ' + __e(translate("Download Project")) + -'\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t'; +'\n </div>\n </div>\n </div>\n '; } ; -__p += '\n\t\t\t'; +__p += '\n '; if (options.show_save_button) { ; -__p += '\n\t\t\t\t<div class="Rk-TopBar-Separator"></div>\n\t\t\t\t<div class="Rk-TopBar-Button Rk-Save-Button">\n\t\t\t\t\t<div class="Rk-TopBar-Tooltip">\n\t\t\t\t\t\t<div class="Rk-TopBar-Tooltip-Contents"></div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t'; +__p += '\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-Save-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents"></div>\n </div>\n </div>\n '; } ; -__p += '\n\t\t\t'; +__p += '\n '; if (options.show_open_button) { ; -__p += '\n\t\t\t\t<div class="Rk-TopBar-Separator"></div>\n\t\t\t\t<div class="Rk-TopBar-Button Rk-Open-Button">\n\t\t\t\t\t<div class="Rk-TopBar-Tooltip">\n\t\t\t\t\t\t<div class="Rk-TopBar-Tooltip-Contents">\n\t\t\t\t\t\t\t' + +__p += '\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-Open-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n ' + __e(translate("Open Project")) + -'\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t'; +'\n </div>\n </div>\n </div>\n '; } ; -__p += '\n\t\t\t'; +__p += '\n '; if (options.show_bookmarklet) { ; -__p += '\n\t\t\t\t<div class="Rk-TopBar-Separator"></div>\n\t\t\t\t<a class="Rk-TopBar-Button Rk-Bookmarklet-Button" href="#">\n\t\t\t\t\t<div class="Rk-TopBar-Tooltip">\n\t\t\t\t\t\t<div class="Rk-TopBar-Tooltip-Contents">\n\t\t\t\t\t\t\t' + +__p += '\n <div class="Rk-TopBar-Separator"></div>\n <a class="Rk-TopBar-Button Rk-Bookmarklet-Button" href="#">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n ' + __e(translate("Renkan \'Drag-to-Add\' bookmarklet")) + -'\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</a>\n\t\t\t\t<div class="Rk-TopBar-Separator"></div>\n\t\t\t'; +'\n </div>\n </div>\n </a>\n <div class="Rk-TopBar-Separator"></div>\n '; } ; -__p += '\n\t\t'; +__p += '\n '; } else { ; -__p += '\n\t\t\t'; +__p += '\n '; if (options.show_export_button) { ; -__p += '\n\t\t\t\t<div class="Rk-TopBar-Separator"></div>\n\t\t\t\t<div class="Rk-TopBar-Button Rk-Export-Button">\n\t\t\t\t\t<div class="Rk-TopBar-Tooltip">\n\t\t\t\t\t\t<div class="Rk-TopBar-Tooltip-Contents">\n\t\t\t\t\t\t\t' + +__p += '\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-Export-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n ' + __e(translate("Download Project")) + -'\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class="Rk-TopBar-Separator"></div>\n\t\t\t'; +'\n </div>\n </div>\n </div>\n <div class="Rk-TopBar-Separator"></div>\n '; } ; -__p += '\n\t\t'; +__p += '\n '; }; ; -__p += '\n\t\t'; +__p += '\n '; if (options.show_search_field) { ; -__p += '\n\t\t\t<form action="#" class="Rk-GraphSearch-Form">\n\t\t\t\t<input type="search" class="Rk-GraphSearch-Field" placeholder="' + +__p += '\n <form action="#" class="Rk-GraphSearch-Form">\n <input type="search" class="Rk-GraphSearch-Field" placeholder="' + __e( translate('Search in graph') ) + -'" />\n\t\t\t</form>\n\t\t\t<div class="Rk-TopBar-Separator"></div>\n\t\t'; +'" />\n </form>\n <div class="Rk-TopBar-Separator"></div>\n '; } ; -__p += '\n\t</div>\n'; +__p += '\n </div>\n'; } ; __p += '\n<div class="Rk-Editing-Space'; if (!options.show_top_bar) { ; __p += ' Rk-Editing-Space-Full'; } ; -__p += '">\n\t<div class="Rk-Labels"></div>\n\t<canvas class="Rk-Canvas" '; +__p += '">\n <div class="Rk-Labels"></div>\n <canvas class="Rk-Canvas" '; if (options.resize) { ; __p += ' resize="" '; } ; -__p += '></canvas>\n\t<div class="Rk-Notifications"></div>\n\t<div class="Rk-Editor">\n\t\t'; +__p += '></canvas>\n <div class="Rk-Notifications"></div>\n <div class="Rk-Editor">\n '; if (options.show_bins) { ; -__p += '\n\t\t\t<div class="Rk-Fold-Bins">«</div>\n\t\t'; +__p += '\n <div class="Rk-Fold-Bins">«</div>\n '; } ; -__p += '\n\t\t'; +__p += '\n '; if (options.show_zoom) { ; -__p += '\n\t\t\t<div class="Rk-ZoomButtons">\n\t\t\t\t<div class="Rk-ZoomIn" title="' + +__p += '\n <div class="Rk-ZoomButtons">\n <div class="Rk-ZoomIn" title="' + __e(translate('Zoom In')) + -'"></div>\n\t\t\t\t<div class="Rk-ZoomFit" title="' + +'"></div>\n <div class="Rk-ZoomFit" title="' + __e(translate('Zoom Fit')) + -'"></div>\n\t\t\t\t<div class="Rk-ZoomOut" title="' + +'"></div>\n <div class="Rk-ZoomOut" title="' + __e(translate('Zoom Out')) + -'"></div>\n\t\t\t\t'; +'"></div>\n '; if (options.editor_mode && options.save_view) { ; -__p += '\n\t\t\t\t\t<div class="Rk-ZoomSave" title="' + +__p += '\n <div class="Rk-ZoomSave" title="' + __e(translate('Zoom Save')) + -'"></div>\n\t\t\t\t'; +'"></div>\n '; } ; -__p += '\n\t\t\t\t'; +__p += '\n '; if (options.save_view) { ; -__p += '\n\t\t\t\t\t<div class="Rk-ZoomSetSaved" title="' + +__p += '\n <div class="Rk-ZoomSetSaved" title="' + __e(translate('View saved zoom')) + -'"></div>\n\t\t\t\t'; +'"></div>\n '; } ; -__p += '\n\t\t\t</div>\n\t\t'; +__p += '\n </div>\n '; } ; -__p += '\n\t</div>\n</div>'; +__p += '\n </div>\n</div>\n'; } return __p @@ -721,23 +723,23 @@ obj || (obj = {}); var __t, __p = '', __e = _.escape; with (obj) { -__p += '<li class="Rk-Wikipedia-Result Rk-Bin-Item" draggable="true"\n\tdata-uri="' + +__p += '<li class="Rk-Wikipedia-Result Rk-Bin-Item" draggable="true"\n data-uri="' + __e(url) + '" data-title="Wikipedia: ' + __e(title) + -'"\n\tdata-description="' + +'"\n data-description="' + __e(description) + -'"\n\tdata-image="' + +'"\n data-image="' + __e( Rkns.Utils.getFullURL( static_url + 'img/wikipedia.png' ) ) + -'">\n\t\n\t<img class="Rk-Wikipedia-Icon" src="' + +'">\n\n <img class="Rk-Wikipedia-Icon" src="' + __e(static_url) + -'img/wikipedia.png">\n\t<h4 class="Rk-Wikipedia-Title">\n\t\t<a href="' + +'img/wikipedia.png">\n <h4 class="Rk-Wikipedia-Title">\n <a href="' + __e(url) + '" target="_blank">' + ((__t = (htitle)) == null ? '' : __t) + -'</a>\n\t</h4>\n\t<p class="Rk-Wikipedia-Snippet">' + +'</a>\n </h4>\n <p class="Rk-Wikipedia-Snippet">' + ((__t = (hdescription)) == null ? '' : __t) + -'</p>\n</li>'; +'</p>\n</li>\n'; } return __p @@ -844,7 +846,7 @@ this.options = _.defaults(_opts, Rkns.defaults, {templates: renkanJST}); this.template = renkanJST['templates/main.html']; - _(this.options.property_files).each(function(f) { + _.each(this.options.property_files,function(f) { Rkns.$.getJSON(f, function(data) { _this.options.properties = _this.options.properties.concat(data); }); @@ -862,7 +864,7 @@ this.current_user = user_id; this.renderer.redrawUsers(); }; - + if (typeof this.options.user_id !== "undefined") { this.current_user = this.options.user_id; } @@ -898,7 +900,7 @@ _select = this.$.find(".Rk-Search-List"), _input = this.$.find(".Rk-Web-Search-Input"), _form = this.$.find(".Rk-Web-Search-Form"); - _(this.options.search).each(function(_search, _key) { + _.each(this.options.search, function(_search, _key) { if (Rkns[_search.type] && Rkns[_search.type].Search) { _this.search_engines.push(new Rkns[_search.type].Search(_this, _search)); } @@ -932,7 +934,7 @@ ); this.setSearchEngine(0); } - _(this.options.bins).each(function(_bin) { + _.each(this.options.bins, function(_bin) { if (Rkns[_bin.type] && Rkns[_bin.type].Bin) { _this.tabs.push(new Rkns[_bin.type].Bin(_this, _bin)); } @@ -957,7 +959,7 @@ var _models = _this.project.get("nodes").where({ uri: $(_t).attr("data-uri") }); - _(_models).each(function(_model) { + _.each(_models, function(_model) { _this.renderer.highlightModel(_model); }); } @@ -1021,7 +1023,7 @@ return; } lastsearch = search.source; - _(_this.tabs).each(function(tab) { + _.each(_this.tabs, function(tab) { tab.render(search); }); @@ -1121,7 +1123,7 @@ this._initialized = true; } }; - _(_class.prototype).extend(_baseClass.prototype); + _.extend(_class.prototype,_baseClass.prototype); return _class; @@ -1142,7 +1144,7 @@ ], remsrc = "[\\" + removeChars.join("\\") + "]", remrx = new RegExp(remsrc, "gm"), - charsrx = _(charsub).map(function(c) { + charsrx = _.map(charsub, function(c) { return new RegExp(c); }); @@ -1158,7 +1160,7 @@ src += remsrc + "*"; } var l = txt[j]; - _(charsub).each(makeReplaceFunc(l)); + _.each(charsub, makeReplaceFunc(l)); src += l; } return src; @@ -1170,7 +1172,7 @@ return replaceText(inp); case "object": var src = ''; - _(inp).each(function(v) { + _.each(inp, function(v) { var res = getSource(v); if (res) { if (src) { @@ -1400,7 +1402,9 @@ .get("_id") : null, size : this.get("size"), clip_path : this.get("clip_path"), - shape : this.get("shape") + shape : this.get("shape"), + type : this.get("type"), + hidden : this.get("hidden") }; } }); @@ -1558,13 +1562,14 @@ }, validate : function(options) { var _project = this; - _( - [].concat(options.users, options.nodes, options.edges, - options.views)).each(function(_item) { + _.each( + [].concat(options.users, options.nodes, options.edges,options.views), + function(_item) { if (_item) { _item.project = _project; } - }); + } + ); }, // Add event handler to remove edges when a node is removed initialize : function() { @@ -2127,7 +2132,7 @@ _this = this, count = 0; _this.title_$.text('LDT Project: "' + _projtitle + '"'); - _(_this.data.tags).map(function(_tag) { + _.map(_this.data.tags,function(_tag) { var _title = _tag.meta["dc:title"]; if (!search.isempty && !search.test(_title)) { return; @@ -2142,7 +2147,7 @@ }); }); _html += '<li><h3>Annotations</h3></li>'; - _(_this.data.annotations).map(function(_annotation) { + _.map(_this.data.annotations,function(_annotation) { var _description = _annotation.content.description, _title = _annotation.content.title.replace(_description,""); if (!search.isempty && !search.test(_title) && !search.test(_description)) { @@ -2264,7 +2269,7 @@ var _html = '', _this = this, count = 0; - _(this.data.objects).each(function(_segment) { + _.each(this.data.objects,function(_segment) { var _description = _segment.abstract, _title = _segment.title; if (!search.isempty && !search.test(_title) && !search.test(_description)) { @@ -2353,7 +2358,7 @@ var _html = "", _this = this, count = 0; - Rkns._(this.data).each(function(_item) { + Rkns._.each(this.data,function(_item) { var _element; if (typeof _item === "string") { if (/^(https?:\/\/|www)/.test(_item)) { @@ -2469,7 +2474,7 @@ var _html = "", _this = this, count = 0; - Rkns._(this.data.query.search).each(function(_result) { + Rkns._.each(this.data.query.search, function(_result) { var title = _result.title, url = "http://" + _this.lang + ".wikipedia.org/wiki/" + encodeURI(title.replace(/ /g,"_")), description = Rkns.$('<div>').html(_result.snippet).text(); @@ -2532,13 +2537,13 @@ if (this.model) { var _this = this; this._changeBinding = function() { - _this.redraw(); + _this.redraw({change: true}); }; this._removeBinding = function() { _renderer.removeRepresentation(_this); - _(function() { + _.defer(function() { _renderer.redraw(); - }).defer(); + }); }; this._selectBinding = function() { _this.select(); @@ -2590,7 +2595,7 @@ this.model.off("unselect", this._unselectBinding ); } } - }); + }).value(); /* End of Rkns.Renderer._BaseRepresentation Class */ @@ -2645,7 +2650,7 @@ destroy: function() { this.sector.destroy(); } - }); + }).value(); return _BaseButton; @@ -2692,12 +2697,12 @@ }, "diamond":{ getShape: function() { - var d = new paper.Path.Rectangle([-2, -2], [2, 2]); + var d = new paper.Path.Rectangle([-Math.SQRT2, -Math.SQRT2], [Math.SQRT2, Math.SQRT2]); d.rotate(45); return d; }, getImageShape: function(center, radius) { - var d = new paper.Path.Rectangle([-radius, -radius], [radius*2, radius*2]); + var d = new paper.Path.Rectangle([-radius*Math.SQRT2/2, -radius*Math.SQRT2/2], [radius*Math.SQRT2, radius*Math.SQRT2]); d.rotate(45); return d; } @@ -2716,15 +2721,15 @@ return new paper.Path(path); }, getImageShape: function(center, radius) { - // No calcul for the moment + // No calcul for the moment return new paper.Path(); } }; } }; - + var ShapeBuilder = function (shape){ - if(typeof shape==="undefined"){ + if(shape === null || typeof shape === "undefined"){ shape = "circle"; } if(shape.substr(0,4)==="svg:"){ @@ -2735,7 +2740,7 @@ } return builders[shape]; }; - + return ShapeBuilder; }); @@ -2798,8 +2803,7 @@ } }, buildShape: function(){ - if(typeof this.model.get("shape_changed")!=="undefined" && this.model.get("shape_changed")===true){ - this.model.set("shape_changed", false); + if( 'shape' in this.model.changed ) { delete this.img; } if(this.circle){ @@ -2810,14 +2814,16 @@ this.shapeBuilder = new ShapeBuilder(this.model.get("shape")); this.circle = this.shapeBuilder.getShape(); this.circle.__representation = this; + this.circle.sendToBack(); this.last_circle_radius = 1; }, - redraw: function(_dontRedrawEdges) { - if(typeof this.model.get("shape_changed")!=="undefined" && this.model.get("shape_changed")===true){ + redraw: function(options) { + if( 'shape' in this.model.changed && 'change' in options && options.change ) { + //if( 'shape' in this.model.changed ) { this.buildShape(); } var _model_coords = new paper.Point(this.model.get("position")), - _baseRadius = this.options.node_size_base * Math.exp((this.model.get("size") || 0) * Utils._NODE_SIZE_STEP); + _baseRadius = this.options.node_size_base * Math.exp((this.model.get("size") || 0) * Utils._NODE_SIZE_STEP); if (!this.is_dragging || !this.paper_coords) { this.paper_coords = this.renderer.toPaperCoords(_model_coords); } @@ -2893,6 +2899,9 @@ this.img = this.model.get("image"); if (this.img && this.img !== lastImage) { this.showImage(); + if(this.circle) { + this.circle.sendToBack(); + } } if (this.node_image && !this.img) { this.node_image.remove(); @@ -2907,7 +2916,7 @@ this.minimap_circle.fitBounds(minipos.subtract(minisize), minisize.multiply(2)); } - if (!_dontRedrawEdges) { + if (typeof options === 'undefined' || !('dontRedrawEdges' in options) || !options.dontRedrawEdges) { var _this = this; _.each( this.project.get("edges").filter( @@ -3046,8 +3055,7 @@ this.node_image.__representation = _this; this.node_image.scale(this.circle_radius / baseRadius); this.node_image.position = this.paper_coords.subtract(this.image_delta.multiply(this.circle_radius)); - this.redraw(); - this.renderer.throttledPaperDraw(); + this.node_image.insertAbove(this.circle); } else { var _this = this; $(_image).on("load", function() { @@ -3180,7 +3188,7 @@ this.node_image.remove(); } } - }); + }).value(); return NodeRepr; @@ -3411,11 +3419,11 @@ b.destroy(); }); var _this = this; - this.bundle.edges = _(this.bundle.edges).reject(function(_edge) { + this.bundle.edges = _.reject(this.bundle.edges, function(_edge) { return _this === _edge; }); } - }); + }).value(); return Edge; @@ -3514,7 +3522,7 @@ this.arrow.remove(); this.line.remove(); } - }); + }).value(); /* TempEdge Class End */ @@ -3537,7 +3545,7 @@ this.renderer.buttons_layer.activate(); this.type = "editor"; this.editor_block = new paper.Path(); - var _pts = _(_.range(8)).map(function() {return [0,0];}); + var _pts = _.map(_.range(8), function() {return [0,0];}); this.editor_block.add.apply(this.editor_block, _pts); this.editor_block.strokeWidth = this.options.tooltip_border_width; this.editor_block.strokeColor = this.options.tooltip_border_color; @@ -3554,7 +3562,7 @@ this.editor_block.remove(); this.editor_$.remove(); } - }); + }).value(); /* _BaseEditor End */ @@ -3573,11 +3581,11 @@ var NodeEditor = Utils.inherit(BaseEditor); _(NodeEditor.prototype).extend({ - _init: function() { - BaseEditor.prototype._init.apply(this); - this.template = this.options.templates['templates/nodeeditor.html']; - this.readOnlyTemplate = this.options.templates['templates/nodeeditor_readonly.html']; - }, + _init: function() { + BaseEditor.prototype._init.apply(this); + this.template = this.options.templates['templates/nodeeditor.html']; + this.readOnlyTemplate = this.options.templates['templates/nodeeditor_readonly.html']; + }, draw: function() { var _model = this.source_representation.model, _created_by = _model.get("created_by") || Utils._USER_PLACEHOLDER(this.renkan), @@ -3608,6 +3616,17 @@ this.redraw(); var _this = this, closeEditor = function() { + _this.editor_$.off("keyup"); + _this.editor_$.find("input, textarea, select").off("change keyup paste"); + _this.editor_$.find(".Rk-Edit-Image-File").off('change'); + _this.editor_$.find(".Rk-Edit-ColorPicker-Wrapper").off('hover'); + _this.editor_$.find(".Rk-Edit-Size-Down").off('click'); + _this.editor_$.find(".Rk-Edit-Size-Up").off('click'); + _this.editor_$.find(".Rk-Edit-Image-Del").off('click'); + _this.editor_$.find(".Rk-Edit-ColorPicker").find("li").off('hover click'); + _this.editor_$.find(".Rk-CloseX").off('click'); + _this.editor_$.find(".Rk-Edit-Goto").off('click'); + _this.renderer.removeRepresentation(_this); paper.view.draw(); }; @@ -3622,41 +3641,36 @@ if (this.renderer.isEditable()) { - var onFieldChange = _(function() { - _(function() { - if (_this.renderer.isEditable()) { - var _data = { - title: _this.editor_$.find(".Rk-Edit-Title").val() - }; - if (_this.options.show_node_editor_uri) { - _data.uri = _this.editor_$.find(".Rk-Edit-URI").val(); - _this.editor_$.find(".Rk-Edit-Goto").attr("href",_data.uri || "#"); - } - if (_this.options.show_node_editor_image) { - _data.image = _this.editor_$.find(".Rk-Edit-Image").val(); - _this.editor_$.find(".Rk-Edit-ImgPreview").attr("src", _data.image || _image_placeholder); - } - if (_this.options.show_node_editor_description) { - _data.description = _this.editor_$.find(".Rk-Edit-Description").val(); + var onFieldChange = _.throttle(function() { + _.defer(function() { + if (_this.renderer.isEditable()) { + var _data = { + title: _this.editor_$.find(".Rk-Edit-Title").val() + }; + if (_this.options.show_node_editor_uri) { + _data.uri = _this.editor_$.find(".Rk-Edit-URI").val(); + _this.editor_$.find(".Rk-Edit-Goto").attr("href",_data.uri || "#"); + } + if (_this.options.show_node_editor_image) { + _data.image = _this.editor_$.find(".Rk-Edit-Image").val(); + _this.editor_$.find(".Rk-Edit-ImgPreview").attr("src", _data.image || _image_placeholder); + } + if (_this.options.show_node_editor_description) { + _data.description = _this.editor_$.find(".Rk-Edit-Description").val(); + } + if (_this.options.change_shapes) { + if(_model.get("shape")!==_this.editor_$.find(".Rk-Edit-Shape").val()){ + _data.shape = _this.editor_$.find(".Rk-Edit-Shape").val(); } - if (_this.options.change_shapes) { - if(_model.get("shape")!==_this.editor_$.find(".Rk-Edit-Shape").val()){ - _data.shape = _this.editor_$.find(".Rk-Edit-Shape").val(); - _data.shape_changed = true; - } - } - _model.set(_data); - _this.redraw(); - // For an unknown reason, we have to set data twice when we change shape, otherwise the image disappears. - if(_data.shape_changed===true){ - _model.set(_data); - } - } else { - closeEditor(); } - }).defer(); - }).throttle(500); - + _model.set(_data); + _this.redraw(); + } else { + closeEditor(); + } + }); + }, 500); + this.editor_$.on("keyup", function(_e) { if (_e.keyCode === 27) { closeEditor(); @@ -3740,10 +3754,10 @@ shiftSize(1); return false; }); - + this.editor_$.find(".Rk-Edit-Image-Del").click(function() { - _this.editor_$.find(".Rk-Edit-Image").val(''); - onFieldChange(); + _this.editor_$.find(".Rk-Edit-Image").val(''); + onFieldChange(); return false; }); } else { @@ -3765,7 +3779,7 @@ this.editor_$.show(); paper.view.draw(); } - }); + }).value(); /* NodeEditor End */ @@ -3785,11 +3799,11 @@ var EdgeEditor = Utils.inherit(BaseEditor); _(EdgeEditor.prototype).extend({ - _init: function() { - BaseEditor.prototype._init.apply(this); - this.template = this.options.templates['templates/edgeeditor.html']; - this.readOnlyTemplate = this.options.templates['templates/edgeeditor_readonly.html']; - }, + _init: function() { + BaseEditor.prototype._init.apply(this); + this.template = this.options.templates['templates/edgeeditor.html']; + this.readOnlyTemplate = this.options.templates['templates/edgeeditor_readonly.html']; + }, draw: function() { var _model = this.source_representation.model, _from_model = _model.get("from"), @@ -3797,7 +3811,7 @@ _created_by = _model.get("created_by") || Utils._USER_PLACEHOLDER(this.renkan), _template = (this.renderer.isEditable() ? this.template : this.readOnlyTemplate); this.editor_$ - .html(_template({ + .html(_template({ edge: { has_creator: !!_model.get("created_by"), title: _model.get("title"), @@ -3831,11 +3845,11 @@ if (this.renderer.isEditable()) { - var onFieldChange = _(function() { - _(function() { + var onFieldChange = _.throttle(function() { + _.defer(function() { if (_this.renderer.isEditable()) { var _data = { - title: _this.editor_$.find(".Rk-Edit-Title").val() + title: _this.editor_$.find(".Rk-Edit-Title").val() }; if (_this.options.show_edge_editor_uri) { _data.uri = _this.editor_$.find(".Rk-Edit-URI").val(); @@ -3846,8 +3860,8 @@ } else { closeEditor(); } - }).defer(); - }).throttle(500); + }); + },500); this.editor_$.on("keyup", function(_e) { if (_e.keyCode === 27) { @@ -3918,7 +3932,7 @@ this.editor_$.show(); paper.view.draw(); } - }); + }).value(); /* EdgeEditor End */ @@ -3969,7 +3983,8 @@ } this.sector.select(); }, - }); + }).value(); + /* _NodeButton End */ @@ -4002,7 +4017,7 @@ this.source_representation.openEditor(); } } - }); + }).value(); /* NodeEditButton End */ @@ -4013,7 +4028,7 @@ define('renderer/noderemovebutton',['jquery', 'underscore', 'requtils', 'renderer/nodebutton'], function ($, _, requtils, NodeButton) { - + var Utils = requtils.getUtils(); /* NodeRemoveButton Begin */ @@ -4049,7 +4064,7 @@ } } } - }); + }).value(); /* NodeRemoveButton End */ @@ -4084,7 +4099,7 @@ this.source_representation.model.unset("delete_scheduled"); } } - }); + }).value(); /* NodeRevertButton End */ @@ -4124,7 +4139,7 @@ this.renderer.addTempEdge(this.source_representation, _point); } } - }); + }).value(); /* NodeLinkButton End */ @@ -4136,7 +4151,7 @@ define('renderer/nodeenlargebutton',['jquery', 'underscore', 'requtils', 'renderer/nodebutton'], function ($, _, requtils, NodeButton) { - + var Utils = requtils.getUtils(); /* NodeEnlargeButton Begin */ @@ -4160,7 +4175,7 @@ this.select(); paper.view.draw(); } - }); + }).value(); /* NodeEnlargeButton End */ @@ -4195,7 +4210,7 @@ this.select(); paper.view.draw(); } - }); + }).value(); /* NodeShrinkButton End */ @@ -4224,7 +4239,7 @@ this.source_representation.openEditor(); } } - }); + }).value(); /* EdgeEditButton End */ @@ -4267,7 +4282,7 @@ } } } - }); + }).value(); /* EdgeRemoveButton End */ @@ -4298,7 +4313,7 @@ this.source_representation.model.unset("delete_scheduled"); } } - }); + }).value(); /* EdgeRevertButton End */ @@ -4326,7 +4341,8 @@ this.renderer.click_target = null; this.renderer.is_dragging = false; } - }); + }).value(); + /* MiniFrame End */ @@ -4365,7 +4381,7 @@ this.buttons_layer = new paper.Layer(); this.delete_list = []; this.redrawActive = true; - + if (_renkan.options.show_minimap) { this.minimap = { background_layer: new paper.Layer(), @@ -4399,7 +4415,7 @@ this.throttledPaperDraw = _(function() { paper.view.draw(); - }).throttle(100); + }).throttle(100).value(); this.bundles = []; this.click_mode = false; @@ -4519,7 +4535,7 @@ _event.preventDefault(); _allowScroll = true; var res = {}; - _(_event.originalEvent.dataTransfer.types).each(function(t) { + _.each(_event.originalEvent.dataTransfer.types, function(t) { try { res[t] = _event.originalEvent.dataTransfer.getData(t); } catch(e) {} @@ -4531,7 +4547,7 @@ case "[": try { var data = JSON.parse(text); - _(res).extend(data); + _.extend(res,data); } catch(e) { if (!res["text/plain"]) { @@ -5125,26 +5141,26 @@ }, removeRepresentation: function(_representation) { _representation.destroy(); - this.representations = _(this.representations).reject( - function(_repr) { - return _repr === _representation; - } + this.representations = _.reject(this.representations, + function(_repr) { + return _repr === _representation; + } ); }, getRepresentationByModel: function(_model) { if (!_model) { return undefined; } - return _(this.representations).find(function(_repr) { + return _.find(this.representations, function(_repr) { return _repr.model === _model; }); }, removeRepresentationsOfType: function(_type) { - var _representations = _(this.representations).filter(function(_repr) { + var _representations = _.filter(this.representations,function(_repr) { return _repr.type === _type; - }), - _this = this; - _(_representations).each(function(_repr) { + }), + _this = this; + _.each(_representations, function(_repr) { _this.removeRepresentation(_repr); }); }, @@ -5155,12 +5171,12 @@ } }, unhighlightAll: function(_model) { - _(this.representations).each(function(_repr) { + _.each(this.representations, function(_repr) { _repr.unhighlight(); }); }, unselectAll: function(_model) { - _(this.representations).each(function(_repr) { + _.each(this.representations, function(_repr) { _repr.unselect(); }); }, @@ -5168,8 +5184,8 @@ if(! this.redrawActive ) { return; } - _(this.representations).each(function(_representation) { - _representation.redraw(true); + _.each(this.representations, function(_representation) { + _representation.redraw({ dontRedrawEdges:true }); }); if (this.minimap) { this.redrawMiniframe(); @@ -5433,7 +5449,7 @@ if (_data["text/json"] || _data["application/json"]) { try { var jsondata = JSON.parse(_data["text/json"] || _data["application/json"]); - _(_data).extend(jsondata); + _.extend(_data,jsondata); } catch(e) {} } @@ -5614,7 +5630,7 @@ }, save: function() { }, open: function() { } - }); + }).value(); /* Scene End */ @@ -5628,7 +5644,9 @@ require.config({ paths: { 'jquery':'../lib/jquery/jquery', - 'underscore':'../lib/underscore/underscore', +// 'underscore':'../lib/underscore/underscore', +// 'underscore':'../lib/lodash-compat/lodash', + 'underscore':'../lib/lodash/lodash', 'filesaver' :'../lib/FileSaver/FileSaver', 'requtils':'require-utils' }
--- a/server/python/django/renkanmanager/static/renkanmanager/lib/renkan/js/renkan.min.js Sat Apr 25 04:37:06 2015 +0200 +++ b/server/python/django/renkanmanager/static/renkanmanager/lib/renkan/js/renkan.min.js Mon Apr 27 17:22:46 2015 +0200 @@ -1,32 +1,34 @@ -/*! - * _____ _ - * | __ \ | | - * | |__) |___ _ __ | | ____ _ _ __ - * | _ // _ \ '_ \| |/ / _` | '_ \ +/*! + * _____ _ + * | __ \ | | + * | |__) |___ _ __ | | ____ _ _ __ + * | _ // _ \ '_ \| |/ / _` | '_ \ * | | \ \ __/ | | | < (_| | | | | * |_| \_\___|_| |_|_|\_\__,_|_| |_| * - * Copyright 2012-2013 Institut de recherche et d'innovation - * contributor(s) : Yves-Marie Haussonne, Raphael Velt, Samuel Huron - * + * Copyright 2012-2015 Institut de recherche et d'innovation + * contributor(s) : Yves-Marie Haussonne, Raphael Velt, Samuel Huron, + * Thibaut CavaliĆ©, Julien Rougeron. + * * contact@iri.centrepompidou.fr - * http://www.iri.centrepompidou.fr - * + * http://www.iri.centrepompidou.fr + * * This software is a computer program whose purpose is to show and add annotations on a video . * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, + * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL-C * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * + * "http://www.cecill.info". + * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ -/*! renkan - v0.8.7 - Copyright Ā© IRI 2015 */ + +/*! renkan - v0.9.0 - Copyright Ā© IRI 2015 */ -this.renkanJST=this.renkanJST||{},this.renkanJST["templates/colorpicker.html"]=function(obj){obj||(obj={});{var __t,__p="";_.escape}with(obj)__p+='<li data-color="'+(null==(__t=c)?"":__t)+'" style="background: '+(null==(__t=c)?"":__t)+'"></li>';return __p},this.renkanJST["templates/edgeeditor.html"]=function(obj){obj||(obj={});{var __t,__p="",__e=_.escape;Array.prototype.join}with(obj)__p+='<h2>\n <span class="Rk-CloseX">×</span>'+__e(renkan.translate("Edit Edge"))+"</span>\n</h2>\n<p>\n <label>"+__e(renkan.translate("Title:"))+'</label>\n <input class="Rk-Edit-Title" type="text" value="'+__e(edge.title)+'" />\n</p>\n',options.show_edge_editor_uri&&(__p+="\n <p>\n <label>"+__e(renkan.translate("URI:"))+'</label>\n <input class="Rk-Edit-URI" type="text" value="'+__e(edge.uri)+'" />\n <a class="Rk-Edit-Goto" href="'+__e(edge.uri)+'" target="_blank"></a>\n </p>\n ',options.properties.length&&(__p+="\n <p>\n <label>"+__e(renkan.translate("Choose from vocabulary:"))+'</label>\n <select class="Rk-Edit-Vocabulary">\n ',_(options.properties).each(function(a){__p+='\n <option class="Rk-Edit-Vocabulary-Class" value="">\n '+__e(renkan.translate(a.label))+"\n </option>\n ",_(a.properties).each(function(b){var c=a["base-uri"]+b.uri;__p+='\n <option class="Rk-Edit-Vocabulary-Property" value="'+__e(c)+'"\n ',c===edge.uri&&(__p+=" selected"),__p+=">\n "+__e(renkan.translate(b.label))+"\n </option>\n "}),__p+="\n "}),__p+="\n </select>\n </p>\n")),__p+="\n",options.show_edge_editor_color&&(__p+='\n <div class="Rk-Editor-p">\n <span class="Rk-Editor-Label">'+__e(renkan.translate("Edge color:"))+'</span>\n <div class="Rk-Edit-ColorPicker-Wrapper">\n <span class="Rk-Edit-Color" style="background: <%-edge.color%>;">\n <span class="Rk-Edit-ColorTip"></span>\n </span>\n '+(null==(__t=renkan.colorPicker)?"":__t)+'\n <span class="Rk-Edit-ColorPicker-Text">'+__e(renkan.translate("Choose color"))+"</span>\n </div>\n </div>\n"),__p+="\n",options.show_edge_editor_direction&&(__p+='\n <p>\n <span class="Rk-Edit-Direction">'+__e(renkan.translate("Change edge direction"))+"</span>\n </p>\n"),__p+="\n",options.show_edge_editor_nodes&&(__p+='\n <p>\n <span class="Rk-Editor-Label">'+__e(renkan.translate("From:"))+'</span>\n <span class="Rk-UserColor" style="background: '+__e(edge.from_color)+';"></span>\n '+__e(shortenText(edge.from_title,25))+'\n </p>\n <p>\n <span class="Rk-Editor-Label">'+__e(renkan.translate("To:"))+'</span>\n <span class="Rk-UserColor" style="background: >%-edge.to_color%>;"></span>\n '+__e(shortenText(edge.to_title,25))+"\n </p>\n"),__p+="\n",options.show_edge_editor_creator&&edge.has_creator&&(__p+='\n <p>\n <span class="Rk-Editor-Label">'+__e(renkan.translate("Created by:"))+'</span>\n <span class="Rk-UserColor" style="background: <%-edge.created_by_color%>;"></span>\n '+__e(shortenText(edge.created_by_title,25))+"\n </p>\n"),__p+="\n";return __p},this.renkanJST["templates/edgeeditor_readonly.html"]=function(obj){obj||(obj={});{var __p="",__e=_.escape;Array.prototype.join}with(obj)__p+='<h2>\n <span class="Rk-CloseX">×</span>\n ',options.show_edge_tooltip_color&&(__p+='\n <span class="Rk-UserColor" style="background: '+__e(edge.color)+';"></span>\n '),__p+='\n <span class="Rk-Display-Title">\n ',edge.uri&&(__p+='\n <a href="'+__e(edge.uri)+'" target="_blank">\n '),__p+="\n "+__e(edge.title)+"\n ",edge.uri&&(__p+=" </a> "),__p+="\n </span>\n</h2>\n",options.show_edge_tooltip_uri&&edge.uri&&(__p+='\n <p class="Rk-Display-URI">\n <a href="'+__e(edge.uri)+'" target="_blank">'+__e(edge.short_uri)+"</a>\n </p>\n"),__p+="\n<p>"+__e(edge.description)+"</p>\n",options.show_edge_tooltip_nodes&&(__p+='\n <p>\n <span class="Rk-Editor-Label">'+__e(renkan.translate("From:"))+'</span>\n <span class="Rk-UserColor" style="background: '+__e(edge.from_color)+';"></span>\n '+__e(shortenText(edge.from_title,25))+'\n </p>\n <p>\n <span class="Rk-Editor-Label">'+__e(renkan.translate("To:"))+'</span>\n <span class="Rk-UserColor" style="background: '+__e(edge.to_color)+';"></span>\n '+__e(shortenText(edge.to_title,25))+"\n </p>\n"),__p+="\n",options.show_edge_tooltip_creator&&edge.has_creator&&(__p+='\n <p>\n <span class="Rk-Editor-Label">'+__e(renkan.translate("Created by:"))+'</span>\n <span class="Rk-UserColor" style="background: '+__e(edge.created_by_color)+';"></span>\n '+__e(shortenText(edge.created_by_title,25))+"\n </p>\n"),__p+="\n";return __p},this.renkanJST["templates/ldtjson-bin/annotationtemplate.html"]=function(obj){obj||(obj={});var __t,__p="",__e=_.escape;with(obj)__p+='<li class="Rk-Bin-Item" draggable="true"\n data-image="'+__e(Rkns.Utils.getFullURL(image))+'"\n data-uri="'+(null==(__t=ldt_platform)?"":__t)+"ldtplatform/ldt/front/player/"+(null==(__t=mediaid)?"":__t)+"/#id="+(null==(__t=annotationid)?"":__t)+'"\n data-title="'+__e(title)+'" data-description="'+__e(description)+'">\n \n <img class="Rk-Ldt-Annotation-Icon" src="'+(null==(__t=image)?"":__t)+'" />\n <h4>'+(null==(__t=htitle)?"":__t)+"</h4>\n <p>"+(null==(__t=hdescription)?"":__t)+"</p>\n <p>Start: "+(null==(__t=start)?"":__t)+", End: "+(null==(__t=end)?"":__t)+", Duration: "+(null==(__t=duration)?"":__t)+'</p>\n <div class="Rk-Clear"></div>\n</li>';return __p},this.renkanJST["templates/ldtjson-bin/segmenttemplate.html"]=function(obj){obj||(obj={});var __t,__p="",__e=_.escape;with(obj)__p+='<li class="Rk-Bin-Item" draggable="true"\n data-image="'+__e(Rkns.Utils.getFullURL(image))+'"\n data-uri="'+(null==(__t=ldt_platform)?"":__t)+"ldtplatform/ldt/front/player/"+(null==(__t=mediaid)?"":__t)+"/#id="+(null==(__t=annotationid)?"":__t)+'"\n data-title="'+__e(title)+'" data-description="'+__e(description)+'">\n \n <img class="Rk-Ldt-Annotation-Icon" src="'+(null==(__t=image)?"":__t)+'" />\n <h4>'+(null==(__t=htitle)?"":__t)+"</h4>\n <p>"+(null==(__t=hdescription)?"":__t)+"</p>\n <p>Start: "+(null==(__t=start)?"":__t)+", End: "+(null==(__t=end)?"":__t)+", Duration: "+(null==(__t=duration)?"":__t)+'</p>\n <div class="Rk-Clear"></div>\n</li>';return __p},this.renkanJST["templates/ldtjson-bin/tagtemplate.html"]=function(obj){obj||(obj={});var __t,__p="",__e=_.escape;with(obj)__p+='<li class="Rk-Bin-Item" draggable="true"\n data-image="'+__e(Rkns.Utils.getFullURL(static_url+"img/ldt-tag.png"))+'"\n data-uri="'+(null==(__t=ldt_platform)?"":__t)+"ldtplatform/ldt/front/search/?search="+(null==(__t=encodedtitle)?"":__t)+'&field=all"\n data-title="'+__e(title)+'" data-description="Tag \''+__e(title)+'\'">\n\n <img class="Rk-Ldt-Tag-Icon" src="'+__e(static_url)+'img/ldt-tag.png" />\n <h4>'+(null==(__t=htitle)?"":__t)+'</h4>\n <div class="Rk-Clear"></div>\n</li>';return __p},this.renkanJST["templates/list-bin.html"]=function(obj){obj||(obj={});{var __t,__p="",__e=_.escape;Array.prototype.join}with(obj)__p+='<li class="Rk-Bin-Item Rk-ResourceList-Item" draggable="true"\n data-uri="'+__e(url)+'" data-title="'+__e(title)+'"\n data-description="'+__e(description)+'"\n ',__p+=image?'\n data-image="'+__e(Rkns.Utils.getFullURL(image))+'"\n ':'\n data-image=""\n ',__p+="\n>",image&&(__p+='\n <img class="Rk-ResourceList-Image" src="'+__e(image)+'" />\n'),__p+='\n<h4 class="Rk-ResourceList-Title">\n ',url&&(__p+='\n <a href="'+__e(url)+'" target="_blank">\n '),__p+="\n "+(null==(__t=htitle)?"":__t)+"\n ",url&&(__p+="</a>"),__p+="\n </h4> \n ",description&&(__p+='\n <p class="Rk-ResourceList-Description">'+(null==(__t=hdescription)?"":__t)+"</p>\n "),__p+="\n ",image&&(__p+='\n <div style="clear: both;"></div>\n '),__p+="\n</li>";return __p},this.renkanJST["templates/main.html"]=function(obj){obj||(obj={});{var __p="",__e=_.escape;Array.prototype.join}with(obj)options.show_bins&&(__p+='\n <div class="Rk-Bins">\n <div class="Rk-Bins-Head">\n <h2 class="Rk-Bins-Title">'+__e(translate("Select contents:"))+'</h2>\n <form class="Rk-Web-Search-Form Rk-Search-Form">\n <input class="Rk-Web-Search-Input Rk-Search-Input" type="search"\n placeholder="'+__e(translate("Search the Web"))+'" />\n <div class="Rk-Search-Select">\n <div class="Rk-Search-Current"></div>\n <ul class="Rk-Search-List"></ul>\n </div>\n <input type="submit" value=""\n class="Rk-Web-Search-Submit Rk-Search-Submit" title="'+__e(translate("Search the Web"))+'" />\n </form>\n <form class="Rk-Bins-Search-Form Rk-Search-Form">\n <input class="Rk-Bins-Search-Input Rk-Search-Input" type="search"\n placeholder="'+__e(translate("Search in Bins"))+'" /> <input\n type="submit" value=""\n class="Rk-Bins-Search-Submit Rk-Search-Submit"\n title="'+__e(translate("Search in Bins"))+'" />\n </form>\n </div>\n <ul class="Rk-Bin-List"></ul>\n </div>\n'),__p+=" ",options.show_editor&&(__p+='\n <div class="Rk-Render Rk-Render-',__p+=options.show_bins?"Panel":"Full",__p+='"></div>\n'),__p+="\n";return __p},this.renkanJST["templates/nodeeditor.html"]=function(obj){obj||(obj={});{var __t,__p="",__e=_.escape;Array.prototype.join}with(obj)__p+='<h2>\n <span class="Rk-CloseX">×</span>'+__e(renkan.translate("Edit Node"))+"</span>\n</h2>\n<p>\n <label>"+__e(renkan.translate("Title:"))+'</label>\n <input class="Rk-Edit-Title" type="text" value="'+__e(node.title)+'" />\n</p>\n',options.show_node_editor_uri&&(__p+="\n <p>\n <label>"+__e(renkan.translate("URI:"))+'</label>\n <input class="Rk-Edit-URI" type="text" value="'+__e(node.uri)+'" />\n <a class="Rk-Edit-Goto" href="'+__e(node.uri)+'" target="_blank"></a>\n </p>\n'),__p+=" ",options.show_node_editor_description&&(__p+="\n <p>\n <label>"+__e(renkan.translate("Description:"))+'</label>\n <textarea class="Rk-Edit-Description">'+__e(node.description)+"</textarea>\n </p>\n"),__p+=" ",options.show_node_editor_size&&(__p+='\n <p>\n <span class="Rk-Editor-Label">'+__e(renkan.translate("Size:"))+'</span>\n <a href="#" class="Rk-Edit-Size-Down">-</a>\n <span class="Rk-Edit-Size-Value">'+__e(node.size)+'</span>\n <a href="#" class="Rk-Edit-Size-Up">+</a>\n </p>\n'),__p+=" ",options.show_node_editor_color&&(__p+='\n <div class="Rk-Editor-p">\n <span class="Rk-Editor-Label">\n '+__e(renkan.translate("Node color:"))+'</span>\n <div class="Rk-Edit-ColorPicker-Wrapper">\n <span class="Rk-Edit-Color" style="background: '+__e(node.color)+';">\n <span class="Rk-Edit-ColorTip"></span>\n </span>\n '+(null==(__t=renkan.colorPicker)?"":__t)+'\n <span class="Rk-Edit-ColorPicker-Text">'+__e(renkan.translate("Choose color"))+"</span>\n </div>\n </div>\n"),__p+=" ",options.show_node_editor_image&&(__p+='\n <div class="Rk-Edit-ImgWrap">\n <div class="Rk-Edit-ImgPreview">\n <img src="'+__e(node.image||node.image_placeholder)+'" />\n ',node.clip_path&&(__p+='\n <svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewbox="0 0 1 1" preserveAspectRatio="none">\n <path style="stroke-width: .02; stroke:red; fill-opacity:.3; fill:red;" d="'+__e(node.clip_path)+'" />\n </svg>\n '),__p+="\n </div>\n </div>\n <p>\n <label>"+__e(renkan.translate("Image URL:"))+'</label>\n <div>\n <a class="Rk-Edit-Image-Del" href="#"></a>\n <input class="Rk-Edit-Image" type="text" value=\''+__e(node.image)+"' />\n </div>\n </p>\n",options.allow_image_upload&&(__p+="\n <p>\n <label>"+__e(renkan.translate("Choose Image File:"))+'</label>\n <input class="Rk-Edit-Image-File" type="file" accept="image/*" />\n </p>\n')),__p+=" ",options.show_node_editor_creator&&node.has_creator&&(__p+='\n <p>\n <span class="Rk-Editor-Label">'+__e(renkan.translate("Created by:"))+'</span>\n <span class="Rk-UserColor" style="background: '+__e(node.created_by_color)+';"></span>\n '+__e(shortenText(node.created_by_title,25))+"\n </p>\n"),__p+=" ",options.change_shapes&&(__p+="\n <p>\n <label>"+__e(renkan.translate("Shapes available"))+':</label>\n <select class="Rk-Edit-Shape">\n <option class="Rk-Edit-Vocabulary-Property" value="circle"',"circle"===node.shape&&(__p+=" selected"),__p+=">\n "+__e(renkan.translate("Circle"))+'\n </option>\n <option class="Rk-Edit-Vocabulary-Property" value="rectangle"',"rectangle"===node.shape&&(__p+=" selected"),__p+=">\n "+__e(renkan.translate("Square"))+'\n </option>\n <option class="Rk-Edit-Vocabulary-Property" value="diamond"',"diamond"===node.shape&&(__p+=" selected"),__p+=">\n "+__e(renkan.translate("Diamond"))+'\n </option>\n <option class="Rk-Edit-Vocabulary-Property" value="polygon"',"polygon"===node.shape&&(__p+=" selected"),__p+=">\n "+__e(renkan.translate("Hexagone"))+'\n </option>\n <option class="Rk-Edit-Vocabulary-Property" value="ellipse"',"ellipse"===node.shape&&(__p+=" selected"),__p+=">\n "+__e(renkan.translate("Ellipse"))+'\n </option>\n <option class="Rk-Edit-Vocabulary-Property" value="star"',"star"===node.shape&&(__p+=" selected"),__p+=">\n "+__e(renkan.translate("Star"))+"\n </option>\n </select>\n </p>\n"),__p+="\n";return __p},this.renkanJST["templates/nodeeditor_readonly.html"]=function(obj){obj||(obj={});{var __p="",__e=_.escape;Array.prototype.join}with(obj)__p+='<h2>\n <span class="Rk-CloseX">×</span>\n ',options.show_node_tooltip_color&&(__p+='\n <span class="Rk-UserColor" style="background: '+__e(node.color)+';"></span>\n '),__p+='\n <span class="Rk-Display-Title">\n ',node.uri&&(__p+='\n <a href="'+__e(node.uri)+'" target="_blank">\n '),__p+="\n "+__e(node.title)+"\n ",node.uri&&(__p+="</a>"),__p+="\n </span>\n</h2>\n",node.uri&&options.show_node_tooltip_uri&&(__p+='\n <p class="Rk-Display-URI">\n <a href="'+__e(node.uri)+'" target="_blank">'+__e(node.short_uri)+"</a>\n </p>\n"),__p+=" ",options.show_node_tooltip_description&&(__p+='\n <p class="Rk-Display-Description">'+__e(node.description)+"</p>\n"),__p+=" ",node.image&&options.show_node_tooltip_image&&(__p+='\n <img class="Rk-Display-ImgPreview" src="'+__e(node.image)+'" />\n'),__p+=" ",node.has_creator&&options.show_node_tooltip_creator&&(__p+='\n <p>\n <span class="Rk-Editor-Label">'+__e(renkan.translate("Created by:"))+'</span>\n <span class="Rk-UserColor" style="background: '+__e(node.created_by_color)+';"></span>\n '+__e(shortenText(node.created_by_title,25))+"\n </p>\n"),__p+="\n";return __p},this.renkanJST["templates/scene.html"]=function(obj){function print(){__p+=__j.call(arguments,"")}obj||(obj={});var __p="",__e=_.escape,__j=Array.prototype.join;with(obj)options.show_top_bar&&(__p+='\n <div class="Rk-TopBar">\n <div class="loader"></div>\n ',__p+=options.editor_mode?'\n <input type="text" class="Rk-PadTitle" value="'+__e(project.get("title")||"")+'" placeholder="'+__e(translate("Untitled project"))+'" />\n ':'\n <h2 class="Rk-PadTitle">\n '+__e(project.get("title")||translate("Untitled project"))+"\n </h2>\n ",__p+="\n ",options.show_user_list&&(__p+='\n <div class="Rk-Users">\n <div class="Rk-CurrentUser">\n ',options.show_user_color&&(__p+='\n <div class="Rk-Edit-ColorPicker-Wrapper">\n <span class="Rk-CurrentUser-Color">\n ',options.user_color_editable&&(__p+='\n <span class="Rk-Edit-ColorTip"></span>\n '),__p+="\n </span>\n ",options.user_color_editable&&print(colorPicker),__p+="\n </div>\n "),__p+='\n <span class="Rk-CurrentUser-Name"><unknown user></span>\n </div>\n <ul class="Rk-UserList"></ul>\n </div>\n '),__p+="\n ",options.home_button_url&&(__p+='\n <div class="Rk-TopBar-Separator"></div>\n <a class="Rk-TopBar-Button Rk-Home-Button" href="'+__e(options.home_button_url)+'">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n '+__e(translate(options.home_button_title))+"\n </div>\n </div>\n </a>\n "),__p+="\n ",options.show_fullscreen_button&&(__p+='\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-FullScreen-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n '+__e(translate("Full Screen"))+"\n </div>\n </div>\n </div>\n "),__p+="\n ",options.editor_mode?(__p+="\n ",options.show_addnode_button&&(__p+='\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-AddNode-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n '+__e(translate("Add Node"))+"\n </div>\n </div>\n </div>\n "),__p+="\n ",options.show_addedge_button&&(__p+='\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-AddEdge-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n '+__e(translate("Add Edge"))+"\n </div>\n </div>\n </div>\n "),__p+="\n ",options.show_export_button&&(__p+='\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-Export-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n '+__e(translate("Download Project"))+"\n </div>\n </div>\n </div>\n "),__p+="\n ",options.show_save_button&&(__p+='\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-Save-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents"></div>\n </div>\n </div>\n '),__p+="\n ",options.show_open_button&&(__p+='\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-Open-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n '+__e(translate("Open Project"))+"\n </div>\n </div>\n </div>\n "),__p+="\n ",options.show_bookmarklet&&(__p+='\n <div class="Rk-TopBar-Separator"></div>\n <a class="Rk-TopBar-Button Rk-Bookmarklet-Button" href="#">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n '+__e(translate("Renkan 'Drag-to-Add' bookmarklet"))+'\n </div>\n </div>\n </a>\n <div class="Rk-TopBar-Separator"></div>\n '),__p+="\n "):(__p+="\n ",options.show_export_button&&(__p+='\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-Export-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n '+__e(translate("Download Project"))+'\n </div>\n </div>\n </div>\n <div class="Rk-TopBar-Separator"></div>\n '),__p+="\n "),__p+="\n ",options.show_search_field&&(__p+='\n <form action="#" class="Rk-GraphSearch-Form">\n <input type="search" class="Rk-GraphSearch-Field" placeholder="'+__e(translate("Search in graph"))+'" />\n </form>\n <div class="Rk-TopBar-Separator"></div>\n '),__p+="\n </div>\n"),__p+='\n<div class="Rk-Editing-Space',options.show_top_bar||(__p+=" Rk-Editing-Space-Full"),__p+='">\n <div class="Rk-Labels"></div>\n <canvas class="Rk-Canvas" ',options.resize&&(__p+=' resize="" '),__p+='></canvas>\n <div class="Rk-Notifications"></div>\n <div class="Rk-Editor">\n ',options.show_bins&&(__p+='\n <div class="Rk-Fold-Bins">«</div>\n '),__p+="\n ",options.show_zoom&&(__p+='\n <div class="Rk-ZoomButtons">\n <div class="Rk-ZoomIn" title="'+__e(translate("Zoom In"))+'"></div>\n <div class="Rk-ZoomFit" title="'+__e(translate("Zoom Fit"))+'"></div>\n <div class="Rk-ZoomOut" title="'+__e(translate("Zoom Out"))+'"></div>\n ',options.editor_mode&&options.save_view&&(__p+='\n <div class="Rk-ZoomSave" title="'+__e(translate("Zoom Save"))+'"></div>\n '),__p+="\n ",options.save_view&&(__p+='\n <div class="Rk-ZoomSetSaved" title="'+__e(translate("View saved zoom"))+'"></div>\n '),__p+="\n </div>\n "),__p+="\n </div>\n</div>";return __p},this.renkanJST["templates/search.html"]=function(obj){obj||(obj={});{var __t,__p="";_.escape}with(obj)__p+='<li class="'+(null==(__t=className)?"":__t)+'" data-key="'+(null==(__t=key)?"":__t)+'">'+(null==(__t=title)?"":__t)+"</li>";return __p},this.renkanJST["templates/wikipedia-bin/resulttemplate.html"]=function(obj){obj||(obj={});var __t,__p="",__e=_.escape;with(obj)__p+='<li class="Rk-Wikipedia-Result Rk-Bin-Item" draggable="true"\n data-uri="'+__e(url)+'" data-title="Wikipedia: '+__e(title)+'"\n data-description="'+__e(description)+'"\n data-image="'+__e(Rkns.Utils.getFullURL(static_url+"img/wikipedia.png"))+'">\n \n <img class="Rk-Wikipedia-Icon" src="'+__e(static_url)+'img/wikipedia.png">\n <h4 class="Rk-Wikipedia-Title">\n <a href="'+__e(url)+'" target="_blank">'+(null==(__t=htitle)?"":__t)+'</a>\n </h4>\n <p class="Rk-Wikipedia-Snippet">'+(null==(__t=hdescription)?"":__t)+"</p>\n</li>";return __p},function(a){"use strict";"object"!=typeof a.Rkns&&(a.Rkns={});var b=a.Rkns,c=b.$=a.jQuery,d=b._=a._;b.pickerColors=["#8f1919","#a80000","#d82626","#ff0000","#e87c7c","#ff6565","#f7d3d3","#fecccc","#8f5419","#a85400","#d87f26","#ff7f00","#e8b27c","#ffb265","#f7e5d3","#fee5cc","#8f8f19","#a8a800","#d8d826","#feff00","#e8e87c","#feff65","#f7f7d3","#fefecc","#198f19","#00a800","#26d826","#00ff00","#7ce87c","#65ff65","#d3f7d3","#ccfecc","#198f8f","#00a8a8","#26d8d8","#00feff","#7ce8e8","#65feff","#d3f7f7","#ccfefe","#19198f","#0000a8","#2626d8","#0000ff","#7c7ce8","#6565ff","#d3d3f7","#ccccfe","#8f198f","#a800a8","#d826d8","#ff00fe","#e87ce8","#ff65fe","#f7d3f7","#feccfe","#000000","#242424","#484848","#6d6d6d","#919191","#b6b6b6","#dadada","#ffffff"],b.__renkans=[];var e=b._BaseBin=function(a,c){if("undefined"!=typeof a){this.renkan=a,this.renkan.$.find(".Rk-Bin-Main").hide(),this.$=b.$("<li>").addClass("Rk-Bin").appendTo(a.$.find(".Rk-Bin-List")),this.title_icon_$=b.$("<span>").addClass("Rk-Bin-Title-Icon").appendTo(this.$);var d=this;b.$("<a>").attr({href:"#",title:a.translate("Close bin")}).addClass("Rk-Bin-Close").html("×").appendTo(this.$).click(function(){return d.destroy(),a.$.find(".Rk-Bin-Main:visible").length||a.$.find(".Rk-Bin-Main:last").slideDown(),a.resizeBins(),!1}),b.$("<a>").attr({href:"#",title:a.translate("Refresh bin")}).addClass("Rk-Bin-Refresh").appendTo(this.$).click(function(){return d.refresh(),!1}),this.count_$=b.$("<div>").addClass("Rk-Bin-Count").appendTo(this.$),this.title_$=b.$("<h2>").addClass("Rk-Bin-Title").appendTo(this.$),this.main_$=b.$("<div>").addClass("Rk-Bin-Main").appendTo(this.$).html('<h4 class="Rk-Bin-Loading">'+a.translate("Loading, please wait")+"</h4>"),this.title_$.html(c.title||"(new bin)"),this.renkan.resizeBins(),c.auto_refresh&&window.setInterval(function(){d.refresh()},c.auto_refresh)}};e.prototype.destroy=function(){this.$.detach(),this.renkan.resizeBins()};var f=b.Renkan=function(a){var e=this;if(b.__renkans.push(this),this.options=d.defaults(a,b.defaults,{templates:renkanJST}),this.template=renkanJST["templates/main.html"],d(this.options.property_files).each(function(a){b.$.getJSON(a,function(a){e.options.properties=e.options.properties.concat(a)})}),this.read_only=this.options.read_only||!this.options.editor_mode,this.project=new b.Models.Project,this.setCurrentUser=function(a,b){this.project.addUser({_id:a,title:b}),this.current_user=a,this.renderer.redrawUsers()},"undefined"!=typeof this.options.user_id&&(this.current_user=this.options.user_id),this.$=b.$("#"+this.options.container),this.$.addClass("Rk-Main").html(this.template(this)),this.tabs=[],this.search_engines=[],this.current_user_list=new b.Models.UsersList,this.current_user_list.on("add remove",function(){this.renderer&&this.renderer.redrawUsers()}),this.colorPicker=function(){var a=renkanJST["templates/colorpicker.html"];return'<ul class="Rk-Edit-ColorPicker">'+b.pickerColors.map(function(b){return a({c:b})}).join("")+"</ul>"}(),this.options.show_editor&&(this.renderer=new b.Renderer.Scene(this)),this.options.search.length){var f=renkanJST["templates/search.html"],g=this.$.find(".Rk-Search-List"),h=this.$.find(".Rk-Web-Search-Input"),i=this.$.find(".Rk-Web-Search-Form");d(this.options.search).each(function(a){b[a.type]&&b[a.type].Search&&e.search_engines.push(new b[a.type].Search(e,a))}),g.html(d(this.search_engines).map(function(a,b){return f({key:b,title:a.getSearchTitle(),className:a.getBgClass()})}).join("")),g.find("li").click(function(){var a=b.$(this);e.setSearchEngine(a.attr("data-key")),i.submit()}),i.submit(function(){if(h.val()){var a=e.search_engine;a.search(h.val())}return!1}),this.$.find(".Rk-Search-Current").mouseenter(function(){g.slideDown()}),this.$.find(".Rk-Search-Select").mouseleave(function(){g.hide()}),this.setSearchEngine(0)}else this.$.find(".Rk-Web-Search-Form").detach();d(this.options.bins).each(function(a){b[a.type]&&b[a.type].Bin&&e.tabs.push(new b[a.type].Bin(e,a))});var j=!1;this.$.find(".Rk-Bins").on("click",".Rk-Bin-Title,.Rk-Bin-Title-Icon",function(){var a=b.$(this).siblings(".Rk-Bin-Main");a.is(":hidden")&&(e.$.find(".Rk-Bin-Main").slideUp(),a.slideDown())}),this.options.show_editor&&this.$.find(".Rk-Bins").on("mouseover",".Rk-Bin-Item",function(){var a=b.$(this);if(a&&c(a).attr("data-uri")){var f=e.project.get("nodes").where({uri:c(a).attr("data-uri")});d(f).each(function(a){e.renderer.highlightModel(a)})}}).mouseout(function(){e.renderer.unhighlightAll()}).on("mousemove",".Rk-Bin-Item",function(){try{this.dragDrop()}catch(a){}}).on("touchstart",".Rk-Bin-Item",function(){j=!1}).on("touchmove",".Rk-Bin-Item",function(a){a.preventDefault();var b=a.originalEvent.changedTouches[0],c=e.renderer.canvas_$.offset(),d=e.renderer.canvas_$.width(),f=e.renderer.canvas_$.height();if(b.pageX>=c.left&&b.pageX<c.left+d&&b.pageY>=c.top&&b.pageY<c.top+f)if(j)e.renderer.onMouseMove(b,!0);else{j=!0;var g=document.createElement("div");g.appendChild(this.cloneNode(!0)),e.renderer.dropData({"text/html":g.innerHTML},b),e.renderer.onMouseDown(b,!0)}}).on("touchend",".Rk-Bin-Item",function(a){j&&e.renderer.onMouseUp(a.originalEvent.changedTouches[0],!0),j=!1}).on("dragstart",".Rk-Bin-Item",function(a){var b=document.createElement("div");b.appendChild(this.cloneNode(!0));try{a.originalEvent.dataTransfer.setData("text/html",b.innerHTML)}catch(c){a.originalEvent.dataTransfer.setData("text",b.innerHTML)}}),b.$(window).resize(function(){e.resizeBins()});var k=!1,l="";this.$.find(".Rk-Bins-Search-Input").on("change keyup paste input",function(){var a=b.$(this).val();if(a!==l){var c=b.Utils.regexpFromTextOrArray(a.length>1?a:null);c.source!==k&&(k=c.source,d(e.tabs).each(function(a){a.render(c)}))}}),this.$.find(".Rk-Bins-Search-Form").submit(function(){return!1})};f.prototype.translate=function(a){return b.i18n[this.options.language]&&b.i18n[this.options.language][a]?b.i18n[this.options.language][a]:this.options.language.length>2&&b.i18n[this.options.language.substr(0,2)]&&b.i18n[this.options.language.substr(0,2)][a]?b.i18n[this.options.language.substr(0,2)][a]:a},f.prototype.onStatusChange=function(){this.renderer.onStatusChange()},f.prototype.setSearchEngine=function(a){this.search_engine=this.search_engines[a],this.$.find(".Rk-Search-Current").attr("class","Rk-Search-Current "+this.search_engine.getBgClass());for(var b=this.search_engine.getBgClass().split(" "),c="",d=0;d<b.length;d++)c+="."+b[d];this.$.find(".Rk-Web-Search-Input.Rk-Search-Input").attr("placeholder",this.translate("Search in ")+this.$.find(".Rk-Search-List "+c).html())},f.prototype.resizeBins=function(){var a=+this.$.find(".Rk-Bins-Head").outerHeight();this.$.find(".Rk-Bin-Title:visible").each(function(){a+=b.$(this).outerHeight()}),this.$.find(".Rk-Bin-Main").css({height:this.$.find(".Rk-Bins").height()-a})};var g=function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=16*Math.random()|0,c="x"===a?b:3&b|8;return c.toString(16)})};b.Utils={getUUID4:g,getUID:function(){function a(a){return 10>a?"0"+a:a}var b=new Date,c=0,d=b.getUTCFullYear()+"-"+a(b.getUTCMonth()+1)+"-"+a(b.getUTCDate())+"-"+g();return function(a){for(var b=(++c).toString(16),e="undefined"==typeof a?"":a+"-";b.length<4;)b="0"+b;return e+d+"-"+b}}(),getFullURL:function(a){if("undefined"==typeof a||null==a)return"";if(/https?:\/\//.test(a))return a;var b=new Image;b.src=a;var c=b.src;return b.src=null,c},inherit:function(a,b){var c=function(){"function"==typeof b&&b.apply(this,Array.prototype.slice.call(arguments,0)),a.apply(this,Array.prototype.slice.call(arguments,0)),"function"!=typeof this._init||this._initialized||(this._init.apply(this,Array.prototype.slice.call(arguments,0)),this._initialized=!0)};return d(c.prototype).extend(a.prototype),c},regexpFromTextOrArray:function(){function a(a){function b(a){return function(b,c){a=a.replace(h[b],c)}}for(var e=a.toLowerCase().replace(g,""),i="",j=0;j<e.length;j++){j&&(i+=f+"*");var k=e[j];d(c).each(b(k)),i+=k}return i}function b(c){switch(typeof c){case"string":return a(c);case"object":var e="";return d(c).each(function(a){var c=b(a);c&&(e&&(e+="|"),e+=c)}),e}return""}var c=["[aÔà âä]","[cƧ]","[eéèêë]","[iĆìîï]","[oóòÓö]","[uùûü]"],e=[String.fromCharCode(768),String.fromCharCode(769),String.fromCharCode(770),String.fromCharCode(771),String.fromCharCode(807),"ļ½","ļ½","ļ¼","ļ¼","ļ¼»","ļ¼½","ć","ć","ć","ć»","ā„","ć","ć","ć","ć","ć","ć","ļ¼","ļ¼","ļ¼","ć",","," ",";","(",")",".","*","+","\\","?","|","{","}","[","]","^","#","/"],f="[\\"+e.join("\\")+"]",g=new RegExp(f,"gm"),h=d(c).map(function(a){return new RegExp(a)});return function(a){var c=b(a);if(c){var d=new RegExp(c,"im"),e=new RegExp("("+c+")","igm");return{isempty:!1,source:c,test:function(a){return d.test(a)},replace:function(a,b){return a.replace(e,b)}}}return{isempty:!0,source:"",test:function(){return!0},replace:function(){return text}}}}(),_MIN_DRAG_DISTANCE:2,_NODE_BUTTON_WIDTH:40,_EDGE_BUTTON_INNER:2,_EDGE_BUTTON_OUTER:40,_CLICKMODE_ADDNODE:1,_CLICKMODE_STARTEDGE:2,_CLICKMODE_ENDEDGE:3,_NODE_SIZE_STEP:Math.LN2/4,_MIN_SCALE:.05,_MAX_SCALE:20,_MOUSEMOVE_RATE:80,_DOUBLETAP_DELAY:800,_DOUBLETAP_DISTANCE:400,_USER_PLACEHOLDER:function(a){return{color:a.options.default_user_color,title:a.translate("(unknown user)"),get:function(a){return this[a]||!1}}},_BOOKMARKLET_CODE:function(a){return"(function(a,b,c,d,e,f,h,i,j,k,l,m,n,o,p,q,r){a=document;b=a.body;c=a.location.href;j='draggable';m='text/x-iri-';d=a.createElement('div');d.innerHTML='<p_style=\"position:fixed;top:0;right:0;font:bold_18px_sans-serif;color:#fff;background:#909;padding:10px;z-index:100000;\">"+a.translate("Drag items from this website, drop them in Renkan").replace(/ /g,"_")+"</p>'.replace(/_/g,String.fromCharCode(32));b.appendChild(d);e=[{r:/https?:\\/\\/[^\\/]*twitter\\.com\\//,s:'.tweet',n:'twitter'},{r:/https?:\\/\\/[^\\/]*google\\.[^\\/]+\\//,s:'.g',n:'google'},{r:/https?:\\/\\/[^\\/]*lemonde\\.fr\\//,s:'[data-vr-contentbox]',n:'lemonde'}];f=false;e.forEach(function(g){if(g.r.test(c)){f=g;}});if(f){h=function(){Array.prototype.forEach.call(a.querySelectorAll(f.s),function(i){i[j]=true;k=i.style;k.borderWidth='2px';k.borderColor='#909';k.borderStyle='solid';k.backgroundColor='rgba(200,0,180,.1)';})};window.setInterval(h,500);h();};a.addEventListener('dragstart',function(k){l=k.dataTransfer;l.setData(m+'source-uri',c);l.setData(m+'source-title',a.title);n=k.target;if(f){o=n;while(!o.attributes[j]){o=o.parentNode;if(o==b){break;}}}if(f&&o.attributes[j]){p=o.cloneNode(true);l.setData(m+'specific-site',f.n)}else{q=a.getSelection();if(q.type==='Range'||!q.type){p=q.getRangeAt(0).cloneContents();}else{p=n.cloneNode();}}r=a.createElement('div');r.appendChild(p);l.setData('text/x-iri-selected-text',r.textContent.trim());l.setData('text/x-iri-selected-html',r.innerHTML);},false);})();"},shortenText:function(a,b){return a.length>b?a.substr(0,b)+"ā¦":a},drawEditBox:function(a,b,c,d,e){e.css({width:a.tooltip_width-2*a.tooltip_padding});var f=e.outerHeight()+2*a.tooltip_padding,g=b.x<paper.view.center.x?1:-1,h=b.x+g*(d+a.tooltip_arrow_length),i=b.x+g*(d+a.tooltip_arrow_length+a.tooltip_width),j=b.y-f/2;j+f>paper.view.size.height-a.tooltip_margin&&(j=Math.max(paper.view.size.height-a.tooltip_margin,b.y+a.tooltip_arrow_width/2)-f),j<a.tooltip_margin&&(j=Math.min(a.tooltip_margin,b.y-a.tooltip_arrow_width/2));var k=j+f;return c.segments[0].point=c.segments[7].point=b.add([g*d,0]),c.segments[1].point.x=c.segments[2].point.x=c.segments[5].point.x=c.segments[6].point.x=h,c.segments[3].point.x=c.segments[4].point.x=i,c.segments[2].point.y=c.segments[3].point.y=j,c.segments[4].point.y=c.segments[5].point.y=k,c.segments[1].point.y=b.y-a.tooltip_arrow_width/2,c.segments[6].point.y=b.y+a.tooltip_arrow_width/2,c.closed=!0,c.fillColor=new paper.GradientColor(new paper.Gradient([a.tooltip_top_color,a.tooltip_bottom_color]),[0,j],[0,k]),e.css({left:a.tooltip_padding+Math.min(h,i),top:a.tooltip_padding+j}),c -}}}(window),function(){"use strict";var a=this,b=a.Backbone,c=a.Rkns.Models={};c.getUID=function(a){var b="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=16*Math.random()|0,c="x"===a?b:3&b|8;return c.toString(16)});return"undefined"!=typeof a?a.type+"-"+b:b};{var d=b.RelationalModel.extend({idAttribute:"_id",constructor:function(a){"undefined"!=typeof a&&(a._id=a._id||a.id||c.getUID(this),a.title=a.title||"",a.description=a.description||"",a.uri=a.uri||"","function"==typeof this.prepare&&(a=this.prepare(a))),b.RelationalModel.prototype.constructor.call(this,a)},validate:function(){return this.type?void 0:"object has no type"},addReference:function(a,b,c,d,e){var f=c.get(d);a[b]="undefined"==typeof f&&"undefined"!=typeof e?e:f}}),e=c.User=d.extend({type:"user",prepare:function(a){return a.color=a.color||"#666666",a},toJSON:function(){return{_id:this.get("_id"),title:this.get("title"),uri:this.get("uri"),description:this.get("description"),color:this.get("color")}}}),f=c.Node=d.extend({type:"node",relations:[{type:b.HasOne,key:"created_by",relatedModel:e}],prepare:function(a){var b=a.project;return this.addReference(a,"created_by",b.get("users"),a.created_by,b.current_user),a.description=a.description||"",a},toJSON:function(){return{_id:this.get("_id"),title:this.get("title"),uri:this.get("uri"),description:this.get("description"),position:this.get("position"),image:this.get("image"),color:this.get("color"),created_by:this.get("created_by")?this.get("created_by").get("_id"):null,size:this.get("size"),clip_path:this.get("clip_path"),shape:this.get("shape")}}}),g=c.Edge=d.extend({type:"edge",relations:[{type:b.HasOne,key:"created_by",relatedModel:e},{type:b.HasOne,key:"from",relatedModel:f},{type:b.HasOne,key:"to",relatedModel:f}],prepare:function(a){var b=a.project;return this.addReference(a,"created_by",b.get("users"),a.created_by,b.current_user),this.addReference(a,"from",b.get("nodes"),a.from),this.addReference(a,"to",b.get("nodes"),a.to),a},toJSON:function(){return{_id:this.get("_id"),title:this.get("title"),uri:this.get("uri"),description:this.get("description"),from:this.get("from")?this.get("from").get("_id"):null,to:this.get("to")?this.get("to").get("_id"):null,color:this.get("color"),created_by:this.get("created_by")?this.get("created_by").get("_id"):null}}}),h=c.View=d.extend({type:"view",relations:[{type:b.HasOne,key:"created_by",relatedModel:e}],prepare:function(a){var b=a.project;if(this.addReference(a,"created_by",b.get("users"),a.created_by,b.current_user),a.description=a.description||"","undefined"!=typeof a.offset){var c={};Array.isArray(a.offset)?(c.x=a.offset[0],c.y=a.offset.length>1?a.offset[1]:a.offset[0]):null!=a.offset.x&&(c.x=a.offset.x,c.y=a.offset.y),a.offset=c}return a},toJSON:function(){return{_id:this.get("_id"),zoom_level:this.get("zoom_level"),offset:this.get("offset"),title:this.get("title"),description:this.get("description"),created_by:this.get("created_by")?this.get("created_by").get("_id"):null}}}),i=(c.Project=d.extend({type:"project",blacklist:["save_status"],relations:[{type:b.HasMany,key:"users",relatedModel:e,reverseRelation:{key:"project",includeInJSON:"_id"}},{type:b.HasMany,key:"nodes",relatedModel:f,reverseRelation:{key:"project",includeInJSON:"_id"}},{type:b.HasMany,key:"edges",relatedModel:g,reverseRelation:{key:"project",includeInJSON:"_id"}},{type:b.HasMany,key:"views",relatedModel:h,reverseRelation:{key:"project",includeInJSON:"_id"}}],addUser:function(a,b){a.project=this;var c=e.findOrCreate(a);return this.get("users").push(c,b),c},addNode:function(a,b){a.project=this;var c=f.findOrCreate(a);return this.get("nodes").push(c,b),c},addEdge:function(a,b){a.project=this;var c=g.findOrCreate(a);return this.get("edges").push(c,b),c},addView:function(a,b){a.project=this;var c=h.findOrCreate(a);return this.get("views").push(c,b),c},removeNode:function(a){this.get("nodes").remove(a)},removeEdge:function(a){this.get("edges").remove(a)},validate:function(a){var b=this;_([].concat(a.users,a.nodes,a.edges,a.views)).each(function(a){a&&(a.project=b)})},initialize:function(){var a=this;this.on("remove:nodes",function(b){a.get("edges").remove(a.get("edges").filter(function(a){return a.get("from")===b||a.get("to")===b}))})},toJSON:function(){var a=_.clone(this.attributes);for(var c in a)(a[c]instanceof b.Model||a[c]instanceof b.Collection||a[c]instanceof d)&&(a[c]=a[c].toJSON());return _.omit(a,this.blacklist)}}),c.RosterUser=b.Model.extend({type:"roster_user",idAttribute:"_id",constructor:function(a){"undefined"!=typeof a&&(a._id=a._id||a.id||c.getUID(this),a.title=a.title||"(untitled "+this.type+")",a.description=a.description||"",a.uri=a.uri||"",a.project=a.project||null,a.site_id=a.site_id||0,"function"==typeof this.prepare&&(a=this.prepare(a))),b.Model.prototype.constructor.call(this,a)},validate:function(){return this.type?void 0:"object has no type"},prepare:function(a){return a.color=a.color||"#666666",a},toJSON:function(){return{_id:this.get("_id"),title:this.get("title"),uri:this.get("uri"),description:this.get("description"),color:this.get("color"),project:null!=this.get("project")?this.get("project").get("id"):null,site_id:this.get("site_id")}}}));c.UsersList=b.Collection.extend({model:i})}}.call(window),Rkns.defaults={language:navigator.language||navigator.userLanguage||"en",container:"renkan",search:[],bins:[],static_url:"",show_bins:!0,properties:[],show_editor:!0,read_only:!1,editor_mode:!0,manual_save:!1,show_top_bar:!0,default_user_color:"#303030",size_bug_fix:!0,force_resize:!1,allow_double_click:!0,zoom_on_scroll:!0,element_delete_delay:0,autoscale_padding:50,resize:!0,show_zoom:!0,save_view:!0,default_view:!1,show_search_field:!0,show_user_list:!0,user_name_editable:!0,user_color_editable:!0,show_user_color:!0,show_save_button:!0,show_export_button:!0,show_open_button:!1,show_addnode_button:!0,show_addedge_button:!0,show_bookmarklet:!0,show_fullscreen_button:!0,home_button_url:!1,home_button_title:"Home",show_minimap:!0,minimap_width:160,minimap_height:120,minimap_padding:20,minimap_background_color:"#ffffff",minimap_border_color:"#cccccc",minimap_highlight_color:"#ffff00",minimap_highlight_weight:5,buttons_background:"#202020",buttons_label_color:"#c000c0",buttons_label_font_size:9,show_node_circles:!0,clip_node_images:!0,node_images_fill_mode:!1,node_size_base:25,node_stroke_width:2,selected_node_stroke_width:4,node_fill_color:"#ffffff",highlighted_node_fill_color:"#ffff00",node_label_distance:5,node_label_max_length:60,label_untitled_nodes:"(untitled)",change_shapes:!0,edge_stroke_width:2,selected_edge_stroke_width:4,edge_label_distance:0,edge_label_max_length:20,edge_arrow_length:18,edge_arrow_width:12,edge_gap_in_bundles:12,label_untitled_edges:"",tooltip_width:275,tooltip_padding:10,tooltip_margin:15,tooltip_arrow_length:20,tooltip_arrow_width:40,tooltip_top_color:"#f0f0f0",tooltip_bottom_color:"#d0d0d0",tooltip_border_color:"#808080",tooltip_border_width:1,show_node_editor_uri:!0,show_node_editor_description:!0,show_node_editor_size:!0,show_node_editor_color:!0,show_node_editor_image:!0,show_node_editor_creator:!0,allow_image_upload:!0,uploaded_image_max_kb:500,show_node_tooltip_uri:!0,show_node_tooltip_description:!0,show_node_tooltip_color:!0,show_node_tooltip_image:!0,show_node_tooltip_creator:!0,show_edge_editor_uri:!0,show_edge_editor_color:!0,show_edge_editor_direction:!0,show_edge_editor_nodes:!0,show_edge_editor_creator:!0,show_edge_tooltip_uri:!0,show_edge_tooltip_color:!0,show_edge_tooltip_nodes:!0,show_edge_tooltip_creator:!0},Rkns.i18n={fr:{"Edit Node":"Ćdition dāun nÅud","Edit Edge":"Ćdition dāun lien","Title:":"Titre :","URI:":"URI :","Description:":"Description :","From:":"De :","To:":"Vers :",Image:"Image","Image URL:":"URL d'Image","Choose Image File:":"Choisir un fichier image","Full Screen":"Mode plein Ć©cran","Add Node":"Ajouter un nÅud","Add Edge":"Ajouter un lien","Save Project":"Enregistrer le projet","Open Project":"Ouvrir un projet","Auto-save enabled":"Enregistrement automatique activĆ©","Connection lost":"Connexion perdue","Created by:":"CrƩƩ par :","Zoom In":"Agrandir lāĆ©chelle","Zoom Out":"Rapetisser lāĆ©chelle",Edit:"Ćditer",Remove:"Supprimer","Cancel deletion":"Annuler la suppression","Link to another node":"CrĆ©er un lien",Enlarge:"Agrandir",Shrink:"RĆ©trĆ©cir","Click on the background canvas to add a node":"Cliquer sur le fond du graphe pour rajouter un nÅud","Click on a first node to start the edge":"Cliquer sur un premier nÅud pour commencer le lien","Click on a second node to complete the edge":"Cliquer sur un second nÅud pour terminer le lien",Wikipedia:"WikipĆ©dia","Wikipedia in ":"WikipĆ©dia en ",French:"FranƧais",English:"Anglais",Japanese:"Japonais","Untitled project":"Projet sans titre","Lignes de Temps":"Lignes de Temps","Loading, please wait":"Chargement en cours, merci de patienter","Edge color:":"Couleur :","Node color:":"Couleur :","Choose color":"Choisir une couleur","Change edge direction":"Changer le sens du lien","Do you really wish to remove node ":"Voulez-vous rĆ©ellement supprimer le nÅud ","Do you really wish to remove edge ":"Voulez-vous rĆ©ellement supprimer le lien ","This file is not an image":"Ce fichier n'est pas une image","Image size must be under ":"L'image doit peser moins de ","Size:":"Taille :",KB:"ko","Choose from vocabulary:":"Choisir dans un vocabulaire :","SKOS Documentation properties":"SKOS: PropriĆ©tĆ©s documentaires","has note":"a pour note","has example":"a pour exemple","has definition":"a pour dĆ©finition","SKOS Semantic relations":"SKOS: Relations sĆ©mantiques","has broader":"a pour concept plus large","has narrower":"a pour concept plus Ć©troit","has related":"a pour concept apparentĆ©","Dublin Core Metadata":"MĆ©tadonnĆ©es Dublin Core","has contributor":"a pour contributeur",covers:"couvre","created by":"crƩƩ par","has date":"a pour date","published by":"Ć©ditĆ© par","has source":"a pour source","has subject":"a pour sujet","Dragged resource":"Ressource glisĆ©e-dĆ©posĆ©e","Search the Web":"Rechercher en ligne","Search in Bins":"Rechercher dans les chutiers","Close bin":"Fermer le chutier","Refresh bin":"RafraĆ®chir le chutier","(untitled)":"(sans titre)","Select contents:":"SĆ©lectionner des contenus :","Drag items from this website, drop them in Renkan":"Glissez des Ć©lĆ©ments de ce site web vers Renkan","Drag this button to your bookmark bar. When on a third-party website, click it to enable drag-and-drop from the website to Renkan.":"Glissez ce bouton vers votre barre de favoris. Ensuite, depuis un site tiers, cliquez dessus pour activer 'Drag-to-Add' puis glissez des Ć©lĆ©ments de ce site vers Renkan","Shapes available":"Formes disponibles",Circle:"Cercle",Square:"CarrĆ©",Diamond:"Losange",Hexagone:"Hexagone",Ellipse:"Ellipse",Star:"Ćtoile","Zoom Fit":"Ajuster le Zoom","Download Project":"TĆ©lĆ©charger le projet","Zoom Save":"Sauver le Zoom","View saved zoom":"Restaurer le Zoom","Renkan 'Drag-to-Add' bookmarklet":"Renkan 'Deplacer-Pour-Ajouter' Signet","(unknown user)":"(non authentifiĆ©)","<unknown user>":"<non authentifiĆ©>","Search in graph":"Rechercher dans carte","Search in ":"Chercher dans "}},Rkns.jsonIO=function(a,b){var c=a.project;"undefined"==typeof b.http_method&&(b.http_method="PUT");var d=function(){a.renderer.redrawActive=!1,c.set({loading_status:!0}),Rkns.$.getJSON(b.url,function(b){c.set(b,{validate:!0}),c.set({loading_status:!1}),c.set({save_status:0}),a.renderer.redrawActive=!0,a.renderer.fixSize()})},e=function(){c.set({save_status:2});var d=c.toJSON();a.read_only||Rkns.$.ajax({type:b.http_method,url:b.url,contentType:"application/json",data:JSON.stringify(d),success:function(){c.set({save_status:0})}})},f=Rkns._.throttle(function(){setTimeout(e,100)},1e3);c.on("add:nodes add:edges add:users add:views",function(a){a.on("change remove",function(){f()}),f()}),c.on("change",function(){1===c.changedAttributes.length&&c.hasChanged("save_status")||f()}),d()},Rkns.jsonIOSaveOnClick=function(a,b){var c=a.project,d=!1,e=function(){return"Project not saved"};"undefined"==typeof b.http_method&&(b.http_method="POST");var f=function(){var d={},e=/id=([^&#?=]+)/,f=document.location.hash.match(e);f&&(d.id=f[1]),Rkns.$.ajax({url:b.url,data:d,beforeSend:function(){c.set({loading_status:!0})},success:function(b){c.set(b,{validate:!0}),c.set({loading_status:!1}),c.set({save_status:0}),a.renderer.autoScale()}})},g=function(){c.set("saved_at",new Date);var a=c.toJSON();Rkns.$.ajax({type:b.http_method,url:b.url,contentType:"application/json",data:JSON.stringify(a),beforeSend:function(){c.set({save_status:2})},success:function(){$(window).off("beforeunload",e),d=!1,c.set({save_status:0})}})},h=function(){c.set({save_status:1});var a=c.get("title");a&&c.get("nodes").length?$(".Rk-Save-Button").removeClass("disabled"):$(".Rk-Save-Button").addClass("disabled"),a&&$(".Rk-PadTitle").css("border-color","#333333"),d||(d=!0,$(window).on("beforeunload",e))};f(),c.on("add:nodes add:edges add:users change",function(a){a.on("change remove",function(a){1===a.changedAttributes.length&&a.hasChanged("save_status")||h()}),1===c.changedAttributes.length&&c.hasChanged("save_status")||h()}),a.renderer.save=function(){$(".Rk-Save-Button").hasClass("disabled")?c.get("title")||$(".Rk-PadTitle").css("border-color","#ff0000"):g()}},function(a){"use strict";var b=a._,c=a.Ldt={},d=(c.Bin=function(a,b){if(b.ldt_type){var d=c[b.ldt_type+"Bin"];if(d)return new d(a,b)}console.error("No such LDT Bin Type")},c.ProjectBin=a.Utils.inherit(a._BaseBin));d.prototype.tagTemplate=renkanJST["templates/ldtjson-bin/tagtemplate.html"],d.prototype.annotationTemplate=renkanJST["templates/ldtjson-bin/annotationtemplate.html"],d.prototype._init=function(a,b){this.renkan=a,this.proj_id=b.project_id,this.ldt_platform=b.ldt_platform||"http://ldt.iri.centrepompidou.fr/",this.title_$.html(b.title),this.title_icon_$.addClass("Rk-Ldt-Title-Icon"),this.refresh()},d.prototype.render=function(c){function d(a){var c=b(a).escape();return f.isempty?c:f.replace(c,"<span class='searchmatch'>$1</span>")}function e(a){function b(a){for(var b=a.toString();b.length<2;)b="0"+b;return b}var c=Math.abs(Math.floor(a/1e3)),d=Math.floor(c/3600),e=Math.floor(c/60)%60,f=c%60,g="";return d&&(g+=b(d)+":"),g+=b(e)+":"+b(f)}var f=c||a.Utils.regexpFromTextOrArray(),g="<li><h3>Tags</h3></li>",h=this.data.meta["dc:title"],i=this,j=0;i.title_$.text('LDT Project: "'+h+'"'),b(i.data.tags).map(function(a){var b=a.meta["dc:title"];(f.isempty||f.test(b))&&(j++,g+=i.tagTemplate({ldt_platform:i.ldt_platform,title:b,htitle:d(b),encodedtitle:encodeURIComponent(b),static_url:i.renkan.options.static_url}))}),g+="<li><h3>Annotations</h3></li>",b(i.data.annotations).map(function(a){var b=a.content.description,c=a.content.title.replace(b,"");if(f.isempty||f.test(c)||f.test(b)){j++;var h=a.end-a.begin,k=a.content&&a.content.img&&a.content.img.src?a.content.img.src:h?i.renkan.options.static_url+"img/ldt-segment.png":i.renkan.options.static_url+"img/ldt-point.png";g+=i.annotationTemplate({ldt_platform:i.ldt_platform,title:c,htitle:d(c),description:b,hdescription:d(b),start:e(a.begin),end:e(a.end),duration:e(h),mediaid:a.media,annotationid:a.id,image:k,static_url:i.renkan.options.static_url})}}),this.main_$.html(g),!f.isempty&&j?this.count_$.text(j).show():this.count_$.hide(),f.isempty||j?this.$.show():this.$.hide(),this.renkan.resizeBins()},d.prototype.refresh=function(){var b=this;a.$.ajax({url:this.ldt_platform+"ldtplatform/ldt/cljson/id/"+this.proj_id,dataType:"jsonp",success:function(a){b.data=a,b.render()}})};var e=c.Search=function(a,b){this.renkan=a,this.lang=b.lang||"en"};e.prototype.getBgClass=function(){return"Rk-Ldt-Icon"},e.prototype.getSearchTitle=function(){return this.renkan.translate("Lignes de Temps")},e.prototype.search=function(a){this.renkan.tabs.push(new f(this.renkan,{search:a}))};var f=c.ResultsBin=a.Utils.inherit(a._BaseBin);f.prototype.segmentTemplate=renkanJST["templates/ldtjson-bin/segmenttemplate.html"],f.prototype._init=function(a,b){this.renkan=a,this.ldt_platform=b.ldt_platform||"http://ldt.iri.centrepompidou.fr/",this.max_results=b.max_results||50,this.search=b.search,this.title_$.html('Lignes de Temps: "'+b.search+'"'),this.title_icon_$.addClass("Rk-Ldt-Title-Icon"),this.refresh()},f.prototype.render=function(c){function d(a){return g.replace(b(a).escape(),"<span class='searchmatch'>$1</span>")}function e(a){function b(a){for(var b=a.toString();b.length<2;)b="0"+b;return b}var c=Math.abs(Math.floor(a/1e3)),d=Math.floor(c/3600),e=Math.floor(c/60)%60,f=c%60,g="";return d&&(g+=b(d)+":"),g+=b(e)+":"+b(f)}if(this.data){var f=c||a.Utils.regexpFromTextOrArray(),g=f.isempty?a.Utils.regexpFromTextOrArray(this.search):f,h="",i=this,j=0;b(this.data.objects).each(function(a){var b=a["abstract"],c=a.title;if(f.isempty||f.test(c)||f.test(b)){j++;var g=a.duration,k=a.start_ts,l=+a.duration+k,m=g?i.renkan.options.static_url+"img/ldt-segment.png":i.renkan.options.static_url+"img/ldt-point.png";h+=i.segmentTemplate({ldt_platform:i.ldt_platform,title:c,htitle:d(c),description:b,hdescription:d(b),start:e(k),end:e(l),duration:e(g),mediaid:a.iri_id,annotationid:a.element_id,image:m})}}),this.main_$.html(h),!f.isempty&&j?this.count_$.text(j).show():this.count_$.hide(),f.isempty||j?this.$.show():this.$.hide(),this.renkan.resizeBins()}},f.prototype.refresh=function(){var b=this;a.$.ajax({url:this.ldt_platform+"ldtplatform/api/ldt/1.0/segments/search/",data:{format:"jsonp",q:this.search,limit:this.max_results},dataType:"jsonp",success:function(a){b.data=a,b.render()}})}}(window.Rkns),Rkns.ResourceList={},Rkns.ResourceList.Bin=Rkns.Utils.inherit(Rkns._BaseBin),Rkns.ResourceList.Bin.prototype.resultTemplate=renkanJST["templates/list-bin.html"],Rkns.ResourceList.Bin.prototype._init=function(a,b){this.renkan=a,this.title_$.html(b.title),b.list&&(this.data=b.list),this.refresh()},Rkns.ResourceList.Bin.prototype.render=function(a){function b(a){var b=_(a).escape();return c.isempty?b:c.replace(b,"<span class='searchmatch'>$1</span>")}var c=a||Rkns.Utils.regexpFromTextOrArray(),d="",e=this,f=0;Rkns._(this.data).each(function(a){var g;if("string"==typeof a)if(/^(https?:\/\/|www)/.test(a))g={url:a};else{g={title:a.replace(/[:,]?\s?(https?:\/\/|www)[\d\w\/.&?=#%-_]+\s?/,"").trim()};var h=a.match(/(https?:\/\/|www)[\d\w\/.&?=#%-_]+/);h&&(g.url=h[0]),g.title.length>80&&(g.description=g.title,g.title=g.title.replace(/^(.{30,60})\s.+$/,"$1ā¦"))}else g=a;var i=g.title||(g.url||"").replace(/^https?:\/\/(www\.)?/,"").replace(/^(.{40}).+$/,"$1ā¦"),j=g.url||"",k=g.description||"",l=g.image||"";j&&!/^https?:\/\//.test(j)&&(j="http://"+j),(c.isempty||c.test(i)||c.test(k))&&(f++,d+=e.resultTemplate({url:j,title:i,htitle:b(i),image:l,description:k,hdescription:b(k),static_url:e.renkan.options.static_url}))}),e.main_$.html(d),!c.isempty&&f?this.count_$.text(f).show():this.count_$.hide(),c.isempty||f?this.$.show():this.$.hide(),this.renkan.resizeBins()},Rkns.ResourceList.Bin.prototype.refresh=function(){this.data&&this.render()},Rkns.Wikipedia={},Rkns.Wikipedia.Search=function(a,b){this.renkan=a,this.lang=b.lang||"en"},Rkns.Wikipedia.Search.prototype.getBgClass=function(){return"Rk-Wikipedia-Search-Icon Rk-Wikipedia-Lang-"+this.lang},Rkns.Wikipedia.Search.prototype.getSearchTitle=function(){var a={fr:"French",en:"English",ja:"Japanese"};return a[this.lang]?this.renkan.translate("Wikipedia in ")+this.renkan.translate(a[this.lang]):this.renkan.translate("Wikipedia")+" ["+this.lang+"]"},Rkns.Wikipedia.Search.prototype.search=function(a){this.renkan.tabs.push(new Rkns.Wikipedia.Bin(this.renkan,{lang:this.lang,search:a}))},Rkns.Wikipedia.Bin=Rkns.Utils.inherit(Rkns._BaseBin),Rkns.Wikipedia.Bin.prototype.resultTemplate=renkanJST["templates/wikipedia-bin/resulttemplate.html"],Rkns.Wikipedia.Bin.prototype._init=function(a,b){this.renkan=a,this.search=b.search,this.lang=b.lang||"en",this.title_icon_$.addClass("Rk-Wikipedia-Title-Icon Rk-Wikipedia-Lang-"+this.lang),this.title_$.html(this.search).addClass("Rk-Wikipedia-Title"),this.refresh()},Rkns.Wikipedia.Bin.prototype.render=function(a){function b(a){return d.replace(_(a).escape(),"<span class='searchmatch'>$1</span>")}var c=a||Rkns.Utils.regexpFromTextOrArray(),d=c.isempty?Rkns.Utils.regexpFromTextOrArray(this.search):c,e="",f=this,g=0;Rkns._(this.data.query.search).each(function(a){var d=a.title,h="http://"+f.lang+".wikipedia.org/wiki/"+encodeURI(d.replace(/ /g,"_")),i=Rkns.$("<div>").html(a.snippet).text();(c.isempty||c.test(d)||c.test(i))&&(g++,e+=f.resultTemplate({url:h,title:d,htitle:b(d),description:i,hdescription:b(i),static_url:f.renkan.options.static_url}))}),f.main_$.html(e),!c.isempty&&g?this.count_$.text(g).show():this.count_$.hide(),c.isempty||g?this.$.show():this.$.hide(),this.renkan.resizeBins()},Rkns.Wikipedia.Bin.prototype.refresh=function(){var a=this;Rkns.$.ajax({url:"http://"+a.lang+".wikipedia.org/w/api.php?action=query&list=search&srsearch="+encodeURIComponent(this.search)+"&format=json",dataType:"jsonp",success:function(b){a.data=b,a.render()}})},define("renderer/baserepresentation",["jquery","underscore"],function(a,b){var c=function(a,c){if("undefined"!=typeof a&&(this.renderer=a,this.renkan=a.renkan,this.project=a.renkan.project,this.options=a.renkan.options,this.model=c,this.model)){var d=this;this._changeBinding=function(){d.redraw()},this._removeBinding=function(){a.removeRepresentation(d),b(function(){a.redraw()}).defer()},this._selectBinding=function(){d.select()},this._unselectBinding=function(){d.unselect()},this.model.on("change",this._changeBinding),this.model.on("remove",this._removeBinding),this.model.on("select",this._selectBinding),this.model.on("unselect",this._unselectBinding)}};return b(c.prototype).extend({_super:function(a){return c.prototype[a].apply(this,Array.prototype.slice.call(arguments,1))},redraw:function(){},moveTo:function(){},show:function(){return"BaseRepresentation.show"},hide:function(){},select:function(){this.model&&this.model.trigger("selected")},unselect:function(){this.model&&this.model.trigger("unselected")},highlight:function(){},unhighlight:function(){},mousedown:function(){},mouseup:function(){this.model&&this.model.trigger("clicked")},destroy:function(){this.model&&(this.model.off("change",this._changeBinding),this.model.off("remove",this._removeBinding),this.model.off("select",this._selectBinding),this.model.off("unselect",this._unselectBinding))}}),c}),define("requtils",[],function(){return{getUtils:function(){return window.Rkns.Utils},getRenderer:function(){return window.Rkns.Renderer}}}),define("renderer/basebutton",["jquery","underscore","requtils","renderer/baserepresentation"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({moveTo:function(a){this.sector.moveTo(a)},show:function(){this.sector.show()},hide:function(){this.sector.hide()},select:function(){this.sector.select()},unselect:function(a){this.sector.unselect(),(!a||a!==this.source_representation&&a.source_representation!==this.source_representation)&&this.source_representation.unselect()},destroy:function(){this.sector.destroy()}}),f}),define("renderer/shapebuilder",[],function(){var a={circle:{getShape:function(){return new paper.Path.Circle([0,0],1)},getImageShape:function(a,b){return new paper.Path.Circle(a,b)}},rectangle:{getShape:function(){return new paper.Path.Rectangle([-2,-2],[2,2])},getImageShape:function(a,b){return new paper.Path.Rectangle([-b,-b],[2*b,2*b])}},ellipse:{getShape:function(){return new paper.Path.Ellipse(new paper.Rectangle([-2,-1],[2,1]))},getImageShape:function(a,b){return new paper.Path.Ellipse(new paper.Rectangle([-b,-b/2],[2*b,b]))}},polygon:{getShape:function(){return new paper.Path.RegularPolygon([0,0],6,1)},getImageShape:function(a,b){return new paper.Path.RegularPolygon([0,0],6,b)}},diamond:{getShape:function(){var a=new paper.Path.Rectangle([-2,-2],[2,2]);return a.rotate(45),a},getImageShape:function(a,b){var c=new paper.Path.Rectangle([-b,-b],[2*b,2*b]);return c.rotate(45),c}},star:{getShape:function(){return new paper.Path.Star([0,0],8,1,.7)},getImageShape:function(a,b){return new paper.Path.Star([0,0],8,1*b,.7*b)}},svg:function(a){return{getShape:function(){return new paper.Path(a)},getImageShape:function(){return new paper.Path}}}},b=function(b){return"undefined"==typeof b&&(b="circle"),"svg:"===b.substr(0,4)?a.svg(b.substr(4)):(b in a||(b="circle"),a[b])};return b}),define("renderer/noderepr",["jquery","underscore","requtils","renderer/baserepresentation","renderer/shapebuilder"],function(a,b,c,d,e){var f=c.getUtils(),g=f.inherit(d);return b(g.prototype).extend({_init:function(){if(this.renderer.node_layer.activate(),this.type="Node",this.buildShape(),this.options.show_node_circles?(this.circle.strokeWidth=this.options.node_stroke_width,this.h_ratio=1):this.h_ratio=0,this.title=a('<div class="Rk-Label">').appendTo(this.renderer.labels_$),this.options.editor_mode){var b=c.getRenderer();this.normal_buttons=[new b.NodeEditButton(this.renderer,null),new b.NodeRemoveButton(this.renderer,null),new b.NodeLinkButton(this.renderer,null),new b.NodeEnlargeButton(this.renderer,null),new b.NodeShrinkButton(this.renderer,null)],this.pending_delete_buttons=[new b.NodeRevertButton(this.renderer,null)],this.all_buttons=this.normal_buttons.concat(this.pending_delete_buttons);for(var d=0;d<this.all_buttons.length;d++)this.all_buttons[d].source_representation=this;this.active_buttons=[]}else this.active_buttons=this.all_buttons=[];this.last_circle_radius=1,this.renderer.minimap&&(this.renderer.minimap.node_layer.activate(),this.minimap_circle=new paper.Path.Circle([0,0],1),this.minimap_circle.__representation=this.renderer.minimap.miniframe.__representation,this.renderer.minimap.node_group.addChild(this.minimap_circle))},buildShape:function(){"undefined"!=typeof this.model.get("shape_changed")&&this.model.get("shape_changed")===!0&&(this.model.set("shape_changed",!1),delete this.img),this.circle&&(this.circle.remove(),delete this.circle),this.shapeBuilder=new e(this.model.get("shape")),this.circle=this.shapeBuilder.getShape(),this.circle.__representation=this,this.last_circle_radius=1},redraw:function(a){"undefined"!=typeof this.model.get("shape_changed")&&this.model.get("shape_changed")===!0&&this.buildShape();var c=new paper.Point(this.model.get("position")),d=this.options.node_size_base*Math.exp((this.model.get("size")||0)*f._NODE_SIZE_STEP);this.is_dragging&&this.paper_coords||(this.paper_coords=this.renderer.toPaperCoords(c)),this.circle_radius=d*this.renderer.scale,this.last_circle_radius!==this.circle_radius&&(this.all_buttons.forEach(function(a){a.setSectorSize()}),this.circle.scale(this.circle_radius/this.last_circle_radius),this.node_image&&this.node_image.scale(this.circle_radius/this.last_circle_radius)),this.circle.position=this.paper_coords,this.node_image&&(this.node_image.position=this.paper_coords.subtract(this.image_delta.multiply(this.circle_radius))),this.last_circle_radius=this.circle_radius;var e=this.active_buttons,g=1;this.model.get("delete_scheduled")?(g=.5,this.active_buttons=this.pending_delete_buttons,this.circle.dashArray=[2,2]):(g=1,this.active_buttons=this.normal_buttons,this.circle.dashArray=null),this.selected&&this.renderer.isEditable()&&(e!==this.active_buttons&&e.forEach(function(a){a.hide()}),this.active_buttons.forEach(function(a){a.show()})),this.node_image&&(this.node_image.opacity=this.highlighted?.5*g:g-.01),this.circle.fillColor=this.highlighted?this.options.highlighted_node_fill_color:this.options.node_fill_color,this.circle.opacity=this.options.show_node_circles?g:.01;var h=this.model.get("title")||this.renkan.translate(this.options.label_untitled_nodes)||"";h=f.shortenText(h,this.options.node_label_max_length),"object"==typeof this.highlighted?this.title.html(this.highlighted.replace(b(h).escape(),'<span class="Rk-Highlighted">$1</span>')):this.title.text(h),this.title.css({left:this.paper_coords.x,top:this.paper_coords.y+this.circle_radius*this.h_ratio+this.options.node_label_distance,opacity:g});var i=this.model.get("color")||(this.model.get("created_by")||f._USER_PLACEHOLDER(this.renkan)).get("color");this.circle.strokeColor=i;var j=this.paper_coords;this.all_buttons.forEach(function(a){a.moveTo(j)});var k=this.img;if(this.img=this.model.get("image"),this.img&&this.img!==k&&this.showImage(),this.node_image&&!this.img&&(this.node_image.remove(),delete this.node_image),this.renderer.minimap){this.minimap_circle.fillColor=i;var l=this.renderer.toMinimapCoords(c),m=this.renderer.minimap.scale*d,n=new paper.Size([m,m]);this.minimap_circle.fitBounds(l.subtract(n),n.multiply(2))}if(!a){var o=this;b.each(this.project.get("edges").filter(function(a){return a.get("to")===o.model||a.get("from")===o.model}),function(a){var b=o.renderer.getRepresentationByModel(a);b&&"undefined"!=typeof b.from_representation&&"undefined"!=typeof b.from_representation.paper_coords&&"undefined"!=typeof b.to_representation&&"undefined"!=typeof b.to_representation.paper_coords&&b.redraw()})}},showImage:function(){var b=null;if("undefined"==typeof this.renderer.image_cache[this.img]?(b=new Image,this.renderer.image_cache[this.img]=b,b.src=this.img):b=this.renderer.image_cache[this.img],b.width){this.node_image&&this.node_image.remove(),this.renderer.node_layer.activate();var c=b.width,d=b.height,e=this.model.get("clip_path"),f="undefined"!=typeof e&&e,g=null,h=null,i=null;if(f){g=new paper.Path;var j=e.match(/[a-z][^a-z]+/gi)||[],k=[0,0],l=1/0,m=1/0,n=-1/0,o=-1/0,p=function(a,b){var e=a.slice(1).map(function(a,e){var f=parseFloat(a),g=e%2;return f=g?(f-.5)*d:(f-.5)*c,b&&(f+=k[g]),g?(m=Math.min(m,f),o=Math.max(o,f)):(l=Math.min(l,f),n=Math.max(n,f)),f});return k=e.slice(-2),e};j.forEach(function(a){var b=a.match(/([a-z]|[0-9.-]+)/gi)||[""];switch(b[0]){case"M":g.moveTo(p(b));break;case"m":g.moveTo(p(b,!0));break;case"L":g.lineTo(p(b));break;case"l":g.lineTo(p(b,!0));break;case"C":g.cubicCurveTo(p(b));break;case"c":g.cubicCurveTo(p(b,!0));break;case"Q":g.quadraticCurveTo(p(b));break;case"q":g.quadraticCurveTo(p(b,!0))}}),h=Math[this.options.node_images_fill_mode?"min":"max"](n-l,o-m)/2,i=new paper.Point((n+l)/2,(o+m)/2),this.options.show_node_circles||(this.h_ratio=(o-m)/(2*h))}else h=Math[this.options.node_images_fill_mode?"min":"max"](c,d)/2,i=new paper.Point(0,0),this.options.show_node_circles||(this.h_ratio=d/(2*h));var q=new paper.Raster(b);if(q.locked=!0,f&&(q=new paper.Group(g,q),q.opacity=.99,q.clipped=!0,g.__representation=this),this.options.clip_node_images){var r=this.shapeBuilder.getImageShape(i,h);q=new paper.Group(r,q),q.opacity=.99,q.clipped=!0,r.__representation=this}this.image_delta=i.divide(h),this.node_image=q,this.node_image.__representation=s,this.node_image.scale(this.circle_radius/h),this.node_image.position=this.paper_coords.subtract(this.image_delta.multiply(this.circle_radius)),this.redraw(),this.renderer.throttledPaperDraw()}else{var s=this;a(b).on("load",function(){s.showImage()})}},paperShift:function(a){this.options.editor_mode?this.renkan.read_only||(this.is_dragging=!0,this.paper_coords=this.paper_coords.add(a),this.redraw()):this.renderer.paperShift(a)},openEditor:function(){this.renderer.removeRepresentationsOfType("editor");var a=this.renderer.addRepresentation("NodeEditor",null);a.source_representation=this,a.draw()},select:function(){this.selected=!0,this.circle.strokeWidth=this.options.selected_node_stroke_width,this.renderer.isEditable()&&this.active_buttons.forEach(function(a){a.show()});var b=this.model.get("uri");b&&a(".Rk-Bin-Item").each(function(){var c=a(this);c.attr("data-uri")===b&&c.addClass("selected")}),this.options.editor_mode||this.openEditor(),this.renderer.minimap&&(this.minimap_circle.strokeWidth=this.options.minimap_highlight_weight,this.minimap_circle.strokeColor=this.options.minimap_highlight_color),this._super("select")},hideButtons:function(){this.all_buttons.forEach(function(a){a.hide()}),delete this.buttonTimeout},unselect:function(b){if(!b||b.source_representation!==this){this.selected=!1; -var c=this;this.buttons_timeout=setTimeout(function(){c.hideButtons()},200),this.circle.strokeWidth=this.options.node_stroke_width,a(".Rk-Bin-Item").removeClass("selected"),this.renderer.minimap&&(this.minimap_circle.strokeColor=void 0),this._super("unselect")}},highlight:function(a){var b=a||!0;this.highlighted!==b&&(this.highlighted=b,this.redraw(),this.renderer.throttledPaperDraw())},unhighlight:function(){this.highlighted&&(this.highlighted=!1,this.redraw(),this.renderer.throttledPaperDraw())},saveCoords:function(){var a=this.renderer.toModelCoords(this.paper_coords),b={position:{x:a.x,y:a.y}};this.renderer.isEditable()&&this.model.set(b)},mousedown:function(a,b){b&&(this.renderer.unselectAll(),this.select())},mouseup:function(a,b){this.renderer.is_dragging&&this.renderer.isEditable()?this.saveCoords():(b||this.model.get("delete_scheduled")||this.openEditor(),this.model.trigger("clicked")),this.renderer.click_target=null,this.renderer.is_dragging=!1,this.is_dragging=!1},destroy:function(){this._super("destroy"),this.all_buttons.forEach(function(a){a.destroy()}),this.circle.remove(),this.title.remove(),this.renderer.minimap&&this.minimap_circle.remove(),this.node_image&&this.node_image.remove()}}),g}),define("renderer/edge",["jquery","underscore","requtils","renderer/baserepresentation"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){if(this.renderer.edge_layer.activate(),this.type="Edge",this.from_representation=this.renderer.getRepresentationByModel(this.model.get("from")),this.to_representation=this.renderer.getRepresentationByModel(this.model.get("to")),this.bundle=this.renderer.addToBundles(this),this.line=new paper.Path,this.line.add([0,0],[0,0],[0,0]),this.line.__representation=this,this.line.strokeWidth=this.options.edge_stroke_width,this.arrow=new paper.Path,this.arrow.add([0,0],[this.options.edge_arrow_length,this.options.edge_arrow_width/2],[0,this.options.edge_arrow_width]),this.arrow.__representation=this,this.text=a('<div class="Rk-Label Rk-Edge-Label">').appendTo(this.renderer.labels_$),this.arrow_angle=0,this.options.editor_mode){var b=c.getRenderer();this.normal_buttons=[new b.EdgeEditButton(this.renderer,null),new b.EdgeRemoveButton(this.renderer,null)],this.pending_delete_buttons=[new b.EdgeRevertButton(this.renderer,null)],this.all_buttons=this.normal_buttons.concat(this.pending_delete_buttons);for(var d=0;d<this.all_buttons.length;d++)this.all_buttons[d].source_representation=this;this.active_buttons=[]}else this.active_buttons=this.all_buttons=[];this.renderer.minimap&&(this.renderer.minimap.edge_layer.activate(),this.minimap_line=new paper.Path,this.minimap_line.add([0,0],[0,0]),this.minimap_line.__representation=this.renderer.minimap.miniframe.__representation,this.minimap_line.strokeWidth=1)},redraw:function(){var a=this.model.get("from"),b=this.model.get("to");if(a&&b&&(this.from_representation=this.renderer.getRepresentationByModel(a),this.to_representation=this.renderer.getRepresentationByModel(b),"undefined"!=typeof this.from_representation&&"undefined"!=typeof this.to_representation)){var c=this.from_representation.paper_coords,d=this.to_representation.paper_coords,f=d.subtract(c),g=f.length,h=f.divide(g),i=new paper.Point([-h.y,h.x]),j=this.bundle.getPosition(this),k=i.multiply(this.options.edge_gap_in_bundles*j),l=c.add(k),m=d.add(k),n=f.angle,o=i.multiply(this.options.edge_label_distance),p=f.divide(3),q=this.model.get("color")||this.model.get("color")||(this.model.get("created_by")||e._USER_PLACEHOLDER(this.renkan)).get("color"),r=1;this.model.get("delete_scheduled")||this.from_representation.model.get("delete_scheduled")||this.to_representation.model.get("delete_scheduled")?(r=.5,this.line.dashArray=[2,2]):(r=1,this.line.dashArray=null);var s=this.active_buttons;this.active_buttons=this.model.get("delete_scheduled")?this.pending_delete_buttons:this.normal_buttons,this.selected&&this.renderer.isEditable()&&s!==this.active_buttons&&(s.forEach(function(a){a.hide()}),this.active_buttons.forEach(function(a){a.show()})),this.paper_coords=l.add(m).divide(2),this.line.strokeColor=q,this.line.opacity=r,this.line.segments[0].point=c,this.line.segments[1].point=this.paper_coords,this.line.segments[1].handleIn=p.multiply(-1),this.line.segments[1].handleOut=p,this.line.segments[2].point=d,this.arrow.rotate(n-this.arrow_angle),this.arrow.fillColor=q,this.arrow.opacity=r,this.arrow.position=this.paper_coords,this.arrow_angle=n,n>90&&(n-=180,o=o.multiply(-1)),-90>n&&(n+=180,o=o.multiply(-1));var t=this.model.get("title")||this.renkan.translate(this.options.label_untitled_edges)||"";t=e.shortenText(t,this.options.node_label_max_length),this.text.text(t);var u=this.paper_coords.add(o);this.text.css({left:u.x,top:u.y,transform:"rotate("+n+"deg)","-moz-transform":"rotate("+n+"deg)","-webkit-transform":"rotate("+n+"deg)",opacity:r}),this.text_angle=n;var v=this.paper_coords;this.all_buttons.forEach(function(a){a.moveTo(v)}),this.renderer.minimap&&(this.minimap_line.strokeColor=q,this.minimap_line.segments[0].point=this.renderer.toMinimapCoords(new paper.Point(this.from_representation.model.get("position"))),this.minimap_line.segments[1].point=this.renderer.toMinimapCoords(new paper.Point(this.to_representation.model.get("position"))))}},openEditor:function(){this.renderer.removeRepresentationsOfType("editor");var a=this.renderer.addRepresentation("EdgeEditor",null);a.source_representation=this,a.draw()},select:function(){this.selected=!0,this.line.strokeWidth=this.options.selected_edge_stroke_width,this.renderer.isEditable()&&this.active_buttons.forEach(function(a){a.show()}),this.options.editor_mode||this.openEditor(),this._super("select")},unselect:function(a){a&&a.source_representation===this||(this.selected=!1,this.options.editor_mode&&this.all_buttons.forEach(function(a){a.hide()}),this.line.strokeWidth=this.options.edge_stroke_width,this._super("unselect"))},mousedown:function(a,b){b&&(this.renderer.unselectAll(),this.select())},mouseup:function(a,b){!this.renkan.read_only&&this.renderer.is_dragging?(this.from_representation.saveCoords(),this.to_representation.saveCoords(),this.from_representation.is_dragging=!1,this.to_representation.is_dragging=!1):(b||this.openEditor(),this.model.trigger("clicked")),this.renderer.click_target=null,this.renderer.is_dragging=!1},paperShift:function(a){this.options.editor_mode?this.options.read_only||(this.from_representation.paperShift(a),this.to_representation.paperShift(a)):this.renderer.paperShift(a)},destroy:function(){this._super("destroy"),this.line.remove(),this.arrow.remove(),this.text.remove(),this.renderer.minimap&&this.minimap_line.remove(),this.all_buttons.forEach(function(a){a.destroy()});var a=this;this.bundle.edges=b(this.bundle.edges).reject(function(b){return a===b})}}),f}),define("renderer/tempedge",["jquery","underscore","requtils","renderer/baserepresentation"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){this.renderer.edge_layer.activate(),this.type="Temp-edge";var a=(this.project.get("users").get(this.renkan.current_user)||e._USER_PLACEHOLDER(this.renkan)).get("color");this.line=new paper.Path,this.line.strokeColor=a,this.line.dashArray=[4,2],this.line.strokeWidth=this.options.selected_edge_stroke_width,this.line.add([0,0],[0,0]),this.line.__representation=this,this.arrow=new paper.Path,this.arrow.fillColor=a,this.arrow.add([0,0],[this.options.edge_arrow_length,this.options.edge_arrow_width/2],[0,this.options.edge_arrow_width]),this.arrow.__representation=this,this.arrow_angle=0},redraw:function(){var a=this.from_representation.paper_coords,b=this.end_pos,c=b.subtract(a).angle,d=a.add(b).divide(2);this.line.segments[0].point=a,this.line.segments[1].point=b,this.arrow.rotate(c-this.arrow_angle),this.arrow.position=d,this.arrow_angle=c},paperShift:function(a){if(!this.renderer.isEditable())return this.renderer.removeRepresentation(_this),void paper.view.draw();this.end_pos=this.end_pos.add(a);var b=paper.project.hitTest(this.end_pos);this.renderer.findTarget(b),this.redraw()},mouseup:function(a){var b=paper.project.hitTest(a.point),c=this.from_representation.model,d=!0;if(b&&"undefined"!=typeof b.item.__representation){var f=b.item.__representation;if("Node"===f.type.substr(0,4)){var g=f.model||f.source_representation.model;if(c!==g){var h={id:e.getUID("edge"),created_by:this.renkan.current_user,from:c,to:g};this.renderer.isEditable()&&this.project.addEdge(h)}}(c===f.model||f.source_representation&&f.source_representation.model===c)&&(d=!1,this.renderer.is_dragging=!0)}d&&(this.renderer.click_target=null,this.renderer.is_dragging=!1,this.renderer.removeRepresentation(this),paper.view.draw())},destroy:function(){this.arrow.remove(),this.line.remove()}}),f}),define("renderer/baseeditor",["jquery","underscore","requtils","renderer/baserepresentation"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){this.renderer.buttons_layer.activate(),this.type="editor",this.editor_block=new paper.Path;var c=b(b.range(8)).map(function(){return[0,0]});this.editor_block.add.apply(this.editor_block,c),this.editor_block.strokeWidth=this.options.tooltip_border_width,this.editor_block.strokeColor=this.options.tooltip_border_color,this.editor_block.opacity=.8,this.editor_$=a("<div>").appendTo(this.renderer.editor_$).css({position:"absolute",opacity:.8}).hide()},destroy:function(){this.editor_block.remove(),this.editor_$.remove()}}),f}),define("renderer/nodeeditor",["jquery","underscore","requtils","renderer/baseeditor"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){d.prototype._init.apply(this),this.template=this.options.templates["templates/nodeeditor.html"],this.readOnlyTemplate=this.options.templates["templates/nodeeditor_readonly.html"]},draw:function(){var c=this.source_representation.model,d=c.get("created_by")||e._USER_PLACEHOLDER(this.renkan),f=this.renderer.isEditable()?this.template:this.readOnlyTemplate,g=this.options.static_url+"img/image-placeholder.png",h=c.get("size")||0;this.editor_$.html(f({node:{has_creator:!!c.get("created_by"),title:c.get("title"),uri:c.get("uri"),short_uri:e.shortenText((c.get("uri")||"").replace(/^(https?:\/\/)?(www\.)?/,"").replace(/\/$/,""),40),description:c.get("description"),image:c.get("image")||"",image_placeholder:g,color:c.get("color")||d.get("color"),clip_path:c.get("clip_path")||!1,created_by_color:d.get("color"),created_by_title:d.get("title"),size:(h>0?"+":"")+h,shape:c.get("shape")||"circle"},renkan:this.renkan,options:this.options,shortenText:e.shortenText})),this.redraw();var i=this,j=function(){i.renderer.removeRepresentation(i),paper.view.draw()};if(this.editor_$.find(".Rk-CloseX").click(j),this.editor_$.find(".Rk-Edit-Goto").click(function(){return c.get("uri")?void 0:!1}),this.renderer.isEditable()){var k=b(function(){b(function(){if(i.renderer.isEditable()){var a={title:i.editor_$.find(".Rk-Edit-Title").val()};i.options.show_node_editor_uri&&(a.uri=i.editor_$.find(".Rk-Edit-URI").val(),i.editor_$.find(".Rk-Edit-Goto").attr("href",a.uri||"#")),i.options.show_node_editor_image&&(a.image=i.editor_$.find(".Rk-Edit-Image").val(),i.editor_$.find(".Rk-Edit-ImgPreview").attr("src",a.image||g)),i.options.show_node_editor_description&&(a.description=i.editor_$.find(".Rk-Edit-Description").val()),i.options.change_shapes&&c.get("shape")!==i.editor_$.find(".Rk-Edit-Shape").val()&&(a.shape=i.editor_$.find(".Rk-Edit-Shape").val(),a.shape_changed=!0),c.set(a),i.redraw(),a.shape_changed===!0&&c.set(a)}else j()}).defer()}).throttle(500);this.editor_$.on("keyup",function(a){27===a.keyCode&&j()}),this.editor_$.find("input, textarea, select").on("change keyup paste",k),i.options.allow_image_upload&&this.editor_$.find(".Rk-Edit-Image-File").change(function(){if(this.files.length){var a=this.files[0],b=new FileReader;if("image"!==a.type.substr(0,5))return void alert(i.renkan.translate("This file is not an image"));if(a.size>1024*i.options.uploaded_image_max_kb)return void alert(i.renkan.translate("Image size must be under ")+i.options.uploaded_image_max_kb+i.renkan.translate("KB"));b.onload=function(a){i.editor_$.find(".Rk-Edit-Image").val(a.target.result),k()},b.readAsDataURL(a)}}),this.editor_$.find(".Rk-Edit-Title")[0].focus();var l=i.editor_$.find(".Rk-Edit-ColorPicker");this.editor_$.find(".Rk-Edit-ColorPicker-Wrapper").hover(function(a){a.preventDefault(),l.show()},function(a){a.preventDefault(),l.hide()}),l.find("li").hover(function(b){b.preventDefault(),i.editor_$.find(".Rk-Edit-Color").css("background",a(this).attr("data-color"))},function(a){a.preventDefault(),i.editor_$.find(".Rk-Edit-Color").css("background",c.get("color")||(c.get("created_by")||e._USER_PLACEHOLDER(i.renkan)).get("color"))}).click(function(b){b.preventDefault(),i.renderer.isEditable()?(c.set("color",a(this).attr("data-color")),l.hide(),paper.view.draw()):j()});var m=function(a){if(i.renderer.isEditable()){var b=a+(c.get("size")||0);i.editor_$.find(".Rk-Edit-Size-Value").text((b>0?"+":"")+b),c.set("size",b),paper.view.draw()}else j()};this.editor_$.find(".Rk-Edit-Size-Down").click(function(){return m(-1),!1}),this.editor_$.find(".Rk-Edit-Size-Up").click(function(){return m(1),!1}),this.editor_$.find(".Rk-Edit-Image-Del").click(function(){return i.editor_$.find(".Rk-Edit-Image").val(""),k(),!1})}else if("object"==typeof this.source_representation.highlighted){var n=this.source_representation.highlighted.replace(b(c.get("title")).escape(),'<span class="Rk-Highlighted">$1</span>');this.editor_$.find(".Rk-Display-Title"+(c.get("uri")?" a":"")).html(n),this.options.show_node_tooltip_description&&this.editor_$.find(".Rk-Display-Description").html(this.source_representation.highlighted.replace(b(c.get("description")).escape(),'<span class="Rk-Highlighted">$1</span>'))}this.editor_$.find("img").load(function(){i.redraw()})},redraw:function(){var a=this.source_representation.paper_coords;e.drawEditBox(this.options,a,this.editor_block,.75*this.source_representation.circle_radius,this.editor_$),this.editor_$.show(),paper.view.draw()}}),f}),define("renderer/edgeeditor",["jquery","underscore","requtils","renderer/baseeditor"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){d.prototype._init.apply(this),this.template=this.options.templates["templates/edgeeditor.html"],this.readOnlyTemplate=this.options.templates["templates/edgeeditor_readonly.html"]},draw:function(){var c=this.source_representation.model,d=c.get("from"),f=c.get("to"),g=c.get("created_by")||e._USER_PLACEHOLDER(this.renkan),h=this.renderer.isEditable()?this.template:this.readOnlyTemplate;this.editor_$.html(h({edge:{has_creator:!!c.get("created_by"),title:c.get("title"),uri:c.get("uri"),short_uri:e.shortenText((c.get("uri")||"").replace(/^(https?:\/\/)?(www\.)?/,"").replace(/\/$/,""),40),description:c.get("description"),color:c.get("color")||g.get("color"),from_title:d.get("title"),to_title:f.get("title"),from_color:d.get("color")||(d.get("created_by")||e._USER_PLACEHOLDER(this.renkan)).get("color"),to_color:f.get("color")||(f.get("created_by")||e._USER_PLACEHOLDER(this.renkan)).get("color"),created_by_color:g.get("color"),created_by_title:g.get("title")},renkan:this.renkan,shortenText:e.shortenText,options:this.options})),this.redraw();var i=this,j=function(){i.renderer.removeRepresentation(i),paper.view.draw()};if(this.editor_$.find(".Rk-CloseX").click(j),this.editor_$.find(".Rk-Edit-Goto").click(function(){return c.get("uri")?void 0:!1}),this.renderer.isEditable()){var k=b(function(){b(function(){if(i.renderer.isEditable()){var a={title:i.editor_$.find(".Rk-Edit-Title").val()};i.options.show_edge_editor_uri&&(a.uri=i.editor_$.find(".Rk-Edit-URI").val()),i.editor_$.find(".Rk-Edit-Goto").attr("href",a.uri||"#"),c.set(a),paper.view.draw()}else j()}).defer()}).throttle(500);this.editor_$.on("keyup",function(a){27===a.keyCode&&j()}),this.editor_$.find("input").on("keyup change paste",k),this.editor_$.find(".Rk-Edit-Vocabulary").change(function(){var b=a(this),c=b.val();c&&(i.editor_$.find(".Rk-Edit-Title").val(b.find(":selected").text()),i.editor_$.find(".Rk-Edit-URI").val(c),k())}),this.editor_$.find(".Rk-Edit-Direction").click(function(){i.renderer.isEditable()?(c.set({from:c.get("to"),to:c.get("from")}),i.draw()):j()});var l=i.editor_$.find(".Rk-Edit-ColorPicker");this.editor_$.find(".Rk-Edit-ColorPicker-Wrapper").hover(function(a){a.preventDefault(),l.show()},function(a){a.preventDefault(),l.hide()}),l.find("li").hover(function(b){b.preventDefault(),i.editor_$.find(".Rk-Edit-Color").css("background",a(this).attr("data-color"))},function(a){a.preventDefault(),i.editor_$.find(".Rk-Edit-Color").css("background",c.get("color")||(c.get("created_by")||e._USER_PLACEHOLDER(i.renkan)).get("color"))}).click(function(b){b.preventDefault(),i.renderer.isEditable()?(c.set("color",a(this).attr("data-color")),l.hide(),paper.view.draw()):j()})}},redraw:function(){var a=this.source_representation.paper_coords;e.drawEditBox(this.options,a,this.editor_block,5,this.editor_$),this.editor_$.show(),paper.view.draw()}}),f}),define("renderer/nodebutton",["jquery","underscore","requtils","renderer/basebutton"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({setSectorSize:function(){var a=this.source_representation.circle_radius;a!==this.lastSectorInner&&(this.sector&&this.sector.destroy(),this.sector=this.renderer.drawSector(this,1+a,e._NODE_BUTTON_WIDTH+a,this.startAngle,this.endAngle,1,this.imageName,this.renkan.translate(this.text)),this.lastSectorInner=a)},unselect:function(){d.prototype.unselect.apply(this,Array.prototype.slice.call(arguments,1)),this.source_representation&&this.source_representation.buttons_timeout&&(clearTimeout(this.source_representation.buttons_timeout),this.source_representation.hideButtons())},select:function(){this.source_representation&&this.source_representation.buttons_timeout&&clearTimeout(this.source_representation.buttons_timeout),this.sector.select()}}),f}),define("renderer/nodeeditbutton",["jquery","underscore","requtils","renderer/nodebutton"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){this.type="Node-edit-button",this.lastSectorInner=0,this.startAngle=-135,this.endAngle=-45,this.imageName="edit",this.text="Edit"},mouseup:function(){this.renderer.is_dragging||this.source_representation.openEditor()}}),f}),define("renderer/noderemovebutton",["jquery","underscore","requtils","renderer/nodebutton"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){this.type="Node-remove-button",this.lastSectorInner=0,this.startAngle=0,this.endAngle=90,this.imageName="remove",this.text="Remove"},mouseup:function(){if(this.renderer.click_target=null,this.renderer.is_dragging=!1,this.renderer.removeRepresentationsOfType("editor"),this.renderer.isEditable())if(this.options.element_delete_delay){var a=e.getUID("delete");this.renderer.delete_list.push({id:a,time:(new Date).valueOf()+this.options.element_delete_delay}),this.source_representation.model.set("delete_scheduled",a)}else confirm(this.renkan.translate("Do you really wish to remove node ")+'"'+this.source_representation.model.get("title")+'"?')&&this.project.removeNode(this.source_representation.model)}}),f}),define("renderer/noderevertbutton",["jquery","underscore","requtils","renderer/nodebutton"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){this.type="Node-revert-button",this.lastSectorInner=0,this.startAngle=-135,this.endAngle=135,this.imageName="revert",this.text="Cancel deletion"},mouseup:function(){this.renderer.click_target=null,this.renderer.is_dragging=!1,this.renderer.isEditable()&&this.source_representation.model.unset("delete_scheduled")}}),f}),define("renderer/nodelinkbutton",["jquery","underscore","requtils","renderer/nodebutton"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){this.type="Node-link-button",this.lastSectorInner=0,this.startAngle=90,this.endAngle=180,this.imageName="link",this.text="Link to another node"},mousedown:function(a){if(this.renderer.isEditable()){var b=this.renderer.canvas_$.offset(),c=new paper.Point([a.pageX-b.left,a.pageY-b.top]);this.renderer.click_target=null,this.renderer.removeRepresentationsOfType("editor"),this.renderer.addTempEdge(this.source_representation,c)}}}),f}),define("renderer/nodeenlargebutton",["jquery","underscore","requtils","renderer/nodebutton"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){this.type="Node-enlarge-button",this.lastSectorInner=0,this.startAngle=-45,this.endAngle=0,this.imageName="enlarge",this.text="Enlarge"},mouseup:function(){var a=1+(this.source_representation.model.get("size")||0);this.source_representation.model.set("size",a),this.source_representation.select(),this.select(),paper.view.draw()}}),f}),define("renderer/nodeshrinkbutton",["jquery","underscore","requtils","renderer/nodebutton"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){this.type="Node-shrink-button",this.lastSectorInner=0,this.startAngle=-180,this.endAngle=-135,this.imageName="shrink",this.text="Shrink"},mouseup:function(){var a=-1+(this.source_representation.model.get("size")||0);this.source_representation.model.set("size",a),this.source_representation.select(),this.select(),paper.view.draw()}}),f}),define("renderer/edgeeditbutton",["jquery","underscore","requtils","renderer/basebutton"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){this.type="Edge-edit-button",this.sector=this.renderer.drawSector(this,e._EDGE_BUTTON_INNER,e._EDGE_BUTTON_OUTER,-270,-90,1,"edit",this.renkan.translate("Edit"))},mouseup:function(){this.renderer.is_dragging||this.source_representation.openEditor()}}),f}),define("renderer/edgeremovebutton",["jquery","underscore","requtils","renderer/basebutton"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){this.type="Edge-remove-button",this.sector=this.renderer.drawSector(this,e._EDGE_BUTTON_INNER,e._EDGE_BUTTON_OUTER,-90,90,1,"remove",this.renkan.translate("Remove"))},mouseup:function(){if(this.renderer.click_target=null,this.renderer.is_dragging=!1,this.renderer.removeRepresentationsOfType("editor"),this.renderer.isEditable())if(this.options.element_delete_delay){var a=e.getUID("delete");this.renderer.delete_list.push({id:a,time:(new Date).valueOf()+this.options.element_delete_delay}),this.source_representation.model.set("delete_scheduled",a)}else confirm(this.renkan.translate("Do you really wish to remove edge ")+'"'+this.source_representation.model.get("title")+'"?')&&this.project.removeEdge(this.source_representation.model)}}),f}),define("renderer/edgerevertbutton",["jquery","underscore","requtils","renderer/basebutton"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){this.type="Edge-revert-button",this.sector=this.renderer.drawSector(this,e._EDGE_BUTTON_INNER,e._EDGE_BUTTON_OUTER,-135,135,1,"revert",this.renkan.translate("Cancel deletion"))},mouseup:function(){this.renderer.click_target=null,this.renderer.is_dragging=!1,this.renderer.isEditable()&&this.source_representation.model.unset("delete_scheduled")}}),f}),define("renderer/miniframe",["jquery","underscore","requtils","renderer/baserepresentation"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({paperShift:function(a){this.renderer.offset=this.renderer.offset.subtract(a.divide(this.renderer.minimap.scale).multiply(this.renderer.scale)),this.renderer.redraw()},mouseup:function(){this.renderer.click_target=null,this.renderer.is_dragging=!1}}),f}),define("renderer/scene",["jquery","underscore","filesaver","requtils","renderer/miniframe"],function(a,b,c,d,e){var f=d.getUtils(),g=function(c){this.renkan=c,this.$=a(".Rk-Render"),this.representations=[],this.$.html(c.options.templates["templates/scene.html"](c)),this.onStatusChange(),this.canvas_$=this.$.find(".Rk-Canvas"),this.labels_$=this.$.find(".Rk-Labels"),this.editor_$=this.$.find(".Rk-Editor"),this.notif_$=this.$.find(".Rk-Notifications"),paper.setup(this.canvas_$[0]),this.scale=1,this.initialScale=1,this.offset=paper.view.center,this.totalScroll=0,this.mouse_down=!1,this.click_target=null,this.selected_target=null,this.edge_layer=new paper.Layer,this.node_layer=new paper.Layer,this.buttons_layer=new paper.Layer,this.delete_list=[],this.redrawActive=!0,c.options.show_minimap&&(this.minimap={background_layer:new paper.Layer,edge_layer:new paper.Layer,node_layer:new paper.Layer,node_group:new paper.Group,size:new paper.Size(c.options.minimap_width,c.options.minimap_height)},this.minimap.background_layer.activate(),this.minimap.topleft=paper.view.bounds.bottomRight.subtract(this.minimap.size),this.minimap.rectangle=new paper.Path.Rectangle(this.minimap.topleft.subtract([2,2]),this.minimap.size.add([4,4])),this.minimap.rectangle.fillColor=c.options.minimap_background_color,this.minimap.rectangle.strokeColor=c.options.minimap_border_color,this.minimap.rectangle.strokeWidth=4,this.minimap.offset=new paper.Point(this.minimap.size.divide(2)),this.minimap.scale=.1,this.minimap.node_layer.activate(),this.minimap.cliprectangle=new paper.Path.Rectangle(this.minimap.topleft,this.minimap.size),this.minimap.node_group.addChild(this.minimap.cliprectangle),this.minimap.node_group.clipped=!0,this.minimap.miniframe=new paper.Path.Rectangle(this.minimap.topleft,this.minimap.size),this.minimap.node_group.addChild(this.minimap.miniframe),this.minimap.miniframe.fillColor="#c0c0ff",this.minimap.miniframe.opacity=.3,this.minimap.miniframe.strokeColor="#000080",this.minimap.miniframe.strokeWidth=2,this.minimap.miniframe.__representation=new e(this,null)),this.throttledPaperDraw=b(function(){paper.view.draw()}).throttle(100),this.bundles=[],this.click_mode=!1;var d=this,g=!0,h=1,i=!1,j=0,k=0;this.image_cache={},this.icon_cache={},["edit","remove","link","enlarge","shrink","revert"].forEach(function(a){var b=new Image;b.src=c.options.static_url+"img/"+a+".png",d.icon_cache[a]=b});var l=b.throttle(function(a,b){d.onMouseMove(a,b)},f._MOUSEMOVE_RATE);this.canvas_$.on({mousedown:function(a){a.preventDefault(),d.onMouseDown(a,!1)},mousemove:function(a){a.preventDefault(),l(a,!1)},mouseup:function(a){a.preventDefault(),d.onMouseUp(a,!1)},mousewheel:function(a,b){c.options.zoom_on_scroll&&(a.preventDefault(),g&&d.onScroll(a,b))},touchstart:function(a){a.preventDefault();var b=a.originalEvent.touches[0];c.options.allow_double_click&&new Date-_lastTap<f._DOUBLETAP_DELAY&&Math.pow(j-b.pageX,2)+Math.pow(k-b.pageY,2)<f._DOUBLETAP_DISTANCE?(_lastTap=0,d.onDoubleClick(b)):(_lastTap=new Date,j=b.pageX,k=b.pageY,h=d.scale,i=!1,d.onMouseDown(b,!0))},touchmove:function(a){if(a.preventDefault(),_lastTap=0,1===a.originalEvent.touches.length)d.onMouseMove(a.originalEvent.touches[0],!0);else{if(i||(d.onMouseUp(a.originalEvent.touches[0],!0),d.click_target=null,d.is_dragging=!1,i=!0),"undefined"===a.originalEvent.scale)return;var b=a.originalEvent.scale*h,c=b/d.scale,e=new paper.Point([d.canvas_$.width(),d.canvas_$.height()]).multiply(.5*(1-c)).add(d.offset.multiply(c));d.setScale(b,e)}},touchend:function(a){a.preventDefault(),d.onMouseUp(a.originalEvent.changedTouches[0],!0)},dblclick:function(a){a.preventDefault(),c.options.allow_double_click&&d.onDoubleClick(a)},mouseleave:function(a){a.preventDefault(),d.onMouseUp(a,!1),d.click_target=null,d.is_dragging=!1},dragover:function(a){a.preventDefault()},dragenter:function(a){a.preventDefault(),g=!1},dragleave:function(a){a.preventDefault(),g=!0},drop:function(a){a.preventDefault(),g=!0;var c={};b(a.originalEvent.dataTransfer.types).each(function(b){try{c[b]=a.originalEvent.dataTransfer.getData(b)}catch(d){}});var e=a.originalEvent.dataTransfer.getData("Text");if("string"==typeof e)switch(e[0]){case"{":case"[":try{var f=JSON.parse(e);b(c).extend(f)}catch(h){c["text/plain"]||(c["text/plain"]=e)}break;case"<":c["text/html"]||(c["text/html"]=e);break;default:c["text/plain"]||(c["text/plain"]=e)}var i=a.originalEvent.dataTransfer.getData("URL");i&&!c["text/uri-list"]&&(c["text/uri-list"]=i),d.dropData(c,a.originalEvent)}});var m=function(a,b){d.$.find(a).click(function(a){return d[b](a),!1})};m(".Rk-ZoomOut","zoomOut"),m(".Rk-ZoomIn","zoomIn"),m(".Rk-ZoomFit","autoScale"),this.$.find(".Rk-ZoomSave").click(function(){d.renkan.project.addView({zoom_level:d.scale,offset:d.offset})}),this.$.find(".Rk-ZoomSetSaved").click(function(){var a=d.renkan.project.get("views").last();a&&d.setScale(a.get("zoom_level"),new paper.Point(a.get("offset")))}),this.renkan.project.get("views").length>0&&this.renkan.options.save_view&&this.$.find(".Rk-ZoomSetSaved").show(),this.$.find(".Rk-CurrentUser").mouseenter(function(){d.$.find(".Rk-UserList").slideDown()}),this.$.find(".Rk-Users").mouseleave(function(){d.$.find(".Rk-UserList").slideUp()}),m(".Rk-FullScreen-Button","fullScreen"),m(".Rk-AddNode-Button","addNodeBtn"),m(".Rk-AddEdge-Button","addEdgeBtn"),m(".Rk-Save-Button","save"),m(".Rk-Open-Button","open"),m(".Rk-Export-Button","exportProject"),this.$.find(".Rk-Bookmarklet-Button").attr("href","javascript:"+f._BOOKMARKLET_CODE(c)).click(function(){return d.notif_$.text(c.translate("Drag this button to your bookmark bar. When on a third-party website, click it to enable drag-and-drop from the website to Renkan.")).fadeIn().delay(5e3).fadeOut(),!1}),this.$.find(".Rk-TopBar-Button").mouseover(function(){a(this).find(".Rk-TopBar-Tooltip").show()}).mouseout(function(){a(this).find(".Rk-TopBar-Tooltip").hide()}),m(".Rk-Fold-Bins","foldBins"),paper.view.onResize=function(a){var b,c=a.width,e=a.height;d.minimap&&(d.minimap.topleft=paper.view.bounds.bottomRight.subtract(d.minimap.size),d.minimap.rectangle.fitBounds(d.minimap.topleft.subtract([2,2]),d.minimap.size.add([4,4])),d.minimap.cliprectangle.fitBounds(d.minimap.topleft,d.minimap.size));var f=e/(e-a.delta.height),g=c/(c-a.delta.width);b=c>e?f:g,d.resizeZoom(g,f,b),d.redraw()};var n=b.throttle(function(){d.redraw()},50);this.addRepresentations("Node",this.renkan.project.get("nodes")),this.addRepresentations("Edge",this.renkan.project.get("edges")),this.renkan.project.on("change:title",function(){d.$.find(".Rk-PadTitle").val(c.project.get("title"))}),this.$.find(".Rk-PadTitle").on("keyup input paste",function(){c.project.set({title:a(this).val()})});var o=b.throttle(function(){d.redrawUsers()},100);if(o(),this.renkan.project.on("change:save_status",function(){switch(d.renkan.project.get("save_status")){case 0:d.$.find(".Rk-Save-Button").removeClass("to-save"),d.$.find(".Rk-Save-Button").removeClass("saving"),d.$.find(".Rk-Save-Button").addClass("saved");break;case 1:d.$.find(".Rk-Save-Button").removeClass("saved"),d.$.find(".Rk-Save-Button").removeClass("saving"),d.$.find(".Rk-Save-Button").addClass("to-save");break;case 2:d.$.find(".Rk-Save-Button").removeClass("saved"),d.$.find(".Rk-Save-Button").removeClass("to-save"),d.$.find(".Rk-Save-Button").addClass("saving")}}),this.renkan.project.on("change:loading_status",function(){if(d.renkan.project.get("loading_status")){d.$.find(".loader").addClass("run"),setTimeout(function(){d.$.find(".loader").hide(250)},3e3)}}),this.renkan.project.on("add:users remove:users",o),this.renkan.project.on("add:views remove:views",function(){d.renkan.project.get("views").length>0?d.$.find(".Rk-ZoomSetSaved").show():d.$.find(".Rk-ZoomSetSaved").hide()}),this.renkan.project.on("add:nodes",function(a){d.addRepresentation("Node",a),d.renkan.project.get("loading_status")||n()}),this.renkan.project.on("add:edges",function(a){d.addRepresentation("Edge",a),d.renkan.project.get("loading_status")||n()}),this.renkan.project.on("change:title",function(a,b){var c=d.$.find(".Rk-PadTitle"); -c.is("input")?c.val()!==b&&c.val(b):c.text(b)}),c.options.size_bug_fix){var p="number"==typeof c.options.size_bug_fix?c.options.size_bug_fix:500;window.setTimeout(function(){d.fixSize()},p)}if(c.options.force_resize&&a(window).resize(function(){d.autoScale()}),c.options.show_user_list&&c.options.user_color_editable){var q=this.$.find(".Rk-Users .Rk-Edit-ColorPicker-Wrapper"),r=this.$.find(".Rk-Users .Rk-Edit-ColorPicker");q.hover(function(a){d.isEditable()&&(a.preventDefault(),r.show())},function(a){a.preventDefault(),r.hide()}),r.find("li").mouseenter(function(b){d.isEditable()&&(b.preventDefault(),d.$.find(".Rk-CurrentUser-Color").css("background",a(this).attr("data-color")))})}if(c.options.show_search_field){var s="";this.$.find(".Rk-GraphSearch-Field").on("keyup change paste input",function(){var b=a(this),e=b.val();if(e!==s)if(s=e,e.length<2)c.project.get("nodes").each(function(a){d.getRepresentationByModel(a).unhighlight()});else{var g=f.regexpFromTextOrArray(e);c.project.get("nodes").each(function(a){g.test(a.get("title"))||g.test(a.get("description"))?d.getRepresentationByModel(a).highlight(g):d.getRepresentationByModel(a).unhighlight()})}})}this.redraw(),window.setInterval(function(){var a=(new Date).valueOf();d.delete_list.forEach(function(b){if(a>=b.time){var d=c.project.get("nodes").findWhere({delete_scheduled:b.id});d&&project.removeNode(d),d=c.project.get("edges").findWhere({delete_scheduled:b.id}),d&&project.removeEdge(d)}}),d.delete_list=d.delete_list.filter(function(a){return c.project.get("nodes").findWhere({delete_scheduled:a.id})||c.project.get("edges").findWhere({delete_scheduled:a.id})})},500),this.minimap&&window.setInterval(function(){d.rescaleMinimap()},2e3)};return b(g.prototype).extend({fixSize:function(){if(this.renkan.options.default_view&&this.renkan.project.get("views").length>0){var a=this.renkan.project.get("views").last();this.setScale(a.get("zoom_level"),new paper.Point(a.get("offset")))}else this.autoScale()},drawSector:function(b,c,d,e,f,g,h,i){var j=this.renkan.options,k=e*Math.PI/180,l=f*Math.PI/180,m=this.icon_cache[h],n=-Math.sin(k),o=Math.cos(k),p=Math.cos(k)*c+g*n,q=Math.sin(k)*c+g*o,r=Math.cos(k)*d+g*n,s=Math.sin(k)*d+g*o,t=-Math.sin(l),u=Math.cos(l),v=Math.cos(l)*c-g*t,w=Math.sin(l)*c-g*u,x=Math.cos(l)*d-g*t,y=Math.sin(l)*d-g*u,z=(c+d)/2,A=(k+l)/2,B=Math.cos(A)*z,C=Math.sin(A)*z,D=Math.cos(A)*c,E=Math.cos(A)*d,F=Math.sin(A)*c,G=Math.sin(A)*d,H=Math.cos(A)*(d+3),I=Math.sin(A)*(d+j.buttons_label_font_size)+j.buttons_label_font_size/2;this.buttons_layer.activate();var J=new paper.Path;J.add([p,q]),J.arcTo([D,F],[v,w]),J.lineTo([x,y]),J.arcTo([E,G],[r,s]),J.fillColor=j.buttons_background,J.opacity=.5,J.closed=!0,J.__representation=b;var K=new paper.PointText(H,I);K.characterStyle={fontSize:j.buttons_label_font_size,fillColor:j.buttons_label_color},K.paragraphStyle.justification=H>2?"left":-2>H?"right":"center",K.visible=!1;var L=!1,M=new paper.Point(-200,-200),N=new paper.Group([J,K]),O=N.position,P=new paper.Point([B,C]),Q=new paper.Point(0,0);K.content=i,N.pivot=N.bounds.center,N.visible=!1,N.position=M;var R={show:function(){L=!0,N.position=Q.add(O),N.visible=!0},moveTo:function(a){Q=a,L&&(N.position=a.add(O))},hide:function(){L=!1,N.visible=!1,N.position=M},select:function(){J.opacity=.8,K.visible=!0},unselect:function(){J.opacity=.5,K.visible=!1},destroy:function(){N.remove()}},S=function(){var a=new paper.Raster(m);a.position=P.add(N.position).subtract(O),a.locked=!0,N.addChild(a)};return m.width?S():a(m).on("load",S),R},addToBundles:function(a){var c=b(this.bundles).find(function(b){return b.from===a.from_representation&&b.to===a.to_representation||b.from===a.to_representation&&b.to===a.from_representation});return"undefined"!=typeof c?c.edges.push(a):(c={from:a.from_representation,to:a.to_representation,edges:[a],getPosition:function(a){var c=a.from_representation===this.from?1:-1;return c*(b(this.edges).indexOf(a)-(this.edges.length-1)/2)}},this.bundles.push(c)),c},isEditable:function(){return this.renkan.options.editor_mode&&!this.renkan.read_only},onStatusChange:function(){var a=this.$.find(".Rk-Save-Button"),b=a.find(".Rk-TopBar-Tooltip-Contents");this.renkan.read_only?(a.removeClass("disabled Rk-Save-Online").addClass("Rk-Save-ReadOnly"),b.text(this.renkan.translate("Connection lost"))):this.renkan.options.manual_save?(a.removeClass("Rk-Save-ReadOnly Rk-Save-Online"),b.text(this.renkan.translate("Save Project"))):(a.removeClass("disabled Rk-Save-ReadOnly").addClass("Rk-Save-Online"),b.text(this.renkan.translate("Auto-save enabled"))),this.redrawUsers()},setScale:function(a,b){a/this.initialScale>f._MIN_SCALE&&a/this.initialScale<f._MAX_SCALE&&(this.scale=a,b&&(this.offset=b),this.redraw())},autoScale:function(a){var b=this.renkan.project.get("nodes");if(b.length>1){var c=b.map(function(a){return a.get("position").x}),d=b.map(function(a){return a.get("position").y}),e=Math.min.apply(Math,c),f=Math.min.apply(Math,d),g=Math.max.apply(Math,c),h=Math.max.apply(Math,d),i=Math.min((paper.view.size.width-2*this.renkan.options.autoscale_padding)/(g-e),(paper.view.size.height-2*this.renkan.options.autoscale_padding)/(h-f));this.initialScale=i,"undefined"!=typeof a&&parseFloat(a.zoom_level)>0&&parseFloat(a.offset.x)>0&&parseFloat(a.offset.y)>0?this.setScale(parseFloat(a.zoom_level),new paper.Point(parseFloat(a.offset.x),parseFloat(a.offset.y))):this.setScale(i,paper.view.center.subtract(new paper.Point([(g+e)/2,(h+f)/2]).multiply(i)))}1===b.length&&this.setScale(1,paper.view.center.subtract(new paper.Point([b.at(0).get("position").x,b.at(0).get("position").y])))},redrawMiniframe:function(){var a=this.toMinimapCoords(this.toModelCoords(new paper.Point([0,0]))),b=this.toMinimapCoords(this.toModelCoords(paper.view.bounds.bottomRight));this.minimap.miniframe.fitBounds(a,b)},rescaleMinimap:function(){var a=this.renkan.project.get("nodes");if(a.length>1){var b=a.map(function(a){return a.get("position").x}),c=a.map(function(a){return a.get("position").y}),d=Math.min.apply(Math,b),e=Math.min.apply(Math,c),f=Math.max.apply(Math,b),g=Math.max.apply(Math,c),h=Math.min(.8*this.scale*this.renkan.options.minimap_width/paper.view.bounds.width,.8*this.scale*this.renkan.options.minimap_height/paper.view.bounds.height,(this.renkan.options.minimap_width-2*this.renkan.options.minimap_padding)/(f-d),(this.renkan.options.minimap_height-2*this.renkan.options.minimap_padding)/(g-e));this.minimap.offset=this.minimap.size.divide(2).subtract(new paper.Point([(f+d)/2,(g+e)/2]).multiply(h)),this.minimap.scale=h}1===a.length&&(this.minimap.scale=.1,this.minimap.offset=this.minimap.size.divide(2).subtract(new paper.Point([a.at(0).get("position").x,a.at(0).get("position").y]).multiply(this.minimap.scale))),this.redraw()},toPaperCoords:function(a){return a.multiply(this.scale).add(this.offset)},toMinimapCoords:function(a){return a.multiply(this.minimap.scale).add(this.minimap.offset).add(this.minimap.topleft)},toModelCoords:function(a){return a.subtract(this.offset).divide(this.scale)},addRepresentation:function(a,b){var c=d.getRenderer()[a],e=new c(this,b);return this.representations.push(e),e},addRepresentations:function(a,b){var c=this;b.forEach(function(b){c.addRepresentation(a,b)})},userTemplate:b.template('<li class="Rk-User"><span class="Rk-UserColor" style="background:<%=background%>;"></span><%=name%></li>'),redrawUsers:function(){if(this.renkan.options.show_user_list){var b=[].concat((this.renkan.project.current_user_list||{}).models||[],(this.renkan.project.get("users")||{}).models||[]),c="",d=this.$.find(".Rk-Users"),e=d.find(".Rk-CurrentUser-Name"),f=d.find(".Rk-Edit-ColorPicker li"),g=d.find(".Rk-CurrentUser-Color"),h=this;e.off("click").text(this.renkan.translate("<unknown user>")),f.off("mouseleave click"),b.forEach(function(b){b.get("_id")===h.renkan.current_user?(e.text(b.get("title")),g.css("background",b.get("color")),h.isEditable()&&(h.renkan.options.user_name_editable&&e.click(function(){var c=a(this),d=a("<input>").val(b.get("title")).blur(function(){b.set("title",a(this).val()),h.redrawUsers(),h.redraw()});c.empty().html(d),d.select()}),h.renkan.options.user_color_editable&&f.click(function(c){c.preventDefault(),h.isEditable()&&b.set("color",a(this).attr("data-color")),a(this).parent().hide()}).mouseleave(function(){g.css("background",b.get("color"))}))):c+=h.userTemplate({name:b.get("title"),background:b.get("color")})}),d.find(".Rk-UserList").html(c)}},removeRepresentation:function(a){a.destroy(),this.representations=b(this.representations).reject(function(b){return b===a})},getRepresentationByModel:function(a){return a?b(this.representations).find(function(b){return b.model===a}):void 0},removeRepresentationsOfType:function(a){var c=b(this.representations).filter(function(b){return b.type===a}),d=this;b(c).each(function(a){d.removeRepresentation(a)})},highlightModel:function(a){var b=this.getRepresentationByModel(a);b&&b.highlight()},unhighlightAll:function(){b(this.representations).each(function(a){a.unhighlight()})},unselectAll:function(){b(this.representations).each(function(a){a.unselect()})},redraw:function(){this.redrawActive&&(b(this.representations).each(function(a){a.redraw(!0)}),this.minimap&&this.redrawMiniframe(),paper.view.draw())},addTempEdge:function(a,b){var c=this.addRepresentation("TempEdge",null);c.end_pos=b,c.from_representation=a,c.redraw(),this.click_target=c},findTarget:function(a){if(a&&"undefined"!=typeof a.item.__representation){var b=a.item.__representation;this.selected_target!==a.item.__representation&&(this.selected_target&&this.selected_target.unselect(b),b.select(this.selected_target),this.selected_target=b)}else this.selected_target&&this.selected_target.unselect(),this.selected_target=null},paperShift:function(a){this.offset=this.offset.add(a),this.redraw()},onMouseMove:function(a){var b=this.canvas_$.offset(),c=new paper.Point([a.pageX-b.left,a.pageY-b.top]),d=c.subtract(this.last_point);this.last_point=c,!this.is_dragging&&this.mouse_down&&d.length>f._MIN_DRAG_DISTANCE&&(this.is_dragging=!0);var e=paper.project.hitTest(c);this.is_dragging?this.click_target&&"function"==typeof this.click_target.paperShift?this.click_target.paperShift(d):this.paperShift(d):this.findTarget(e),paper.view.draw()},onMouseDown:function(b,c){var d=this.canvas_$.offset(),e=new paper.Point([b.pageX-d.left,b.pageY-d.top]);if(this.last_point=e,this.mouse_down=!0,!this.click_target||"Temp-edge"!==this.click_target.type){this.removeRepresentationsOfType("editor"),this.is_dragging=!1;var g=paper.project.hitTest(e);if(g&&"undefined"!=typeof g.item.__representation)this.click_target=g.item.__representation,this.click_target.mousedown(b,c);else if(this.click_target=null,this.isEditable()&&this.click_mode===f._CLICKMODE_ADDNODE){var h=this.toModelCoords(e),i={id:f.getUID("node"),created_by:this.renkan.current_user,position:{x:h.x,y:h.y}};_node=this.renkan.project.addNode(i),this.getRepresentationByModel(_node).openEditor()}}this.click_mode&&(this.isEditable()&&this.click_mode===f._CLICKMODE_STARTEDGE&&this.click_target&&"Node"===this.click_target.type?(this.removeRepresentationsOfType("editor"),this.addTempEdge(this.click_target,e),this.click_mode=f._CLICKMODE_ENDEDGE,this.notif_$.fadeOut(function(){a(this).html(this.renkan.translate("Click on a second node to complete the edge")).fadeIn()})):(this.notif_$.hide(),this.click_mode=!1)),paper.view.draw()},onMouseUp:function(a,b){if(this.mouse_down=!1,this.click_target){var c=this.canvas_$.offset();this.click_target.mouseup({point:new paper.Point([a.pageX-c.left,a.pageY-c.top])},b)}else this.click_target=null,this.is_dragging=!1,b&&this.unselectAll();paper.view.draw()},onScroll:function(a,b){if(this.totalScroll+=b,Math.abs(this.totalScroll)>=1){var c=this.canvas_$.offset(),d=new paper.Point([a.pageX-c.left,a.pageY-c.top]).subtract(this.offset).multiply(Math.SQRT2-1);this.totalScroll>0?this.setScale(this.scale*Math.SQRT2,this.offset.subtract(d)):this.setScale(this.scale*Math.SQRT1_2,this.offset.add(d.divide(Math.SQRT2))),this.totalScroll=0}},onDoubleClick:function(a){if(this.isEditable()){var b=this.canvas_$.offset(),c=new paper.Point([a.pageX-b.left,a.pageY-b.top]),d=paper.project.hitTest(c);if(this.isEditable()&&(!d||"undefined"==typeof d.item.__representation)){var e=this.toModelCoords(c),g={id:f.getUID("node"),created_by:this.renkan.current_user,position:{x:e.x,y:e.y}},h=this.renkan.project.addNode(g);this.getRepresentationByModel(h).openEditor()}paper.view.draw()}},defaultDropHandler:function(b){var c={},d="";switch(b["text/x-iri-specific-site"]){case"twitter":d=a("<div>").html(b["text/x-iri-selected-html"]);var e=d.find(".tweet");c.title=this.renkan.translate("Tweet by ")+e.attr("data-name"),c.uri="http://twitter.com/"+e.attr("data-screen-name")+"/status/"+e.attr("data-tweet-id"),c.image=e.find(".avatar").attr("src"),c.description=e.find(".js-tweet-text:first").text();break;case"google":d=a("<div>").html(b["text/x-iri-selected-html"]),c.title=d.find("h3:first").text().trim(),c.uri=d.find("h3 a").attr("href"),c.description=d.find(".st:first").text().trim();break;default:b["text/x-iri-source-uri"]&&(c.uri=b["text/x-iri-source-uri"])}if((b["text/plain"]||b["text/x-iri-selected-text"])&&(c.description=(b["text/plain"]||b["text/x-iri-selected-text"]).replace(/[\s\n]+/gm," ").trim()),b["text/html"]||b["text/x-iri-selected-html"]){d=a("<div>").html(b["text/html"]||b["text/x-iri-selected-html"]);var f=d.find("image");f.length&&(c.image=f.attr("xlink:href"));var g=d.find("path");g.length&&(c.clipPath=g.attr("d"));var h=d.find("img");h.length&&(c.image=h[0].src);var i=d.find("a");i.length&&(c.uri=i[0].href),c.title=d.find("[title]").attr("title")||c.title,c.description=d.text().replace(/[\s\n]+/gm," ").trim()}b["text/uri-list"]&&(c.uri=b["text/uri-list"]),b["text/x-moz-url"]&&!c.title&&(c.title=(b["text/x-moz-url"].split("\n")[1]||"").trim(),c.title===c.uri&&(c.title=!1)),b["text/x-iri-source-title"]&&!c.title&&(c.title=b["text/x-iri-source-title"]),(b["text/html"]||b["text/x-iri-selected-html"])&&(d=a("<div>").html(b["text/html"]||b["text/x-iri-selected-html"]),c.image=d.find("[data-image]").attr("data-image")||c.image,c.uri=d.find("[data-uri]").attr("data-uri")||c.uri,c.title=d.find("[data-title]").attr("data-title")||c.title,c.description=d.find("[data-description]").attr("data-description")||c.description,c.clipPath=d.find("[data-clip-path]").attr("data-clip-path")||c.clipPath),c.title||(c.title=this.renkan.translate("Dragged resource"));for(var j=["title","description","uri","image"],k=0;k<j.length;k++){var l=j[k];(b["text/x-iri-"+l]||b[l])&&(c[l]=b["text/x-iri-"+l]||b[l]),("none"===c[l]||"null"===c[l])&&(c[l]=void 0)}return"function"==typeof this.renkan.options.drop_enhancer&&(c=this.renkan.options.drop_enhancer(c,b)),c},dropData:function(a,c){if(this.isEditable()){if(a["text/json"]||a["application/json"])try{var d=JSON.parse(a["text/json"]||a["application/json"]);b(a).extend(d)}catch(e){}var g="undefined"==typeof this.renkan.options.drop_handler?this.defaultDropHandler(a):this.renkan.options.drop_handler(a),h=this.canvas_$.offset(),i=new paper.Point([c.pageX-h.left,c.pageY-h.top]),j=this.toModelCoords(i),k={id:f.getUID("node"),created_by:this.renkan.current_user,uri:g.uri||"",title:g.title||"",description:g.description||"",image:g.image||"",color:g.color||void 0,clip_path:g.clipPath||void 0,position:{x:j.x,y:j.y}},l=this.renkan.project.addNode(k),m=this.getRepresentationByModel(l);"drop"===c.type&&m.openEditor()}},fullScreen:function(){var a,b=document.fullScreen||document.mozFullScreen||document.webkitIsFullScreen,c=this.renkan.$[0],d=["requestFullScreen","mozRequestFullScreen","webkitRequestFullScreen"],e=["cancelFullScreen","mozCancelFullScreen","webkitCancelFullScreen"];if(b){for(a=0;a<e.length;a++)if("function"==typeof document[e[a]]){document[e[a]]();break}var f=this.$.width(),g=this.$.height();this.renkan.options.show_top_bar&&(g-=this.$.find(".Rk-TopBar").height()),this.renkan.options.show_bins&&this.renkan.$.find(".Rk-Bins").position().left>0&&(f-=this.renkan.$.find(".Rk-Bins").width()),paper.view.viewSize=new paper.Size([f,g])}else{for(a=0;a<d.length;a++)if("function"==typeof c[d[a]]){c[d[a]]();break}this.redraw()}},zoomOut:function(){var a=this.scale*Math.SQRT1_2,b=new paper.Point([this.canvas_$.width(),this.canvas_$.height()]).multiply(.5*(1-Math.SQRT1_2)).add(this.offset.multiply(Math.SQRT1_2));this.setScale(a,b)},zoomIn:function(){var a=this.scale*Math.SQRT2,b=new paper.Point([this.canvas_$.width(),this.canvas_$.height()]).multiply(.5*(1-Math.SQRT2)).add(this.offset.multiply(Math.SQRT2));this.setScale(a,b)},resizeZoom:function(a,b,c){var d=this.scale*c,e=new paper.Point([this.offset.x*a,this.offset.y*b]);this.setScale(d,e)},addNodeBtn:function(){return this.click_mode===f._CLICKMODE_ADDNODE?(this.click_mode=!1,this.notif_$.hide()):(this.click_mode=f._CLICKMODE_ADDNODE,this.notif_$.text(this.renkan.translate("Click on the background canvas to add a node")).fadeIn()),!1},addEdgeBtn:function(){return this.click_mode===f._CLICKMODE_STARTEDGE||this.click_mode===f._CLICKMODE_ENDEDGE?(this.click_mode=!1,this.notif_$.hide()):(this.click_mode=f._CLICKMODE_STARTEDGE,this.notif_$.text(this.renkan.translate("Click on a first node to start the edge")).fadeIn()),!1},exportProject:function(){var a=this.renkan.project.toJSON(),d=(document.createElement("a"),a.id),e=d+".json";delete a.id,delete a._id,delete a.space_id;var g,h={};b.each(a.nodes,function(a){g=a.id||a._id,delete a._id,delete a.id,h[g]=a["@id"]=f.getUUID4()}),b.each(a.edges,function(a){delete a._id,delete a.id,a.to=h[a.to],a.from=h[a.from]}),b.each(a.views,function(a){g=a.id||a._id,delete a._id,delete a.id}),a.users=[];var i=JSON.stringify(a,null,2),j=new Blob([i],{type:"application/json;charset=utf-8"});c(j,e)},foldBins:function(){var a,b=this.$.find(".Rk-Fold-Bins"),c=this.renkan.$.find(".Rk-Bins"),d=this,e=d.canvas_$.width();c.position().left<0?(c.animate({left:0},250),this.$.animate({left:300},250,function(){var a=d.$.width();paper.view.viewSize=new paper.Size([a,d.canvas_$.height()])}),a=e-c.width()<c.height()?e:e-c.width(),b.html("«")):(c.animate({left:-300},250),this.$.animate({left:0},250,function(){var a=d.$.width();paper.view.viewSize=new paper.Size([a,d.canvas_$.height()])}),a=e+300,b.html("»")),d.resizeZoom(1,1,a/e)},save:function(){},open:function(){}}),g}),"function"==typeof require.config&&require.config({paths:{jquery:"../lib/jquery/jquery",underscore:"../lib/underscore/underscore",filesaver:"../lib/FileSaver/FileSaver",requtils:"require-utils"}}),require(["renderer/baserepresentation","renderer/basebutton","renderer/noderepr","renderer/edge","renderer/tempedge","renderer/baseeditor","renderer/nodeeditor","renderer/edgeeditor","renderer/nodebutton","renderer/nodeeditbutton","renderer/noderemovebutton","renderer/noderevertbutton","renderer/nodelinkbutton","renderer/nodeenlargebutton","renderer/nodeshrinkbutton","renderer/edgeeditbutton","renderer/edgeremovebutton","renderer/edgerevertbutton","renderer/miniframe","renderer/scene"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t){var u=window.Rkns;"undefined"==typeof u.Renderer&&(u.Renderer={});var v=u.Renderer;v._BaseRepresentation=a,v._BaseButton=b,v.Node=c,v.Edge=d,v.TempEdge=e,v._BaseEditor=f,v.NodeEditor=g,v.EdgeEditor=h,v._NodeButton=i,v.NodeEditButton=j,v.NodeRemoveButton=k,v.NodeRevertButton=l,v.NodeLinkButton=m,v.NodeEnlargeButton=n,v.NodeShrinkButton=o,v.EdgeEditButton=p,v.EdgeRemoveButton=q,v.EdgeRevertButton=r,v.MiniFrame=s,v.Scene=t,startRenkan()}),define("main-renderer",function(){}); +this.renkanJST=this.renkanJST||{},this.renkanJST["templates/colorpicker.html"]=function(obj){obj||(obj={});{var __t,__p="";_.escape}with(obj)__p+='<li data-color="'+(null==(__t=c)?"":__t)+'" style="background: '+(null==(__t=c)?"":__t)+'"></li>';return __p},this.renkanJST["templates/edgeeditor.html"]=function(obj){obj||(obj={});{var __t,__p="",__e=_.escape;Array.prototype.join}with(obj)__p+='<h2>\n <span class="Rk-CloseX">×</span>'+__e(renkan.translate("Edit Edge"))+"</span>\n</h2>\n<p>\n <label>"+__e(renkan.translate("Title:"))+'</label>\n <input class="Rk-Edit-Title" type="text" value="'+__e(edge.title)+'" />\n</p>\n',options.show_edge_editor_uri&&(__p+="\n <p>\n <label>"+__e(renkan.translate("URI:"))+'</label>\n <input class="Rk-Edit-URI" type="text" value="'+__e(edge.uri)+'" />\n <a class="Rk-Edit-Goto" href="'+__e(edge.uri)+'" target="_blank"></a>\n </p>\n ',options.properties.length&&(__p+="\n <p>\n <label>"+__e(renkan.translate("Choose from vocabulary:"))+'</label>\n <select class="Rk-Edit-Vocabulary">\n ',_.each(options.properties,function(a){__p+='\n <option class="Rk-Edit-Vocabulary-Class" value="">\n '+__e(renkan.translate(a.label))+"\n </option>\n ",_.each(a.properties,function(b){var c=a["base-uri"]+b.uri;__p+='\n <option class="Rk-Edit-Vocabulary-Property" value="'+__e(c)+'"\n ',c===edge.uri&&(__p+=" selected"),__p+=">\n "+__e(renkan.translate(b.label))+"\n </option>\n "}),__p+="\n "}),__p+="\n </select>\n </p>\n")),__p+="\n",options.show_edge_editor_color&&(__p+='\n <div class="Rk-Editor-p">\n <span class="Rk-Editor-Label">'+__e(renkan.translate("Edge color:"))+'</span>\n <div class="Rk-Edit-ColorPicker-Wrapper">\n <span class="Rk-Edit-Color" style="background: <%-edge.color%>;">\n <span class="Rk-Edit-ColorTip"></span>\n </span>\n '+(null==(__t=renkan.colorPicker)?"":__t)+'\n <span class="Rk-Edit-ColorPicker-Text">'+__e(renkan.translate("Choose color"))+"</span>\n </div>\n </div>\n"),__p+="\n",options.show_edge_editor_direction&&(__p+='\n <p>\n <span class="Rk-Edit-Direction">'+__e(renkan.translate("Change edge direction"))+"</span>\n </p>\n"),__p+="\n",options.show_edge_editor_nodes&&(__p+='\n <p>\n <span class="Rk-Editor-Label">'+__e(renkan.translate("From:"))+'</span>\n <span class="Rk-UserColor" style="background: '+__e(edge.from_color)+';"></span>\n '+__e(shortenText(edge.from_title,25))+'\n </p>\n <p>\n <span class="Rk-Editor-Label">'+__e(renkan.translate("To:"))+'</span>\n <span class="Rk-UserColor" style="background: >%-edge.to_color%>;"></span>\n '+__e(shortenText(edge.to_title,25))+"\n </p>\n"),__p+="\n",options.show_edge_editor_creator&&edge.has_creator&&(__p+='\n <p>\n <span class="Rk-Editor-Label">'+__e(renkan.translate("Created by:"))+'</span>\n <span class="Rk-UserColor" style="background: <%-edge.created_by_color%>;"></span>\n '+__e(shortenText(edge.created_by_title,25))+"\n </p>\n"),__p+="\n";return __p},this.renkanJST["templates/edgeeditor_readonly.html"]=function(obj){obj||(obj={});{var __p="",__e=_.escape;Array.prototype.join}with(obj)__p+='<h2>\n <span class="Rk-CloseX">×</span>\n ',options.show_edge_tooltip_color&&(__p+='\n <span class="Rk-UserColor" style="background: '+__e(edge.color)+';"></span>\n '),__p+='\n <span class="Rk-Display-Title">\n ',edge.uri&&(__p+='\n <a href="'+__e(edge.uri)+'" target="_blank">\n '),__p+="\n "+__e(edge.title)+"\n ",edge.uri&&(__p+=" </a> "),__p+="\n </span>\n</h2>\n",options.show_edge_tooltip_uri&&edge.uri&&(__p+='\n <p class="Rk-Display-URI">\n <a href="'+__e(edge.uri)+'" target="_blank">'+__e(edge.short_uri)+"</a>\n </p>\n"),__p+="\n<p>"+__e(edge.description)+"</p>\n",options.show_edge_tooltip_nodes&&(__p+='\n <p>\n <span class="Rk-Editor-Label">'+__e(renkan.translate("From:"))+'</span>\n <span class="Rk-UserColor" style="background: '+__e(edge.from_color)+';"></span>\n '+__e(shortenText(edge.from_title,25))+'\n </p>\n <p>\n <span class="Rk-Editor-Label">'+__e(renkan.translate("To:"))+'</span>\n <span class="Rk-UserColor" style="background: '+__e(edge.to_color)+';"></span>\n '+__e(shortenText(edge.to_title,25))+"\n </p>\n"),__p+="\n",options.show_edge_tooltip_creator&&edge.has_creator&&(__p+='\n <p>\n <span class="Rk-Editor-Label">'+__e(renkan.translate("Created by:"))+'</span>\n <span class="Rk-UserColor" style="background: '+__e(edge.created_by_color)+';"></span>\n '+__e(shortenText(edge.created_by_title,25))+"\n </p>\n"),__p+="\n";return __p},this.renkanJST["templates/ldtjson-bin/annotationtemplate.html"]=function(obj){obj||(obj={});var __t,__p="",__e=_.escape;with(obj)__p+='<li class="Rk-Bin-Item" draggable="true"\n data-image="'+__e(Rkns.Utils.getFullURL(image))+'"\n data-uri="'+(null==(__t=ldt_platform)?"":__t)+"ldtplatform/ldt/front/player/"+(null==(__t=mediaid)?"":__t)+"/#id="+(null==(__t=annotationid)?"":__t)+'"\n data-title="'+__e(title)+'" data-description="'+__e(description)+'">\n\n <img class="Rk-Ldt-Annotation-Icon" src="'+(null==(__t=image)?"":__t)+'" />\n <h4>'+(null==(__t=htitle)?"":__t)+"</h4>\n <p>"+(null==(__t=hdescription)?"":__t)+"</p>\n <p>Start: "+(null==(__t=start)?"":__t)+", End: "+(null==(__t=end)?"":__t)+", Duration: "+(null==(__t=duration)?"":__t)+'</p>\n <div class="Rk-Clear"></div>\n</li>\n';return __p},this.renkanJST["templates/ldtjson-bin/segmenttemplate.html"]=function(obj){obj||(obj={});var __t,__p="",__e=_.escape;with(obj)__p+='<li class="Rk-Bin-Item" draggable="true"\n data-image="'+__e(Rkns.Utils.getFullURL(image))+'"\n data-uri="'+(null==(__t=ldt_platform)?"":__t)+"ldtplatform/ldt/front/player/"+(null==(__t=mediaid)?"":__t)+"/#id="+(null==(__t=annotationid)?"":__t)+'"\n data-title="'+__e(title)+'" data-description="'+__e(description)+'">\n\n <img class="Rk-Ldt-Annotation-Icon" src="'+(null==(__t=image)?"":__t)+'" />\n <h4>'+(null==(__t=htitle)?"":__t)+"</h4>\n <p>"+(null==(__t=hdescription)?"":__t)+"</p>\n <p>Start: "+(null==(__t=start)?"":__t)+", End: "+(null==(__t=end)?"":__t)+", Duration: "+(null==(__t=duration)?"":__t)+'</p>\n <div class="Rk-Clear"></div>\n</li>\n';return __p},this.renkanJST["templates/ldtjson-bin/tagtemplate.html"]=function(obj){obj||(obj={});var __t,__p="",__e=_.escape;with(obj)__p+='<li class="Rk-Bin-Item" draggable="true"\n data-image="'+__e(Rkns.Utils.getFullURL(static_url+"img/ldt-tag.png"))+'"\n data-uri="'+(null==(__t=ldt_platform)?"":__t)+"ldtplatform/ldt/front/search/?search="+(null==(__t=encodedtitle)?"":__t)+'&field=all"\n data-title="'+__e(title)+'" data-description="Tag \''+__e(title)+'\'">\n\n <img class="Rk-Ldt-Tag-Icon" src="'+__e(static_url)+'img/ldt-tag.png" />\n <h4>'+(null==(__t=htitle)?"":__t)+'</h4>\n <div class="Rk-Clear"></div>\n</li>\n';return __p},this.renkanJST["templates/list-bin.html"]=function(obj){obj||(obj={});{var __t,__p="",__e=_.escape;Array.prototype.join}with(obj)__p+='<li class="Rk-Bin-Item Rk-ResourceList-Item" draggable="true"\n data-uri="'+__e(url)+'" data-title="'+__e(title)+'"\n data-description="'+__e(description)+'"\n ',__p+=image?'\n data-image="'+__e(Rkns.Utils.getFullURL(image))+'"\n ':'\n data-image=""\n ',__p+="\n>",image&&(__p+='\n <img class="Rk-ResourceList-Image" src="'+__e(image)+'" />\n'),__p+='\n<h4 class="Rk-ResourceList-Title">\n ',url&&(__p+='\n <a href="'+__e(url)+'" target="_blank">\n '),__p+="\n "+(null==(__t=htitle)?"":__t)+"\n ",url&&(__p+="</a>"),__p+="\n </h4>\n ",description&&(__p+='\n <p class="Rk-ResourceList-Description">'+(null==(__t=hdescription)?"":__t)+"</p>\n "),__p+="\n ",image&&(__p+='\n <div style="clear: both;"></div>\n '),__p+="\n</li>\n";return __p},this.renkanJST["templates/main.html"]=function(obj){obj||(obj={});{var __p="",__e=_.escape;Array.prototype.join}with(obj)options.show_bins&&(__p+='\n <div class="Rk-Bins">\n <div class="Rk-Bins-Head">\n <h2 class="Rk-Bins-Title">'+__e(translate("Select contents:"))+'</h2>\n <form class="Rk-Web-Search-Form Rk-Search-Form">\n <input class="Rk-Web-Search-Input Rk-Search-Input" type="search"\n placeholder="'+__e(translate("Search the Web"))+'" />\n <div class="Rk-Search-Select">\n <div class="Rk-Search-Current"></div>\n <ul class="Rk-Search-List"></ul>\n </div>\n <input type="submit" value=""\n class="Rk-Web-Search-Submit Rk-Search-Submit" title="'+__e(translate("Search the Web"))+'" />\n </form>\n <form class="Rk-Bins-Search-Form Rk-Search-Form">\n <input class="Rk-Bins-Search-Input Rk-Search-Input" type="search"\n placeholder="'+__e(translate("Search in Bins"))+'" /> <input\n type="submit" value=""\n class="Rk-Bins-Search-Submit Rk-Search-Submit"\n title="'+__e(translate("Search in Bins"))+'" />\n </form>\n </div>\n <ul class="Rk-Bin-List"></ul>\n </div>\n'),__p+=" ",options.show_editor&&(__p+='\n <div class="Rk-Render Rk-Render-',__p+=options.show_bins?"Panel":"Full",__p+='"></div>\n'),__p+="\n";return __p},this.renkanJST["templates/nodeeditor.html"]=function(obj){obj||(obj={});{var __t,__p="",__e=_.escape;Array.prototype.join}with(obj)__p+='<h2>\n <span class="Rk-CloseX">×</span>'+__e(renkan.translate("Edit Node"))+"</span>\n</h2>\n<p>\n <label>"+__e(renkan.translate("Title:"))+'</label>\n <input class="Rk-Edit-Title" type="text" value="'+__e(node.title)+'" />\n</p>\n',options.show_node_editor_uri&&(__p+="\n <p>\n <label>"+__e(renkan.translate("URI:"))+'</label>\n <input class="Rk-Edit-URI" type="text" value="'+__e(node.uri)+'" />\n <a class="Rk-Edit-Goto" href="'+__e(node.uri)+'" target="_blank"></a>\n </p>\n'),__p+=" ",options.show_node_editor_description&&(__p+="\n <p>\n <label>"+__e(renkan.translate("Description:"))+'</label>\n <textarea class="Rk-Edit-Description">'+__e(node.description)+"</textarea>\n </p>\n"),__p+=" ",options.show_node_editor_size&&(__p+='\n <p>\n <span class="Rk-Editor-Label">'+__e(renkan.translate("Size:"))+'</span>\n <a href="#" class="Rk-Edit-Size-Down">-</a>\n <span class="Rk-Edit-Size-Value">'+__e(node.size)+'</span>\n <a href="#" class="Rk-Edit-Size-Up">+</a>\n </p>\n'),__p+=" ",options.show_node_editor_color&&(__p+='\n <div class="Rk-Editor-p">\n <span class="Rk-Editor-Label">\n '+__e(renkan.translate("Node color:"))+'</span>\n <div class="Rk-Edit-ColorPicker-Wrapper">\n <span class="Rk-Edit-Color" style="background: '+__e(node.color)+';">\n <span class="Rk-Edit-ColorTip"></span>\n </span>\n '+(null==(__t=renkan.colorPicker)?"":__t)+'\n <span class="Rk-Edit-ColorPicker-Text">'+__e(renkan.translate("Choose color"))+"</span>\n </div>\n </div>\n"),__p+=" ",options.show_node_editor_image&&(__p+='\n <div class="Rk-Edit-ImgWrap">\n <div class="Rk-Edit-ImgPreview">\n <img src="'+__e(node.image||node.image_placeholder)+'" />\n ',node.clip_path&&(__p+='\n <svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewbox="0 0 1 1" preserveAspectRatio="none">\n <path style="stroke-width: .02; stroke:red; fill-opacity:.3; fill:red;" d="'+__e(node.clip_path)+'" />\n </svg>\n '),__p+="\n </div>\n </div>\n <p>\n <label>"+__e(renkan.translate("Image URL:"))+'</label>\n <div>\n <a class="Rk-Edit-Image-Del" href="#"></a>\n <input class="Rk-Edit-Image" type="text" value=\''+__e(node.image)+"' />\n </div>\n </p>\n",options.allow_image_upload&&(__p+="\n <p>\n <label>"+__e(renkan.translate("Choose Image File:"))+'</label>\n <input class="Rk-Edit-Image-File" type="file" accept="image/*" />\n </p>\n')),__p+=" ",options.show_node_editor_creator&&node.has_creator&&(__p+='\n <p>\n <span class="Rk-Editor-Label">'+__e(renkan.translate("Created by:"))+'</span>\n <span class="Rk-UserColor" style="background: '+__e(node.created_by_color)+';"></span>\n '+__e(shortenText(node.created_by_title,25))+"\n </p>\n"),__p+=" ",options.change_shapes&&(__p+="\n <p>\n <label>"+__e(renkan.translate("Shapes available"))+':</label>\n <select class="Rk-Edit-Shape">\n <option class="Rk-Edit-Vocabulary-Property" value="circle"',"circle"===node.shape&&(__p+=" selected"),__p+=">\n "+__e(renkan.translate("Circle"))+'\n </option>\n <option class="Rk-Edit-Vocabulary-Property" value="rectangle"',"rectangle"===node.shape&&(__p+=" selected"),__p+=">\n "+__e(renkan.translate("Square"))+'\n </option>\n <option class="Rk-Edit-Vocabulary-Property" value="diamond"',"diamond"===node.shape&&(__p+=" selected"),__p+=">\n "+__e(renkan.translate("Diamond"))+'\n </option>\n <option class="Rk-Edit-Vocabulary-Property" value="polygon"',"polygon"===node.shape&&(__p+=" selected"),__p+=">\n "+__e(renkan.translate("Hexagone"))+'\n </option>\n <option class="Rk-Edit-Vocabulary-Property" value="ellipse"',"ellipse"===node.shape&&(__p+=" selected"),__p+=">\n "+__e(renkan.translate("Ellipse"))+'\n </option>\n <option class="Rk-Edit-Vocabulary-Property" value="star"',"star"===node.shape&&(__p+=" selected"),__p+=">\n "+__e(renkan.translate("Star"))+"\n </option>\n </select>\n </p>\n"),__p+="\n";return __p},this.renkanJST["templates/nodeeditor_readonly.html"]=function(obj){obj||(obj={});{var __p="",__e=_.escape;Array.prototype.join}with(obj)__p+='<h2>\n <span class="Rk-CloseX">×</span>\n ',options.show_node_tooltip_color&&(__p+='\n <span class="Rk-UserColor" style="background: '+__e(node.color)+';"></span>\n '),__p+='\n <span class="Rk-Display-Title">\n ',node.uri&&(__p+='\n <a href="'+__e(node.uri)+'" target="_blank">\n '),__p+="\n "+__e(node.title)+"\n ",node.uri&&(__p+="</a>"),__p+="\n </span>\n</h2>\n",node.uri&&options.show_node_tooltip_uri&&(__p+='\n <p class="Rk-Display-URI">\n <a href="'+__e(node.uri)+'" target="_blank">'+__e(node.short_uri)+"</a>\n </p>\n"),__p+=" ",options.show_node_tooltip_description&&(__p+='\n <p class="Rk-Display-Description">'+__e(node.description)+"</p>\n"),__p+=" ",node.image&&options.show_node_tooltip_image&&(__p+='\n <img class="Rk-Display-ImgPreview" src="'+__e(node.image)+'" />\n'),__p+=" ",node.has_creator&&options.show_node_tooltip_creator&&(__p+='\n <p>\n <span class="Rk-Editor-Label">'+__e(renkan.translate("Created by:"))+'</span>\n <span class="Rk-UserColor" style="background: '+__e(node.created_by_color)+';"></span>\n '+__e(shortenText(node.created_by_title,25))+"\n </p>\n"),__p+="\n";return __p},this.renkanJST["templates/scene.html"]=function(obj){function print(){__p+=__j.call(arguments,"")}obj||(obj={});var __p="",__e=_.escape,__j=Array.prototype.join;with(obj)options.show_top_bar&&(__p+='\n <div class="Rk-TopBar">\n <div class="loader"></div>\n ',__p+=options.editor_mode?'\n <input type="text" class="Rk-PadTitle" value="'+__e(project.get("title")||"")+'" placeholder="'+__e(translate("Untitled project"))+'" />\n ':'\n <h2 class="Rk-PadTitle">\n '+__e(project.get("title")||translate("Untitled project"))+"\n </h2>\n ",__p+="\n ",options.show_user_list&&(__p+='\n <div class="Rk-Users">\n <div class="Rk-CurrentUser">\n ',options.show_user_color&&(__p+='\n <div class="Rk-Edit-ColorPicker-Wrapper">\n <span class="Rk-CurrentUser-Color">\n ',options.user_color_editable&&(__p+='\n <span class="Rk-Edit-ColorTip"></span>\n '),__p+="\n </span>\n ",options.user_color_editable&&print(colorPicker),__p+="\n </div>\n "),__p+='\n <span class="Rk-CurrentUser-Name"><unknown user></span>\n </div>\n <ul class="Rk-UserList"></ul>\n </div>\n '),__p+="\n ",options.home_button_url&&(__p+='\n <div class="Rk-TopBar-Separator"></div>\n <a class="Rk-TopBar-Button Rk-Home-Button" href="'+__e(options.home_button_url)+'">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n '+__e(translate(options.home_button_title))+"\n </div>\n </div>\n </a>\n "),__p+="\n ",options.show_fullscreen_button&&(__p+='\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-FullScreen-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n '+__e(translate("Full Screen"))+"\n </div>\n </div>\n </div>\n "),__p+="\n ",options.editor_mode?(__p+="\n ",options.show_addnode_button&&(__p+='\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-AddNode-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n '+__e(translate("Add Node"))+"\n </div>\n </div>\n </div>\n "),__p+="\n ",options.show_addedge_button&&(__p+='\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-AddEdge-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n '+__e(translate("Add Edge"))+"\n </div>\n </div>\n </div>\n "),__p+="\n ",options.show_export_button&&(__p+='\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-Export-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n '+__e(translate("Download Project"))+"\n </div>\n </div>\n </div>\n "),__p+="\n ",options.show_save_button&&(__p+='\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-Save-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents"></div>\n </div>\n </div>\n '),__p+="\n ",options.show_open_button&&(__p+='\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-Open-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n '+__e(translate("Open Project"))+"\n </div>\n </div>\n </div>\n "),__p+="\n ",options.show_bookmarklet&&(__p+='\n <div class="Rk-TopBar-Separator"></div>\n <a class="Rk-TopBar-Button Rk-Bookmarklet-Button" href="#">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n '+__e(translate("Renkan 'Drag-to-Add' bookmarklet"))+'\n </div>\n </div>\n </a>\n <div class="Rk-TopBar-Separator"></div>\n '),__p+="\n "):(__p+="\n ",options.show_export_button&&(__p+='\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-Export-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n '+__e(translate("Download Project"))+'\n </div>\n </div>\n </div>\n <div class="Rk-TopBar-Separator"></div>\n '),__p+="\n "),__p+="\n ",options.show_search_field&&(__p+='\n <form action="#" class="Rk-GraphSearch-Form">\n <input type="search" class="Rk-GraphSearch-Field" placeholder="'+__e(translate("Search in graph"))+'" />\n </form>\n <div class="Rk-TopBar-Separator"></div>\n '),__p+="\n </div>\n"),__p+='\n<div class="Rk-Editing-Space',options.show_top_bar||(__p+=" Rk-Editing-Space-Full"),__p+='">\n <div class="Rk-Labels"></div>\n <canvas class="Rk-Canvas" ',options.resize&&(__p+=' resize="" '),__p+='></canvas>\n <div class="Rk-Notifications"></div>\n <div class="Rk-Editor">\n ',options.show_bins&&(__p+='\n <div class="Rk-Fold-Bins">«</div>\n '),__p+="\n ",options.show_zoom&&(__p+='\n <div class="Rk-ZoomButtons">\n <div class="Rk-ZoomIn" title="'+__e(translate("Zoom In"))+'"></div>\n <div class="Rk-ZoomFit" title="'+__e(translate("Zoom Fit"))+'"></div>\n <div class="Rk-ZoomOut" title="'+__e(translate("Zoom Out"))+'"></div>\n ',options.editor_mode&&options.save_view&&(__p+='\n <div class="Rk-ZoomSave" title="'+__e(translate("Zoom Save"))+'"></div>\n '),__p+="\n ",options.save_view&&(__p+='\n <div class="Rk-ZoomSetSaved" title="'+__e(translate("View saved zoom"))+'"></div>\n '),__p+="\n </div>\n "),__p+="\n </div>\n</div>\n";return __p},this.renkanJST["templates/search.html"]=function(obj){obj||(obj={});{var __t,__p="";_.escape}with(obj)__p+='<li class="'+(null==(__t=className)?"":__t)+'" data-key="'+(null==(__t=key)?"":__t)+'">'+(null==(__t=title)?"":__t)+"</li>";return __p},this.renkanJST["templates/wikipedia-bin/resulttemplate.html"]=function(obj){obj||(obj={});var __t,__p="",__e=_.escape;with(obj)__p+='<li class="Rk-Wikipedia-Result Rk-Bin-Item" draggable="true"\n data-uri="'+__e(url)+'" data-title="Wikipedia: '+__e(title)+'"\n data-description="'+__e(description)+'"\n data-image="'+__e(Rkns.Utils.getFullURL(static_url+"img/wikipedia.png"))+'">\n\n <img class="Rk-Wikipedia-Icon" src="'+__e(static_url)+'img/wikipedia.png">\n <h4 class="Rk-Wikipedia-Title">\n <a href="'+__e(url)+'" target="_blank">'+(null==(__t=htitle)?"":__t)+'</a>\n </h4>\n <p class="Rk-Wikipedia-Snippet">'+(null==(__t=hdescription)?"":__t)+"</p>\n</li>\n";return __p},function(a){"use strict";"object"!=typeof a.Rkns&&(a.Rkns={});var b=a.Rkns,c=b.$=a.jQuery,d=b._=a._;b.pickerColors=["#8f1919","#a80000","#d82626","#ff0000","#e87c7c","#ff6565","#f7d3d3","#fecccc","#8f5419","#a85400","#d87f26","#ff7f00","#e8b27c","#ffb265","#f7e5d3","#fee5cc","#8f8f19","#a8a800","#d8d826","#feff00","#e8e87c","#feff65","#f7f7d3","#fefecc","#198f19","#00a800","#26d826","#00ff00","#7ce87c","#65ff65","#d3f7d3","#ccfecc","#198f8f","#00a8a8","#26d8d8","#00feff","#7ce8e8","#65feff","#d3f7f7","#ccfefe","#19198f","#0000a8","#2626d8","#0000ff","#7c7ce8","#6565ff","#d3d3f7","#ccccfe","#8f198f","#a800a8","#d826d8","#ff00fe","#e87ce8","#ff65fe","#f7d3f7","#feccfe","#000000","#242424","#484848","#6d6d6d","#919191","#b6b6b6","#dadada","#ffffff"],b.__renkans=[];var e=b._BaseBin=function(a,c){if("undefined"!=typeof a){this.renkan=a,this.renkan.$.find(".Rk-Bin-Main").hide(),this.$=b.$("<li>").addClass("Rk-Bin").appendTo(a.$.find(".Rk-Bin-List")),this.title_icon_$=b.$("<span>").addClass("Rk-Bin-Title-Icon").appendTo(this.$);var d=this;b.$("<a>").attr({href:"#",title:a.translate("Close bin")}).addClass("Rk-Bin-Close").html("×").appendTo(this.$).click(function(){return d.destroy(),a.$.find(".Rk-Bin-Main:visible").length||a.$.find(".Rk-Bin-Main:last").slideDown(),a.resizeBins(),!1}),b.$("<a>").attr({href:"#",title:a.translate("Refresh bin")}).addClass("Rk-Bin-Refresh").appendTo(this.$).click(function(){return d.refresh(),!1}),this.count_$=b.$("<div>").addClass("Rk-Bin-Count").appendTo(this.$),this.title_$=b.$("<h2>").addClass("Rk-Bin-Title").appendTo(this.$),this.main_$=b.$("<div>").addClass("Rk-Bin-Main").appendTo(this.$).html('<h4 class="Rk-Bin-Loading">'+a.translate("Loading, please wait")+"</h4>"),this.title_$.html(c.title||"(new bin)"),this.renkan.resizeBins(),c.auto_refresh&&window.setInterval(function(){d.refresh()},c.auto_refresh)}};e.prototype.destroy=function(){this.$.detach(),this.renkan.resizeBins()};var f=b.Renkan=function(a){var e=this;if(b.__renkans.push(this),this.options=d.defaults(a,b.defaults,{templates:renkanJST}),this.template=renkanJST["templates/main.html"],d.each(this.options.property_files,function(a){b.$.getJSON(a,function(a){e.options.properties=e.options.properties.concat(a)})}),this.read_only=this.options.read_only||!this.options.editor_mode,this.project=new b.Models.Project,this.setCurrentUser=function(a,b){this.project.addUser({_id:a,title:b}),this.current_user=a,this.renderer.redrawUsers()},"undefined"!=typeof this.options.user_id&&(this.current_user=this.options.user_id),this.$=b.$("#"+this.options.container),this.$.addClass("Rk-Main").html(this.template(this)),this.tabs=[],this.search_engines=[],this.current_user_list=new b.Models.UsersList,this.current_user_list.on("add remove",function(){this.renderer&&this.renderer.redrawUsers()}),this.colorPicker=function(){var a=renkanJST["templates/colorpicker.html"];return'<ul class="Rk-Edit-ColorPicker">'+b.pickerColors.map(function(b){return a({c:b})}).join("")+"</ul>"}(),this.options.show_editor&&(this.renderer=new b.Renderer.Scene(this)),this.options.search.length){var f=renkanJST["templates/search.html"],g=this.$.find(".Rk-Search-List"),h=this.$.find(".Rk-Web-Search-Input"),i=this.$.find(".Rk-Web-Search-Form");d.each(this.options.search,function(a){b[a.type]&&b[a.type].Search&&e.search_engines.push(new b[a.type].Search(e,a))}),g.html(d(this.search_engines).map(function(a,b){return f({key:b,title:a.getSearchTitle(),className:a.getBgClass()})}).join("")),g.find("li").click(function(){var a=b.$(this);e.setSearchEngine(a.attr("data-key")),i.submit()}),i.submit(function(){if(h.val()){var a=e.search_engine;a.search(h.val())}return!1}),this.$.find(".Rk-Search-Current").mouseenter(function(){g.slideDown()}),this.$.find(".Rk-Search-Select").mouseleave(function(){g.hide()}),this.setSearchEngine(0)}else this.$.find(".Rk-Web-Search-Form").detach();d.each(this.options.bins,function(a){b[a.type]&&b[a.type].Bin&&e.tabs.push(new b[a.type].Bin(e,a))});var j=!1;this.$.find(".Rk-Bins").on("click",".Rk-Bin-Title,.Rk-Bin-Title-Icon",function(){var a=b.$(this).siblings(".Rk-Bin-Main");a.is(":hidden")&&(e.$.find(".Rk-Bin-Main").slideUp(),a.slideDown())}),this.options.show_editor&&this.$.find(".Rk-Bins").on("mouseover",".Rk-Bin-Item",function(){var a=b.$(this);if(a&&c(a).attr("data-uri")){var f=e.project.get("nodes").where({uri:c(a).attr("data-uri")});d.each(f,function(a){e.renderer.highlightModel(a)})}}).mouseout(function(){e.renderer.unhighlightAll()}).on("mousemove",".Rk-Bin-Item",function(){try{this.dragDrop()}catch(a){}}).on("touchstart",".Rk-Bin-Item",function(){j=!1}).on("touchmove",".Rk-Bin-Item",function(a){a.preventDefault();var b=a.originalEvent.changedTouches[0],c=e.renderer.canvas_$.offset(),d=e.renderer.canvas_$.width(),f=e.renderer.canvas_$.height();if(b.pageX>=c.left&&b.pageX<c.left+d&&b.pageY>=c.top&&b.pageY<c.top+f)if(j)e.renderer.onMouseMove(b,!0);else{j=!0;var g=document.createElement("div");g.appendChild(this.cloneNode(!0)),e.renderer.dropData({"text/html":g.innerHTML},b),e.renderer.onMouseDown(b,!0)}}).on("touchend",".Rk-Bin-Item",function(a){j&&e.renderer.onMouseUp(a.originalEvent.changedTouches[0],!0),j=!1}).on("dragstart",".Rk-Bin-Item",function(a){var b=document.createElement("div");b.appendChild(this.cloneNode(!0));try{a.originalEvent.dataTransfer.setData("text/html",b.innerHTML)}catch(c){a.originalEvent.dataTransfer.setData("text",b.innerHTML)}}),b.$(window).resize(function(){e.resizeBins()});var k=!1,l="";this.$.find(".Rk-Bins-Search-Input").on("change keyup paste input",function(){var a=b.$(this).val();if(a!==l){var c=b.Utils.regexpFromTextOrArray(a.length>1?a:null);c.source!==k&&(k=c.source,d.each(e.tabs,function(a){a.render(c)}))}}),this.$.find(".Rk-Bins-Search-Form").submit(function(){return!1})};f.prototype.translate=function(a){return b.i18n[this.options.language]&&b.i18n[this.options.language][a]?b.i18n[this.options.language][a]:this.options.language.length>2&&b.i18n[this.options.language.substr(0,2)]&&b.i18n[this.options.language.substr(0,2)][a]?b.i18n[this.options.language.substr(0,2)][a]:a},f.prototype.onStatusChange=function(){this.renderer.onStatusChange()},f.prototype.setSearchEngine=function(a){this.search_engine=this.search_engines[a],this.$.find(".Rk-Search-Current").attr("class","Rk-Search-Current "+this.search_engine.getBgClass());for(var b=this.search_engine.getBgClass().split(" "),c="",d=0;d<b.length;d++)c+="."+b[d];this.$.find(".Rk-Web-Search-Input.Rk-Search-Input").attr("placeholder",this.translate("Search in ")+this.$.find(".Rk-Search-List "+c).html())},f.prototype.resizeBins=function(){var a=+this.$.find(".Rk-Bins-Head").outerHeight();this.$.find(".Rk-Bin-Title:visible").each(function(){a+=b.$(this).outerHeight()}),this.$.find(".Rk-Bin-Main").css({height:this.$.find(".Rk-Bins").height()-a})};var g=function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=16*Math.random()|0,c="x"===a?b:3&b|8;return c.toString(16)})};b.Utils={getUUID4:g,getUID:function(){function a(a){return 10>a?"0"+a:a}var b=new Date,c=0,d=b.getUTCFullYear()+"-"+a(b.getUTCMonth()+1)+"-"+a(b.getUTCDate())+"-"+g();return function(a){for(var b=(++c).toString(16),e="undefined"==typeof a?"":a+"-";b.length<4;)b="0"+b;return e+d+"-"+b}}(),getFullURL:function(a){if("undefined"==typeof a||null==a)return"";if(/https?:\/\//.test(a))return a;var b=new Image;b.src=a;var c=b.src;return b.src=null,c},inherit:function(a,b){var c=function(){"function"==typeof b&&b.apply(this,Array.prototype.slice.call(arguments,0)),a.apply(this,Array.prototype.slice.call(arguments,0)),"function"!=typeof this._init||this._initialized||(this._init.apply(this,Array.prototype.slice.call(arguments,0)),this._initialized=!0)};return d.extend(c.prototype,a.prototype),c},regexpFromTextOrArray:function(){function a(a){function b(a){return function(b,c){a=a.replace(h[b],c)}}for(var e=a.toLowerCase().replace(g,""),i="",j=0;j<e.length;j++){j&&(i+=f+"*");var k=e[j];d.each(c,b(k)),i+=k}return i +}function b(c){switch(typeof c){case"string":return a(c);case"object":var e="";return d.each(c,function(a){var c=b(a);c&&(e&&(e+="|"),e+=c)}),e}return""}var c=["[aÔà âä]","[cƧ]","[eéèêë]","[iĆìîï]","[oóòÓö]","[uùûü]"],e=[String.fromCharCode(768),String.fromCharCode(769),String.fromCharCode(770),String.fromCharCode(771),String.fromCharCode(807),"ļ½","ļ½","ļ¼","ļ¼","ļ¼»","ļ¼½","ć","ć","ć","ć»","ā„","ć","ć","ć","ć","ć","ć","ļ¼","ļ¼","ļ¼","ć",","," ",";","(",")",".","*","+","\\","?","|","{","}","[","]","^","#","/"],f="[\\"+e.join("\\")+"]",g=new RegExp(f,"gm"),h=d.map(c,function(a){return new RegExp(a)});return function(a){var c=b(a);if(c){var d=new RegExp(c,"im"),e=new RegExp("("+c+")","igm");return{isempty:!1,source:c,test:function(a){return d.test(a)},replace:function(a,b){return a.replace(e,b)}}}return{isempty:!0,source:"",test:function(){return!0},replace:function(){return text}}}}(),_MIN_DRAG_DISTANCE:2,_NODE_BUTTON_WIDTH:40,_EDGE_BUTTON_INNER:2,_EDGE_BUTTON_OUTER:40,_CLICKMODE_ADDNODE:1,_CLICKMODE_STARTEDGE:2,_CLICKMODE_ENDEDGE:3,_NODE_SIZE_STEP:Math.LN2/4,_MIN_SCALE:.05,_MAX_SCALE:20,_MOUSEMOVE_RATE:80,_DOUBLETAP_DELAY:800,_DOUBLETAP_DISTANCE:400,_USER_PLACEHOLDER:function(a){return{color:a.options.default_user_color,title:a.translate("(unknown user)"),get:function(a){return this[a]||!1}}},_BOOKMARKLET_CODE:function(a){return"(function(a,b,c,d,e,f,h,i,j,k,l,m,n,o,p,q,r){a=document;b=a.body;c=a.location.href;j='draggable';m='text/x-iri-';d=a.createElement('div');d.innerHTML='<p_style=\"position:fixed;top:0;right:0;font:bold_18px_sans-serif;color:#fff;background:#909;padding:10px;z-index:100000;\">"+a.translate("Drag items from this website, drop them in Renkan").replace(/ /g,"_")+"</p>'.replace(/_/g,String.fromCharCode(32));b.appendChild(d);e=[{r:/https?:\\/\\/[^\\/]*twitter\\.com\\//,s:'.tweet',n:'twitter'},{r:/https?:\\/\\/[^\\/]*google\\.[^\\/]+\\//,s:'.g',n:'google'},{r:/https?:\\/\\/[^\\/]*lemonde\\.fr\\//,s:'[data-vr-contentbox]',n:'lemonde'}];f=false;e.forEach(function(g){if(g.r.test(c)){f=g;}});if(f){h=function(){Array.prototype.forEach.call(a.querySelectorAll(f.s),function(i){i[j]=true;k=i.style;k.borderWidth='2px';k.borderColor='#909';k.borderStyle='solid';k.backgroundColor='rgba(200,0,180,.1)';})};window.setInterval(h,500);h();};a.addEventListener('dragstart',function(k){l=k.dataTransfer;l.setData(m+'source-uri',c);l.setData(m+'source-title',a.title);n=k.target;if(f){o=n;while(!o.attributes[j]){o=o.parentNode;if(o==b){break;}}}if(f&&o.attributes[j]){p=o.cloneNode(true);l.setData(m+'specific-site',f.n)}else{q=a.getSelection();if(q.type==='Range'||!q.type){p=q.getRangeAt(0).cloneContents();}else{p=n.cloneNode();}}r=a.createElement('div');r.appendChild(p);l.setData('text/x-iri-selected-text',r.textContent.trim());l.setData('text/x-iri-selected-html',r.innerHTML);},false);})();"},shortenText:function(a,b){return a.length>b?a.substr(0,b)+"ā¦":a},drawEditBox:function(a,b,c,d,e){e.css({width:a.tooltip_width-2*a.tooltip_padding});var f=e.outerHeight()+2*a.tooltip_padding,g=b.x<paper.view.center.x?1:-1,h=b.x+g*(d+a.tooltip_arrow_length),i=b.x+g*(d+a.tooltip_arrow_length+a.tooltip_width),j=b.y-f/2;j+f>paper.view.size.height-a.tooltip_margin&&(j=Math.max(paper.view.size.height-a.tooltip_margin,b.y+a.tooltip_arrow_width/2)-f),j<a.tooltip_margin&&(j=Math.min(a.tooltip_margin,b.y-a.tooltip_arrow_width/2));var k=j+f;return c.segments[0].point=c.segments[7].point=b.add([g*d,0]),c.segments[1].point.x=c.segments[2].point.x=c.segments[5].point.x=c.segments[6].point.x=h,c.segments[3].point.x=c.segments[4].point.x=i,c.segments[2].point.y=c.segments[3].point.y=j,c.segments[4].point.y=c.segments[5].point.y=k,c.segments[1].point.y=b.y-a.tooltip_arrow_width/2,c.segments[6].point.y=b.y+a.tooltip_arrow_width/2,c.closed=!0,c.fillColor=new paper.GradientColor(new paper.Gradient([a.tooltip_top_color,a.tooltip_bottom_color]),[0,j],[0,k]),e.css({left:a.tooltip_padding+Math.min(h,i),top:a.tooltip_padding+j}),c}}}(window),function(){"use strict";var a=this,b=a.Backbone,c=a.Rkns.Models={};c.getUID=function(a){var b="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=16*Math.random()|0,c="x"===a?b:3&b|8;return c.toString(16)});return"undefined"!=typeof a?a.type+"-"+b:b};{var d=b.RelationalModel.extend({idAttribute:"_id",constructor:function(a){"undefined"!=typeof a&&(a._id=a._id||a.id||c.getUID(this),a.title=a.title||"",a.description=a.description||"",a.uri=a.uri||"","function"==typeof this.prepare&&(a=this.prepare(a))),b.RelationalModel.prototype.constructor.call(this,a)},validate:function(){return this.type?void 0:"object has no type"},addReference:function(a,b,c,d,e){var f=c.get(d);a[b]="undefined"==typeof f&&"undefined"!=typeof e?e:f}}),e=c.User=d.extend({type:"user",prepare:function(a){return a.color=a.color||"#666666",a},toJSON:function(){return{_id:this.get("_id"),title:this.get("title"),uri:this.get("uri"),description:this.get("description"),color:this.get("color")}}}),f=c.Node=d.extend({type:"node",relations:[{type:b.HasOne,key:"created_by",relatedModel:e}],prepare:function(a){var b=a.project;return this.addReference(a,"created_by",b.get("users"),a.created_by,b.current_user),a.description=a.description||"",a},toJSON:function(){return{_id:this.get("_id"),title:this.get("title"),uri:this.get("uri"),description:this.get("description"),position:this.get("position"),image:this.get("image"),color:this.get("color"),created_by:this.get("created_by")?this.get("created_by").get("_id"):null,size:this.get("size"),clip_path:this.get("clip_path"),shape:this.get("shape"),type:this.get("type"),hidden:this.get("hidden")}}}),g=c.Edge=d.extend({type:"edge",relations:[{type:b.HasOne,key:"created_by",relatedModel:e},{type:b.HasOne,key:"from",relatedModel:f},{type:b.HasOne,key:"to",relatedModel:f}],prepare:function(a){var b=a.project;return this.addReference(a,"created_by",b.get("users"),a.created_by,b.current_user),this.addReference(a,"from",b.get("nodes"),a.from),this.addReference(a,"to",b.get("nodes"),a.to),a},toJSON:function(){return{_id:this.get("_id"),title:this.get("title"),uri:this.get("uri"),description:this.get("description"),from:this.get("from")?this.get("from").get("_id"):null,to:this.get("to")?this.get("to").get("_id"):null,color:this.get("color"),created_by:this.get("created_by")?this.get("created_by").get("_id"):null}}}),h=c.View=d.extend({type:"view",relations:[{type:b.HasOne,key:"created_by",relatedModel:e}],prepare:function(a){var b=a.project;if(this.addReference(a,"created_by",b.get("users"),a.created_by,b.current_user),a.description=a.description||"","undefined"!=typeof a.offset){var c={};Array.isArray(a.offset)?(c.x=a.offset[0],c.y=a.offset.length>1?a.offset[1]:a.offset[0]):null!=a.offset.x&&(c.x=a.offset.x,c.y=a.offset.y),a.offset=c}return a},toJSON:function(){return{_id:this.get("_id"),zoom_level:this.get("zoom_level"),offset:this.get("offset"),title:this.get("title"),description:this.get("description"),created_by:this.get("created_by")?this.get("created_by").get("_id"):null}}}),i=(c.Project=d.extend({type:"project",blacklist:["save_status"],relations:[{type:b.HasMany,key:"users",relatedModel:e,reverseRelation:{key:"project",includeInJSON:"_id"}},{type:b.HasMany,key:"nodes",relatedModel:f,reverseRelation:{key:"project",includeInJSON:"_id"}},{type:b.HasMany,key:"edges",relatedModel:g,reverseRelation:{key:"project",includeInJSON:"_id"}},{type:b.HasMany,key:"views",relatedModel:h,reverseRelation:{key:"project",includeInJSON:"_id"}}],addUser:function(a,b){a.project=this;var c=e.findOrCreate(a);return this.get("users").push(c,b),c},addNode:function(a,b){a.project=this;var c=f.findOrCreate(a);return this.get("nodes").push(c,b),c},addEdge:function(a,b){a.project=this;var c=g.findOrCreate(a);return this.get("edges").push(c,b),c},addView:function(a,b){a.project=this;var c=h.findOrCreate(a);return this.get("views").push(c,b),c},removeNode:function(a){this.get("nodes").remove(a)},removeEdge:function(a){this.get("edges").remove(a)},validate:function(a){var b=this;_.each([].concat(a.users,a.nodes,a.edges,a.views),function(a){a&&(a.project=b)})},initialize:function(){var a=this;this.on("remove:nodes",function(b){a.get("edges").remove(a.get("edges").filter(function(a){return a.get("from")===b||a.get("to")===b}))})},toJSON:function(){var a=_.clone(this.attributes);for(var c in a)(a[c]instanceof b.Model||a[c]instanceof b.Collection||a[c]instanceof d)&&(a[c]=a[c].toJSON());return _.omit(a,this.blacklist)}}),c.RosterUser=b.Model.extend({type:"roster_user",idAttribute:"_id",constructor:function(a){"undefined"!=typeof a&&(a._id=a._id||a.id||c.getUID(this),a.title=a.title||"(untitled "+this.type+")",a.description=a.description||"",a.uri=a.uri||"",a.project=a.project||null,a.site_id=a.site_id||0,"function"==typeof this.prepare&&(a=this.prepare(a))),b.Model.prototype.constructor.call(this,a)},validate:function(){return this.type?void 0:"object has no type"},prepare:function(a){return a.color=a.color||"#666666",a},toJSON:function(){return{_id:this.get("_id"),title:this.get("title"),uri:this.get("uri"),description:this.get("description"),color:this.get("color"),project:null!=this.get("project")?this.get("project").get("id"):null,site_id:this.get("site_id")}}}));c.UsersList=b.Collection.extend({model:i})}}.call(window),Rkns.defaults={language:navigator.language||navigator.userLanguage||"en",container:"renkan",search:[],bins:[],static_url:"",show_bins:!0,properties:[],show_editor:!0,read_only:!1,editor_mode:!0,manual_save:!1,show_top_bar:!0,default_user_color:"#303030",size_bug_fix:!0,force_resize:!1,allow_double_click:!0,zoom_on_scroll:!0,element_delete_delay:0,autoscale_padding:50,resize:!0,show_zoom:!0,save_view:!0,default_view:!1,show_search_field:!0,show_user_list:!0,user_name_editable:!0,user_color_editable:!0,show_user_color:!0,show_save_button:!0,show_export_button:!0,show_open_button:!1,show_addnode_button:!0,show_addedge_button:!0,show_bookmarklet:!0,show_fullscreen_button:!0,home_button_url:!1,home_button_title:"Home",show_minimap:!0,minimap_width:160,minimap_height:120,minimap_padding:20,minimap_background_color:"#ffffff",minimap_border_color:"#cccccc",minimap_highlight_color:"#ffff00",minimap_highlight_weight:5,buttons_background:"#202020",buttons_label_color:"#c000c0",buttons_label_font_size:9,show_node_circles:!0,clip_node_images:!0,node_images_fill_mode:!1,node_size_base:25,node_stroke_width:2,selected_node_stroke_width:4,node_fill_color:"#ffffff",highlighted_node_fill_color:"#ffff00",node_label_distance:5,node_label_max_length:60,label_untitled_nodes:"(untitled)",change_shapes:!0,edge_stroke_width:2,selected_edge_stroke_width:4,edge_label_distance:0,edge_label_max_length:20,edge_arrow_length:18,edge_arrow_width:12,edge_gap_in_bundles:12,label_untitled_edges:"",tooltip_width:275,tooltip_padding:10,tooltip_margin:15,tooltip_arrow_length:20,tooltip_arrow_width:40,tooltip_top_color:"#f0f0f0",tooltip_bottom_color:"#d0d0d0",tooltip_border_color:"#808080",tooltip_border_width:1,show_node_editor_uri:!0,show_node_editor_description:!0,show_node_editor_size:!0,show_node_editor_color:!0,show_node_editor_image:!0,show_node_editor_creator:!0,allow_image_upload:!0,uploaded_image_max_kb:500,show_node_tooltip_uri:!0,show_node_tooltip_description:!0,show_node_tooltip_color:!0,show_node_tooltip_image:!0,show_node_tooltip_creator:!0,show_edge_editor_uri:!0,show_edge_editor_color:!0,show_edge_editor_direction:!0,show_edge_editor_nodes:!0,show_edge_editor_creator:!0,show_edge_tooltip_uri:!0,show_edge_tooltip_color:!0,show_edge_tooltip_nodes:!0,show_edge_tooltip_creator:!0},Rkns.i18n={fr:{"Edit Node":"Ćdition dāun nÅud","Edit Edge":"Ćdition dāun lien","Title:":"Titre :","URI:":"URI :","Description:":"Description :","From:":"De :","To:":"Vers :",Image:"Image","Image URL:":"URL d'Image","Choose Image File:":"Choisir un fichier image","Full Screen":"Mode plein Ć©cran","Add Node":"Ajouter un nÅud","Add Edge":"Ajouter un lien","Save Project":"Enregistrer le projet","Open Project":"Ouvrir un projet","Auto-save enabled":"Enregistrement automatique activĆ©","Connection lost":"Connexion perdue","Created by:":"CrƩƩ par :","Zoom In":"Agrandir lāĆ©chelle","Zoom Out":"Rapetisser lāĆ©chelle",Edit:"Ćditer",Remove:"Supprimer","Cancel deletion":"Annuler la suppression","Link to another node":"CrĆ©er un lien",Enlarge:"Agrandir",Shrink:"RĆ©trĆ©cir","Click on the background canvas to add a node":"Cliquer sur le fond du graphe pour rajouter un nÅud","Click on a first node to start the edge":"Cliquer sur un premier nÅud pour commencer le lien","Click on a second node to complete the edge":"Cliquer sur un second nÅud pour terminer le lien",Wikipedia:"WikipĆ©dia","Wikipedia in ":"WikipĆ©dia en ",French:"FranƧais",English:"Anglais",Japanese:"Japonais","Untitled project":"Projet sans titre","Lignes de Temps":"Lignes de Temps","Loading, please wait":"Chargement en cours, merci de patienter","Edge color:":"Couleur :","Node color:":"Couleur :","Choose color":"Choisir une couleur","Change edge direction":"Changer le sens du lien","Do you really wish to remove node ":"Voulez-vous rĆ©ellement supprimer le nÅud ","Do you really wish to remove edge ":"Voulez-vous rĆ©ellement supprimer le lien ","This file is not an image":"Ce fichier n'est pas une image","Image size must be under ":"L'image doit peser moins de ","Size:":"Taille :",KB:"ko","Choose from vocabulary:":"Choisir dans un vocabulaire :","SKOS Documentation properties":"SKOS: PropriĆ©tĆ©s documentaires","has note":"a pour note","has example":"a pour exemple","has definition":"a pour dĆ©finition","SKOS Semantic relations":"SKOS: Relations sĆ©mantiques","has broader":"a pour concept plus large","has narrower":"a pour concept plus Ć©troit","has related":"a pour concept apparentĆ©","Dublin Core Metadata":"MĆ©tadonnĆ©es Dublin Core","has contributor":"a pour contributeur",covers:"couvre","created by":"crƩƩ par","has date":"a pour date","published by":"Ć©ditĆ© par","has source":"a pour source","has subject":"a pour sujet","Dragged resource":"Ressource glisĆ©e-dĆ©posĆ©e","Search the Web":"Rechercher en ligne","Search in Bins":"Rechercher dans les chutiers","Close bin":"Fermer le chutier","Refresh bin":"RafraĆ®chir le chutier","(untitled)":"(sans titre)","Select contents:":"SĆ©lectionner des contenus :","Drag items from this website, drop them in Renkan":"Glissez des Ć©lĆ©ments de ce site web vers Renkan","Drag this button to your bookmark bar. When on a third-party website, click it to enable drag-and-drop from the website to Renkan.":"Glissez ce bouton vers votre barre de favoris. Ensuite, depuis un site tiers, cliquez dessus pour activer 'Drag-to-Add' puis glissez des Ć©lĆ©ments de ce site vers Renkan","Shapes available":"Formes disponibles",Circle:"Cercle",Square:"CarrĆ©",Diamond:"Losange",Hexagone:"Hexagone",Ellipse:"Ellipse",Star:"Ćtoile","Zoom Fit":"Ajuster le Zoom","Download Project":"TĆ©lĆ©charger le projet","Zoom Save":"Sauver le Zoom","View saved zoom":"Restaurer le Zoom","Renkan 'Drag-to-Add' bookmarklet":"Renkan 'Deplacer-Pour-Ajouter' Signet","(unknown user)":"(non authentifiĆ©)","<unknown user>":"<non authentifiĆ©>","Search in graph":"Rechercher dans carte","Search in ":"Chercher dans "}},Rkns.jsonIO=function(a,b){var c=a.project;"undefined"==typeof b.http_method&&(b.http_method="PUT");var d=function(){a.renderer.redrawActive=!1,c.set({loading_status:!0}),Rkns.$.getJSON(b.url,function(b){c.set(b,{validate:!0}),c.set({loading_status:!1}),c.set({save_status:0}),a.renderer.redrawActive=!0,a.renderer.fixSize()})},e=function(){c.set({save_status:2});var d=c.toJSON();a.read_only||Rkns.$.ajax({type:b.http_method,url:b.url,contentType:"application/json",data:JSON.stringify(d),success:function(){c.set({save_status:0})}})},f=Rkns._.throttle(function(){setTimeout(e,100)},1e3);c.on("add:nodes add:edges add:users add:views",function(a){a.on("change remove",function(){f()}),f()}),c.on("change",function(){1===c.changedAttributes.length&&c.hasChanged("save_status")||f()}),d()},Rkns.jsonIOSaveOnClick=function(a,b){var c=a.project,d=!1,e=function(){return"Project not saved"};"undefined"==typeof b.http_method&&(b.http_method="POST");var f=function(){var d={},e=/id=([^&#?=]+)/,f=document.location.hash.match(e);f&&(d.id=f[1]),Rkns.$.ajax({url:b.url,data:d,beforeSend:function(){c.set({loading_status:!0})},success:function(b){c.set(b,{validate:!0}),c.set({loading_status:!1}),c.set({save_status:0}),a.renderer.autoScale()}})},g=function(){c.set("saved_at",new Date);var a=c.toJSON();Rkns.$.ajax({type:b.http_method,url:b.url,contentType:"application/json",data:JSON.stringify(a),beforeSend:function(){c.set({save_status:2})},success:function(){$(window).off("beforeunload",e),d=!1,c.set({save_status:0})}})},h=function(){c.set({save_status:1});var a=c.get("title");a&&c.get("nodes").length?$(".Rk-Save-Button").removeClass("disabled"):$(".Rk-Save-Button").addClass("disabled"),a&&$(".Rk-PadTitle").css("border-color","#333333"),d||(d=!0,$(window).on("beforeunload",e))};f(),c.on("add:nodes add:edges add:users change",function(a){a.on("change remove",function(a){1===a.changedAttributes.length&&a.hasChanged("save_status")||h()}),1===c.changedAttributes.length&&c.hasChanged("save_status")||h()}),a.renderer.save=function(){$(".Rk-Save-Button").hasClass("disabled")?c.get("title")||$(".Rk-PadTitle").css("border-color","#ff0000"):g()}},function(a){"use strict";var b=a._,c=a.Ldt={},d=(c.Bin=function(a,b){if(b.ldt_type){var d=c[b.ldt_type+"Bin"];if(d)return new d(a,b)}console.error("No such LDT Bin Type")},c.ProjectBin=a.Utils.inherit(a._BaseBin));d.prototype.tagTemplate=renkanJST["templates/ldtjson-bin/tagtemplate.html"],d.prototype.annotationTemplate=renkanJST["templates/ldtjson-bin/annotationtemplate.html"],d.prototype._init=function(a,b){this.renkan=a,this.proj_id=b.project_id,this.ldt_platform=b.ldt_platform||"http://ldt.iri.centrepompidou.fr/",this.title_$.html(b.title),this.title_icon_$.addClass("Rk-Ldt-Title-Icon"),this.refresh()},d.prototype.render=function(c){function d(a){var c=b(a).escape();return f.isempty?c:f.replace(c,"<span class='searchmatch'>$1</span>")}function e(a){function b(a){for(var b=a.toString();b.length<2;)b="0"+b;return b}var c=Math.abs(Math.floor(a/1e3)),d=Math.floor(c/3600),e=Math.floor(c/60)%60,f=c%60,g="";return d&&(g+=b(d)+":"),g+=b(e)+":"+b(f)}var f=c||a.Utils.regexpFromTextOrArray(),g="<li><h3>Tags</h3></li>",h=this.data.meta["dc:title"],i=this,j=0;i.title_$.text('LDT Project: "'+h+'"'),b.map(i.data.tags,function(a){var b=a.meta["dc:title"];(f.isempty||f.test(b))&&(j++,g+=i.tagTemplate({ldt_platform:i.ldt_platform,title:b,htitle:d(b),encodedtitle:encodeURIComponent(b),static_url:i.renkan.options.static_url}))}),g+="<li><h3>Annotations</h3></li>",b.map(i.data.annotations,function(a){var b=a.content.description,c=a.content.title.replace(b,"");if(f.isempty||f.test(c)||f.test(b)){j++;var h=a.end-a.begin,k=a.content&&a.content.img&&a.content.img.src?a.content.img.src:h?i.renkan.options.static_url+"img/ldt-segment.png":i.renkan.options.static_url+"img/ldt-point.png";g+=i.annotationTemplate({ldt_platform:i.ldt_platform,title:c,htitle:d(c),description:b,hdescription:d(b),start:e(a.begin),end:e(a.end),duration:e(h),mediaid:a.media,annotationid:a.id,image:k,static_url:i.renkan.options.static_url})}}),this.main_$.html(g),!f.isempty&&j?this.count_$.text(j).show():this.count_$.hide(),f.isempty||j?this.$.show():this.$.hide(),this.renkan.resizeBins()},d.prototype.refresh=function(){var b=this;a.$.ajax({url:this.ldt_platform+"ldtplatform/ldt/cljson/id/"+this.proj_id,dataType:"jsonp",success:function(a){b.data=a,b.render()}})};var e=c.Search=function(a,b){this.renkan=a,this.lang=b.lang||"en"};e.prototype.getBgClass=function(){return"Rk-Ldt-Icon"},e.prototype.getSearchTitle=function(){return this.renkan.translate("Lignes de Temps")},e.prototype.search=function(a){this.renkan.tabs.push(new f(this.renkan,{search:a}))};var f=c.ResultsBin=a.Utils.inherit(a._BaseBin);f.prototype.segmentTemplate=renkanJST["templates/ldtjson-bin/segmenttemplate.html"],f.prototype._init=function(a,b){this.renkan=a,this.ldt_platform=b.ldt_platform||"http://ldt.iri.centrepompidou.fr/",this.max_results=b.max_results||50,this.search=b.search,this.title_$.html('Lignes de Temps: "'+b.search+'"'),this.title_icon_$.addClass("Rk-Ldt-Title-Icon"),this.refresh()},f.prototype.render=function(c){function d(a){return g.replace(b(a).escape(),"<span class='searchmatch'>$1</span>")}function e(a){function b(a){for(var b=a.toString();b.length<2;)b="0"+b;return b}var c=Math.abs(Math.floor(a/1e3)),d=Math.floor(c/3600),e=Math.floor(c/60)%60,f=c%60,g="";return d&&(g+=b(d)+":"),g+=b(e)+":"+b(f)}if(this.data){var f=c||a.Utils.regexpFromTextOrArray(),g=f.isempty?a.Utils.regexpFromTextOrArray(this.search):f,h="",i=this,j=0;b.each(this.data.objects,function(a){var b=a["abstract"],c=a.title;if(f.isempty||f.test(c)||f.test(b)){j++;var g=a.duration,k=a.start_ts,l=+a.duration+k,m=g?i.renkan.options.static_url+"img/ldt-segment.png":i.renkan.options.static_url+"img/ldt-point.png";h+=i.segmentTemplate({ldt_platform:i.ldt_platform,title:c,htitle:d(c),description:b,hdescription:d(b),start:e(k),end:e(l),duration:e(g),mediaid:a.iri_id,annotationid:a.element_id,image:m})}}),this.main_$.html(h),!f.isempty&&j?this.count_$.text(j).show():this.count_$.hide(),f.isempty||j?this.$.show():this.$.hide(),this.renkan.resizeBins()}},f.prototype.refresh=function(){var b=this;a.$.ajax({url:this.ldt_platform+"ldtplatform/api/ldt/1.0/segments/search/",data:{format:"jsonp",q:this.search,limit:this.max_results},dataType:"jsonp",success:function(a){b.data=a,b.render()}})}}(window.Rkns),Rkns.ResourceList={},Rkns.ResourceList.Bin=Rkns.Utils.inherit(Rkns._BaseBin),Rkns.ResourceList.Bin.prototype.resultTemplate=renkanJST["templates/list-bin.html"],Rkns.ResourceList.Bin.prototype._init=function(a,b){this.renkan=a,this.title_$.html(b.title),b.list&&(this.data=b.list),this.refresh()},Rkns.ResourceList.Bin.prototype.render=function(a){function b(a){var b=_(a).escape();return c.isempty?b:c.replace(b,"<span class='searchmatch'>$1</span>")}var c=a||Rkns.Utils.regexpFromTextOrArray(),d="",e=this,f=0;Rkns._.each(this.data,function(a){var g;if("string"==typeof a)if(/^(https?:\/\/|www)/.test(a))g={url:a};else{g={title:a.replace(/[:,]?\s?(https?:\/\/|www)[\d\w\/.&?=#%-_]+\s?/,"").trim()};var h=a.match(/(https?:\/\/|www)[\d\w\/.&?=#%-_]+/);h&&(g.url=h[0]),g.title.length>80&&(g.description=g.title,g.title=g.title.replace(/^(.{30,60})\s.+$/,"$1ā¦"))}else g=a;var i=g.title||(g.url||"").replace(/^https?:\/\/(www\.)?/,"").replace(/^(.{40}).+$/,"$1ā¦"),j=g.url||"",k=g.description||"",l=g.image||"";j&&!/^https?:\/\//.test(j)&&(j="http://"+j),(c.isempty||c.test(i)||c.test(k))&&(f++,d+=e.resultTemplate({url:j,title:i,htitle:b(i),image:l,description:k,hdescription:b(k),static_url:e.renkan.options.static_url}))}),e.main_$.html(d),!c.isempty&&f?this.count_$.text(f).show():this.count_$.hide(),c.isempty||f?this.$.show():this.$.hide(),this.renkan.resizeBins()},Rkns.ResourceList.Bin.prototype.refresh=function(){this.data&&this.render()},Rkns.Wikipedia={},Rkns.Wikipedia.Search=function(a,b){this.renkan=a,this.lang=b.lang||"en"},Rkns.Wikipedia.Search.prototype.getBgClass=function(){return"Rk-Wikipedia-Search-Icon Rk-Wikipedia-Lang-"+this.lang},Rkns.Wikipedia.Search.prototype.getSearchTitle=function(){var a={fr:"French",en:"English",ja:"Japanese"};return a[this.lang]?this.renkan.translate("Wikipedia in ")+this.renkan.translate(a[this.lang]):this.renkan.translate("Wikipedia")+" ["+this.lang+"]"},Rkns.Wikipedia.Search.prototype.search=function(a){this.renkan.tabs.push(new Rkns.Wikipedia.Bin(this.renkan,{lang:this.lang,search:a}))},Rkns.Wikipedia.Bin=Rkns.Utils.inherit(Rkns._BaseBin),Rkns.Wikipedia.Bin.prototype.resultTemplate=renkanJST["templates/wikipedia-bin/resulttemplate.html"],Rkns.Wikipedia.Bin.prototype._init=function(a,b){this.renkan=a,this.search=b.search,this.lang=b.lang||"en",this.title_icon_$.addClass("Rk-Wikipedia-Title-Icon Rk-Wikipedia-Lang-"+this.lang),this.title_$.html(this.search).addClass("Rk-Wikipedia-Title"),this.refresh()},Rkns.Wikipedia.Bin.prototype.render=function(a){function b(a){return d.replace(_(a).escape(),"<span class='searchmatch'>$1</span>")}var c=a||Rkns.Utils.regexpFromTextOrArray(),d=c.isempty?Rkns.Utils.regexpFromTextOrArray(this.search):c,e="",f=this,g=0;Rkns._.each(this.data.query.search,function(a){var d=a.title,h="http://"+f.lang+".wikipedia.org/wiki/"+encodeURI(d.replace(/ /g,"_")),i=Rkns.$("<div>").html(a.snippet).text();(c.isempty||c.test(d)||c.test(i))&&(g++,e+=f.resultTemplate({url:h,title:d,htitle:b(d),description:i,hdescription:b(i),static_url:f.renkan.options.static_url}))}),f.main_$.html(e),!c.isempty&&g?this.count_$.text(g).show():this.count_$.hide(),c.isempty||g?this.$.show():this.$.hide(),this.renkan.resizeBins()},Rkns.Wikipedia.Bin.prototype.refresh=function(){var a=this;Rkns.$.ajax({url:"http://"+a.lang+".wikipedia.org/w/api.php?action=query&list=search&srsearch="+encodeURIComponent(this.search)+"&format=json",dataType:"jsonp",success:function(b){a.data=b,a.render()}})},define("renderer/baserepresentation",["jquery","underscore"],function(a,b){var c=function(a,c){if("undefined"!=typeof a&&(this.renderer=a,this.renkan=a.renkan,this.project=a.renkan.project,this.options=a.renkan.options,this.model=c,this.model)){var d=this;this._changeBinding=function(){d.redraw({change:!0})},this._removeBinding=function(){a.removeRepresentation(d),b.defer(function(){a.redraw()})},this._selectBinding=function(){d.select()},this._unselectBinding=function(){d.unselect()},this.model.on("change",this._changeBinding),this.model.on("remove",this._removeBinding),this.model.on("select",this._selectBinding),this.model.on("unselect",this._unselectBinding)}};return b(c.prototype).extend({_super:function(a){return c.prototype[a].apply(this,Array.prototype.slice.call(arguments,1))},redraw:function(){},moveTo:function(){},show:function(){return"BaseRepresentation.show"},hide:function(){},select:function(){this.model&&this.model.trigger("selected")},unselect:function(){this.model&&this.model.trigger("unselected")},highlight:function(){},unhighlight:function(){},mousedown:function(){},mouseup:function(){this.model&&this.model.trigger("clicked")},destroy:function(){this.model&&(this.model.off("change",this._changeBinding),this.model.off("remove",this._removeBinding),this.model.off("select",this._selectBinding),this.model.off("unselect",this._unselectBinding))}}).value(),c}),define("requtils",[],function(){return{getUtils:function(){return window.Rkns.Utils},getRenderer:function(){return window.Rkns.Renderer}}}),define("renderer/basebutton",["jquery","underscore","requtils","renderer/baserepresentation"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({moveTo:function(a){this.sector.moveTo(a)},show:function(){this.sector.show()},hide:function(){this.sector.hide()},select:function(){this.sector.select()},unselect:function(a){this.sector.unselect(),(!a||a!==this.source_representation&&a.source_representation!==this.source_representation)&&this.source_representation.unselect()},destroy:function(){this.sector.destroy()}}).value(),f}),define("renderer/shapebuilder",[],function(){var a={circle:{getShape:function(){return new paper.Path.Circle([0,0],1)},getImageShape:function(a,b){return new paper.Path.Circle(a,b)}},rectangle:{getShape:function(){return new paper.Path.Rectangle([-2,-2],[2,2])},getImageShape:function(a,b){return new paper.Path.Rectangle([-b,-b],[2*b,2*b])}},ellipse:{getShape:function(){return new paper.Path.Ellipse(new paper.Rectangle([-2,-1],[2,1]))},getImageShape:function(a,b){return new paper.Path.Ellipse(new paper.Rectangle([-b,-b/2],[2*b,b]))}},polygon:{getShape:function(){return new paper.Path.RegularPolygon([0,0],6,1)},getImageShape:function(a,b){return new paper.Path.RegularPolygon([0,0],6,b)}},diamond:{getShape:function(){var a=new paper.Path.Rectangle([-Math.SQRT2,-Math.SQRT2],[Math.SQRT2,Math.SQRT2]);return a.rotate(45),a},getImageShape:function(a,b){var c=new paper.Path.Rectangle([-b*Math.SQRT2/2,-b*Math.SQRT2/2],[b*Math.SQRT2,b*Math.SQRT2]);return c.rotate(45),c}},star:{getShape:function(){return new paper.Path.Star([0,0],8,1,.7)},getImageShape:function(a,b){return new paper.Path.Star([0,0],8,1*b,.7*b)}},svg:function(a){return{getShape:function(){return new paper.Path(a)},getImageShape:function(){return new paper.Path}}}},b=function(b){return(null===b||"undefined"==typeof b)&&(b="circle"),"svg:"===b.substr(0,4)?a.svg(b.substr(4)):(b in a||(b="circle"),a[b])};return b}),define("renderer/noderepr",["jquery","underscore","requtils","renderer/baserepresentation","renderer/shapebuilder"],function(a,b,c,d,e){var f=c.getUtils(),g=f.inherit(d);return b(g.prototype).extend({_init:function(){if(this.renderer.node_layer.activate(),this.type="Node",this.buildShape(),this.options.show_node_circles?(this.circle.strokeWidth=this.options.node_stroke_width,this.h_ratio=1):this.h_ratio=0,this.title=a('<div class="Rk-Label">').appendTo(this.renderer.labels_$),this.options.editor_mode){var b=c.getRenderer();this.normal_buttons=[new b.NodeEditButton(this.renderer,null),new b.NodeRemoveButton(this.renderer,null),new b.NodeLinkButton(this.renderer,null),new b.NodeEnlargeButton(this.renderer,null),new b.NodeShrinkButton(this.renderer,null)],this.pending_delete_buttons=[new b.NodeRevertButton(this.renderer,null)],this.all_buttons=this.normal_buttons.concat(this.pending_delete_buttons);for(var d=0;d<this.all_buttons.length;d++)this.all_buttons[d].source_representation=this;this.active_buttons=[]}else this.active_buttons=this.all_buttons=[];this.last_circle_radius=1,this.renderer.minimap&&(this.renderer.minimap.node_layer.activate(),this.minimap_circle=new paper.Path.Circle([0,0],1),this.minimap_circle.__representation=this.renderer.minimap.miniframe.__representation,this.renderer.minimap.node_group.addChild(this.minimap_circle))},buildShape:function(){"shape"in this.model.changed&&delete this.img,this.circle&&(this.circle.remove(),delete this.circle),this.shapeBuilder=new e(this.model.get("shape")),this.circle=this.shapeBuilder.getShape(),this.circle.__representation=this,this.circle.sendToBack(),this.last_circle_radius=1},redraw:function(a){"shape"in this.model.changed&&"change"in a&&a.change&&this.buildShape();var c=new paper.Point(this.model.get("position")),d=this.options.node_size_base*Math.exp((this.model.get("size")||0)*f._NODE_SIZE_STEP);this.is_dragging&&this.paper_coords||(this.paper_coords=this.renderer.toPaperCoords(c)),this.circle_radius=d*this.renderer.scale,this.last_circle_radius!==this.circle_radius&&(this.all_buttons.forEach(function(a){a.setSectorSize()}),this.circle.scale(this.circle_radius/this.last_circle_radius),this.node_image&&this.node_image.scale(this.circle_radius/this.last_circle_radius)),this.circle.position=this.paper_coords,this.node_image&&(this.node_image.position=this.paper_coords.subtract(this.image_delta.multiply(this.circle_radius))),this.last_circle_radius=this.circle_radius;var e=this.active_buttons,g=1;this.model.get("delete_scheduled")?(g=.5,this.active_buttons=this.pending_delete_buttons,this.circle.dashArray=[2,2]):(g=1,this.active_buttons=this.normal_buttons,this.circle.dashArray=null),this.selected&&this.renderer.isEditable()&&(e!==this.active_buttons&&e.forEach(function(a){a.hide()}),this.active_buttons.forEach(function(a){a.show()})),this.node_image&&(this.node_image.opacity=this.highlighted?.5*g:g-.01),this.circle.fillColor=this.highlighted?this.options.highlighted_node_fill_color:this.options.node_fill_color,this.circle.opacity=this.options.show_node_circles?g:.01;var h=this.model.get("title")||this.renkan.translate(this.options.label_untitled_nodes)||"";h=f.shortenText(h,this.options.node_label_max_length),"object"==typeof this.highlighted?this.title.html(this.highlighted.replace(b(h).escape(),'<span class="Rk-Highlighted">$1</span>')):this.title.text(h),this.title.css({left:this.paper_coords.x,top:this.paper_coords.y+this.circle_radius*this.h_ratio+this.options.node_label_distance,opacity:g}); +var i=this.model.get("color")||(this.model.get("created_by")||f._USER_PLACEHOLDER(this.renkan)).get("color");this.circle.strokeColor=i;var j=this.paper_coords;this.all_buttons.forEach(function(a){a.moveTo(j)});var k=this.img;if(this.img=this.model.get("image"),this.img&&this.img!==k&&(this.showImage(),this.circle&&this.circle.sendToBack()),this.node_image&&!this.img&&(this.node_image.remove(),delete this.node_image),this.renderer.minimap){this.minimap_circle.fillColor=i;var l=this.renderer.toMinimapCoords(c),m=this.renderer.minimap.scale*d,n=new paper.Size([m,m]);this.minimap_circle.fitBounds(l.subtract(n),n.multiply(2))}if(!("undefined"!=typeof a&&"dontRedrawEdges"in a&&a.dontRedrawEdges)){var o=this;b.each(this.project.get("edges").filter(function(a){return a.get("to")===o.model||a.get("from")===o.model}),function(a){var b=o.renderer.getRepresentationByModel(a);b&&"undefined"!=typeof b.from_representation&&"undefined"!=typeof b.from_representation.paper_coords&&"undefined"!=typeof b.to_representation&&"undefined"!=typeof b.to_representation.paper_coords&&b.redraw()})}},showImage:function(){var b=null;if("undefined"==typeof this.renderer.image_cache[this.img]?(b=new Image,this.renderer.image_cache[this.img]=b,b.src=this.img):b=this.renderer.image_cache[this.img],b.width){this.node_image&&this.node_image.remove(),this.renderer.node_layer.activate();var c=b.width,d=b.height,e=this.model.get("clip_path"),f="undefined"!=typeof e&&e,g=null,h=null,i=null;if(f){g=new paper.Path;var j=e.match(/[a-z][^a-z]+/gi)||[],k=[0,0],l=1/0,m=1/0,n=-1/0,o=-1/0,p=function(a,b){var e=a.slice(1).map(function(a,e){var f=parseFloat(a),g=e%2;return f=g?(f-.5)*d:(f-.5)*c,b&&(f+=k[g]),g?(m=Math.min(m,f),o=Math.max(o,f)):(l=Math.min(l,f),n=Math.max(n,f)),f});return k=e.slice(-2),e};j.forEach(function(a){var b=a.match(/([a-z]|[0-9.-]+)/gi)||[""];switch(b[0]){case"M":g.moveTo(p(b));break;case"m":g.moveTo(p(b,!0));break;case"L":g.lineTo(p(b));break;case"l":g.lineTo(p(b,!0));break;case"C":g.cubicCurveTo(p(b));break;case"c":g.cubicCurveTo(p(b,!0));break;case"Q":g.quadraticCurveTo(p(b));break;case"q":g.quadraticCurveTo(p(b,!0))}}),h=Math[this.options.node_images_fill_mode?"min":"max"](n-l,o-m)/2,i=new paper.Point((n+l)/2,(o+m)/2),this.options.show_node_circles||(this.h_ratio=(o-m)/(2*h))}else h=Math[this.options.node_images_fill_mode?"min":"max"](c,d)/2,i=new paper.Point(0,0),this.options.show_node_circles||(this.h_ratio=d/(2*h));var q=new paper.Raster(b);if(q.locked=!0,f&&(q=new paper.Group(g,q),q.opacity=.99,q.clipped=!0,g.__representation=this),this.options.clip_node_images){var r=this.shapeBuilder.getImageShape(i,h);q=new paper.Group(r,q),q.opacity=.99,q.clipped=!0,r.__representation=this}this.image_delta=i.divide(h),this.node_image=q,this.node_image.__representation=s,this.node_image.scale(this.circle_radius/h),this.node_image.position=this.paper_coords.subtract(this.image_delta.multiply(this.circle_radius)),this.node_image.insertAbove(this.circle)}else{var s=this;a(b).on("load",function(){s.showImage()})}},paperShift:function(a){this.options.editor_mode?this.renkan.read_only||(this.is_dragging=!0,this.paper_coords=this.paper_coords.add(a),this.redraw()):this.renderer.paperShift(a)},openEditor:function(){this.renderer.removeRepresentationsOfType("editor");var a=this.renderer.addRepresentation("NodeEditor",null);a.source_representation=this,a.draw()},select:function(){this.selected=!0,this.circle.strokeWidth=this.options.selected_node_stroke_width,this.renderer.isEditable()&&this.active_buttons.forEach(function(a){a.show()});var b=this.model.get("uri");b&&a(".Rk-Bin-Item").each(function(){var c=a(this);c.attr("data-uri")===b&&c.addClass("selected")}),this.options.editor_mode||this.openEditor(),this.renderer.minimap&&(this.minimap_circle.strokeWidth=this.options.minimap_highlight_weight,this.minimap_circle.strokeColor=this.options.minimap_highlight_color),this._super("select")},hideButtons:function(){this.all_buttons.forEach(function(a){a.hide()}),delete this.buttonTimeout},unselect:function(b){if(!b||b.source_representation!==this){this.selected=!1;var c=this;this.buttons_timeout=setTimeout(function(){c.hideButtons()},200),this.circle.strokeWidth=this.options.node_stroke_width,a(".Rk-Bin-Item").removeClass("selected"),this.renderer.minimap&&(this.minimap_circle.strokeColor=void 0),this._super("unselect")}},highlight:function(a){var b=a||!0;this.highlighted!==b&&(this.highlighted=b,this.redraw(),this.renderer.throttledPaperDraw())},unhighlight:function(){this.highlighted&&(this.highlighted=!1,this.redraw(),this.renderer.throttledPaperDraw())},saveCoords:function(){var a=this.renderer.toModelCoords(this.paper_coords),b={position:{x:a.x,y:a.y}};this.renderer.isEditable()&&this.model.set(b)},mousedown:function(a,b){b&&(this.renderer.unselectAll(),this.select())},mouseup:function(a,b){this.renderer.is_dragging&&this.renderer.isEditable()?this.saveCoords():(b||this.model.get("delete_scheduled")||this.openEditor(),this.model.trigger("clicked")),this.renderer.click_target=null,this.renderer.is_dragging=!1,this.is_dragging=!1},destroy:function(){this._super("destroy"),this.all_buttons.forEach(function(a){a.destroy()}),this.circle.remove(),this.title.remove(),this.renderer.minimap&&this.minimap_circle.remove(),this.node_image&&this.node_image.remove()}}).value(),g}),define("renderer/edge",["jquery","underscore","requtils","renderer/baserepresentation"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){if(this.renderer.edge_layer.activate(),this.type="Edge",this.from_representation=this.renderer.getRepresentationByModel(this.model.get("from")),this.to_representation=this.renderer.getRepresentationByModel(this.model.get("to")),this.bundle=this.renderer.addToBundles(this),this.line=new paper.Path,this.line.add([0,0],[0,0],[0,0]),this.line.__representation=this,this.line.strokeWidth=this.options.edge_stroke_width,this.arrow=new paper.Path,this.arrow.add([0,0],[this.options.edge_arrow_length,this.options.edge_arrow_width/2],[0,this.options.edge_arrow_width]),this.arrow.__representation=this,this.text=a('<div class="Rk-Label Rk-Edge-Label">').appendTo(this.renderer.labels_$),this.arrow_angle=0,this.options.editor_mode){var b=c.getRenderer();this.normal_buttons=[new b.EdgeEditButton(this.renderer,null),new b.EdgeRemoveButton(this.renderer,null)],this.pending_delete_buttons=[new b.EdgeRevertButton(this.renderer,null)],this.all_buttons=this.normal_buttons.concat(this.pending_delete_buttons);for(var d=0;d<this.all_buttons.length;d++)this.all_buttons[d].source_representation=this;this.active_buttons=[]}else this.active_buttons=this.all_buttons=[];this.renderer.minimap&&(this.renderer.minimap.edge_layer.activate(),this.minimap_line=new paper.Path,this.minimap_line.add([0,0],[0,0]),this.minimap_line.__representation=this.renderer.minimap.miniframe.__representation,this.minimap_line.strokeWidth=1)},redraw:function(){var a=this.model.get("from"),b=this.model.get("to");if(a&&b&&(this.from_representation=this.renderer.getRepresentationByModel(a),this.to_representation=this.renderer.getRepresentationByModel(b),"undefined"!=typeof this.from_representation&&"undefined"!=typeof this.to_representation)){var c=this.from_representation.paper_coords,d=this.to_representation.paper_coords,f=d.subtract(c),g=f.length,h=f.divide(g),i=new paper.Point([-h.y,h.x]),j=this.bundle.getPosition(this),k=i.multiply(this.options.edge_gap_in_bundles*j),l=c.add(k),m=d.add(k),n=f.angle,o=i.multiply(this.options.edge_label_distance),p=f.divide(3),q=this.model.get("color")||this.model.get("color")||(this.model.get("created_by")||e._USER_PLACEHOLDER(this.renkan)).get("color"),r=1;this.model.get("delete_scheduled")||this.from_representation.model.get("delete_scheduled")||this.to_representation.model.get("delete_scheduled")?(r=.5,this.line.dashArray=[2,2]):(r=1,this.line.dashArray=null);var s=this.active_buttons;this.active_buttons=this.model.get("delete_scheduled")?this.pending_delete_buttons:this.normal_buttons,this.selected&&this.renderer.isEditable()&&s!==this.active_buttons&&(s.forEach(function(a){a.hide()}),this.active_buttons.forEach(function(a){a.show()})),this.paper_coords=l.add(m).divide(2),this.line.strokeColor=q,this.line.opacity=r,this.line.segments[0].point=c,this.line.segments[1].point=this.paper_coords,this.line.segments[1].handleIn=p.multiply(-1),this.line.segments[1].handleOut=p,this.line.segments[2].point=d,this.arrow.rotate(n-this.arrow_angle),this.arrow.fillColor=q,this.arrow.opacity=r,this.arrow.position=this.paper_coords,this.arrow_angle=n,n>90&&(n-=180,o=o.multiply(-1)),-90>n&&(n+=180,o=o.multiply(-1));var t=this.model.get("title")||this.renkan.translate(this.options.label_untitled_edges)||"";t=e.shortenText(t,this.options.node_label_max_length),this.text.text(t);var u=this.paper_coords.add(o);this.text.css({left:u.x,top:u.y,transform:"rotate("+n+"deg)","-moz-transform":"rotate("+n+"deg)","-webkit-transform":"rotate("+n+"deg)",opacity:r}),this.text_angle=n;var v=this.paper_coords;this.all_buttons.forEach(function(a){a.moveTo(v)}),this.renderer.minimap&&(this.minimap_line.strokeColor=q,this.minimap_line.segments[0].point=this.renderer.toMinimapCoords(new paper.Point(this.from_representation.model.get("position"))),this.minimap_line.segments[1].point=this.renderer.toMinimapCoords(new paper.Point(this.to_representation.model.get("position"))))}},openEditor:function(){this.renderer.removeRepresentationsOfType("editor");var a=this.renderer.addRepresentation("EdgeEditor",null);a.source_representation=this,a.draw()},select:function(){this.selected=!0,this.line.strokeWidth=this.options.selected_edge_stroke_width,this.renderer.isEditable()&&this.active_buttons.forEach(function(a){a.show()}),this.options.editor_mode||this.openEditor(),this._super("select")},unselect:function(a){a&&a.source_representation===this||(this.selected=!1,this.options.editor_mode&&this.all_buttons.forEach(function(a){a.hide()}),this.line.strokeWidth=this.options.edge_stroke_width,this._super("unselect"))},mousedown:function(a,b){b&&(this.renderer.unselectAll(),this.select())},mouseup:function(a,b){!this.renkan.read_only&&this.renderer.is_dragging?(this.from_representation.saveCoords(),this.to_representation.saveCoords(),this.from_representation.is_dragging=!1,this.to_representation.is_dragging=!1):(b||this.openEditor(),this.model.trigger("clicked")),this.renderer.click_target=null,this.renderer.is_dragging=!1},paperShift:function(a){this.options.editor_mode?this.options.read_only||(this.from_representation.paperShift(a),this.to_representation.paperShift(a)):this.renderer.paperShift(a)},destroy:function(){this._super("destroy"),this.line.remove(),this.arrow.remove(),this.text.remove(),this.renderer.minimap&&this.minimap_line.remove(),this.all_buttons.forEach(function(a){a.destroy()});var a=this;this.bundle.edges=b.reject(this.bundle.edges,function(b){return a===b})}}).value(),f}),define("renderer/tempedge",["jquery","underscore","requtils","renderer/baserepresentation"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){this.renderer.edge_layer.activate(),this.type="Temp-edge";var a=(this.project.get("users").get(this.renkan.current_user)||e._USER_PLACEHOLDER(this.renkan)).get("color");this.line=new paper.Path,this.line.strokeColor=a,this.line.dashArray=[4,2],this.line.strokeWidth=this.options.selected_edge_stroke_width,this.line.add([0,0],[0,0]),this.line.__representation=this,this.arrow=new paper.Path,this.arrow.fillColor=a,this.arrow.add([0,0],[this.options.edge_arrow_length,this.options.edge_arrow_width/2],[0,this.options.edge_arrow_width]),this.arrow.__representation=this,this.arrow_angle=0},redraw:function(){var a=this.from_representation.paper_coords,b=this.end_pos,c=b.subtract(a).angle,d=a.add(b).divide(2);this.line.segments[0].point=a,this.line.segments[1].point=b,this.arrow.rotate(c-this.arrow_angle),this.arrow.position=d,this.arrow_angle=c},paperShift:function(a){if(!this.renderer.isEditable())return this.renderer.removeRepresentation(_this),void paper.view.draw();this.end_pos=this.end_pos.add(a);var b=paper.project.hitTest(this.end_pos);this.renderer.findTarget(b),this.redraw()},mouseup:function(a){var b=paper.project.hitTest(a.point),c=this.from_representation.model,d=!0;if(b&&"undefined"!=typeof b.item.__representation){var f=b.item.__representation;if("Node"===f.type.substr(0,4)){var g=f.model||f.source_representation.model;if(c!==g){var h={id:e.getUID("edge"),created_by:this.renkan.current_user,from:c,to:g};this.renderer.isEditable()&&this.project.addEdge(h)}}(c===f.model||f.source_representation&&f.source_representation.model===c)&&(d=!1,this.renderer.is_dragging=!0)}d&&(this.renderer.click_target=null,this.renderer.is_dragging=!1,this.renderer.removeRepresentation(this),paper.view.draw())},destroy:function(){this.arrow.remove(),this.line.remove()}}).value(),f}),define("renderer/baseeditor",["jquery","underscore","requtils","renderer/baserepresentation"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){this.renderer.buttons_layer.activate(),this.type="editor",this.editor_block=new paper.Path;var c=b.map(b.range(8),function(){return[0,0]});this.editor_block.add.apply(this.editor_block,c),this.editor_block.strokeWidth=this.options.tooltip_border_width,this.editor_block.strokeColor=this.options.tooltip_border_color,this.editor_block.opacity=.8,this.editor_$=a("<div>").appendTo(this.renderer.editor_$).css({position:"absolute",opacity:.8}).hide()},destroy:function(){this.editor_block.remove(),this.editor_$.remove()}}).value(),f}),define("renderer/nodeeditor",["jquery","underscore","requtils","renderer/baseeditor"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){d.prototype._init.apply(this),this.template=this.options.templates["templates/nodeeditor.html"],this.readOnlyTemplate=this.options.templates["templates/nodeeditor_readonly.html"]},draw:function(){var c=this.source_representation.model,d=c.get("created_by")||e._USER_PLACEHOLDER(this.renkan),f=this.renderer.isEditable()?this.template:this.readOnlyTemplate,g=this.options.static_url+"img/image-placeholder.png",h=c.get("size")||0;this.editor_$.html(f({node:{has_creator:!!c.get("created_by"),title:c.get("title"),uri:c.get("uri"),short_uri:e.shortenText((c.get("uri")||"").replace(/^(https?:\/\/)?(www\.)?/,"").replace(/\/$/,""),40),description:c.get("description"),image:c.get("image")||"",image_placeholder:g,color:c.get("color")||d.get("color"),clip_path:c.get("clip_path")||!1,created_by_color:d.get("color"),created_by_title:d.get("title"),size:(h>0?"+":"")+h,shape:c.get("shape")||"circle"},renkan:this.renkan,options:this.options,shortenText:e.shortenText})),this.redraw();var i=this,j=function(){i.editor_$.off("keyup"),i.editor_$.find("input, textarea, select").off("change keyup paste"),i.editor_$.find(".Rk-Edit-Image-File").off("change"),i.editor_$.find(".Rk-Edit-ColorPicker-Wrapper").off("hover"),i.editor_$.find(".Rk-Edit-Size-Down").off("click"),i.editor_$.find(".Rk-Edit-Size-Up").off("click"),i.editor_$.find(".Rk-Edit-Image-Del").off("click"),i.editor_$.find(".Rk-Edit-ColorPicker").find("li").off("hover click"),i.editor_$.find(".Rk-CloseX").off("click"),i.editor_$.find(".Rk-Edit-Goto").off("click"),i.renderer.removeRepresentation(i),paper.view.draw()};if(this.editor_$.find(".Rk-CloseX").click(j),this.editor_$.find(".Rk-Edit-Goto").click(function(){return c.get("uri")?void 0:!1}),this.renderer.isEditable()){var k=b.throttle(function(){b.defer(function(){if(i.renderer.isEditable()){var a={title:i.editor_$.find(".Rk-Edit-Title").val()};i.options.show_node_editor_uri&&(a.uri=i.editor_$.find(".Rk-Edit-URI").val(),i.editor_$.find(".Rk-Edit-Goto").attr("href",a.uri||"#")),i.options.show_node_editor_image&&(a.image=i.editor_$.find(".Rk-Edit-Image").val(),i.editor_$.find(".Rk-Edit-ImgPreview").attr("src",a.image||g)),i.options.show_node_editor_description&&(a.description=i.editor_$.find(".Rk-Edit-Description").val()),i.options.change_shapes&&c.get("shape")!==i.editor_$.find(".Rk-Edit-Shape").val()&&(a.shape=i.editor_$.find(".Rk-Edit-Shape").val()),c.set(a),i.redraw()}else j()})},500);this.editor_$.on("keyup",function(a){27===a.keyCode&&j()}),this.editor_$.find("input, textarea, select").on("change keyup paste",k),i.options.allow_image_upload&&this.editor_$.find(".Rk-Edit-Image-File").change(function(){if(this.files.length){var a=this.files[0],b=new FileReader;if("image"!==a.type.substr(0,5))return void alert(i.renkan.translate("This file is not an image"));if(a.size>1024*i.options.uploaded_image_max_kb)return void alert(i.renkan.translate("Image size must be under ")+i.options.uploaded_image_max_kb+i.renkan.translate("KB"));b.onload=function(a){i.editor_$.find(".Rk-Edit-Image").val(a.target.result),k()},b.readAsDataURL(a)}}),this.editor_$.find(".Rk-Edit-Title")[0].focus();var l=i.editor_$.find(".Rk-Edit-ColorPicker");this.editor_$.find(".Rk-Edit-ColorPicker-Wrapper").hover(function(a){a.preventDefault(),l.show()},function(a){a.preventDefault(),l.hide()}),l.find("li").hover(function(b){b.preventDefault(),i.editor_$.find(".Rk-Edit-Color").css("background",a(this).attr("data-color"))},function(a){a.preventDefault(),i.editor_$.find(".Rk-Edit-Color").css("background",c.get("color")||(c.get("created_by")||e._USER_PLACEHOLDER(i.renkan)).get("color"))}).click(function(b){b.preventDefault(),i.renderer.isEditable()?(c.set("color",a(this).attr("data-color")),l.hide(),paper.view.draw()):j()});var m=function(a){if(i.renderer.isEditable()){var b=a+(c.get("size")||0);i.editor_$.find(".Rk-Edit-Size-Value").text((b>0?"+":"")+b),c.set("size",b),paper.view.draw()}else j()};this.editor_$.find(".Rk-Edit-Size-Down").click(function(){return m(-1),!1}),this.editor_$.find(".Rk-Edit-Size-Up").click(function(){return m(1),!1}),this.editor_$.find(".Rk-Edit-Image-Del").click(function(){return i.editor_$.find(".Rk-Edit-Image").val(""),k(),!1})}else if("object"==typeof this.source_representation.highlighted){var n=this.source_representation.highlighted.replace(b(c.get("title")).escape(),'<span class="Rk-Highlighted">$1</span>');this.editor_$.find(".Rk-Display-Title"+(c.get("uri")?" a":"")).html(n),this.options.show_node_tooltip_description&&this.editor_$.find(".Rk-Display-Description").html(this.source_representation.highlighted.replace(b(c.get("description")).escape(),'<span class="Rk-Highlighted">$1</span>'))}this.editor_$.find("img").load(function(){i.redraw()})},redraw:function(){var a=this.source_representation.paper_coords;e.drawEditBox(this.options,a,this.editor_block,.75*this.source_representation.circle_radius,this.editor_$),this.editor_$.show(),paper.view.draw()}}).value(),f}),define("renderer/edgeeditor",["jquery","underscore","requtils","renderer/baseeditor"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){d.prototype._init.apply(this),this.template=this.options.templates["templates/edgeeditor.html"],this.readOnlyTemplate=this.options.templates["templates/edgeeditor_readonly.html"]},draw:function(){var c=this.source_representation.model,d=c.get("from"),f=c.get("to"),g=c.get("created_by")||e._USER_PLACEHOLDER(this.renkan),h=this.renderer.isEditable()?this.template:this.readOnlyTemplate;this.editor_$.html(h({edge:{has_creator:!!c.get("created_by"),title:c.get("title"),uri:c.get("uri"),short_uri:e.shortenText((c.get("uri")||"").replace(/^(https?:\/\/)?(www\.)?/,"").replace(/\/$/,""),40),description:c.get("description"),color:c.get("color")||g.get("color"),from_title:d.get("title"),to_title:f.get("title"),from_color:d.get("color")||(d.get("created_by")||e._USER_PLACEHOLDER(this.renkan)).get("color"),to_color:f.get("color")||(f.get("created_by")||e._USER_PLACEHOLDER(this.renkan)).get("color"),created_by_color:g.get("color"),created_by_title:g.get("title")},renkan:this.renkan,shortenText:e.shortenText,options:this.options})),this.redraw();var i=this,j=function(){i.renderer.removeRepresentation(i),paper.view.draw()};if(this.editor_$.find(".Rk-CloseX").click(j),this.editor_$.find(".Rk-Edit-Goto").click(function(){return c.get("uri")?void 0:!1}),this.renderer.isEditable()){var k=b.throttle(function(){b.defer(function(){if(i.renderer.isEditable()){var a={title:i.editor_$.find(".Rk-Edit-Title").val()};i.options.show_edge_editor_uri&&(a.uri=i.editor_$.find(".Rk-Edit-URI").val()),i.editor_$.find(".Rk-Edit-Goto").attr("href",a.uri||"#"),c.set(a),paper.view.draw()}else j()})},500);this.editor_$.on("keyup",function(a){27===a.keyCode&&j()}),this.editor_$.find("input").on("keyup change paste",k),this.editor_$.find(".Rk-Edit-Vocabulary").change(function(){var b=a(this),c=b.val();c&&(i.editor_$.find(".Rk-Edit-Title").val(b.find(":selected").text()),i.editor_$.find(".Rk-Edit-URI").val(c),k())}),this.editor_$.find(".Rk-Edit-Direction").click(function(){i.renderer.isEditable()?(c.set({from:c.get("to"),to:c.get("from")}),i.draw()):j()});var l=i.editor_$.find(".Rk-Edit-ColorPicker");this.editor_$.find(".Rk-Edit-ColorPicker-Wrapper").hover(function(a){a.preventDefault(),l.show()},function(a){a.preventDefault(),l.hide()}),l.find("li").hover(function(b){b.preventDefault(),i.editor_$.find(".Rk-Edit-Color").css("background",a(this).attr("data-color"))},function(a){a.preventDefault(),i.editor_$.find(".Rk-Edit-Color").css("background",c.get("color")||(c.get("created_by")||e._USER_PLACEHOLDER(i.renkan)).get("color"))}).click(function(b){b.preventDefault(),i.renderer.isEditable()?(c.set("color",a(this).attr("data-color")),l.hide(),paper.view.draw()):j()})}},redraw:function(){var a=this.source_representation.paper_coords;e.drawEditBox(this.options,a,this.editor_block,5,this.editor_$),this.editor_$.show(),paper.view.draw()}}).value(),f}),define("renderer/nodebutton",["jquery","underscore","requtils","renderer/basebutton"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({setSectorSize:function(){var a=this.source_representation.circle_radius;a!==this.lastSectorInner&&(this.sector&&this.sector.destroy(),this.sector=this.renderer.drawSector(this,1+a,e._NODE_BUTTON_WIDTH+a,this.startAngle,this.endAngle,1,this.imageName,this.renkan.translate(this.text)),this.lastSectorInner=a)},unselect:function(){d.prototype.unselect.apply(this,Array.prototype.slice.call(arguments,1)),this.source_representation&&this.source_representation.buttons_timeout&&(clearTimeout(this.source_representation.buttons_timeout),this.source_representation.hideButtons())},select:function(){this.source_representation&&this.source_representation.buttons_timeout&&clearTimeout(this.source_representation.buttons_timeout),this.sector.select()}}).value(),f}),define("renderer/nodeeditbutton",["jquery","underscore","requtils","renderer/nodebutton"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){this.type="Node-edit-button",this.lastSectorInner=0,this.startAngle=-135,this.endAngle=-45,this.imageName="edit",this.text="Edit"},mouseup:function(){this.renderer.is_dragging||this.source_representation.openEditor()}}).value(),f}),define("renderer/noderemovebutton",["jquery","underscore","requtils","renderer/nodebutton"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){this.type="Node-remove-button",this.lastSectorInner=0,this.startAngle=0,this.endAngle=90,this.imageName="remove",this.text="Remove"},mouseup:function(){if(this.renderer.click_target=null,this.renderer.is_dragging=!1,this.renderer.removeRepresentationsOfType("editor"),this.renderer.isEditable())if(this.options.element_delete_delay){var a=e.getUID("delete");this.renderer.delete_list.push({id:a,time:(new Date).valueOf()+this.options.element_delete_delay}),this.source_representation.model.set("delete_scheduled",a)}else confirm(this.renkan.translate("Do you really wish to remove node ")+'"'+this.source_representation.model.get("title")+'"?')&&this.project.removeNode(this.source_representation.model)}}).value(),f}),define("renderer/noderevertbutton",["jquery","underscore","requtils","renderer/nodebutton"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){this.type="Node-revert-button",this.lastSectorInner=0,this.startAngle=-135,this.endAngle=135,this.imageName="revert",this.text="Cancel deletion"},mouseup:function(){this.renderer.click_target=null,this.renderer.is_dragging=!1,this.renderer.isEditable()&&this.source_representation.model.unset("delete_scheduled")}}).value(),f}),define("renderer/nodelinkbutton",["jquery","underscore","requtils","renderer/nodebutton"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){this.type="Node-link-button",this.lastSectorInner=0,this.startAngle=90,this.endAngle=180,this.imageName="link",this.text="Link to another node"},mousedown:function(a){if(this.renderer.isEditable()){var b=this.renderer.canvas_$.offset(),c=new paper.Point([a.pageX-b.left,a.pageY-b.top]);this.renderer.click_target=null,this.renderer.removeRepresentationsOfType("editor"),this.renderer.addTempEdge(this.source_representation,c)}}}).value(),f}),define("renderer/nodeenlargebutton",["jquery","underscore","requtils","renderer/nodebutton"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){this.type="Node-enlarge-button",this.lastSectorInner=0,this.startAngle=-45,this.endAngle=0,this.imageName="enlarge",this.text="Enlarge"},mouseup:function(){var a=1+(this.source_representation.model.get("size")||0);this.source_representation.model.set("size",a),this.source_representation.select(),this.select(),paper.view.draw()}}).value(),f}),define("renderer/nodeshrinkbutton",["jquery","underscore","requtils","renderer/nodebutton"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){this.type="Node-shrink-button",this.lastSectorInner=0,this.startAngle=-180,this.endAngle=-135,this.imageName="shrink",this.text="Shrink"},mouseup:function(){var a=-1+(this.source_representation.model.get("size")||0);this.source_representation.model.set("size",a),this.source_representation.select(),this.select(),paper.view.draw()}}).value(),f}),define("renderer/edgeeditbutton",["jquery","underscore","requtils","renderer/basebutton"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){this.type="Edge-edit-button",this.sector=this.renderer.drawSector(this,e._EDGE_BUTTON_INNER,e._EDGE_BUTTON_OUTER,-270,-90,1,"edit",this.renkan.translate("Edit"))},mouseup:function(){this.renderer.is_dragging||this.source_representation.openEditor()}}).value(),f}),define("renderer/edgeremovebutton",["jquery","underscore","requtils","renderer/basebutton"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){this.type="Edge-remove-button",this.sector=this.renderer.drawSector(this,e._EDGE_BUTTON_INNER,e._EDGE_BUTTON_OUTER,-90,90,1,"remove",this.renkan.translate("Remove"))},mouseup:function(){if(this.renderer.click_target=null,this.renderer.is_dragging=!1,this.renderer.removeRepresentationsOfType("editor"),this.renderer.isEditable())if(this.options.element_delete_delay){var a=e.getUID("delete");this.renderer.delete_list.push({id:a,time:(new Date).valueOf()+this.options.element_delete_delay}),this.source_representation.model.set("delete_scheduled",a)}else confirm(this.renkan.translate("Do you really wish to remove edge ")+'"'+this.source_representation.model.get("title")+'"?')&&this.project.removeEdge(this.source_representation.model)}}).value(),f}),define("renderer/edgerevertbutton",["jquery","underscore","requtils","renderer/basebutton"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({_init:function(){this.type="Edge-revert-button",this.sector=this.renderer.drawSector(this,e._EDGE_BUTTON_INNER,e._EDGE_BUTTON_OUTER,-135,135,1,"revert",this.renkan.translate("Cancel deletion"))},mouseup:function(){this.renderer.click_target=null,this.renderer.is_dragging=!1,this.renderer.isEditable()&&this.source_representation.model.unset("delete_scheduled")}}).value(),f}),define("renderer/miniframe",["jquery","underscore","requtils","renderer/baserepresentation"],function(a,b,c,d){var e=c.getUtils(),f=e.inherit(d);return b(f.prototype).extend({paperShift:function(a){this.renderer.offset=this.renderer.offset.subtract(a.divide(this.renderer.minimap.scale).multiply(this.renderer.scale)),this.renderer.redraw()},mouseup:function(){this.renderer.click_target=null,this.renderer.is_dragging=!1}}).value(),f}),define("renderer/scene",["jquery","underscore","filesaver","requtils","renderer/miniframe"],function(a,b,c,d,e){var f=d.getUtils(),g=function(c){this.renkan=c,this.$=a(".Rk-Render"),this.representations=[],this.$.html(c.options.templates["templates/scene.html"](c)),this.onStatusChange(),this.canvas_$=this.$.find(".Rk-Canvas"),this.labels_$=this.$.find(".Rk-Labels"),this.editor_$=this.$.find(".Rk-Editor"),this.notif_$=this.$.find(".Rk-Notifications"),paper.setup(this.canvas_$[0]),this.scale=1,this.initialScale=1,this.offset=paper.view.center,this.totalScroll=0,this.mouse_down=!1,this.click_target=null,this.selected_target=null,this.edge_layer=new paper.Layer,this.node_layer=new paper.Layer,this.buttons_layer=new paper.Layer,this.delete_list=[],this.redrawActive=!0,c.options.show_minimap&&(this.minimap={background_layer:new paper.Layer,edge_layer:new paper.Layer,node_layer:new paper.Layer,node_group:new paper.Group,size:new paper.Size(c.options.minimap_width,c.options.minimap_height)},this.minimap.background_layer.activate(),this.minimap.topleft=paper.view.bounds.bottomRight.subtract(this.minimap.size),this.minimap.rectangle=new paper.Path.Rectangle(this.minimap.topleft.subtract([2,2]),this.minimap.size.add([4,4])),this.minimap.rectangle.fillColor=c.options.minimap_background_color,this.minimap.rectangle.strokeColor=c.options.minimap_border_color,this.minimap.rectangle.strokeWidth=4,this.minimap.offset=new paper.Point(this.minimap.size.divide(2)),this.minimap.scale=.1,this.minimap.node_layer.activate(),this.minimap.cliprectangle=new paper.Path.Rectangle(this.minimap.topleft,this.minimap.size),this.minimap.node_group.addChild(this.minimap.cliprectangle),this.minimap.node_group.clipped=!0,this.minimap.miniframe=new paper.Path.Rectangle(this.minimap.topleft,this.minimap.size),this.minimap.node_group.addChild(this.minimap.miniframe),this.minimap.miniframe.fillColor="#c0c0ff",this.minimap.miniframe.opacity=.3,this.minimap.miniframe.strokeColor="#000080",this.minimap.miniframe.strokeWidth=2,this.minimap.miniframe.__representation=new e(this,null)),this.throttledPaperDraw=b(function(){paper.view.draw()}).throttle(100).value(),this.bundles=[],this.click_mode=!1;var d=this,g=!0,h=1,i=!1,j=0,k=0;this.image_cache={},this.icon_cache={},["edit","remove","link","enlarge","shrink","revert"].forEach(function(a){var b=new Image;b.src=c.options.static_url+"img/"+a+".png",d.icon_cache[a]=b});var l=b.throttle(function(a,b){d.onMouseMove(a,b)},f._MOUSEMOVE_RATE);this.canvas_$.on({mousedown:function(a){a.preventDefault(),d.onMouseDown(a,!1)},mousemove:function(a){a.preventDefault(),l(a,!1)},mouseup:function(a){a.preventDefault(),d.onMouseUp(a,!1)},mousewheel:function(a,b){c.options.zoom_on_scroll&&(a.preventDefault(),g&&d.onScroll(a,b))},touchstart:function(a){a.preventDefault();var b=a.originalEvent.touches[0];c.options.allow_double_click&&new Date-_lastTap<f._DOUBLETAP_DELAY&&Math.pow(j-b.pageX,2)+Math.pow(k-b.pageY,2)<f._DOUBLETAP_DISTANCE?(_lastTap=0,d.onDoubleClick(b)):(_lastTap=new Date,j=b.pageX,k=b.pageY,h=d.scale,i=!1,d.onMouseDown(b,!0))},touchmove:function(a){if(a.preventDefault(),_lastTap=0,1===a.originalEvent.touches.length)d.onMouseMove(a.originalEvent.touches[0],!0);else{if(i||(d.onMouseUp(a.originalEvent.touches[0],!0),d.click_target=null,d.is_dragging=!1,i=!0),"undefined"===a.originalEvent.scale)return; +var b=a.originalEvent.scale*h,c=b/d.scale,e=new paper.Point([d.canvas_$.width(),d.canvas_$.height()]).multiply(.5*(1-c)).add(d.offset.multiply(c));d.setScale(b,e)}},touchend:function(a){a.preventDefault(),d.onMouseUp(a.originalEvent.changedTouches[0],!0)},dblclick:function(a){a.preventDefault(),c.options.allow_double_click&&d.onDoubleClick(a)},mouseleave:function(a){a.preventDefault(),d.onMouseUp(a,!1),d.click_target=null,d.is_dragging=!1},dragover:function(a){a.preventDefault()},dragenter:function(a){a.preventDefault(),g=!1},dragleave:function(a){a.preventDefault(),g=!0},drop:function(a){a.preventDefault(),g=!0;var c={};b.each(a.originalEvent.dataTransfer.types,function(b){try{c[b]=a.originalEvent.dataTransfer.getData(b)}catch(d){}});var e=a.originalEvent.dataTransfer.getData("Text");if("string"==typeof e)switch(e[0]){case"{":case"[":try{var f=JSON.parse(e);b.extend(c,f)}catch(h){c["text/plain"]||(c["text/plain"]=e)}break;case"<":c["text/html"]||(c["text/html"]=e);break;default:c["text/plain"]||(c["text/plain"]=e)}var i=a.originalEvent.dataTransfer.getData("URL");i&&!c["text/uri-list"]&&(c["text/uri-list"]=i),d.dropData(c,a.originalEvent)}});var m=function(a,b){d.$.find(a).click(function(a){return d[b](a),!1})};m(".Rk-ZoomOut","zoomOut"),m(".Rk-ZoomIn","zoomIn"),m(".Rk-ZoomFit","autoScale"),this.$.find(".Rk-ZoomSave").click(function(){d.renkan.project.addView({zoom_level:d.scale,offset:d.offset})}),this.$.find(".Rk-ZoomSetSaved").click(function(){var a=d.renkan.project.get("views").last();a&&d.setScale(a.get("zoom_level"),new paper.Point(a.get("offset")))}),this.renkan.project.get("views").length>0&&this.renkan.options.save_view&&this.$.find(".Rk-ZoomSetSaved").show(),this.$.find(".Rk-CurrentUser").mouseenter(function(){d.$.find(".Rk-UserList").slideDown()}),this.$.find(".Rk-Users").mouseleave(function(){d.$.find(".Rk-UserList").slideUp()}),m(".Rk-FullScreen-Button","fullScreen"),m(".Rk-AddNode-Button","addNodeBtn"),m(".Rk-AddEdge-Button","addEdgeBtn"),m(".Rk-Save-Button","save"),m(".Rk-Open-Button","open"),m(".Rk-Export-Button","exportProject"),this.$.find(".Rk-Bookmarklet-Button").attr("href","javascript:"+f._BOOKMARKLET_CODE(c)).click(function(){return d.notif_$.text(c.translate("Drag this button to your bookmark bar. When on a third-party website, click it to enable drag-and-drop from the website to Renkan.")).fadeIn().delay(5e3).fadeOut(),!1}),this.$.find(".Rk-TopBar-Button").mouseover(function(){a(this).find(".Rk-TopBar-Tooltip").show()}).mouseout(function(){a(this).find(".Rk-TopBar-Tooltip").hide()}),m(".Rk-Fold-Bins","foldBins"),paper.view.onResize=function(a){var b,c=a.width,e=a.height;d.minimap&&(d.minimap.topleft=paper.view.bounds.bottomRight.subtract(d.minimap.size),d.minimap.rectangle.fitBounds(d.minimap.topleft.subtract([2,2]),d.minimap.size.add([4,4])),d.minimap.cliprectangle.fitBounds(d.minimap.topleft,d.minimap.size));var f=e/(e-a.delta.height),g=c/(c-a.delta.width);b=c>e?f:g,d.resizeZoom(g,f,b),d.redraw()};var n=b.throttle(function(){d.redraw()},50);this.addRepresentations("Node",this.renkan.project.get("nodes")),this.addRepresentations("Edge",this.renkan.project.get("edges")),this.renkan.project.on("change:title",function(){d.$.find(".Rk-PadTitle").val(c.project.get("title"))}),this.$.find(".Rk-PadTitle").on("keyup input paste",function(){c.project.set({title:a(this).val()})});var o=b.throttle(function(){d.redrawUsers()},100);if(o(),this.renkan.project.on("change:save_status",function(){switch(d.renkan.project.get("save_status")){case 0:d.$.find(".Rk-Save-Button").removeClass("to-save"),d.$.find(".Rk-Save-Button").removeClass("saving"),d.$.find(".Rk-Save-Button").addClass("saved");break;case 1:d.$.find(".Rk-Save-Button").removeClass("saved"),d.$.find(".Rk-Save-Button").removeClass("saving"),d.$.find(".Rk-Save-Button").addClass("to-save");break;case 2:d.$.find(".Rk-Save-Button").removeClass("saved"),d.$.find(".Rk-Save-Button").removeClass("to-save"),d.$.find(".Rk-Save-Button").addClass("saving")}}),this.renkan.project.on("change:loading_status",function(){if(d.renkan.project.get("loading_status")){d.$.find(".loader").addClass("run"),setTimeout(function(){d.$.find(".loader").hide(250)},3e3)}}),this.renkan.project.on("add:users remove:users",o),this.renkan.project.on("add:views remove:views",function(){d.renkan.project.get("views").length>0?d.$.find(".Rk-ZoomSetSaved").show():d.$.find(".Rk-ZoomSetSaved").hide()}),this.renkan.project.on("add:nodes",function(a){d.addRepresentation("Node",a),d.renkan.project.get("loading_status")||n()}),this.renkan.project.on("add:edges",function(a){d.addRepresentation("Edge",a),d.renkan.project.get("loading_status")||n()}),this.renkan.project.on("change:title",function(a,b){var c=d.$.find(".Rk-PadTitle");c.is("input")?c.val()!==b&&c.val(b):c.text(b)}),c.options.size_bug_fix){var p="number"==typeof c.options.size_bug_fix?c.options.size_bug_fix:500;window.setTimeout(function(){d.fixSize()},p)}if(c.options.force_resize&&a(window).resize(function(){d.autoScale()}),c.options.show_user_list&&c.options.user_color_editable){var q=this.$.find(".Rk-Users .Rk-Edit-ColorPicker-Wrapper"),r=this.$.find(".Rk-Users .Rk-Edit-ColorPicker");q.hover(function(a){d.isEditable()&&(a.preventDefault(),r.show())},function(a){a.preventDefault(),r.hide()}),r.find("li").mouseenter(function(b){d.isEditable()&&(b.preventDefault(),d.$.find(".Rk-CurrentUser-Color").css("background",a(this).attr("data-color")))})}if(c.options.show_search_field){var s="";this.$.find(".Rk-GraphSearch-Field").on("keyup change paste input",function(){var b=a(this),e=b.val();if(e!==s)if(s=e,e.length<2)c.project.get("nodes").each(function(a){d.getRepresentationByModel(a).unhighlight()});else{var g=f.regexpFromTextOrArray(e);c.project.get("nodes").each(function(a){g.test(a.get("title"))||g.test(a.get("description"))?d.getRepresentationByModel(a).highlight(g):d.getRepresentationByModel(a).unhighlight()})}})}this.redraw(),window.setInterval(function(){var a=(new Date).valueOf();d.delete_list.forEach(function(b){if(a>=b.time){var d=c.project.get("nodes").findWhere({delete_scheduled:b.id});d&&project.removeNode(d),d=c.project.get("edges").findWhere({delete_scheduled:b.id}),d&&project.removeEdge(d)}}),d.delete_list=d.delete_list.filter(function(a){return c.project.get("nodes").findWhere({delete_scheduled:a.id})||c.project.get("edges").findWhere({delete_scheduled:a.id})})},500),this.minimap&&window.setInterval(function(){d.rescaleMinimap()},2e3)};return b(g.prototype).extend({fixSize:function(){if(this.renkan.options.default_view&&this.renkan.project.get("views").length>0){var a=this.renkan.project.get("views").last();this.setScale(a.get("zoom_level"),new paper.Point(a.get("offset")))}else this.autoScale()},drawSector:function(b,c,d,e,f,g,h,i){var j=this.renkan.options,k=e*Math.PI/180,l=f*Math.PI/180,m=this.icon_cache[h],n=-Math.sin(k),o=Math.cos(k),p=Math.cos(k)*c+g*n,q=Math.sin(k)*c+g*o,r=Math.cos(k)*d+g*n,s=Math.sin(k)*d+g*o,t=-Math.sin(l),u=Math.cos(l),v=Math.cos(l)*c-g*t,w=Math.sin(l)*c-g*u,x=Math.cos(l)*d-g*t,y=Math.sin(l)*d-g*u,z=(c+d)/2,A=(k+l)/2,B=Math.cos(A)*z,C=Math.sin(A)*z,D=Math.cos(A)*c,E=Math.cos(A)*d,F=Math.sin(A)*c,G=Math.sin(A)*d,H=Math.cos(A)*(d+3),I=Math.sin(A)*(d+j.buttons_label_font_size)+j.buttons_label_font_size/2;this.buttons_layer.activate();var J=new paper.Path;J.add([p,q]),J.arcTo([D,F],[v,w]),J.lineTo([x,y]),J.arcTo([E,G],[r,s]),J.fillColor=j.buttons_background,J.opacity=.5,J.closed=!0,J.__representation=b;var K=new paper.PointText(H,I);K.characterStyle={fontSize:j.buttons_label_font_size,fillColor:j.buttons_label_color},K.paragraphStyle.justification=H>2?"left":-2>H?"right":"center",K.visible=!1;var L=!1,M=new paper.Point(-200,-200),N=new paper.Group([J,K]),O=N.position,P=new paper.Point([B,C]),Q=new paper.Point(0,0);K.content=i,N.pivot=N.bounds.center,N.visible=!1,N.position=M;var R={show:function(){L=!0,N.position=Q.add(O),N.visible=!0},moveTo:function(a){Q=a,L&&(N.position=a.add(O))},hide:function(){L=!1,N.visible=!1,N.position=M},select:function(){J.opacity=.8,K.visible=!0},unselect:function(){J.opacity=.5,K.visible=!1},destroy:function(){N.remove()}},S=function(){var a=new paper.Raster(m);a.position=P.add(N.position).subtract(O),a.locked=!0,N.addChild(a)};return m.width?S():a(m).on("load",S),R},addToBundles:function(a){var c=b(this.bundles).find(function(b){return b.from===a.from_representation&&b.to===a.to_representation||b.from===a.to_representation&&b.to===a.from_representation});return"undefined"!=typeof c?c.edges.push(a):(c={from:a.from_representation,to:a.to_representation,edges:[a],getPosition:function(a){var c=a.from_representation===this.from?1:-1;return c*(b(this.edges).indexOf(a)-(this.edges.length-1)/2)}},this.bundles.push(c)),c},isEditable:function(){return this.renkan.options.editor_mode&&!this.renkan.read_only},onStatusChange:function(){var a=this.$.find(".Rk-Save-Button"),b=a.find(".Rk-TopBar-Tooltip-Contents");this.renkan.read_only?(a.removeClass("disabled Rk-Save-Online").addClass("Rk-Save-ReadOnly"),b.text(this.renkan.translate("Connection lost"))):this.renkan.options.manual_save?(a.removeClass("Rk-Save-ReadOnly Rk-Save-Online"),b.text(this.renkan.translate("Save Project"))):(a.removeClass("disabled Rk-Save-ReadOnly").addClass("Rk-Save-Online"),b.text(this.renkan.translate("Auto-save enabled"))),this.redrawUsers()},setScale:function(a,b){a/this.initialScale>f._MIN_SCALE&&a/this.initialScale<f._MAX_SCALE&&(this.scale=a,b&&(this.offset=b),this.redraw())},autoScale:function(a){var b=this.renkan.project.get("nodes");if(b.length>1){var c=b.map(function(a){return a.get("position").x}),d=b.map(function(a){return a.get("position").y}),e=Math.min.apply(Math,c),f=Math.min.apply(Math,d),g=Math.max.apply(Math,c),h=Math.max.apply(Math,d),i=Math.min((paper.view.size.width-2*this.renkan.options.autoscale_padding)/(g-e),(paper.view.size.height-2*this.renkan.options.autoscale_padding)/(h-f));this.initialScale=i,"undefined"!=typeof a&&parseFloat(a.zoom_level)>0&&parseFloat(a.offset.x)>0&&parseFloat(a.offset.y)>0?this.setScale(parseFloat(a.zoom_level),new paper.Point(parseFloat(a.offset.x),parseFloat(a.offset.y))):this.setScale(i,paper.view.center.subtract(new paper.Point([(g+e)/2,(h+f)/2]).multiply(i)))}1===b.length&&this.setScale(1,paper.view.center.subtract(new paper.Point([b.at(0).get("position").x,b.at(0).get("position").y])))},redrawMiniframe:function(){var a=this.toMinimapCoords(this.toModelCoords(new paper.Point([0,0]))),b=this.toMinimapCoords(this.toModelCoords(paper.view.bounds.bottomRight));this.minimap.miniframe.fitBounds(a,b)},rescaleMinimap:function(){var a=this.renkan.project.get("nodes");if(a.length>1){var b=a.map(function(a){return a.get("position").x}),c=a.map(function(a){return a.get("position").y}),d=Math.min.apply(Math,b),e=Math.min.apply(Math,c),f=Math.max.apply(Math,b),g=Math.max.apply(Math,c),h=Math.min(.8*this.scale*this.renkan.options.minimap_width/paper.view.bounds.width,.8*this.scale*this.renkan.options.minimap_height/paper.view.bounds.height,(this.renkan.options.minimap_width-2*this.renkan.options.minimap_padding)/(f-d),(this.renkan.options.minimap_height-2*this.renkan.options.minimap_padding)/(g-e));this.minimap.offset=this.minimap.size.divide(2).subtract(new paper.Point([(f+d)/2,(g+e)/2]).multiply(h)),this.minimap.scale=h}1===a.length&&(this.minimap.scale=.1,this.minimap.offset=this.minimap.size.divide(2).subtract(new paper.Point([a.at(0).get("position").x,a.at(0).get("position").y]).multiply(this.minimap.scale))),this.redraw()},toPaperCoords:function(a){return a.multiply(this.scale).add(this.offset)},toMinimapCoords:function(a){return a.multiply(this.minimap.scale).add(this.minimap.offset).add(this.minimap.topleft)},toModelCoords:function(a){return a.subtract(this.offset).divide(this.scale)},addRepresentation:function(a,b){var c=d.getRenderer()[a],e=new c(this,b);return this.representations.push(e),e},addRepresentations:function(a,b){var c=this;b.forEach(function(b){c.addRepresentation(a,b)})},userTemplate:b.template('<li class="Rk-User"><span class="Rk-UserColor" style="background:<%=background%>;"></span><%=name%></li>'),redrawUsers:function(){if(this.renkan.options.show_user_list){var b=[].concat((this.renkan.project.current_user_list||{}).models||[],(this.renkan.project.get("users")||{}).models||[]),c="",d=this.$.find(".Rk-Users"),e=d.find(".Rk-CurrentUser-Name"),f=d.find(".Rk-Edit-ColorPicker li"),g=d.find(".Rk-CurrentUser-Color"),h=this;e.off("click").text(this.renkan.translate("<unknown user>")),f.off("mouseleave click"),b.forEach(function(b){b.get("_id")===h.renkan.current_user?(e.text(b.get("title")),g.css("background",b.get("color")),h.isEditable()&&(h.renkan.options.user_name_editable&&e.click(function(){var c=a(this),d=a("<input>").val(b.get("title")).blur(function(){b.set("title",a(this).val()),h.redrawUsers(),h.redraw()});c.empty().html(d),d.select()}),h.renkan.options.user_color_editable&&f.click(function(c){c.preventDefault(),h.isEditable()&&b.set("color",a(this).attr("data-color")),a(this).parent().hide()}).mouseleave(function(){g.css("background",b.get("color"))}))):c+=h.userTemplate({name:b.get("title"),background:b.get("color")})}),d.find(".Rk-UserList").html(c)}},removeRepresentation:function(a){a.destroy(),this.representations=b.reject(this.representations,function(b){return b===a})},getRepresentationByModel:function(a){return a?b.find(this.representations,function(b){return b.model===a}):void 0},removeRepresentationsOfType:function(a){var c=b.filter(this.representations,function(b){return b.type===a}),d=this;b.each(c,function(a){d.removeRepresentation(a)})},highlightModel:function(a){var b=this.getRepresentationByModel(a);b&&b.highlight()},unhighlightAll:function(){b.each(this.representations,function(a){a.unhighlight()})},unselectAll:function(){b.each(this.representations,function(a){a.unselect()})},redraw:function(){this.redrawActive&&(b.each(this.representations,function(a){a.redraw({dontRedrawEdges:!0})}),this.minimap&&this.redrawMiniframe(),paper.view.draw())},addTempEdge:function(a,b){var c=this.addRepresentation("TempEdge",null);c.end_pos=b,c.from_representation=a,c.redraw(),this.click_target=c},findTarget:function(a){if(a&&"undefined"!=typeof a.item.__representation){var b=a.item.__representation;this.selected_target!==a.item.__representation&&(this.selected_target&&this.selected_target.unselect(b),b.select(this.selected_target),this.selected_target=b)}else this.selected_target&&this.selected_target.unselect(),this.selected_target=null},paperShift:function(a){this.offset=this.offset.add(a),this.redraw()},onMouseMove:function(a){var b=this.canvas_$.offset(),c=new paper.Point([a.pageX-b.left,a.pageY-b.top]),d=c.subtract(this.last_point);this.last_point=c,!this.is_dragging&&this.mouse_down&&d.length>f._MIN_DRAG_DISTANCE&&(this.is_dragging=!0);var e=paper.project.hitTest(c);this.is_dragging?this.click_target&&"function"==typeof this.click_target.paperShift?this.click_target.paperShift(d):this.paperShift(d):this.findTarget(e),paper.view.draw()},onMouseDown:function(b,c){var d=this.canvas_$.offset(),e=new paper.Point([b.pageX-d.left,b.pageY-d.top]);if(this.last_point=e,this.mouse_down=!0,!this.click_target||"Temp-edge"!==this.click_target.type){this.removeRepresentationsOfType("editor"),this.is_dragging=!1;var g=paper.project.hitTest(e);if(g&&"undefined"!=typeof g.item.__representation)this.click_target=g.item.__representation,this.click_target.mousedown(b,c);else if(this.click_target=null,this.isEditable()&&this.click_mode===f._CLICKMODE_ADDNODE){var h=this.toModelCoords(e),i={id:f.getUID("node"),created_by:this.renkan.current_user,position:{x:h.x,y:h.y}};_node=this.renkan.project.addNode(i),this.getRepresentationByModel(_node).openEditor()}}this.click_mode&&(this.isEditable()&&this.click_mode===f._CLICKMODE_STARTEDGE&&this.click_target&&"Node"===this.click_target.type?(this.removeRepresentationsOfType("editor"),this.addTempEdge(this.click_target,e),this.click_mode=f._CLICKMODE_ENDEDGE,this.notif_$.fadeOut(function(){a(this).html(this.renkan.translate("Click on a second node to complete the edge")).fadeIn()})):(this.notif_$.hide(),this.click_mode=!1)),paper.view.draw()},onMouseUp:function(a,b){if(this.mouse_down=!1,this.click_target){var c=this.canvas_$.offset();this.click_target.mouseup({point:new paper.Point([a.pageX-c.left,a.pageY-c.top])},b)}else this.click_target=null,this.is_dragging=!1,b&&this.unselectAll();paper.view.draw()},onScroll:function(a,b){if(this.totalScroll+=b,Math.abs(this.totalScroll)>=1){var c=this.canvas_$.offset(),d=new paper.Point([a.pageX-c.left,a.pageY-c.top]).subtract(this.offset).multiply(Math.SQRT2-1);this.totalScroll>0?this.setScale(this.scale*Math.SQRT2,this.offset.subtract(d)):this.setScale(this.scale*Math.SQRT1_2,this.offset.add(d.divide(Math.SQRT2))),this.totalScroll=0}},onDoubleClick:function(a){if(this.isEditable()){var b=this.canvas_$.offset(),c=new paper.Point([a.pageX-b.left,a.pageY-b.top]),d=paper.project.hitTest(c);if(this.isEditable()&&(!d||"undefined"==typeof d.item.__representation)){var e=this.toModelCoords(c),g={id:f.getUID("node"),created_by:this.renkan.current_user,position:{x:e.x,y:e.y}},h=this.renkan.project.addNode(g);this.getRepresentationByModel(h).openEditor()}paper.view.draw()}},defaultDropHandler:function(b){var c={},d="";switch(b["text/x-iri-specific-site"]){case"twitter":d=a("<div>").html(b["text/x-iri-selected-html"]);var e=d.find(".tweet");c.title=this.renkan.translate("Tweet by ")+e.attr("data-name"),c.uri="http://twitter.com/"+e.attr("data-screen-name")+"/status/"+e.attr("data-tweet-id"),c.image=e.find(".avatar").attr("src"),c.description=e.find(".js-tweet-text:first").text();break;case"google":d=a("<div>").html(b["text/x-iri-selected-html"]),c.title=d.find("h3:first").text().trim(),c.uri=d.find("h3 a").attr("href"),c.description=d.find(".st:first").text().trim();break;default:b["text/x-iri-source-uri"]&&(c.uri=b["text/x-iri-source-uri"])}if((b["text/plain"]||b["text/x-iri-selected-text"])&&(c.description=(b["text/plain"]||b["text/x-iri-selected-text"]).replace(/[\s\n]+/gm," ").trim()),b["text/html"]||b["text/x-iri-selected-html"]){d=a("<div>").html(b["text/html"]||b["text/x-iri-selected-html"]);var f=d.find("image");f.length&&(c.image=f.attr("xlink:href"));var g=d.find("path");g.length&&(c.clipPath=g.attr("d"));var h=d.find("img");h.length&&(c.image=h[0].src);var i=d.find("a");i.length&&(c.uri=i[0].href),c.title=d.find("[title]").attr("title")||c.title,c.description=d.text().replace(/[\s\n]+/gm," ").trim()}b["text/uri-list"]&&(c.uri=b["text/uri-list"]),b["text/x-moz-url"]&&!c.title&&(c.title=(b["text/x-moz-url"].split("\n")[1]||"").trim(),c.title===c.uri&&(c.title=!1)),b["text/x-iri-source-title"]&&!c.title&&(c.title=b["text/x-iri-source-title"]),(b["text/html"]||b["text/x-iri-selected-html"])&&(d=a("<div>").html(b["text/html"]||b["text/x-iri-selected-html"]),c.image=d.find("[data-image]").attr("data-image")||c.image,c.uri=d.find("[data-uri]").attr("data-uri")||c.uri,c.title=d.find("[data-title]").attr("data-title")||c.title,c.description=d.find("[data-description]").attr("data-description")||c.description,c.clipPath=d.find("[data-clip-path]").attr("data-clip-path")||c.clipPath),c.title||(c.title=this.renkan.translate("Dragged resource"));for(var j=["title","description","uri","image"],k=0;k<j.length;k++){var l=j[k];(b["text/x-iri-"+l]||b[l])&&(c[l]=b["text/x-iri-"+l]||b[l]),("none"===c[l]||"null"===c[l])&&(c[l]=void 0)}return"function"==typeof this.renkan.options.drop_enhancer&&(c=this.renkan.options.drop_enhancer(c,b)),c},dropData:function(a,c){if(this.isEditable()){if(a["text/json"]||a["application/json"])try{var d=JSON.parse(a["text/json"]||a["application/json"]);b.extend(a,d)}catch(e){}var g="undefined"==typeof this.renkan.options.drop_handler?this.defaultDropHandler(a):this.renkan.options.drop_handler(a),h=this.canvas_$.offset(),i=new paper.Point([c.pageX-h.left,c.pageY-h.top]),j=this.toModelCoords(i),k={id:f.getUID("node"),created_by:this.renkan.current_user,uri:g.uri||"",title:g.title||"",description:g.description||"",image:g.image||"",color:g.color||void 0,clip_path:g.clipPath||void 0,position:{x:j.x,y:j.y}},l=this.renkan.project.addNode(k),m=this.getRepresentationByModel(l);"drop"===c.type&&m.openEditor()}},fullScreen:function(){var a,b=document.fullScreen||document.mozFullScreen||document.webkitIsFullScreen,c=this.renkan.$[0],d=["requestFullScreen","mozRequestFullScreen","webkitRequestFullScreen"],e=["cancelFullScreen","mozCancelFullScreen","webkitCancelFullScreen"];if(b){for(a=0;a<e.length;a++)if("function"==typeof document[e[a]]){document[e[a]]();break}var f=this.$.width(),g=this.$.height();this.renkan.options.show_top_bar&&(g-=this.$.find(".Rk-TopBar").height()),this.renkan.options.show_bins&&this.renkan.$.find(".Rk-Bins").position().left>0&&(f-=this.renkan.$.find(".Rk-Bins").width()),paper.view.viewSize=new paper.Size([f,g])}else{for(a=0;a<d.length;a++)if("function"==typeof c[d[a]]){c[d[a]]();break}this.redraw()}},zoomOut:function(){var a=this.scale*Math.SQRT1_2,b=new paper.Point([this.canvas_$.width(),this.canvas_$.height()]).multiply(.5*(1-Math.SQRT1_2)).add(this.offset.multiply(Math.SQRT1_2));this.setScale(a,b)},zoomIn:function(){var a=this.scale*Math.SQRT2,b=new paper.Point([this.canvas_$.width(),this.canvas_$.height()]).multiply(.5*(1-Math.SQRT2)).add(this.offset.multiply(Math.SQRT2));this.setScale(a,b)},resizeZoom:function(a,b,c){var d=this.scale*c,e=new paper.Point([this.offset.x*a,this.offset.y*b]);this.setScale(d,e)},addNodeBtn:function(){return this.click_mode===f._CLICKMODE_ADDNODE?(this.click_mode=!1,this.notif_$.hide()):(this.click_mode=f._CLICKMODE_ADDNODE,this.notif_$.text(this.renkan.translate("Click on the background canvas to add a node")).fadeIn()),!1},addEdgeBtn:function(){return this.click_mode===f._CLICKMODE_STARTEDGE||this.click_mode===f._CLICKMODE_ENDEDGE?(this.click_mode=!1,this.notif_$.hide()):(this.click_mode=f._CLICKMODE_STARTEDGE,this.notif_$.text(this.renkan.translate("Click on a first node to start the edge")).fadeIn()),!1},exportProject:function(){var a=this.renkan.project.toJSON(),d=(document.createElement("a"),a.id),e=d+".json";delete a.id,delete a._id,delete a.space_id;var g,h={};b.each(a.nodes,function(a){g=a.id||a._id,delete a._id,delete a.id,h[g]=a["@id"]=f.getUUID4()}),b.each(a.edges,function(a){delete a._id,delete a.id,a.to=h[a.to],a.from=h[a.from]}),b.each(a.views,function(a){g=a.id||a._id,delete a._id,delete a.id}),a.users=[];var i=JSON.stringify(a,null,2),j=new Blob([i],{type:"application/json;charset=utf-8"});c(j,e)},foldBins:function(){var a,b=this.$.find(".Rk-Fold-Bins"),c=this.renkan.$.find(".Rk-Bins"),d=this,e=d.canvas_$.width();c.position().left<0?(c.animate({left:0},250),this.$.animate({left:300},250,function(){var a=d.$.width();paper.view.viewSize=new paper.Size([a,d.canvas_$.height()])}),a=e-c.width()<c.height()?e:e-c.width(),b.html("«")):(c.animate({left:-300},250),this.$.animate({left:0},250,function(){var a=d.$.width();paper.view.viewSize=new paper.Size([a,d.canvas_$.height()])}),a=e+300,b.html("»")),d.resizeZoom(1,1,a/e)},save:function(){},open:function(){}}).value(),g}),"function"==typeof require.config&&require.config({paths:{jquery:"../lib/jquery/jquery",underscore:"../lib/lodash/lodash",filesaver:"../lib/FileSaver/FileSaver",requtils:"require-utils"}}),require(["renderer/baserepresentation","renderer/basebutton","renderer/noderepr","renderer/edge","renderer/tempedge","renderer/baseeditor","renderer/nodeeditor","renderer/edgeeditor","renderer/nodebutton","renderer/nodeeditbutton","renderer/noderemovebutton","renderer/noderevertbutton","renderer/nodelinkbutton","renderer/nodeenlargebutton","renderer/nodeshrinkbutton","renderer/edgeeditbutton","renderer/edgeremovebutton","renderer/edgerevertbutton","renderer/miniframe","renderer/scene"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t){var u=window.Rkns;"undefined"==typeof u.Renderer&&(u.Renderer={});var v=u.Renderer;v._BaseRepresentation=a,v._BaseButton=b,v.Node=c,v.Edge=d,v.TempEdge=e,v._BaseEditor=f,v.NodeEditor=g,v.EdgeEditor=h,v._NodeButton=i,v.NodeEditButton=j,v.NodeRemoveButton=k,v.NodeRevertButton=l,v.NodeLinkButton=m,v.NodeEnlargeButton=n,v.NodeShrinkButton=o,v.EdgeEditButton=p,v.EdgeRemoveButton=q,v.EdgeRevertButton=r,v.MiniFrame=s,v.Scene=t,startRenkan()}),define("main-renderer",function(){}); //# sourceMappingURL=renkan.min.map \ No newline at end of file
--- a/server/python/django/renkanmanager/static/renkanmanager/lib/renkan/js/renkan.min.map Sat Apr 25 04:37:06 2015 +0200 +++ b/server/python/django/renkanmanager/static/renkanmanager/lib/renkan/js/renkan.min.map Mon Apr 27 17:22:46 2015 +0200 @@ -1,1 +1,1 @@ -{"version":3,"file":"renkan.min.js","sources":["templates.js","../../js/main.js","../../js/models.js","../../js/defaults.js","../../js/i18n.js","../../js/full-json.js","../../js/save-once.js","../../js/ldtjson-bin.js","../../js/list-bin.js","../../js/wikipedia-bin.js","paper-renderer.js"],"names":["this","obj","__t","__p","_","escape","__e","Array","prototype","join","renkan","translate","edge","title","options","show_edge_editor_uri","uri","properties","length","each","ontology","label","property","show_edge_editor_color","show_edge_editor_direction","show_edge_editor_nodes","from_color","shortenText","from_title","to_title","show_edge_editor_creator","has_creator","created_by_title","show_edge_tooltip_color","color","show_edge_tooltip_uri","short_uri","description","show_edge_tooltip_nodes","to_color","show_edge_tooltip_creator","created_by_color","Rkns","Utils","getFullURL","image","static_url","url","show_bins","show_editor","node","show_node_editor_uri","show_node_editor_description","show_node_editor_size","size","show_node_editor_color","show_node_editor_image","image_placeholder","clip_path","allow_image_upload","show_node_editor_creator","change_shapes","shape","show_node_tooltip_color","show_node_tooltip_uri","show_node_tooltip_description","show_node_tooltip_image","show_node_tooltip_creator","print","__j","call","arguments","show_top_bar","editor_mode","project","get","show_user_list","show_user_color","user_color_editable","colorPicker","home_button_url","home_button_title","show_fullscreen_button","show_addnode_button","show_addedge_button","show_export_button","show_save_button","show_open_button","show_bookmarklet","show_search_field","resize","show_zoom","save_view","root","$","jQuery","pickerColors","__renkans","_BaseBin","_renkan","_opts","find","hide","addClass","appendTo","title_icon_$","_this","attr","href","html","click","destroy","slideDown","resizeBins","refresh","count_$","title_$","main_$","auto_refresh","window","setInterval","detach","Renkan","push","defaults","templates","renkanJST","template","property_files","f","getJSON","data","concat","read_only","Models","Project","setCurrentUser","user_id","user_name","addUser","_id","current_user","renderer","redrawUsers","container","tabs","search_engines","current_user_list","UsersList","on","_tmpl","map","c","Renderer","Scene","search","_select","_input","_form","_search","type","Search","_key","key","getSearchTitle","className","getBgClass","_el","setSearchEngine","submit","val","search_engine","mouseenter","mouseleave","bins","_bin","Bin","elementDropped","_mainDiv","siblings","is","slideUp","_t","_models","where","_model","highlightModel","mouseout","unhighlightAll","dragDrop","err","e","preventDefault","touch","originalEvent","changedTouches","off","canvas_$","offset","w","width","h","height","pageX","left","pageY","top","onMouseMove","div","document","createElement","appendChild","cloneNode","dropData","text/html","innerHTML","onMouseDown","onMouseUp","dataTransfer","setData","lastsearch","lastval","regexpFromTextOrArray","source","tab","render","_text","i18n","language","substr","onStatusChange","listClasses","split","classes","i","_d","outerHeight","css","getUUID4","replace","r","Math","random","v","toString","getUID","pad","n","Date","ID_AUTO_INCREMENT","ID_BASE","getUTCFullYear","getUTCMonth","getUTCDate","_base","_n","_uidbase","test","img","Image","src","res","inherit","_baseClass","_callbefore","_class","apply","slice","_init","_initialized","extend","replaceText","makeReplaceFunc","l","k","charsrx","txt","toLowerCase","remrx","j","remsrc","charsub","getSource","inp","removeChars","String","fromCharCode","RegExp","_textOrArray","testrx","replacerx","isempty","_replace","text","_MIN_DRAG_DISTANCE","_NODE_BUTTON_WIDTH","_EDGE_BUTTON_INNER","_EDGE_BUTTON_OUTER","_CLICKMODE_ADDNODE","_CLICKMODE_STARTEDGE","_CLICKMODE_ENDEDGE","_NODE_SIZE_STEP","LN2","_MIN_SCALE","_MAX_SCALE","_MOUSEMOVE_RATE","_DOUBLETAP_DELAY","_DOUBLETAP_DISTANCE","_USER_PLACEHOLDER","default_user_color","_BOOKMARKLET_CODE","_maxlength","drawEditBox","_options","_coords","_path","_xmargin","_selector","tooltip_width","tooltip_padding","_height","_isLeft","x","paper","view","center","_left","tooltip_arrow_length","_right","_top","y","tooltip_margin","max","tooltip_arrow_width","min","_bottom","segments","point","add","closed","fillColor","GradientColor","Gradient","tooltip_top_color","tooltip_bottom_color","Backbone","guid","RenkanModel","RelationalModel","idAttribute","constructor","id","prepare","validate","addReference","_propName","_list","_default","_element","User","toJSON","Node","relations","HasOne","relatedModel","created_by","position","Edge","from","to","View","isArray","zoom_level","RosterUser","blacklist","HasMany","reverseRelation","includeInJSON","_props","_user","findOrCreate","addNode","_node","addEdge","_edge","addView","_view","removeNode","remove","removeEdge","_project","users","nodes","edges","views","_item","initialize","filter","json","clone","attributes","Model","Collection","omit","site_id","model","navigator","userLanguage","manual_save","size_bug_fix","force_resize","allow_double_click","zoom_on_scroll","element_delete_delay","autoscale_padding","default_view","user_name_editable","show_minimap","minimap_width","minimap_height","minimap_padding","minimap_background_color","minimap_border_color","minimap_highlight_color","minimap_highlight_weight","buttons_background","buttons_label_color","buttons_label_font_size","show_node_circles","clip_node_images","node_images_fill_mode","node_size_base","node_stroke_width","selected_node_stroke_width","node_fill_color","highlighted_node_fill_color","node_label_distance","node_label_max_length","label_untitled_nodes","edge_stroke_width","selected_edge_stroke_width","edge_label_distance","edge_label_max_length","edge_arrow_length","edge_arrow_width","edge_gap_in_bundles","label_untitled_edges","tooltip_border_color","tooltip_border_width","uploaded_image_max_kb","fr","Edit Node","Edit Edge","Title:","URI:","Description:","From:","To:","Image URL:","Choose Image File:","Full Screen","Add Node","Add Edge","Save Project","Open Project","Auto-save enabled","Connection lost","Created by:","Zoom In","Zoom Out","Edit","Remove","Cancel deletion","Link to another node","Enlarge","Shrink","Click on the background canvas to add a node","Click on a first node to start the edge","Click on a second node to complete the edge","Wikipedia","Wikipedia in ","French","English","Japanese","Untitled project","Lignes de Temps","Loading, please wait","Edge color:","Node color:","Choose color","Change edge direction","Do you really wish to remove node ","Do you really wish to remove edge ","This file is not an image","Image size must be under ","Size:","KB","Choose from vocabulary:","SKOS Documentation properties","has note","has example","has definition","SKOS Semantic relations","has broader","has narrower","has related","Dublin Core Metadata","has contributor","covers","created by","has date","published by","has source","has subject","Dragged resource","Search the Web","Search in Bins","Close bin","Refresh bin","(untitled)","Select contents:","Drag items from this website, drop them in Renkan","Drag this button to your bookmark bar. When on a third-party website, click it to enable drag-and-drop from the website to Renkan.","Shapes available","Circle","Square","Diamond","Hexagone","Ellipse","Star","Zoom Fit","Download Project","Zoom Save","View saved zoom","Renkan 'Drag-to-Add' bookmarklet","(unknown user)","<unknown user>","Search in graph","Search in ","jsonIO","_proj","http_method","_load","redrawActive","set","loading_status","_data","save_status","fixSize","_save","ajax","contentType","JSON","stringify","success","_thrSave","throttle","setTimeout","changedAttributes","hasChanged","jsonIOSaveOnClick","_saveWarn","_onLeave","getdata","rx","matches","location","hash","match","beforeSend","autoScale","_checkLeave","removeClass","save","hasClass","Ldt","ProjectBin","ldt_type","Resclass","console","error","tagTemplate","annotationTemplate","proj_id","project_id","ldt_platform","searchbase","highlight","_e","convertTC","_ms","_res","_totalSeconds","abs","floor","_hours","_minutes","_seconds","_html","_projtitle","meta","count","tags","_tag","_title","htitle","encodedtitle","encodeURIComponent","annotations","_annotation","_description","content","_duration","end","begin","_img","hdescription","start","duration","mediaid","media","annotationid","show","dataType","lang","_q","ResultsBin","segmentTemplate","max_results","highlightrx","objects","_segment","_begin","start_ts","_end","iri_id","element_id","format","q","limit","ResourceList","resultTemplate","list","trim","_match","langs","en","ja","query","_result","encodeURI","snippet","define","_BaseRepresentation","_renderer","_changeBinding","redraw","_removeBinding","removeRepresentation","defer","_selectBinding","select","_unselectBinding","unselect","_super","_func","moveTo","trigger","unhighlight","mousedown","mouseup","getUtils","getRenderer","requtils","BaseRepresentation","_BaseButton","_pos","sector","_newTarget","source_representation","builders","circle","getShape","Path","getImageShape","radius","rectangle","Rectangle","ellipse","polygon","RegularPolygon","diamond","d","rotate","star","svg","path","ShapeBuilder","NodeRepr","node_layer","activate","buildShape","strokeWidth","h_ratio","labels_$","normal_buttons","NodeEditButton","NodeRemoveButton","NodeLinkButton","NodeEnlargeButton","NodeShrinkButton","pending_delete_buttons","NodeRevertButton","all_buttons","active_buttons","last_circle_radius","minimap","minimap_circle","__representation","miniframe","node_group","addChild","shapeBuilder","_dontRedrawEdges","_model_coords","Point","_baseRadius","exp","is_dragging","paper_coords","toPaperCoords","circle_radius","scale","forEach","b","setSectorSize","node_image","subtract","image_delta","multiply","old_act_btn","opacity","dashArray","selected","isEditable","highlighted","_color","strokeColor","_pc","lastImage","showImage","minipos","toMinimapCoords","miniradius","minisize","Size","fitBounds","ed","repr","getRepresentationByModel","from_representation","to_representation","_image","image_cache","clipPath","hasClipPath","_clip","baseRadius","centerPoint","instructions","lastCoords","minX","Infinity","minY","maxX","maxY","transformCoords","tabc","relative","newCoords","parseFloat","isY","instr","coords","lineTo","cubicCurveTo","quadraticCurveTo","_raster","Raster","locked","Group","clipped","_circleClip","divide","throttledPaperDraw","paperShift","_delta","openEditor","removeRepresentationsOfType","_editor","addRepresentation","draw","_uri","hideButtons","buttons_timeout","undefined","textToReplace","hlvalue","saveCoords","toModelCoords","_event","_isTouch","unselectAll","click_target","edge_layer","bundle","addToBundles","line","arrow","arrow_angle","EdgeEditButton","EdgeRemoveButton","EdgeRevertButton","minimap_line","_p0a","_p1a","_v","_r","_u","_ortho","_group_pos","getPosition","_p0b","_p1b","_a","angle","_textdelta","_handle","handleIn","handleOut","_textpos","transform","-moz-transform","-webkit-transform","text_angle","reject","TempEdge","_p0","_p1","end_pos","_c","_hitResult","hitTest","findTarget","_endDrag","item","_target","_destmodel","_BaseEditor","buttons_layer","editor_block","_pts","range","editor_$","BaseEditor","NodeEditor","readOnlyTemplate","_created_by","_template","_image_placeholder","_size","closeEditor","onFieldChange","shape_changed","keyCode","change","files","FileReader","alert","onload","target","result","readAsDataURL","focus","_picker","hover","shiftSize","_newsize","titlehtml","load","EdgeEditor","_from_model","_to_model","BaseButton","_NodeButton","sectorInner","lastSectorInner","drawSector","startAngle","endAngle","imageName","clearTimeout","NodeButton","delid","delete_list","time","valueOf","confirm","unset","_off","_point","addTempEdge","MiniFrame","filesaver","representations","notif_$","setup","initialScale","totalScroll","mouse_down","selected_target","Layer","background_layer","topleft","bounds","bottomRight","cliprectangle","bundles","click_mode","_allowScroll","_originalScale","_zooming","_lastTapX","_lastTapY","icon_cache","imgname","throttledMouseMove","mousemove","mousewheel","onScroll","touchstart","_touches","touches","_lastTap","pow","onDoubleClick","touchmove","_newScale","_scaleRatio","_newOffset","setScale","touchend","dblclick","dragover","dragenter","dragleave","drop","types","t","getData","parse","bindClick","selector","fname","evt","last","fadeIn","delay","fadeOut","mouseover","onResize","_ratio","newWidth","newHeight","ratioH","delta","ratioW","resizeZoom","_thRedraw","addRepresentations","_thRedrawUsers","el","_delay","$cpwrapper","$cplist","$this","rxs","_now","findWhere","delete_scheduled","rescaleMinimap","_repr","_inR","_outR","_startAngle","_endAngle","_padding","_imgname","_caption","_startRads","PI","_endRads","_startdx","sin","_startdy","cos","_startXIn","_startYIn","_startXOut","_startYOut","_enddx","_enddy","_endXIn","_endYIn","_endXOut","_endYOut","_centerR","_centerRads","_centerX","_centerY","_centerXIn","_centerXOut","_centerYIn","_centerYOut","_textX","_textY","arcTo","PointText","characterStyle","fontSize","paragraphStyle","justification","visible","_visible","_restPos","_grp","_imgdelta","_currentPos","pivot","_edgeRepr","_bundle","_er","_dir","indexOf","savebtn","tip","_offset","force_view","_xx","_yy","_minx","_miny","_maxx","_maxy","_scale","at","redrawMiniframe","bottomright","_type","RendererType","_collection","userTemplate","allUsers","models","ulistHtml","$userpanel","$name","$cpitems","$colorsquare","$input","blur","empty","parent","name","background","_representation","_representations","_from","_tmpEdge","last_point","_scrolldelta","SQRT2","SQRT1_2","defaultDropHandler","newNode","tweetdiv","_svgimgs","_svgpaths","_imgs","_as","fields","drop_enhancer","jsondata","drop_handler","_nodedata","fullScreen","_isFull","mozFullScreen","webkitIsFullScreen","_requestMethods","_cancelMethods","widthAft","heightAft","viewSize","zoomOut","zoomIn","_scaleWidth","_scaleHeight","addNodeBtn","addEdgeBtn","exportProject","projectJSON","projectId","fileNameToSaveAs","space_id","objId","idsMap","projectJSONStr","blob","Blob","foldBins","sizeAft","foldBinsButton","sizeBef","animate","open","require","config","paths","jquery","underscore","startRenkan"],"mappings":"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","sourcesContent":["this[\"renkanJST\"] = this[\"renkanJST\"] || {};\n\nthis[\"renkanJST\"][\"templates/colorpicker.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape;\nwith (obj) {\n__p += '<li data-color=\"' +\n((__t = (c)) == null ? '' : __t) +\n'\" style=\"background: ' +\n((__t = (c)) == null ? '' : __t) +\n'\"></li>';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/edgeeditor.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape, __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\nwith (obj) {\n__p += '<h2>\\n\\t<span class=\"Rk-CloseX\">×</span>' +\n__e(renkan.translate(\"Edit Edge\")) +\n'</span>\\n</h2>\\n<p>\\n\\t<label>' +\n__e(renkan.translate(\"Title:\")) +\n'</label>\\n\\t<input class=\"Rk-Edit-Title\" type=\"text\" value=\"' +\n__e(edge.title) +\n'\" />\\n</p>\\n';\n if (options.show_edge_editor_uri) { ;\n__p += '\\n\\t<p>\\n\\t\\t<label>' +\n__e(renkan.translate(\"URI:\")) +\n'</label>\\n\\t\\t<input class=\"Rk-Edit-URI\" type=\"text\" value=\"' +\n__e(edge.uri) +\n'\" />\\n\\t\\t<a class=\"Rk-Edit-Goto\" href=\"' +\n__e(edge.uri) +\n'\" target=\"_blank\"></a>\\n\\t</p>\\n\\t';\n if (options.properties.length) { ;\n__p += '\\n\\t\\t<p>\\n\\t\\t\\t<label>' +\n__e(renkan.translate(\"Choose from vocabulary:\")) +\n'</label>\\n\\t\\t\\t<select class=\"Rk-Edit-Vocabulary\">\\n\\t\\t\\t\\t';\n _(options.properties).each(function(ontology) { ;\n__p += '\\n\\t\\t\\t\\t\\t<option class=\"Rk-Edit-Vocabulary-Class\" value=\"\">\\n\\t\\t\\t\\t\\t\\t' +\n__e( renkan.translate(ontology.label) ) +\n'\\n\\t\\t\\t\\t\\t</option>\\n\\t\\t\\t\\t\\t';\n _(ontology.properties).each(function(property) { var uri = ontology[\"base-uri\"] + property.uri; ;\n__p += '\\n\\t\\t\\t\\t\\t\\t<option class=\"Rk-Edit-Vocabulary-Property\" value=\"' +\n__e( uri ) +\n'\"\\n\\t\\t\\t\\t\\t\\t\\t';\n if (uri === edge.uri) { ;\n__p += ' selected';\n } ;\n__p += '>\\n\\t\\t\\t\\t\\t\\t\\t' +\n__e( renkan.translate(property.label) ) +\n'\\n\\t\\t\\t\\t\\t\\t</option>\\n\\t\\t\\t\\t\\t';\n }) ;\n__p += '\\n\\t\\t\\t\\t';\n }) ;\n__p += '\\n\\t\\t\\t</select>\\n\\t\\t</p>\\n';\n } } ;\n__p += '\\n';\n if (options.show_edge_editor_color) { ;\n__p += '\\n\\t<div class=\"Rk-Editor-p\">\\n\\t\\t<span class=\"Rk-Editor-Label\">' +\n__e(renkan.translate(\"Edge color:\")) +\n'</span>\\n\\t\\t<div class=\"Rk-Edit-ColorPicker-Wrapper\">\\n\\t\\t\\t<span class=\"Rk-Edit-Color\" style=\"background: <%-edge.color%>;\">\\n\\t\\t\\t\\t<span class=\"Rk-Edit-ColorTip\"></span>\\n\\t\\t\\t</span>\\n\\t\\t\\t' +\n((__t = ( renkan.colorPicker )) == null ? '' : __t) +\n'\\n\\t\\t\\t<span class=\"Rk-Edit-ColorPicker-Text\">' +\n__e( renkan.translate(\"Choose color\") ) +\n'</span>\\n\\t\\t</div>\\n\\t</div>\\n';\n } ;\n__p += '\\n';\n if (options.show_edge_editor_direction) { ;\n__p += '\\n\\t<p>\\n\\t\\t<span class=\"Rk-Edit-Direction\">' +\n__e( renkan.translate(\"Change edge direction\") ) +\n'</span>\\n\\t</p>\\n';\n } ;\n__p += '\\n';\n if (options.show_edge_editor_nodes) { ;\n__p += '\\n\\t<p>\\n\\t\\t<span class=\"Rk-Editor-Label\">' +\n__e(renkan.translate(\"From:\")) +\n'</span>\\n\\t\\t<span class=\"Rk-UserColor\" style=\"background: ' +\n__e(edge.from_color) +\n';\"></span>\\n\\t\\t' +\n__e( shortenText(edge.from_title, 25) ) +\n'\\n\\t</p>\\n\\t<p>\\n\\t\\t<span class=\"Rk-Editor-Label\">' +\n__e(renkan.translate(\"To:\")) +\n'</span>\\n\\t\\t<span class=\"Rk-UserColor\" style=\"background: >%-edge.to_color%>;\"></span>\\n\\t\\t' +\n__e( shortenText(edge.to_title, 25) ) +\n'\\n\\t</p>\\n';\n } ;\n__p += '\\n';\n if (options.show_edge_editor_creator && edge.has_creator) { ;\n__p += '\\n\\t<p>\\n\\t\\t<span class=\"Rk-Editor-Label\">' +\n__e(renkan.translate(\"Created by:\")) +\n'</span>\\n\\t\\t<span class=\"Rk-UserColor\" style=\"background: <%-edge.created_by_color%>;\"></span>\\n\\t\\t' +\n__e( shortenText(edge.created_by_title, 25) ) +\n'\\n\\t</p>\\n';\n } ;\n__p += '\\n';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/edgeeditor_readonly.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape, __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\nwith (obj) {\n__p += '<h2>\\n\\t<span class=\"Rk-CloseX\">×</span>\\n\\t';\n if (options.show_edge_tooltip_color) { ;\n__p += '\\n\\t\\t<span class=\"Rk-UserColor\" style=\"background: ' +\n__e( edge.color ) +\n';\"></span>\\n\\t';\n } ;\n__p += '\\n\\t<span class=\"Rk-Display-Title\">\\n\\t\\t';\n if (edge.uri) { ;\n__p += '\\n\\t\\t\\t<a href=\"' +\n__e(edge.uri) +\n'\" target=\"_blank\">\\n\\t\\t';\n } ;\n__p += '\\n\\t\\t' +\n__e(edge.title) +\n'\\n\\t\\t';\n if (edge.uri) { ;\n__p += ' </a> ';\n } ;\n__p += '\\n\\t</span>\\n</h2>\\n';\n if (options.show_edge_tooltip_uri && edge.uri) { ;\n__p += '\\n\\t<p class=\"Rk-Display-URI\">\\n\\t\\t<a href=\"' +\n__e(edge.uri) +\n'\" target=\"_blank\">' +\n__e( edge.short_uri ) +\n'</a>\\n\\t</p>\\n';\n } ;\n__p += '\\n<p>' +\n__e(edge.description) +\n'</p>\\n';\n if (options.show_edge_tooltip_nodes) { ;\n__p += '\\n\\t<p>\\n\\t\\t<span class=\"Rk-Editor-Label\">' +\n__e(renkan.translate(\"From:\")) +\n'</span>\\n\\t\\t<span class=\"Rk-UserColor\" style=\"background: ' +\n__e( edge.from_color ) +\n';\"></span>\\n\\t\\t' +\n__e( shortenText(edge.from_title, 25) ) +\n'\\n\\t</p>\\n\\t<p>\\n\\t\\t<span class=\"Rk-Editor-Label\">' +\n__e(renkan.translate(\"To:\")) +\n'</span>\\n\\t\\t<span class=\"Rk-UserColor\" style=\"background: ' +\n__e( edge.to_color ) +\n';\"></span>\\n\\t\\t' +\n__e( shortenText(edge.to_title, 25) ) +\n'\\n\\t</p>\\n';\n } ;\n__p += '\\n';\n if (options.show_edge_tooltip_creator && edge.has_creator) { ;\n__p += '\\n\\t<p>\\n\\t\\t<span class=\"Rk-Editor-Label\">' +\n__e(renkan.translate(\"Created by:\")) +\n'</span>\\n\\t\\t<span class=\"Rk-UserColor\" style=\"background: ' +\n__e( edge.created_by_color ) +\n';\"></span>\\n\\t\\t' +\n__e( shortenText(edge.created_by_title, 25) ) +\n'\\n\\t</p>\\n';\n } ;\n__p += '\\n';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/ldtjson-bin/annotationtemplate.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape;\nwith (obj) {\n__p += '<li class=\"Rk-Bin-Item\" draggable=\"true\"\\n\\tdata-image=\"' +\n__e( Rkns.Utils.getFullURL(image) ) +\n'\"\\n\\tdata-uri=\"' +\n((__t = (ldt_platform)) == null ? '' : __t) +\n'ldtplatform/ldt/front/player/' +\n((__t = (mediaid)) == null ? '' : __t) +\n'/#id=' +\n((__t = (annotationid)) == null ? '' : __t) +\n'\"\\n\\tdata-title=\"' +\n__e(title) +\n'\" data-description=\"' +\n__e(description) +\n'\">\\n\\t\\n\\t<img class=\"Rk-Ldt-Annotation-Icon\" src=\"' +\n((__t = (image)) == null ? '' : __t) +\n'\" />\\n\\t<h4>' +\n((__t = (htitle)) == null ? '' : __t) +\n'</h4>\\n\\t<p>' +\n((__t = (hdescription)) == null ? '' : __t) +\n'</p>\\n\\t<p>Start: ' +\n((__t = (start)) == null ? '' : __t) +\n', End: ' +\n((__t = (end)) == null ? '' : __t) +\n', Duration: ' +\n((__t = (duration)) == null ? '' : __t) +\n'</p>\\n\\t<div class=\"Rk-Clear\"></div>\\n</li>';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/ldtjson-bin/segmenttemplate.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape;\nwith (obj) {\n__p += '<li class=\"Rk-Bin-Item\" draggable=\"true\"\\n\\tdata-image=\"' +\n__e( Rkns.Utils.getFullURL(image) ) +\n'\"\\n\\tdata-uri=\"' +\n((__t = (ldt_platform)) == null ? '' : __t) +\n'ldtplatform/ldt/front/player/' +\n((__t = (mediaid)) == null ? '' : __t) +\n'/#id=' +\n((__t = (annotationid)) == null ? '' : __t) +\n'\"\\n\\tdata-title=\"' +\n__e(title) +\n'\" data-description=\"' +\n__e(description) +\n'\">\\n\\t\\n\\t<img class=\"Rk-Ldt-Annotation-Icon\" src=\"' +\n((__t = (image)) == null ? '' : __t) +\n'\" />\\n\\t<h4>' +\n((__t = (htitle)) == null ? '' : __t) +\n'</h4>\\n\\t<p>' +\n((__t = (hdescription)) == null ? '' : __t) +\n'</p>\\n\\t<p>Start: ' +\n((__t = (start)) == null ? '' : __t) +\n', End: ' +\n((__t = (end)) == null ? '' : __t) +\n', Duration: ' +\n((__t = (duration)) == null ? '' : __t) +\n'</p>\\n\\t<div class=\"Rk-Clear\"></div>\\n</li>';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/ldtjson-bin/tagtemplate.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape;\nwith (obj) {\n__p += '<li class=\"Rk-Bin-Item\" draggable=\"true\"\\n\\tdata-image=\"' +\n__e( Rkns.Utils.getFullURL(static_url+'img/ldt-tag.png') ) +\n'\"\\n\\tdata-uri=\"' +\n((__t = (ldt_platform)) == null ? '' : __t) +\n'ldtplatform/ldt/front/search/?search=' +\n((__t = (encodedtitle)) == null ? '' : __t) +\n'&field=all\"\\n\\tdata-title=\"' +\n__e(title) +\n'\" data-description=\"Tag \\'' +\n__e(title) +\n'\\'\">\\n\\n\\t<img class=\"Rk-Ldt-Tag-Icon\" src=\"' +\n__e(static_url) +\n'img/ldt-tag.png\" />\\n\\t<h4>' +\n((__t = (htitle)) == null ? '' : __t) +\n'</h4>\\n\\t<div class=\"Rk-Clear\"></div>\\n</li>';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/list-bin.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape, __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\nwith (obj) {\n__p += '<li class=\"Rk-Bin-Item Rk-ResourceList-Item\" draggable=\"true\"\\n\\tdata-uri=\"' +\n__e(url) +\n'\" data-title=\"' +\n__e(title) +\n'\"\\n\\tdata-description=\"' +\n__e(description) +\n'\"\\n\\t';\n if (image) { ;\n__p += '\\n\\t\\tdata-image=\"' +\n__e( Rkns.Utils.getFullURL(image) ) +\n'\"\\n\\t';\n } else { ;\n__p += '\\n\\t\\tdata-image=\"\"\\n\\t';\n } ;\n__p += '\\n>';\n if (image) { ;\n__p += '\\n\\t<img class=\"Rk-ResourceList-Image\" src=\"' +\n__e(image) +\n'\" />\\n';\n } ;\n__p += '\\n<h4 class=\"Rk-ResourceList-Title\">\\n\\t';\n if (url) { ;\n__p += '\\n\\t\\t<a href=\"' +\n__e(url) +\n'\" target=\"_blank\">\\n\\t';\n } ;\n__p += '\\n\\t' +\n((__t = (htitle)) == null ? '' : __t) +\n'\\n\\t';\n if (url) { ;\n__p += '</a>';\n } ;\n__p += '\\n\\t</h4> \\n\\t';\n if (description) { ;\n__p += '\\n\\t\\t<p class=\"Rk-ResourceList-Description\">' +\n((__t = (hdescription)) == null ? '' : __t) +\n'</p>\\n\\t';\n } ;\n__p += '\\n\\t';\n if (image) { ;\n__p += '\\n\\t\\t<div style=\"clear: both;\"></div>\\n\\t';\n } ;\n__p += '\\n</li>';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/main.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape, __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\nwith (obj) {\n\n if (options.show_bins) { ;\n__p += '\\n\\t<div class=\"Rk-Bins\">\\n\\t\\t<div class=\"Rk-Bins-Head\">\\n\\t\\t\\t<h2 class=\"Rk-Bins-Title\">' +\n__e( translate(\"Select contents:\")) +\n'</h2>\\n\\t\\t\\t<form class=\"Rk-Web-Search-Form Rk-Search-Form\">\\n\\t\\t\\t\\t<input class=\"Rk-Web-Search-Input Rk-Search-Input\" type=\"search\"\\n\\t\\t\\t\\t\\tplaceholder=\"' +\n__e( translate('Search the Web') ) +\n'\" />\\n\\t\\t\\t\\t<div class=\"Rk-Search-Select\">\\n\\t\\t\\t\\t\\t<div class=\"Rk-Search-Current\"></div>\\n\\t\\t\\t\\t\\t<ul class=\"Rk-Search-List\"></ul>\\n\\t\\t\\t\\t</div>\\n\\t\\t\\t\\t<input type=\"submit\" value=\"\"\\n\\t\\t\\t\\t\\tclass=\"Rk-Web-Search-Submit Rk-Search-Submit\" title=\"' +\n__e( translate('Search the Web') ) +\n'\" />\\n\\t\\t\\t</form>\\n\\t\\t\\t<form class=\"Rk-Bins-Search-Form Rk-Search-Form\">\\n\\t\\t\\t\\t<input class=\"Rk-Bins-Search-Input Rk-Search-Input\" type=\"search\"\\n\\t\\t\\t\\t\\tplaceholder=\"' +\n__e( translate('Search in Bins') ) +\n'\" /> <input\\n\\t\\t\\t\\t\\ttype=\"submit\" value=\"\"\\n\\t\\t\\t\\t\\tclass=\"Rk-Bins-Search-Submit Rk-Search-Submit\"\\n\\t\\t\\t\\t\\ttitle=\"' +\n__e( translate('Search in Bins') ) +\n'\" />\\n\\t\\t\\t</form>\\n\\t\\t</div>\\n\\t\\t<ul class=\"Rk-Bin-List\"></ul>\\n\\t</div>\\n';\n } ;\n__p += ' ';\n if (options.show_editor) { ;\n__p += '\\n\\t<div class=\"Rk-Render Rk-Render-';\n if (options.show_bins) { ;\n__p += 'Panel';\n } else { ;\n__p += 'Full';\n } ;\n__p += '\"></div>\\n';\n } ;\n__p += '\\n';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/nodeeditor.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape, __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\nwith (obj) {\n__p += '<h2>\\n\\t<span class=\"Rk-CloseX\">×</span>' +\n__e(renkan.translate(\"Edit Node\")) +\n'</span>\\n</h2>\\n<p>\\n\\t<label>' +\n__e(renkan.translate(\"Title:\")) +\n'</label>\\n\\t<input class=\"Rk-Edit-Title\" type=\"text\" value=\"' +\n__e(node.title) +\n'\" />\\n</p>\\n';\n if (options.show_node_editor_uri) { ;\n__p += '\\n\\t<p>\\n\\t\\t<label>' +\n__e(renkan.translate(\"URI:\")) +\n'</label>\\n\\t\\t<input class=\"Rk-Edit-URI\" type=\"text\" value=\"' +\n__e(node.uri) +\n'\" />\\n\\t\\t<a class=\"Rk-Edit-Goto\" href=\"' +\n__e(node.uri) +\n'\" target=\"_blank\"></a>\\n\\t</p>\\n';\n } ;\n__p += ' ';\n if (options.show_node_editor_description) { ;\n__p += '\\n\\t<p>\\n\\t\\t<label>' +\n__e(renkan.translate(\"Description:\")) +\n'</label>\\n\\t\\t<textarea class=\"Rk-Edit-Description\">' +\n__e(node.description) +\n'</textarea>\\n\\t</p>\\n';\n } ;\n__p += ' ';\n if (options.show_node_editor_size) { ;\n__p += '\\n\\t<p>\\n\\t\\t<span class=\"Rk-Editor-Label\">' +\n__e(renkan.translate(\"Size:\")) +\n'</span>\\n\\t\\t<a href=\"#\" class=\"Rk-Edit-Size-Down\">-</a>\\n\\t\\t<span class=\"Rk-Edit-Size-Value\">' +\n__e(node.size) +\n'</span>\\n\\t\\t<a href=\"#\" class=\"Rk-Edit-Size-Up\">+</a>\\n\\t</p>\\n';\n } ;\n__p += ' ';\n if (options.show_node_editor_color) { ;\n__p += '\\n\\t<div class=\"Rk-Editor-p\">\\n\\t\\t<span class=\"Rk-Editor-Label\">\\n\\t\\t' +\n__e(renkan.translate(\"Node color:\")) +\n'</span>\\n\\t\\t<div class=\"Rk-Edit-ColorPicker-Wrapper\">\\n\\t\\t\\t<span class=\"Rk-Edit-Color\" style=\"background: ' +\n__e(node.color) +\n';\">\\n\\t\\t\\t\\t<span class=\"Rk-Edit-ColorTip\"></span>\\n\\t\\t\\t</span>\\n\\t\\t\\t' +\n((__t = ( renkan.colorPicker )) == null ? '' : __t) +\n'\\n\\t\\t\\t<span class=\"Rk-Edit-ColorPicker-Text\">' +\n__e( renkan.translate(\"Choose color\") ) +\n'</span>\\n\\t\\t</div>\\n\\t</div>\\n';\n } ;\n__p += ' ';\n if (options.show_node_editor_image) { ;\n__p += '\\n\\t<div class=\"Rk-Edit-ImgWrap\">\\n\\t\\t<div class=\"Rk-Edit-ImgPreview\">\\n\\t\\t\\t<img src=\"' +\n__e(node.image || node.image_placeholder) +\n'\" />\\n\\t\\t\\t';\n if (node.clip_path) { ;\n__p += '\\n\\t\\t\\t\\t<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewbox=\"0 0 1 1\" preserveAspectRatio=\"none\">\\n\\t\\t\\t\\t\\t<path style=\"stroke-width: .02; stroke:red; fill-opacity:.3; fill:red;\" d=\"' +\n__e( node.clip_path ) +\n'\" />\\n\\t\\t\\t\\t</svg>\\n\\t\\t\\t';\n };\n__p += '\\n\\t\\t</div>\\n\\t</div>\\n\\t<p>\\n\\t\\t<label>' +\n__e(renkan.translate(\"Image URL:\")) +\n'</label>\\n\\t\\t<div>\\n\\t\\t\\t<a class=\"Rk-Edit-Image-Del\" href=\"#\"></a>\\n\\t\\t\\t<input class=\"Rk-Edit-Image\" type=\"text\" value=\\'' +\n__e(node.image) +\n'\\' />\\n\\t\\t</div>\\n\\t</p>\\n';\n if (options.allow_image_upload) { ;\n__p += '\\n\\t<p>\\n\\t\\t<label>' +\n__e(renkan.translate(\"Choose Image File:\")) +\n'</label>\\n\\t\\t<input class=\"Rk-Edit-Image-File\" type=\"file\" accept=\"image/*\" />\\n\\t</p>\\n';\n };\n\n } ;\n__p += ' ';\n if (options.show_node_editor_creator && node.has_creator) { ;\n__p += '\\n\\t<p>\\n\\t\\t<span class=\"Rk-Editor-Label\">' +\n__e(renkan.translate(\"Created by:\")) +\n'</span>\\n\\t\\t<span class=\"Rk-UserColor\" style=\"background: ' +\n__e(node.created_by_color) +\n';\"></span>\\n\\t\\t' +\n__e( shortenText(node.created_by_title, 25) ) +\n'\\n\\t</p>\\n';\n } ;\n__p += ' ';\n if (options.change_shapes) { ;\n__p += '\\n\\t<p>\\n\\t\\t<label>' +\n__e(renkan.translate(\"Shapes available\")) +\n':</label>\\n\\t\\t<select class=\"Rk-Edit-Shape\">\\n\\t\\t\\t<option class=\"Rk-Edit-Vocabulary-Property\" value=\"circle\"';\n if (node.shape === \"circle\") { ;\n__p += ' selected';\n } ;\n__p += '>\\n\\t\\t\\t\\t' +\n__e( renkan.translate(\"Circle\") ) +\n'\\n\\t\\t\\t</option>\\n\\t\\t\\t<option class=\"Rk-Edit-Vocabulary-Property\" value=\"rectangle\"';\n if (node.shape === \"rectangle\") { ;\n__p += ' selected';\n } ;\n__p += '>\\n\\t\\t\\t\\t' +\n__e( renkan.translate(\"Square\") ) +\n'\\n\\t\\t\\t</option>\\n\\t\\t\\t<option class=\"Rk-Edit-Vocabulary-Property\" value=\"diamond\"';\n if (node.shape === \"diamond\") { ;\n__p += ' selected';\n } ;\n__p += '>\\n\\t\\t\\t\\t' +\n__e( renkan.translate(\"Diamond\") ) +\n'\\n\\t\\t\\t</option>\\n\\t\\t\\t<option class=\"Rk-Edit-Vocabulary-Property\" value=\"polygon\"';\n if (node.shape === \"polygon\") { ;\n__p += ' selected';\n } ;\n__p += '>\\n\\t\\t\\t\\t' +\n__e( renkan.translate(\"Hexagone\") ) +\n'\\n\\t\\t\\t</option>\\n\\t\\t\\t<option class=\"Rk-Edit-Vocabulary-Property\" value=\"ellipse\"';\n if (node.shape === \"ellipse\") { ;\n__p += ' selected';\n } ;\n__p += '>\\n\\t\\t\\t\\t' +\n__e( renkan.translate(\"Ellipse\") ) +\n'\\n\\t\\t\\t</option>\\n\\t\\t\\t<option class=\"Rk-Edit-Vocabulary-Property\" value=\"star\"';\n if (node.shape === \"star\") { ;\n__p += ' selected';\n } ;\n__p += '>\\n\\t\\t\\t\\t' +\n__e( renkan.translate(\"Star\") ) +\n'\\n\\t\\t\\t</option>\\n\\t\\t</select>\\n\\t</p>\\n';\n } ;\n__p += '\\n';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/nodeeditor_readonly.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape, __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\nwith (obj) {\n__p += '<h2>\\n\\t<span class=\"Rk-CloseX\">×</span>\\n\\t';\n if (options.show_node_tooltip_color) { ;\n__p += '\\n\\t\\t<span class=\"Rk-UserColor\" style=\"background: ' +\n__e(node.color) +\n';\"></span>\\n\\t';\n } ;\n__p += '\\n\\t<span class=\"Rk-Display-Title\">\\n\\t\\t';\n if (node.uri) { ;\n__p += '\\n\\t\\t\\t<a href=\"' +\n__e(node.uri) +\n'\" target=\"_blank\">\\n\\t\\t';\n } ;\n__p += '\\n\\t\\t' +\n__e(node.title) +\n'\\n\\t\\t';\n if (node.uri) { ;\n__p += '</a>';\n } ;\n__p += '\\n\\t</span>\\n</h2>\\n';\n if (node.uri && options.show_node_tooltip_uri) { ;\n__p += '\\n\\t<p class=\"Rk-Display-URI\">\\n\\t\\t<a href=\"' +\n__e(node.uri) +\n'\" target=\"_blank\">' +\n__e(node.short_uri) +\n'</a>\\n\\t</p>\\n';\n } ;\n__p += ' ';\n if (options.show_node_tooltip_description) { ;\n__p += '\\n\\t<p class=\"Rk-Display-Description\">' +\n__e(node.description) +\n'</p>\\n';\n } ;\n__p += ' ';\n if (node.image && options.show_node_tooltip_image) { ;\n__p += '\\n\\t<img class=\"Rk-Display-ImgPreview\" src=\"' +\n__e(node.image) +\n'\" />\\n';\n } ;\n__p += ' ';\n if (node.has_creator && options.show_node_tooltip_creator) { ;\n__p += '\\n\\t<p>\\n\\t\\t<span class=\"Rk-Editor-Label\">' +\n__e(renkan.translate(\"Created by:\")) +\n'</span>\\n\\t\\t<span class=\"Rk-UserColor\" style=\"background: ' +\n__e(node.created_by_color) +\n';\"></span>\\n\\t\\t' +\n__e( shortenText(node.created_by_title, 25) ) +\n'\\n\\t</p>\\n';\n } ;\n__p += '\\n';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/scene.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape, __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\nwith (obj) {\n\n if (options.show_top_bar) { ;\n__p += '\\n\\t<div class=\"Rk-TopBar\">\\n\\t\\t<div class=\"loader\"></div>\\n\\t\\t';\n if (!options.editor_mode) { ;\n__p += '\\n\\t\\t\\t<h2 class=\"Rk-PadTitle\">\\n\\t\\t\\t\\t' +\n__e( project.get(\"title\") || translate(\"Untitled project\")) +\n'\\n\\t\\t\\t</h2>\\n\\t\\t';\n } else { ;\n__p += '\\n\\t\\t\\t<input type=\"text\" class=\"Rk-PadTitle\" value=\"' +\n__e( project.get('title') || '' ) +\n'\" placeholder=\"' +\n__e(translate('Untitled project')) +\n'\" />\\n\\t\\t';\n } ;\n__p += '\\n\\t\\t';\n if (options.show_user_list) { ;\n__p += '\\n\\t\\t\\t<div class=\"Rk-Users\">\\n\\t\\t\\t\\t<div class=\"Rk-CurrentUser\">\\n\\t\\t\\t\\t\\t';\n if (options.show_user_color) { ;\n__p += '\\n\\t\\t\\t\\t\\t\\t<div class=\"Rk-Edit-ColorPicker-Wrapper\">\\n\\t\\t\\t\\t\\t\\t\\t<span class=\"Rk-CurrentUser-Color\">\\n\\t\\t\\t\\t\\t\\t\\t';\n if (options.user_color_editable) { ;\n__p += '\\n\\t\\t\\t\\t\\t\\t\\t\\t<span class=\"Rk-Edit-ColorTip\"></span>\\n\\t\\t\\t\\t\\t\\t\\t';\n } ;\n__p += '\\n\\t\\t\\t\\t\\t\\t\\t</span>\\n\\t\\t\\t\\t\\t\\t\\t';\n if (options.user_color_editable) { print(colorPicker) } ;\n__p += '\\n\\t\\t\\t\\t\\t\\t</div>\\n\\t\\t\\t\\t\\t';\n } ;\n__p += '\\n\\t\\t\\t\\t\\t<span class=\"Rk-CurrentUser-Name\"><unknown user></span>\\n\\t\\t\\t\\t</div>\\n\\t\\t\\t\\t<ul class=\"Rk-UserList\"></ul>\\n\\t\\t\\t</div>\\n\\t\\t';\n } ;\n__p += '\\n\\t\\t';\n if (options.home_button_url) {;\n__p += '\\n\\t\\t\\t<div class=\"Rk-TopBar-Separator\"></div>\\n\\t\\t\\t<a class=\"Rk-TopBar-Button Rk-Home-Button\" href=\"' +\n__e( options.home_button_url ) +\n'\">\\n\\t\\t\\t\\t<div class=\"Rk-TopBar-Tooltip\">\\n\\t\\t\\t\\t\\t<div class=\"Rk-TopBar-Tooltip-Contents\">\\n\\t\\t\\t\\t\\t\\t' +\n__e( translate(options.home_button_title) ) +\n'\\n\\t\\t\\t\\t\\t</div>\\n\\t\\t\\t\\t</div>\\n\\t\\t\\t</a>\\n\\t\\t';\n } ;\n__p += '\\n\\t\\t';\n if (options.show_fullscreen_button) { ;\n__p += '\\n\\t\\t\\t<div class=\"Rk-TopBar-Separator\"></div>\\n\\t\\t\\t<div class=\"Rk-TopBar-Button Rk-FullScreen-Button\">\\n\\t\\t\\t\\t<div class=\"Rk-TopBar-Tooltip\">\\n\\t\\t\\t\\t\\t<div class=\"Rk-TopBar-Tooltip-Contents\">\\n\\t\\t\\t\\t\\t\\t' +\n__e(translate(\"Full Screen\")) +\n'\\n\\t\\t\\t\\t\\t</div>\\n\\t\\t\\t\\t</div>\\n\\t\\t\\t</div>\\n\\t\\t';\n } ;\n__p += '\\n\\t\\t';\n if (options.editor_mode) { ;\n__p += '\\n\\t\\t\\t';\n if (options.show_addnode_button) { ;\n__p += '\\n\\t\\t\\t\\t<div class=\"Rk-TopBar-Separator\"></div>\\n\\t\\t\\t\\t<div class=\"Rk-TopBar-Button Rk-AddNode-Button\">\\n\\t\\t\\t\\t\\t<div class=\"Rk-TopBar-Tooltip\">\\n\\t\\t\\t\\t\\t\\t<div class=\"Rk-TopBar-Tooltip-Contents\">\\n\\t\\t\\t\\t\\t\\t\\t' +\n__e(translate(\"Add Node\")) +\n'\\n\\t\\t\\t\\t\\t\\t</div>\\n\\t\\t\\t\\t\\t</div>\\n\\t\\t\\t\\t</div>\\n\\t\\t\\t';\n } ;\n__p += '\\n\\t\\t\\t';\n if (options.show_addedge_button) { ;\n__p += '\\n\\t\\t\\t\\t<div class=\"Rk-TopBar-Separator\"></div>\\n\\t\\t\\t\\t<div class=\"Rk-TopBar-Button Rk-AddEdge-Button\">\\n\\t\\t\\t\\t\\t<div class=\"Rk-TopBar-Tooltip\">\\n\\t\\t\\t\\t\\t\\t<div class=\"Rk-TopBar-Tooltip-Contents\">\\n\\t\\t\\t\\t\\t\\t\\t' +\n__e(translate(\"Add Edge\")) +\n'\\n\\t\\t\\t\\t\\t\\t</div>\\n\\t\\t\\t\\t\\t</div>\\n\\t\\t\\t\\t</div>\\n\\t\\t\\t';\n } ;\n__p += '\\n\\t\\t\\t';\n if (options.show_export_button) { ;\n__p += '\\n\\t\\t\\t\\t<div class=\"Rk-TopBar-Separator\"></div>\\n\\t\\t\\t\\t<div class=\"Rk-TopBar-Button Rk-Export-Button\">\\n\\t\\t\\t\\t\\t<div class=\"Rk-TopBar-Tooltip\">\\n\\t\\t\\t\\t\\t\\t<div class=\"Rk-TopBar-Tooltip-Contents\">\\n\\t\\t\\t\\t\\t\\t\\t' +\n__e(translate(\"Download Project\")) +\n'\\n\\t\\t\\t\\t\\t\\t</div>\\n\\t\\t\\t\\t\\t</div>\\n\\t\\t\\t\\t</div>\\n\\t\\t\\t';\n } ;\n__p += '\\n\\t\\t\\t';\n if (options.show_save_button) { ;\n__p += '\\n\\t\\t\\t\\t<div class=\"Rk-TopBar-Separator\"></div>\\n\\t\\t\\t\\t<div class=\"Rk-TopBar-Button Rk-Save-Button\">\\n\\t\\t\\t\\t\\t<div class=\"Rk-TopBar-Tooltip\">\\n\\t\\t\\t\\t\\t\\t<div class=\"Rk-TopBar-Tooltip-Contents\"></div>\\n\\t\\t\\t\\t\\t</div>\\n\\t\\t\\t\\t</div>\\n\\t\\t\\t';\n } ;\n__p += '\\n\\t\\t\\t';\n if (options.show_open_button) { ;\n__p += '\\n\\t\\t\\t\\t<div class=\"Rk-TopBar-Separator\"></div>\\n\\t\\t\\t\\t<div class=\"Rk-TopBar-Button Rk-Open-Button\">\\n\\t\\t\\t\\t\\t<div class=\"Rk-TopBar-Tooltip\">\\n\\t\\t\\t\\t\\t\\t<div class=\"Rk-TopBar-Tooltip-Contents\">\\n\\t\\t\\t\\t\\t\\t\\t' +\n__e(translate(\"Open Project\")) +\n'\\n\\t\\t\\t\\t\\t\\t</div>\\n\\t\\t\\t\\t\\t</div>\\n\\t\\t\\t\\t</div>\\n\\t\\t\\t';\n } ;\n__p += '\\n\\t\\t\\t';\n if (options.show_bookmarklet) { ;\n__p += '\\n\\t\\t\\t\\t<div class=\"Rk-TopBar-Separator\"></div>\\n\\t\\t\\t\\t<a class=\"Rk-TopBar-Button Rk-Bookmarklet-Button\" href=\"#\">\\n\\t\\t\\t\\t\\t<div class=\"Rk-TopBar-Tooltip\">\\n\\t\\t\\t\\t\\t\\t<div class=\"Rk-TopBar-Tooltip-Contents\">\\n\\t\\t\\t\\t\\t\\t\\t' +\n__e(translate(\"Renkan \\'Drag-to-Add\\' bookmarklet\")) +\n'\\n\\t\\t\\t\\t\\t\\t</div>\\n\\t\\t\\t\\t\\t</div>\\n\\t\\t\\t\\t</a>\\n\\t\\t\\t\\t<div class=\"Rk-TopBar-Separator\"></div>\\n\\t\\t\\t';\n } ;\n__p += '\\n\\t\\t';\n } else { ;\n__p += '\\n\\t\\t\\t';\n if (options.show_export_button) { ;\n__p += '\\n\\t\\t\\t\\t<div class=\"Rk-TopBar-Separator\"></div>\\n\\t\\t\\t\\t<div class=\"Rk-TopBar-Button Rk-Export-Button\">\\n\\t\\t\\t\\t\\t<div class=\"Rk-TopBar-Tooltip\">\\n\\t\\t\\t\\t\\t\\t<div class=\"Rk-TopBar-Tooltip-Contents\">\\n\\t\\t\\t\\t\\t\\t\\t' +\n__e(translate(\"Download Project\")) +\n'\\n\\t\\t\\t\\t\\t\\t</div>\\n\\t\\t\\t\\t\\t</div>\\n\\t\\t\\t\\t</div>\\n\\t\\t\\t\\t<div class=\"Rk-TopBar-Separator\"></div>\\n\\t\\t\\t';\n } ;\n__p += '\\n\\t\\t';\n }; ;\n__p += '\\n\\t\\t';\n if (options.show_search_field) { ;\n__p += '\\n\\t\\t\\t<form action=\"#\" class=\"Rk-GraphSearch-Form\">\\n\\t\\t\\t\\t<input type=\"search\" class=\"Rk-GraphSearch-Field\" placeholder=\"' +\n__e( translate('Search in graph') ) +\n'\" />\\n\\t\\t\\t</form>\\n\\t\\t\\t<div class=\"Rk-TopBar-Separator\"></div>\\n\\t\\t';\n } ;\n__p += '\\n\\t</div>\\n';\n } ;\n__p += '\\n<div class=\"Rk-Editing-Space';\n if (!options.show_top_bar) { ;\n__p += ' Rk-Editing-Space-Full';\n } ;\n__p += '\">\\n\\t<div class=\"Rk-Labels\"></div>\\n\\t<canvas class=\"Rk-Canvas\" ';\n if (options.resize) { ;\n__p += ' resize=\"\" ';\n } ;\n__p += '></canvas>\\n\\t<div class=\"Rk-Notifications\"></div>\\n\\t<div class=\"Rk-Editor\">\\n\\t\\t';\n if (options.show_bins) { ;\n__p += '\\n\\t\\t\\t<div class=\"Rk-Fold-Bins\">«</div>\\n\\t\\t';\n } ;\n__p += '\\n\\t\\t';\n if (options.show_zoom) { ;\n__p += '\\n\\t\\t\\t<div class=\"Rk-ZoomButtons\">\\n\\t\\t\\t\\t<div class=\"Rk-ZoomIn\" title=\"' +\n__e(translate('Zoom In')) +\n'\"></div>\\n\\t\\t\\t\\t<div class=\"Rk-ZoomFit\" title=\"' +\n__e(translate('Zoom Fit')) +\n'\"></div>\\n\\t\\t\\t\\t<div class=\"Rk-ZoomOut\" title=\"' +\n__e(translate('Zoom Out')) +\n'\"></div>\\n\\t\\t\\t\\t';\n if (options.editor_mode && options.save_view) { ;\n__p += '\\n\\t\\t\\t\\t\\t<div class=\"Rk-ZoomSave\" title=\"' +\n__e(translate('Zoom Save')) +\n'\"></div>\\n\\t\\t\\t\\t';\n } ;\n__p += '\\n\\t\\t\\t\\t';\n if (options.save_view) { ;\n__p += '\\n\\t\\t\\t\\t\\t<div class=\"Rk-ZoomSetSaved\" title=\"' +\n__e(translate('View saved zoom')) +\n'\"></div>\\n\\t\\t\\t\\t';\n } ;\n__p += '\\n\\t\\t\\t</div>\\n\\t\\t';\n } ;\n__p += '\\n\\t</div>\\n</div>';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/search.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape;\nwith (obj) {\n__p += '<li class=\"' +\n((__t = ( className )) == null ? '' : __t) +\n'\" data-key=\"' +\n((__t = ( key )) == null ? '' : __t) +\n'\">' +\n((__t = ( title )) == null ? '' : __t) +\n'</li>';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/wikipedia-bin/resulttemplate.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape;\nwith (obj) {\n__p += '<li class=\"Rk-Wikipedia-Result Rk-Bin-Item\" draggable=\"true\"\\n\\tdata-uri=\"' +\n__e(url) +\n'\" data-title=\"Wikipedia: ' +\n__e(title) +\n'\"\\n\\tdata-description=\"' +\n__e(description) +\n'\"\\n\\tdata-image=\"' +\n__e( Rkns.Utils.getFullURL( static_url + 'img/wikipedia.png' ) ) +\n'\">\\n\\t\\n\\t<img class=\"Rk-Wikipedia-Icon\" src=\"' +\n__e(static_url) +\n'img/wikipedia.png\">\\n\\t<h4 class=\"Rk-Wikipedia-Title\">\\n\\t\\t<a href=\"' +\n__e(url) +\n'\" target=\"_blank\">' +\n((__t = (htitle)) == null ? '' : __t) +\n'</a>\\n\\t</h4>\\n\\t<p class=\"Rk-Wikipedia-Snippet\">' +\n((__t = (hdescription)) == null ? '' : __t) +\n'</p>\\n</li>';\n\n}\nreturn __p\n};","\n/* Declaring the Renkan Namespace Rkns and Default values */\n\n(function(root) {\n\n\"use strict\";\n\nif (typeof root.Rkns !== \"object\") {\n root.Rkns = {};\n}\n\nvar Rkns = root.Rkns;\nvar $ = Rkns.$ = root.jQuery;\nvar _ = Rkns._ = root._;\n\nRkns.pickerColors = [\"#8f1919\", \"#a80000\", \"#d82626\", \"#ff0000\", \"#e87c7c\", \"#ff6565\", \"#f7d3d3\", \"#fecccc\",\n \"#8f5419\", \"#a85400\", \"#d87f26\", \"#ff7f00\", \"#e8b27c\", \"#ffb265\", \"#f7e5d3\", \"#fee5cc\",\n \"#8f8f19\", \"#a8a800\", \"#d8d826\", \"#feff00\", \"#e8e87c\", \"#feff65\", \"#f7f7d3\", \"#fefecc\",\n \"#198f19\", \"#00a800\", \"#26d826\", \"#00ff00\", \"#7ce87c\", \"#65ff65\", \"#d3f7d3\", \"#ccfecc\",\n \"#198f8f\", \"#00a8a8\", \"#26d8d8\", \"#00feff\", \"#7ce8e8\", \"#65feff\", \"#d3f7f7\", \"#ccfefe\",\n \"#19198f\", \"#0000a8\", \"#2626d8\", \"#0000ff\", \"#7c7ce8\", \"#6565ff\", \"#d3d3f7\", \"#ccccfe\",\n \"#8f198f\", \"#a800a8\", \"#d826d8\", \"#ff00fe\", \"#e87ce8\", \"#ff65fe\", \"#f7d3f7\", \"#feccfe\",\n \"#000000\", \"#242424\", \"#484848\", \"#6d6d6d\", \"#919191\", \"#b6b6b6\", \"#dadada\", \"#ffffff\"];\n\nRkns.__renkans = [];\n\nvar _BaseBin = Rkns._BaseBin = function(_renkan, _opts) {\n if (typeof _renkan !== \"undefined\") {\n this.renkan = _renkan;\n this.renkan.$.find(\".Rk-Bin-Main\").hide();\n this.$ = Rkns.$('<li>')\n .addClass(\"Rk-Bin\")\n .appendTo(_renkan.$.find(\".Rk-Bin-List\"));\n this.title_icon_$ = Rkns.$('<span>')\n .addClass(\"Rk-Bin-Title-Icon\")\n .appendTo(this.$);\n\n var _this = this;\n\n Rkns.$('<a>')\n .attr({\n href: \"#\",\n title: _renkan.translate(\"Close bin\")\n })\n .addClass(\"Rk-Bin-Close\")\n .html('×')\n .appendTo(this.$)\n .click(function() {\n _this.destroy();\n if (!_renkan.$.find(\".Rk-Bin-Main:visible\").length) {\n _renkan.$.find(\".Rk-Bin-Main:last\").slideDown();\n }\n _renkan.resizeBins();\n return false;\n });\n Rkns.$('<a>')\n .attr({\n href: \"#\",\n title: _renkan.translate(\"Refresh bin\")\n })\n .addClass(\"Rk-Bin-Refresh\")\n .appendTo(this.$)\n .click(function() {\n _this.refresh();\n return false;\n });\n this.count_$ = Rkns.$('<div>')\n .addClass(\"Rk-Bin-Count\")\n .appendTo(this.$);\n this.title_$ = Rkns.$('<h2>')\n .addClass(\"Rk-Bin-Title\")\n .appendTo(this.$);\n this.main_$ = Rkns.$('<div>')\n .addClass(\"Rk-Bin-Main\")\n .appendTo(this.$)\n .html('<h4 class=\"Rk-Bin-Loading\">' + _renkan.translate(\"Loading, please wait\") + '</h4>');\n this.title_$.html(_opts.title || '(new bin)');\n this.renkan.resizeBins();\n\n if (_opts.auto_refresh) {\n window.setInterval(function() {\n _this.refresh();\n },_opts.auto_refresh);\n }\n }\n};\n\n_BaseBin.prototype.destroy = function() {\n this.$.detach();\n this.renkan.resizeBins();\n};\n\n/* Point of entry */\n\nvar Renkan = Rkns.Renkan = function(_opts) {\n var _this = this;\n\n Rkns.__renkans.push(this);\n\n this.options = _.defaults(_opts, Rkns.defaults, {templates: renkanJST});\n this.template = renkanJST['templates/main.html'];\n\n _(this.options.property_files).each(function(f) {\n Rkns.$.getJSON(f, function(data) {\n _this.options.properties = _this.options.properties.concat(data);\n });\n });\n\n this.read_only = this.options.read_only || !this.options.editor_mode;\n\n this.project = new Rkns.Models.Project();\n\n this.setCurrentUser = function (user_id, user_name) {\n \tthis.project.addUser({\n \t\t_id:user_id,\n \t\ttitle: user_name\n \t});\n \tthis.current_user = user_id;\n \tthis.renderer.redrawUsers();\n };\n \n if (typeof this.options.user_id !== \"undefined\") {\n this.current_user = this.options.user_id;\n }\n this.$ = Rkns.$(\"#\" + this.options.container);\n this.$\n .addClass(\"Rk-Main\")\n .html(this.template(this));\n\n this.tabs = [];\n this.search_engines = [];\n\n this.current_user_list = new Rkns.Models.UsersList();\n\n this.current_user_list.on(\"add remove\", function() {\n if (this.renderer) {\n this.renderer.redrawUsers();\n }\n });\n\n this.colorPicker = (function() {\n var _tmpl = renkanJST['templates/colorpicker.html'];\n return '<ul class=\"Rk-Edit-ColorPicker\">' + Rkns.pickerColors.map(function(c) { return _tmpl({c:c});}).join(\"\") + '</ul>';\n })();\n\n if (this.options.show_editor) {\n this.renderer = new Rkns.Renderer.Scene(this);\n }\n\n if (!this.options.search.length) {\n this.$.find(\".Rk-Web-Search-Form\").detach();\n } else {\n var _tmpl = renkanJST['templates/search.html'],\n _select = this.$.find(\".Rk-Search-List\"),\n _input = this.$.find(\".Rk-Web-Search-Input\"),\n _form = this.$.find(\".Rk-Web-Search-Form\");\n _(this.options.search).each(function(_search, _key) {\n if (Rkns[_search.type] && Rkns[_search.type].Search) {\n _this.search_engines.push(new Rkns[_search.type].Search(_this, _search));\n }\n });\n _select.html(\n _(this.search_engines).map(function(_search, _key) {\n return _tmpl({\n key: _key,\n title: _search.getSearchTitle(),\n className: _search.getBgClass()\n });\n }).join(\"\")\n );\n _select.find(\"li\").click(function() {\n var _el = Rkns.$(this);\n _this.setSearchEngine(_el.attr(\"data-key\"));\n _form.submit();\n });\n _form.submit(function() {\n if (_input.val()) {\n var _search = _this.search_engine;\n _search.search(_input.val());\n }\n return false;\n });\n this.$.find(\".Rk-Search-Current\").mouseenter(\n function() { _select.slideDown(); }\n );\n this.$.find(\".Rk-Search-Select\").mouseleave(\n function() { _select.hide(); }\n );\n this.setSearchEngine(0);\n }\n _(this.options.bins).each(function(_bin) {\n if (Rkns[_bin.type] && Rkns[_bin.type].Bin) {\n _this.tabs.push(new Rkns[_bin.type].Bin(_this, _bin));\n }\n });\n\n var elementDropped = false;\n\n this.$.find(\".Rk-Bins\")\n .on(\"click\",\".Rk-Bin-Title,.Rk-Bin-Title-Icon\", function() {\n var _mainDiv = Rkns.$(this).siblings(\".Rk-Bin-Main\");\n if (_mainDiv.is(\":hidden\")) {\n _this.$.find(\".Rk-Bin-Main\").slideUp();\n _mainDiv.slideDown();\n }\n });\n\n if (this.options.show_editor) {\n\n this.$.find(\".Rk-Bins\").on(\"mouseover\", \".Rk-Bin-Item\", function(_e) {\n var _t = Rkns.$(this);\n if (_t && $(_t).attr(\"data-uri\")) {\n var _models = _this.project.get(\"nodes\").where({\n uri: $(_t).attr(\"data-uri\")\n });\n _(_models).each(function(_model) {\n _this.renderer.highlightModel(_model);\n });\n }\n }).mouseout(function() {\n _this.renderer.unhighlightAll();\n }).on(\"mousemove\", \".Rk-Bin-Item\", function(e) {\n try {\n this.dragDrop();\n }\n catch(err) {}\n }).on(\"touchstart\", \".Rk-Bin-Item\", function(e) {\n elementDropped = false;\n }).on(\"touchmove\", \".Rk-Bin-Item\", function(e) {\n e.preventDefault();\n var touch = e.originalEvent.changedTouches[0],\n off = _this.renderer.canvas_$.offset(),\n w = _this.renderer.canvas_$.width(),\n h = _this.renderer.canvas_$.height();\n if (touch.pageX >= off.left && touch.pageX < (off.left + w) && touch.pageY >= off.top && touch.pageY < (off.top + h)) {\n if (elementDropped) {\n _this.renderer.onMouseMove(touch, true);\n } else {\n elementDropped = true;\n var div = document.createElement('div');\n div.appendChild(this.cloneNode(true));\n _this.renderer.dropData({\"text/html\": div.innerHTML}, touch);\n _this.renderer.onMouseDown(touch, true);\n }\n }\n }).on(\"touchend\", \".Rk-Bin-Item\", function(e) {\n if (elementDropped) {\n _this.renderer.onMouseUp(e.originalEvent.changedTouches[0], true);\n }\n elementDropped = false;\n }).on(\"dragstart\", \".Rk-Bin-Item\", function(e) {\n var div = document.createElement('div');\n div.appendChild(this.cloneNode(true));\n try {\n e.originalEvent.dataTransfer.setData(\"text/html\",div.innerHTML);\n }\n catch(err) {\n e.originalEvent.dataTransfer.setData(\"text\",div.innerHTML);\n }\n });\n\n }\n\n Rkns.$(window).resize(function() {\n _this.resizeBins();\n });\n\n var lastsearch = false, lastval = '';\n\n this.$.find(\".Rk-Bins-Search-Input\").on(\"change keyup paste input\", function() {\n var val = Rkns.$(this).val();\n if (val === lastval) {\n return;\n }\n var search = Rkns.Utils.regexpFromTextOrArray(val.length > 1 ? val: null);\n if (search.source === lastsearch) {\n return;\n }\n lastsearch = search.source;\n _(_this.tabs).each(function(tab) {\n tab.render(search);\n });\n\n });\n this.$.find(\".Rk-Bins-Search-Form\").submit(function() {\n return false;\n });\n\n};\n\nRenkan.prototype.translate = function(_text) {\n if (Rkns.i18n[this.options.language] && Rkns.i18n[this.options.language][_text]) {\n return Rkns.i18n[this.options.language][_text];\n }\n if (this.options.language.length > 2 && Rkns.i18n[this.options.language.substr(0,2)] && Rkns.i18n[this.options.language.substr(0,2)][_text]) {\n return Rkns.i18n[this.options.language.substr(0,2)][_text];\n }\n return _text;\n};\n\nRenkan.prototype.onStatusChange = function() {\n this.renderer.onStatusChange();\n};\n\nRenkan.prototype.setSearchEngine = function(_key) {\n this.search_engine = this.search_engines[_key];\n this.$.find(\".Rk-Search-Current\").attr(\"class\",\"Rk-Search-Current \" + this.search_engine.getBgClass());\n var listClasses = this.search_engine.getBgClass().split(\" \");\n var classes = \"\";\n for\t(var i= 0; i < listClasses.length; i++) {\n classes += \".\" + listClasses[i];\n }\n this.$.find(\".Rk-Web-Search-Input.Rk-Search-Input\").attr(\"placeholder\", this.translate(\"Search in \") + this.$.find(\".Rk-Search-List \"+ classes).html());\n};\n\nRenkan.prototype.resizeBins = function() {\n var _d = + this.$.find(\".Rk-Bins-Head\").outerHeight();\n this.$.find(\".Rk-Bin-Title:visible\").each(function() {\n _d += Rkns.$(this).outerHeight();\n });\n this.$.find(\".Rk-Bin-Main\").css({\n height: this.$.find(\".Rk-Bins\").height() - _d\n });\n};\n\n/* Utility functions */\nvar getUUID4 = function() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {\n var r = Math.random()*16|0, v = c === 'x' ? r : (r&0x3|0x8);\n return v.toString(16);\n });\n};\n\nRkns.Utils = {\n getUUID4 : getUUID4,\n getUID : (function() {\n function pad(n){\n return n<10 ? '0'+n : n;\n }\n var _d = new Date(),\n ID_AUTO_INCREMENT = 0,\n ID_BASE = _d.getUTCFullYear() + '-' +\n pad(_d.getUTCMonth()+1) + '-' +\n pad(_d.getUTCDate()) + '-' +\n getUUID4();\n return function(_base) {\n var _n = (++ID_AUTO_INCREMENT).toString(16),\n _uidbase = (typeof _base === \"undefined\" ? \"\" : _base + \"-\" );\n while (_n.length < 4) { _n = '0' + _n; }\n return _uidbase + ID_BASE + '-' + _n;\n };\n })(),\n getFullURL : function(url) {\n\n if(typeof(url) === 'undefined' || url == null ) {\n return \"\";\n }\n if(/https?:\\/\\//.test(url)) {\n return url;\n }\n var img = new Image();\n img.src = url;\n var res = img.src;\n img.src = null;\n return res;\n\n },\n inherit : function(_baseClass, _callbefore) {\n\n var _class = function(_arg) {\n if (typeof _callbefore === \"function\") {\n _callbefore.apply(this, Array.prototype.slice.call(arguments, 0));\n }\n _baseClass.apply(this, Array.prototype.slice.call(arguments, 0));\n if (typeof this._init === \"function\" && !this._initialized) {\n this._init.apply(this, Array.prototype.slice.call(arguments, 0));\n this._initialized = true;\n }\n };\n _(_class.prototype).extend(_baseClass.prototype);\n\n return _class;\n\n },\n regexpFromTextOrArray: (function() {\n var charsub = [\n '[aÔà âä]',\n '[cƧ]',\n '[eéèêë]',\n '[iĆìîï]',\n '[oóòÓö]',\n '[uùûü]'\n ],\n removeChars = [\n String.fromCharCode(768), String.fromCharCode(769), String.fromCharCode(770), String.fromCharCode(771), String.fromCharCode(807),\n \"ļ½\", \"ļ½\", \"ļ¼\", \"ļ¼\", \"ļ¼»\", \"ļ¼½\", \"ć\", \"ć\", \"ć\", \"ć»\", \"ā„\", \"ć\", \"ć\", \"ć\", \"ć\", \"ć\", \"ć\", \"ļ¼\", \"ļ¼\", \"ļ¼\", \"ć\",\n \",\", \" \", \";\", \"(\", \")\", \".\", \"*\", \"+\", \"\\\\\", \"?\", \"|\", \"{\", \"}\", \"[\", \"]\", \"^\", \"#\", \"/\"\n ],\n remsrc = \"[\\\\\" + removeChars.join(\"\\\\\") + \"]\",\n remrx = new RegExp(remsrc, \"gm\"),\n charsrx = _(charsub).map(function(c) {\n return new RegExp(c);\n });\n\n function replaceText(_text) {\n var txt = _text.toLowerCase().replace(remrx,\"\"), src = \"\";\n function makeReplaceFunc(l) {\n return function(k,v) {\n l = l.replace(charsrx[k], v);\n };\n }\n for (var j = 0; j < txt.length; j++) {\n if (j) {\n src += remsrc + \"*\";\n }\n var l = txt[j];\n _(charsub).each(makeReplaceFunc(l));\n src += l;\n }\n return src;\n }\n\n function getSource(inp) {\n switch (typeof inp) {\n case \"string\":\n return replaceText(inp);\n case \"object\":\n var src = '';\n _(inp).each(function(v) {\n var res = getSource(v);\n if (res) {\n if (src) {\n src += '|';\n }\n src += res;\n }\n });\n return src;\n }\n return '';\n }\n\n return function(_textOrArray) {\n var source = getSource(_textOrArray);\n if (source) {\n var testrx = new RegExp( source, \"im\"),\n replacerx = new RegExp( '(' + source + ')', \"igm\");\n return {\n isempty: false,\n source: source,\n test: function(_t) { return testrx.test(_t); },\n replace: function(_text, _replace) { return _text.replace(replacerx, _replace); }\n };\n } else {\n return {\n isempty: true,\n source: '',\n test: function() { return true; },\n replace: function(_text) { return text; }\n };\n }\n };\n })(),\n /* The minimum distance (in pixels) the mouse has to move to consider an element was dragged */\n _MIN_DRAG_DISTANCE: 2,\n /* Distance between the inner and outer radius of buttons that appear when hovering on a node */\n _NODE_BUTTON_WIDTH: 40,\n\n _EDGE_BUTTON_INNER: 2,\n _EDGE_BUTTON_OUTER: 40,\n /* Constants used to know if a specific action is to be performed when clicking on the canvas */\n _CLICKMODE_ADDNODE: 1,\n _CLICKMODE_STARTEDGE: 2,\n _CLICKMODE_ENDEDGE: 3,\n /* Node size step: Used to calculate the size change when clicking the +/- buttons */\n _NODE_SIZE_STEP: Math.LN2/4,\n _MIN_SCALE: 1/20,\n _MAX_SCALE: 20,\n _MOUSEMOVE_RATE: 80,\n _DOUBLETAP_DELAY: 800,\n /* Maximum distance in pixels (squared, to reduce calculations)\n * between two taps when double-tapping on a touch terminal */\n _DOUBLETAP_DISTANCE: 20*20,\n /* A placeholder so a default colour is displayed when a node has a null value for its user property */\n _USER_PLACEHOLDER: function(_renkan) {\n return {\n color: _renkan.options.default_user_color,\n title: _renkan.translate(\"(unknown user)\"),\n get: function(attr) {\n return this[attr] || false;\n }\n };\n },\n /* The code for the \"Drag and Add Bookmarklet\", slightly minified and with whitespaces removed, though\n * it doesn't seem that it's still a requirement in newer browsers (i.e. the ones compatibles with canvas drawing)\n */\n _BOOKMARKLET_CODE: function(_renkan) {\n return \"(function(a,b,c,d,e,f,h,i,j,k,l,m,n,o,p,q,r){a=document;b=a.body;c=a.location.href;j='draggable';m='text/x-iri-';d=a.createElement('div');d.innerHTML='<p_style=\\\"position:fixed;top:0;right:0;font:bold_18px_sans-serif;color:#fff;background:#909;padding:10px;z-index:100000;\\\">\" +\n _renkan.translate(\"Drag items from this website, drop them in Renkan\").replace(/ /g,\"_\") +\n \"</p>'.replace(/_/g,String.fromCharCode(32));b.appendChild(d);e=[{r:/https?:\\\\/\\\\/[^\\\\/]*twitter\\\\.com\\\\//,s:'.tweet',n:'twitter'},{r:/https?:\\\\/\\\\/[^\\\\/]*google\\\\.[^\\\\/]+\\\\//,s:'.g',n:'google'},{r:/https?:\\\\/\\\\/[^\\\\/]*lemonde\\\\.fr\\\\//,s:'[data-vr-contentbox]',n:'lemonde'}];f=false;e.forEach(function(g){if(g.r.test(c)){f=g;}});if(f){h=function(){Array.prototype.forEach.call(a.querySelectorAll(f.s),function(i){i[j]=true;k=i.style;k.borderWidth='2px';k.borderColor='#909';k.borderStyle='solid';k.backgroundColor='rgba(200,0,180,.1)';})};window.setInterval(h,500);h();};a.addEventListener('dragstart',function(k){l=k.dataTransfer;l.setData(m+'source-uri',c);l.setData(m+'source-title',a.title);n=k.target;if(f){o=n;while(!o.attributes[j]){o=o.parentNode;if(o==b){break;}}}if(f&&o.attributes[j]){p=o.cloneNode(true);l.setData(m+'specific-site',f.n)}else{q=a.getSelection();if(q.type==='Range'||!q.type){p=q.getRangeAt(0).cloneContents();}else{p=n.cloneNode();}}r=a.createElement('div');r.appendChild(p);l.setData('text/x-iri-selected-text',r.textContent.trim());l.setData('text/x-iri-selected-html',r.innerHTML);},false);})();\";\n },\n /* Shortens text to the required length then adds ellipsis */\n shortenText: function(_text, _maxlength) {\n return (_text.length > _maxlength ? (_text.substr(0,_maxlength) + 'ā¦') : _text);\n },\n /* Drawing an edit box with an arrow and positioning the edit box according to the position of the node/edge being edited\n * Called by Rkns.Renderer.NodeEditor and Rkns.Renderer.EdgeEditor */\n drawEditBox: function(_options, _coords, _path, _xmargin, _selector) {\n _selector.css({\n width: ( _options.tooltip_width - 2* _options.tooltip_padding )\n });\n var _height = _selector.outerHeight() + 2* _options.tooltip_padding,\n _isLeft = (_coords.x < paper.view.center.x ? 1 : -1),\n _left = _coords.x + _isLeft * ( _xmargin + _options.tooltip_arrow_length ),\n _right = _coords.x + _isLeft * ( _xmargin + _options.tooltip_arrow_length + _options.tooltip_width ),\n _top = _coords.y - _height / 2;\n if (_top + _height > (paper.view.size.height - _options.tooltip_margin)) {\n _top = Math.max( paper.view.size.height - _options.tooltip_margin, _coords.y + _options.tooltip_arrow_width / 2 ) - _height;\n }\n if (_top < _options.tooltip_margin) {\n _top = Math.min( _options.tooltip_margin, _coords.y - _options.tooltip_arrow_width / 2 );\n }\n var _bottom = _top + _height;\n /* jshint laxbreak:true */\n _path.segments[0].point\n = _path.segments[7].point\n = _coords.add([_isLeft * _xmargin, 0]);\n _path.segments[1].point.x\n = _path.segments[2].point.x\n = _path.segments[5].point.x\n = _path.segments[6].point.x\n = _left;\n _path.segments[3].point.x\n = _path.segments[4].point.x\n = _right;\n _path.segments[2].point.y\n = _path.segments[3].point.y\n = _top;\n _path.segments[4].point.y\n = _path.segments[5].point.y\n = _bottom;\n _path.segments[1].point.y = _coords.y - _options.tooltip_arrow_width / 2;\n _path.segments[6].point.y = _coords.y + _options.tooltip_arrow_width / 2;\n _path.closed = true;\n _path.fillColor = new paper.GradientColor(new paper.Gradient([_options.tooltip_top_color, _options.tooltip_bottom_color]), [0,_top], [0, _bottom]);\n _selector.css({\n left: (_options.tooltip_padding + Math.min(_left, _right)),\n top: (_options.tooltip_padding + _top)\n });\n return _path;\n }\n};\n})(window);\n\n/* END main.js */\n","(function() {\n \"use strict\";\n var root = this;\n\n var Backbone = root.Backbone;\n\n var Models = root.Rkns.Models = {};\n\n Models.getUID = function(obj) {\n var guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,\n function(c) {\n var r = Math.random() * 16 | 0, v = c === 'x' ? r\n : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n if (typeof obj !== 'undefined') {\n return obj.type + \"-\" + guid;\n }\n else {\n return guid;\n }\n };\n\n var RenkanModel = Backbone.RelationalModel.extend({\n idAttribute : \"_id\",\n constructor : function(options) {\n\n if (typeof options !== \"undefined\") {\n options._id = options._id || options.id || Models.getUID(this);\n options.title = options.title || \"\";\n options.description = options.description || \"\";\n options.uri = options.uri || \"\";\n\n if (typeof this.prepare === \"function\") {\n options = this.prepare(options);\n }\n }\n Backbone.RelationalModel.prototype.constructor.call(this, options);\n },\n validate : function() {\n if (!this.type) {\n return \"object has no type\";\n }\n },\n addReference : function(_options, _propName, _list, _id, _default) {\n var _element = _list.get(_id);\n if (typeof _element === \"undefined\" &&\n typeof _default !== \"undefined\") {\n _options[_propName] = _default;\n }\n else {\n _options[_propName] = _element;\n }\n }\n });\n\n // USER\n var User = Models.User = RenkanModel.extend({\n type : \"user\",\n prepare : function(options) {\n options.color = options.color || \"#666666\";\n return options;\n },\n toJSON : function() {\n return {\n _id : this.get(\"_id\"),\n title : this.get(\"title\"),\n uri : this.get(\"uri\"),\n description : this.get(\"description\"),\n color : this.get(\"color\")\n };\n }\n });\n\n // NODE\n var Node = Models.Node = RenkanModel.extend({\n type : \"node\",\n relations : [ {\n type : Backbone.HasOne,\n key : \"created_by\",\n relatedModel : User\n } ],\n prepare : function(options) {\n var project = options.project;\n this.addReference(options, \"created_by\", project.get(\"users\"),\n options.created_by, project.current_user);\n options.description = options.description || \"\";\n return options;\n },\n toJSON : function() {\n return {\n _id : this.get(\"_id\"),\n title : this.get(\"title\"),\n uri : this.get(\"uri\"),\n description : this.get(\"description\"),\n position : this.get(\"position\"),\n image : this.get(\"image\"),\n color : this.get(\"color\"),\n created_by : this.get(\"created_by\") ? this.get(\"created_by\")\n .get(\"_id\") : null,\n size : this.get(\"size\"),\n clip_path : this.get(\"clip_path\"),\n shape : this.get(\"shape\")\n };\n }\n });\n\n // EDGE\n var Edge = Models.Edge = RenkanModel.extend({\n type : \"edge\",\n relations : [ {\n type : Backbone.HasOne,\n key : \"created_by\",\n relatedModel : User\n }, {\n type : Backbone.HasOne,\n key : \"from\",\n relatedModel : Node\n }, {\n type : Backbone.HasOne,\n key : \"to\",\n relatedModel : Node\n } ],\n prepare : function(options) {\n var project = options.project;\n this.addReference(options, \"created_by\", project.get(\"users\"),\n options.created_by, project.current_user);\n this.addReference(options, \"from\", project.get(\"nodes\"),\n options.from);\n this.addReference(options, \"to\", project.get(\"nodes\"), options.to);\n return options;\n },\n toJSON : function() {\n return {\n _id : this.get(\"_id\"),\n title : this.get(\"title\"),\n uri : this.get(\"uri\"),\n description : this.get(\"description\"),\n from : this.get(\"from\") ? this.get(\"from\").get(\"_id\") : null,\n to : this.get(\"to\") ? this.get(\"to\").get(\"_id\") : null,\n color : this.get(\"color\"),\n created_by : this.get(\"created_by\") ? this.get(\"created_by\")\n .get(\"_id\") : null\n };\n }\n });\n\n // View\n var View = Models.View = RenkanModel.extend({\n type : \"view\",\n relations : [ {\n type : Backbone.HasOne,\n key : \"created_by\",\n relatedModel : User\n } ],\n prepare : function(options) {\n var project = options.project;\n this.addReference(options, \"created_by\", project.get(\"users\"),\n options.created_by, project.current_user);\n options.description = options.description || \"\";\n if (typeof options.offset !== \"undefined\") {\n var offset = {};\n if (Array.isArray(options.offset)) {\n offset.x = options.offset[0];\n offset.y = options.offset.length > 1 ? options.offset[1]\n : options.offset[0];\n }\n else if (options.offset.x != null) {\n offset.x = options.offset.x;\n offset.y = options.offset.y;\n }\n options.offset = offset;\n }\n return options;\n },\n toJSON : function() {\n return {\n _id : this.get(\"_id\"),\n zoom_level : this.get(\"zoom_level\"),\n offset : this.get(\"offset\"),\n title : this.get(\"title\"),\n description : this.get(\"description\"),\n created_by : this.get(\"created_by\") ? this.get(\"created_by\")\n .get(\"_id\") : null\n // Don't need project id\n };\n }\n });\n\n // PROJECT\n var Project = Models.Project = RenkanModel.extend({\n type : \"project\",\n blacklist : [ 'save_status', ],\n relations : [ {\n type : Backbone.HasMany,\n key : \"users\",\n relatedModel : User,\n reverseRelation : {\n key : 'project',\n includeInJSON : '_id'\n }\n }, {\n type : Backbone.HasMany,\n key : \"nodes\",\n relatedModel : Node,\n reverseRelation : {\n key : 'project',\n includeInJSON : '_id'\n }\n }, {\n type : Backbone.HasMany,\n key : \"edges\",\n relatedModel : Edge,\n reverseRelation : {\n key : 'project',\n includeInJSON : '_id'\n }\n }, {\n type : Backbone.HasMany,\n key : \"views\",\n relatedModel : View,\n reverseRelation : {\n key : 'project',\n includeInJSON : '_id'\n }\n } ],\n addUser : function(_props, _options) {\n _props.project = this;\n var _user = User.findOrCreate(_props);\n this.get(\"users\").push(_user, _options);\n return _user;\n },\n addNode : function(_props, _options) {\n _props.project = this;\n var _node = Node.findOrCreate(_props);\n this.get(\"nodes\").push(_node, _options);\n return _node;\n },\n addEdge : function(_props, _options) {\n _props.project = this;\n var _edge = Edge.findOrCreate(_props);\n this.get(\"edges\").push(_edge, _options);\n return _edge;\n },\n addView : function(_props, _options) {\n _props.project = this;\n // TODO: check if need to replace with create only\n var _view = View.findOrCreate(_props);\n // TODO: Should we remember only one view?\n this.get(\"views\").push(_view, _options);\n return _view;\n },\n removeNode : function(_model) {\n this.get(\"nodes\").remove(_model);\n },\n removeEdge : function(_model) {\n this.get(\"edges\").remove(_model);\n },\n validate : function(options) {\n var _project = this;\n _(\n [].concat(options.users, options.nodes, options.edges,\n options.views)).each(function(_item) {\n if (_item) {\n _item.project = _project;\n }\n });\n },\n // Add event handler to remove edges when a node is removed\n initialize : function() {\n var _this = this;\n this.on(\"remove:nodes\", function(_node) {\n _this.get(\"edges\").remove(\n _this.get(\"edges\").filter(\n function(_edge) {\n return _edge.get(\"from\") === _node ||\n _edge.get(\"to\") === _node;\n }));\n });\n },\n toJSON : function() {\n var json = _.clone(this.attributes);\n for ( var attr in json) {\n if ((json[attr] instanceof Backbone.Model) ||\n (json[attr] instanceof Backbone.Collection) ||\n (json[attr] instanceof RenkanModel)) {\n json[attr] = json[attr].toJSON();\n }\n }\n return _.omit(json, this.blacklist);\n }\n });\n\n var RosterUser = Models.RosterUser = Backbone.Model\n .extend({\n type : \"roster_user\",\n idAttribute : \"_id\",\n\n constructor : function(options) {\n\n if (typeof options !== \"undefined\") {\n options._id = options._id ||\n options.id ||\n Models.getUID(this);\n options.title = options.title || \"(untitled \" + this.type + \")\";\n options.description = options.description || \"\";\n options.uri = options.uri || \"\";\n options.project = options.project || null;\n options.site_id = options.site_id || 0;\n\n if (typeof this.prepare === \"function\") {\n options = this.prepare(options);\n }\n }\n Backbone.Model.prototype.constructor.call(this, options);\n },\n\n validate : function() {\n if (!this.type) {\n return \"object has no type\";\n }\n },\n\n prepare : function(options) {\n options.color = options.color || \"#666666\";\n return options;\n },\n\n toJSON : function() {\n return {\n _id : this.get(\"_id\"),\n title : this.get(\"title\"),\n uri : this.get(\"uri\"),\n description : this.get(\"description\"),\n color : this.get(\"color\"),\n project : (this.get(\"project\") != null) ? this.get(\n \"project\").get(\"id\") : null,\n site_id : this.get(\"site_id\")\n };\n }\n });\n\n var UsersList = Models.UsersList = Backbone.Collection.extend({\n model : RosterUser\n });\n\n}).call(window);\n","Rkns.defaults = {\n\n language: (navigator.language || navigator.userLanguage || \"en\"),\n /* GUI Language */\n container: \"renkan\",\n /* GUI Container DOM element ID */\n search: [],\n /* List of Search Engines */\n bins: [],\n /* List of Bins */\n static_url: \"\",\n /* URL for static resources */\n show_bins: true,\n /* Show bins in left column */\n properties: [],\n /* Semantic properties for edges */\n show_editor: true,\n /* Show the graph editor... Setting this to \"false\" only shows the bins part ! */\n read_only: false,\n /* Allows editing of renkan without changing the rest of the GUI. Can be switched on/off on the fly to block/enable editing */\n editor_mode: true,\n /* Switch for Publish/Edit GUI. If editor_mode is false, read_only will be true. */\n manual_save: false,\n /* In snapshot mode, clicking on the floppy will save a snapshot. Otherwise, it will show the connection status */\n show_top_bar: true,\n /* Show the top bar, (title, buttons, users) */\n default_user_color: \"#303030\",\n size_bug_fix: true,\n /* Resize the canvas after load (fixes a bug on iPad and FF Mac) */\n force_resize: false,\n allow_double_click: true,\n /* Allows Double Click to create a node on an empty background */\n zoom_on_scroll: true,\n /* Allows to use the scrollwheel to zoom */\n element_delete_delay: 0,\n /* Delay between clicking on the bin on an element and really deleting it\n Set to 0 for delete confirm */\n autoscale_padding: 50,\n resize: true,\n \n /* zoom options */\n show_zoom: true,\n /* show zoom buttons */\n save_view: true,\n /* show buttons to save view */\n default_view: false,\n /* Allows to load default view (zoom+offset) at start on read_only mode, instead of autoScale. the default_view will be the last */\n \n \n /* TOP BAR BUTTONS */\n show_search_field: true,\n show_user_list: true,\n user_name_editable: true,\n user_color_editable: true,\n show_user_color: true,\n show_save_button: true,\n show_export_button: true,\n show_open_button: false,\n show_addnode_button: true,\n show_addedge_button: true,\n show_bookmarklet: true,\n show_fullscreen_button: true,\n home_button_url: false,\n home_button_title: \"Home\",\n\n /* MINI-MAP OPTIONS */\n\n show_minimap: true,\n /* Show a small map at the bottom right */\n minimap_width: 160,\n minimap_height: 120,\n minimap_padding: 20,\n minimap_background_color: \"#ffffff\",\n minimap_border_color: \"#cccccc\",\n minimap_highlight_color: \"#ffff00\",\n minimap_highlight_weight: 5,\n \n\n /* EDGE/NODE COMMON OPTIONS */\n\n buttons_background: \"#202020\",\n buttons_label_color: \"#c000c0\",\n buttons_label_font_size: 9,\n\n /* NODE DISPLAY OPTIONS */\n\n show_node_circles: true,\n /* Show circles for nodes */\n clip_node_images: true,\n /* Constraint node images to circles */\n node_images_fill_mode: false,\n /* Set to false for \"letterboxing\" (height/width of node adapted to show full image)\n Set to true for \"crop\" (adapted to fill circle) */\n node_size_base: 25,\n node_stroke_width: 2,\n selected_node_stroke_width: 4,\n node_fill_color: \"#ffffff\",\n highlighted_node_fill_color: \"#ffff00\",\n node_label_distance: 5,\n /* Vertical distance between node and label */\n node_label_max_length: 60,\n /* Maximum displayed text length */\n label_untitled_nodes: \"(untitled)\",\n /* Label to display on untitled nodes */\n change_shapes: true,\n /* Change shapes enabled */\n\n /* EDGE DISPLAY OPTIONS */\n\n edge_stroke_width: 2,\n selected_edge_stroke_width: 4,\n edge_label_distance: 0,\n edge_label_max_length: 20,\n edge_arrow_length: 18,\n edge_arrow_width: 12,\n edge_gap_in_bundles: 12,\n label_untitled_edges: \"\",\n\n /* CONTEXTUAL DISPLAY (TOOLTIP OR EDITOR) OPTIONS */\n\n tooltip_width: 275,\n tooltip_padding: 10,\n tooltip_margin: 15,\n tooltip_arrow_length : 20,\n tooltip_arrow_width : 40,\n tooltip_top_color: \"#f0f0f0\",\n tooltip_bottom_color: \"#d0d0d0\",\n tooltip_border_color: \"#808080\",\n tooltip_border_width: 1,\n\n /* NODE EDITOR OPTIONS */\n\n show_node_editor_uri: true,\n show_node_editor_description: true,\n show_node_editor_size: true,\n show_node_editor_color: true,\n show_node_editor_image: true,\n show_node_editor_creator: true,\n allow_image_upload: true,\n uploaded_image_max_kb: 500,\n\n /* NODE TOOLTIP OPTIONS */\n\n show_node_tooltip_uri: true,\n show_node_tooltip_description: true,\n show_node_tooltip_color: true,\n show_node_tooltip_image: true,\n show_node_tooltip_creator: true,\n\n /* EDGE EDITOR OPTIONS */\n\n show_edge_editor_uri: true,\n show_edge_editor_color: true,\n show_edge_editor_direction: true,\n show_edge_editor_nodes: true,\n show_edge_editor_creator: true,\n\n /* EDGE TOOLTIP OPTIONS */\n\n show_edge_tooltip_uri: true,\n show_edge_tooltip_color: true,\n show_edge_tooltip_nodes: true,\n show_edge_tooltip_creator: true\n\n /* */\n\n};\n","Rkns.i18n = {\n fr: {\n \"Edit Node\": \"Ćdition dāun nÅud\",\n \"Edit Edge\": \"Ćdition dāun lien\",\n \"Title:\": \"Titre :\",\n \"URI:\": \"URI :\",\n \"Description:\": \"Description :\",\n \"From:\": \"De :\",\n \"To:\": \"Vers :\",\n \"Image\": \"Image\",\n \"Image URL:\": \"URL d'Image\",\n \"Choose Image File:\": \"Choisir un fichier image\",\n \"Full Screen\": \"Mode plein Ć©cran\",\n \"Add Node\": \"Ajouter un nÅud\",\n \"Add Edge\": \"Ajouter un lien\",\n \"Save Project\": \"Enregistrer le projet\",\n \"Open Project\": \"Ouvrir un projet\",\n \"Auto-save enabled\": \"Enregistrement automatique activĆ©\",\n \"Connection lost\": \"Connexion perdue\",\n \"Created by:\": \"CrƩƩ par :\",\n \"Zoom In\": \"Agrandir lāĆ©chelle\",\n \"Zoom Out\": \"Rapetisser lāĆ©chelle\",\n \"Edit\": \"Ćditer\",\n \"Remove\": \"Supprimer\",\n \"Cancel deletion\": \"Annuler la suppression\",\n \"Link to another node\": \"CrĆ©er un lien\",\n \"Enlarge\": \"Agrandir\",\n \"Shrink\": \"RĆ©trĆ©cir\",\n \"Click on the background canvas to add a node\": \"Cliquer sur le fond du graphe pour rajouter un nÅud\",\n \"Click on a first node to start the edge\": \"Cliquer sur un premier nÅud pour commencer le lien\",\n \"Click on a second node to complete the edge\": \"Cliquer sur un second nÅud pour terminer le lien\",\n \"Wikipedia\": \"WikipĆ©dia\",\n \"Wikipedia in \": \"WikipĆ©dia en \",\n \"French\": \"FranƧais\",\n \"English\": \"Anglais\",\n \"Japanese\": \"Japonais\",\n \"Untitled project\": \"Projet sans titre\",\n \"Lignes de Temps\": \"Lignes de Temps\",\n \"Loading, please wait\": \"Chargement en cours, merci de patienter\",\n \"Edge color:\": \"Couleur :\",\n \"Node color:\": \"Couleur :\",\n \"Choose color\": \"Choisir une couleur\",\n \"Change edge direction\": \"Changer le sens du lien\",\n \"Do you really wish to remove node \": \"Voulez-vous rĆ©ellement supprimer le nÅud \",\n \"Do you really wish to remove edge \": \"Voulez-vous rĆ©ellement supprimer le lien \",\n \"This file is not an image\": \"Ce fichier n'est pas une image\",\n \"Image size must be under \": \"L'image doit peser moins de \",\n \"Size:\": \"Taille :\",\n \"KB\": \"ko\",\n \"Choose from vocabulary:\": \"Choisir dans un vocabulaire :\",\n \"SKOS Documentation properties\": \"SKOS: PropriĆ©tĆ©s documentaires\",\n \"has note\": \"a pour note\",\n \"has example\": \"a pour exemple\",\n \"has definition\": \"a pour dĆ©finition\",\n \"SKOS Semantic relations\": \"SKOS: Relations sĆ©mantiques\",\n \"has broader\": \"a pour concept plus large\",\n \"has narrower\": \"a pour concept plus Ć©troit\",\n \"has related\": \"a pour concept apparentĆ©\",\n \"Dublin Core Metadata\": \"MĆ©tadonnĆ©es Dublin Core\",\n \"has contributor\": \"a pour contributeur\",\n \"covers\": \"couvre\",\n \"created by\": \"crƩƩ par\",\n \"has date\": \"a pour date\",\n \"published by\": \"Ć©ditĆ© par\",\n \"has source\": \"a pour source\",\n \"has subject\": \"a pour sujet\",\n \"Dragged resource\": \"Ressource glisĆ©e-dĆ©posĆ©e\",\n \"Search the Web\": \"Rechercher en ligne\",\n \"Search in Bins\": \"Rechercher dans les chutiers\",\n \"Close bin\": \"Fermer le chutier\",\n \"Refresh bin\": \"RafraĆ®chir le chutier\",\n \"(untitled)\": \"(sans titre)\",\n \"Select contents:\": \"SĆ©lectionner des contenus :\",\n \"Drag items from this website, drop them in Renkan\": \"Glissez des Ć©lĆ©ments de ce site web vers Renkan\",\n \"Drag this button to your bookmark bar. When on a third-party website, click it to enable drag-and-drop from the website to Renkan.\": \"Glissez ce bouton vers votre barre de favoris. Ensuite, depuis un site tiers, cliquez dessus pour activer 'Drag-to-Add' puis glissez des Ć©lĆ©ments de ce site vers Renkan\",\n \"Shapes available\": \"Formes disponibles\",\n \"Circle\": \"Cercle\",\n \"Square\": \"CarrĆ©\",\n \"Diamond\": \"Losange\",\n \"Hexagone\": \"Hexagone\",\n \"Ellipse\": \"Ellipse\",\n \"Star\": \"Ćtoile\",\n \"Zoom Fit\": \"Ajuster le Zoom\",\n \"Download Project\": \"TĆ©lĆ©charger le projet\",\n \"Zoom Save\": \"Sauver le Zoom\",\n \"View saved zoom\": \"Restaurer le Zoom\",\n \"Renkan \\'Drag-to-Add\\' bookmarklet\": \"Renkan \\'Deplacer-Pour-Ajouter\\' Signet\",\n \"(unknown user)\":\"(non authentifiĆ©)\",\n \"<unknown user>\":\"<non authentifiĆ©>\",\n \"Search in graph\":\"Rechercher dans carte\",\n \"Search in \" : \"Chercher dans \"\n }\n};\n","/* Saves the Full JSON at each modification */\n\nRkns.jsonIO = function(_renkan, _opts) {\n var _proj = _renkan.project;\n if (typeof _opts.http_method === \"undefined\") {\n _opts.http_method = 'PUT';\n }\n var _load = function() {\n _renkan.renderer.redrawActive = false;\n _proj.set({\n loading_status : true\n });\n Rkns.$.getJSON(_opts.url, function(_data) {\n _proj.set(_data, {\n validate : true\n });\n _proj.set({\n loading_status : false\n });\n _proj.set({\n save_status : 0\n });\n _renkan.renderer.redrawActive = true;\n _renkan.renderer.fixSize();\n });\n };\n var _save = function() {\n _proj.set({\n save_status : 2\n });\n var _data = _proj.toJSON();\n if (!_renkan.read_only) {\n Rkns.$.ajax({\n type : _opts.http_method,\n url : _opts.url,\n contentType : \"application/json\",\n data : JSON.stringify(_data),\n success : function(data, textStatus, jqXHR) {\n _proj.set({\n save_status : 0\n });\n }\n });\n }\n\n };\n var _thrSave = Rkns._.throttle(function() {\n setTimeout(_save, 100);\n }, 1000);\n _proj.on(\"add:nodes add:edges add:users add:views\", function(_model) {\n _model.on(\"change remove\", function(_model) {\n _thrSave();\n });\n _thrSave();\n });\n _proj.on(\"change\", function() {\n if (!(_proj.changedAttributes.length === 1 && _proj\n .hasChanged('save_status'))) {\n _thrSave();\n }\n });\n\n _load();\n};\n","/* Saves the Full JSON once */\n\nRkns.jsonIOSaveOnClick = function(_renkan, _opts) {\n var _proj = _renkan.project,\n _saveWarn = false,\n _onLeave = function() {\n return \"Project not saved\";\n };\n if (typeof _opts.http_method === \"undefined\") {\n _opts.http_method = 'POST';\n }\n var _load = function() {\n var getdata = {},\n rx = /id=([^&#?=]+)/,\n matches = document.location.hash.match(rx);\n if (matches) {\n getdata.id = matches[1];\n }\n Rkns.$.ajax({\n url: _opts.url,\n data: getdata,\n beforeSend: function(){\n \t_proj.set({loading_status:true});\n },\n success: function(_data) {\n _proj.set(_data, {validate: true});\n \t_proj.set({loading_status:false});\n _proj.set({save_status:0});\n \t_renkan.renderer.autoScale();\n }\n });\n };\n var _save = function() {\n _proj.set(\"saved_at\", new Date());\n var _data = _proj.toJSON();\n Rkns.$.ajax({\n type: _opts.http_method,\n url: _opts.url,\n contentType: \"application/json\",\n data: JSON.stringify(_data),\n beforeSend: function(){\n \t_proj.set({save_status:2});\n },\n success: function(data, textStatus, jqXHR) {\n $(window).off(\"beforeunload\", _onLeave);\n _saveWarn = false;\n _proj.set({save_status:0});\n //document.location.hash = \"#id=\" + data.id;\n //$(\".Rk-Notifications\").text(\"Saved as \"+document.location.href).fadeIn().delay(2000).fadeOut();\n }\n });\n };\n var _checkLeave = function() {\n \t_proj.set({save_status:1});\n \t\n var title = _proj.get(\"title\");\n if (title && _proj.get(\"nodes\").length) {\n $(\".Rk-Save-Button\").removeClass(\"disabled\");\n } else {\n $(\".Rk-Save-Button\").addClass(\"disabled\");\n }\n if (title) {\n $(\".Rk-PadTitle\").css(\"border-color\",\"#333333\");\n }\n if (!_saveWarn) {\n _saveWarn = true;\n $(window).on(\"beforeunload\", _onLeave);\n }\n };\n _load();\n _proj.on(\"add:nodes add:edges add:users change\", function(_model) {\n\t _model.on(\"change remove\", function(_model) {\n\t \tif(!(_model.changedAttributes.length === 1 && _model.hasChanged('save_status'))) {\n\t \t\t_checkLeave();\n\t \t}\n\t });\n\t\tif(!(_proj.changedAttributes.length === 1 && _proj.hasChanged('save_status'))) {\n\t\t _checkLeave();\n \t}\n });\n _renkan.renderer.save = function() {\n if ($(\".Rk-Save-Button\").hasClass(\"disabled\")) {\n if (!_proj.get(\"title\")) {\n $(\".Rk-PadTitle\").css(\"border-color\",\"#ff0000\");\n }\n } else {\n _save();\n }\n };\n};\n","(function(Rkns) {\n\"use strict\";\n\nvar _ = Rkns._;\n\nvar Ldt = Rkns.Ldt = {};\n\nvar Bin = Ldt.Bin = function(_renkan, _opts) {\n if (_opts.ldt_type) {\n var Resclass = Ldt[_opts.ldt_type+\"Bin\"];\n if (Resclass) {\n return new Resclass(_renkan, _opts);\n }\n }\n console.error(\"No such LDT Bin Type\");\n};\n\nvar ProjectBin = Ldt.ProjectBin = Rkns.Utils.inherit(Rkns._BaseBin);\n\nProjectBin.prototype.tagTemplate = renkanJST['templates/ldtjson-bin/tagtemplate.html'];\n\nProjectBin.prototype.annotationTemplate = renkanJST['templates/ldtjson-bin/annotationtemplate.html'];\n\nProjectBin.prototype._init = function(_renkan, _opts) {\n this.renkan = _renkan;\n this.proj_id = _opts.project_id;\n this.ldt_platform = _opts.ldt_platform || \"http://ldt.iri.centrepompidou.fr/\";\n this.title_$.html(_opts.title);\n this.title_icon_$.addClass('Rk-Ldt-Title-Icon');\n this.refresh();\n};\n\nProjectBin.prototype.render = function(searchbase) {\n var search = searchbase || Rkns.Utils.regexpFromTextOrArray();\n function highlight(_text) {\n var _e = _(_text).escape();\n return search.isempty ? _e : search.replace(_e, \"<span class='searchmatch'>$1</span>\");\n }\n function convertTC(_ms) {\n function pad(_n) {\n var _res = _n.toString();\n while (_res.length < 2) {\n _res = '0' + _res;\n }\n return _res;\n }\n var _totalSeconds = Math.abs(Math.floor(_ms/1000)),\n _hours = Math.floor(_totalSeconds / 3600),\n _minutes = (Math.floor(_totalSeconds / 60) % 60),\n _seconds = _totalSeconds % 60,\n _res = '';\n if (_hours) {\n _res += pad(_hours) + ':';\n }\n _res += pad(_minutes) + ':' + pad(_seconds);\n return _res;\n }\n\n var _html = '<li><h3>Tags</h3></li>',\n _projtitle = this.data.meta[\"dc:title\"],\n _this = this,\n count = 0;\n _this.title_$.text('LDT Project: \"' + _projtitle + '\"');\n _(_this.data.tags).map(function(_tag) {\n var _title = _tag.meta[\"dc:title\"];\n if (!search.isempty && !search.test(_title)) {\n return;\n }\n count++;\n _html += _this.tagTemplate({\n ldt_platform: _this.ldt_platform,\n title: _title,\n htitle: highlight(_title),\n encodedtitle : encodeURIComponent(_title),\n static_url: _this.renkan.options.static_url\n });\n });\n _html += '<li><h3>Annotations</h3></li>';\n _(_this.data.annotations).map(function(_annotation) {\n var _description = _annotation.content.description,\n _title = _annotation.content.title.replace(_description,\"\");\n if (!search.isempty && !search.test(_title) && !search.test(_description)) {\n return;\n }\n count++;\n var _duration = _annotation.end - _annotation.begin,\n _img = (\n (_annotation.content && _annotation.content.img && _annotation.content.img.src) ?\n _annotation.content.img.src :\n ( _duration ? _this.renkan.options.static_url+\"img/ldt-segment.png\" : _this.renkan.options.static_url+\"img/ldt-point.png\" )\n );\n _html += _this.annotationTemplate({\n ldt_platform: _this.ldt_platform,\n title: _title,\n htitle: highlight(_title),\n description: _description,\n hdescription: highlight(_description),\n start: convertTC(_annotation.begin),\n end: convertTC(_annotation.end),\n duration: convertTC(_duration),\n mediaid: _annotation.media,\n annotationid: _annotation.id,\n image: _img,\n static_url: _this.renkan.options.static_url\n });\n });\n\n this.main_$.html(_html);\n if (!search.isempty && count) {\n this.count_$.text(count).show();\n } else {\n this.count_$.hide();\n }\n if (!search.isempty && !count) {\n this.$.hide();\n } else {\n this.$.show();\n }\n this.renkan.resizeBins();\n};\n\nProjectBin.prototype.refresh = function() {\n var _this = this;\n Rkns.$.ajax({\n url: this.ldt_platform + 'ldtplatform/ldt/cljson/id/' + this.proj_id,\n dataType: \"jsonp\",\n success: function(_data) {\n _this.data = _data;\n _this.render();\n }\n });\n};\n\nvar Search = Ldt.Search = function(_renkan, _opts) {\n this.renkan = _renkan;\n this.lang = _opts.lang || \"en\";\n};\n\nSearch.prototype.getBgClass = function() {\n return \"Rk-Ldt-Icon\";\n};\n\nSearch.prototype.getSearchTitle = function() {\n return this.renkan.translate(\"Lignes de Temps\");\n};\n\nSearch.prototype.search = function(_q) {\n this.renkan.tabs.push(\n new ResultsBin(this.renkan, {\n search: _q\n })\n );\n};\n\nvar ResultsBin = Ldt.ResultsBin = Rkns.Utils.inherit(Rkns._BaseBin);\n\nResultsBin.prototype.segmentTemplate = renkanJST['templates/ldtjson-bin/segmenttemplate.html'];\n\nResultsBin.prototype._init = function(_renkan, _opts) {\n this.renkan = _renkan;\n this.ldt_platform = _opts.ldt_platform || \"http://ldt.iri.centrepompidou.fr/\";\n this.max_results = _opts.max_results || 50;\n this.search = _opts.search;\n this.title_$.html('Lignes de Temps: \"' + _opts.search + '\"');\n this.title_icon_$.addClass('Rk-Ldt-Title-Icon');\n this.refresh();\n};\n\nResultsBin.prototype.render = function(searchbase) {\n if (!this.data) {\n return;\n }\n var search = searchbase || Rkns.Utils.regexpFromTextOrArray();\n var highlightrx = (search.isempty ? Rkns.Utils.regexpFromTextOrArray(this.search) : search);\n function highlight(_text) {\n return highlightrx.replace(_(_text).escape(), \"<span class='searchmatch'>$1</span>\");\n }\n function convertTC(_ms) {\n function pad(_n) {\n var _res = _n.toString();\n while (_res.length < 2) {\n _res = '0' + _res;\n }\n return _res;\n }\n var _totalSeconds = Math.abs(Math.floor(_ms/1000)),\n _hours = Math.floor(_totalSeconds / 3600),\n _minutes = (Math.floor(_totalSeconds / 60) % 60),\n _seconds = _totalSeconds % 60,\n _res = '';\n if (_hours) {\n _res += pad(_hours) + ':';\n }\n _res += pad(_minutes) + ':' + pad(_seconds);\n return _res;\n }\n\n var _html = '',\n _this = this,\n count = 0;\n _(this.data.objects).each(function(_segment) {\n var _description = _segment.abstract,\n _title = _segment.title;\n if (!search.isempty && !search.test(_title) && !search.test(_description)) {\n return;\n }\n count++;\n var _duration = _segment.duration,\n _begin = _segment.start_ts,\n _end = + _segment.duration + _begin,\n _img = (\n _duration ?\n _this.renkan.options.static_url + \"img/ldt-segment.png\" :\n _this.renkan.options.static_url + \"img/ldt-point.png\"\n );\n _html += _this.segmentTemplate({\n ldt_platform: _this.ldt_platform,\n title: _title,\n htitle: highlight(_title),\n description: _description,\n hdescription: highlight(_description),\n start: convertTC(_begin),\n end: convertTC(_end),\n duration: convertTC(_duration),\n mediaid: _segment.iri_id,\n //projectid: _segment.project_id,\n //cuttingid: _segment.cutting_id,\n annotationid: _segment.element_id,\n image: _img\n });\n });\n\n this.main_$.html(_html);\n if (!search.isempty && count) {\n this.count_$.text(count).show();\n } else {\n this.count_$.hide();\n }\n if (!search.isempty && !count) {\n this.$.hide();\n } else {\n this.$.show();\n }\n this.renkan.resizeBins();\n};\n\nResultsBin.prototype.refresh = function() {\n var _this = this;\n Rkns.$.ajax({\n url: this.ldt_platform + 'ldtplatform/api/ldt/1.0/segments/search/',\n data: {\n format: \"jsonp\",\n q: this.search,\n limit: this.max_results\n },\n dataType: \"jsonp\",\n success: function(_data) {\n _this.data = _data;\n _this.render();\n }\n });\n};\n\n})(window.Rkns);\n","Rkns.ResourceList = {};\n\nRkns.ResourceList.Bin = Rkns.Utils.inherit(Rkns._BaseBin);\n\nRkns.ResourceList.Bin.prototype.resultTemplate = renkanJST['templates/list-bin.html'];\n\nRkns.ResourceList.Bin.prototype._init = function(_renkan, _opts) {\n this.renkan = _renkan;\n this.title_$.html(_opts.title);\n if (_opts.list) {\n this.data = _opts.list;\n }\n this.refresh();\n};\n\nRkns.ResourceList.Bin.prototype.render = function(searchbase) {\n var search = searchbase || Rkns.Utils.regexpFromTextOrArray();\n function highlight(_text) {\n var _e = _(_text).escape();\n return search.isempty ? _e : search.replace(_e, \"<span class='searchmatch'>$1</span>\");\n }\n var _html = \"\",\n _this = this,\n count = 0;\n Rkns._(this.data).each(function(_item) {\n var _element;\n if (typeof _item === \"string\") {\n if (/^(https?:\\/\\/|www)/.test(_item)) {\n _element = { url: _item };\n } else {\n _element = { title: _item.replace(/[:,]?\\s?(https?:\\/\\/|www)[\\d\\w\\/.&?=#%-_]+\\s?/,'').trim() };\n var _match = _item.match(/(https?:\\/\\/|www)[\\d\\w\\/.&?=#%-_]+/);\n if (_match) {\n _element.url = _match[0];\n }\n if (_element.title.length > 80) {\n _element.description = _element.title;\n _element.title = _element.title.replace(/^(.{30,60})\\s.+$/,'$1ā¦');\n }\n }\n } else {\n _element = _item;\n }\n var title = _element.title || (_element.url || \"\").replace(/^https?:\\/\\/(www\\.)?/,'').replace(/^(.{40}).+$/,'$1ā¦'),\n url = _element.url || \"\",\n description = _element.description || \"\",\n image = _element.image || \"\";\n if (url && !/^https?:\\/\\//.test(url)) {\n url = 'http://' + url;\n }\n if (!search.isempty && !search.test(title) && !search.test(description)) {\n return;\n }\n count++;\n _html += _this.resultTemplate({\n url: url,\n title: title,\n htitle: highlight(title),\n image: image,\n description: description,\n hdescription: highlight(description),\n static_url: _this.renkan.options.static_url\n });\n });\n _this.main_$.html(_html);\n if (!search.isempty && count) {\n this.count_$.text(count).show();\n } else {\n this.count_$.hide();\n }\n if (!search.isempty && !count) {\n this.$.hide();\n } else {\n this.$.show();\n }\n this.renkan.resizeBins();\n};\n\nRkns.ResourceList.Bin.prototype.refresh = function() {\n if (this.data) {\n this.render();\n }\n};\n","Rkns.Wikipedia = {\n};\n\nRkns.Wikipedia.Search = function(_renkan, _opts) {\n this.renkan = _renkan;\n this.lang = _opts.lang || \"en\";\n};\n\nRkns.Wikipedia.Search.prototype.getBgClass = function() {\n return \"Rk-Wikipedia-Search-Icon Rk-Wikipedia-Lang-\" + this.lang;\n};\n\nRkns.Wikipedia.Search.prototype.getSearchTitle = function() {\n var langs = {\n \"fr\": \"French\",\n \"en\": \"English\",\n \"ja\": \"Japanese\"\n };\n if (langs[this.lang]) {\n return this.renkan.translate(\"Wikipedia in \") + this.renkan.translate(langs[this.lang]);\n } else {\n return this.renkan.translate(\"Wikipedia\") + \" [\" + this.lang + \"]\";\n }\n};\n\nRkns.Wikipedia.Search.prototype.search = function(_q) {\n this.renkan.tabs.push(\n new Rkns.Wikipedia.Bin(this.renkan, {\n lang: this.lang,\n search: _q\n })\n );\n};\n\nRkns.Wikipedia.Bin = Rkns.Utils.inherit(Rkns._BaseBin);\n\nRkns.Wikipedia.Bin.prototype.resultTemplate = renkanJST['templates/wikipedia-bin/resulttemplate.html'];\n\nRkns.Wikipedia.Bin.prototype._init = function(_renkan, _opts) {\n this.renkan = _renkan;\n this.search = _opts.search;\n this.lang = _opts.lang || \"en\";\n this.title_icon_$.addClass('Rk-Wikipedia-Title-Icon Rk-Wikipedia-Lang-' + this.lang);\n this.title_$.html(this.search).addClass(\"Rk-Wikipedia-Title\");\n this.refresh();\n};\n\nRkns.Wikipedia.Bin.prototype.render = function(searchbase) {\n var search = searchbase || Rkns.Utils.regexpFromTextOrArray();\n var highlightrx = (search.isempty ? Rkns.Utils.regexpFromTextOrArray(this.search) : search);\n function highlight(_text) {\n return highlightrx.replace(_(_text).escape(), \"<span class='searchmatch'>$1</span>\");\n }\n var _html = \"\",\n _this = this,\n count = 0;\n Rkns._(this.data.query.search).each(function(_result) {\n var title = _result.title,\n url = \"http://\" + _this.lang + \".wikipedia.org/wiki/\" + encodeURI(title.replace(/ /g,\"_\")),\n description = Rkns.$('<div>').html(_result.snippet).text();\n if (!search.isempty && !search.test(title) && !search.test(description)) {\n return;\n }\n count++;\n _html += _this.resultTemplate({\n url: url,\n title: title,\n htitle: highlight(title),\n description: description,\n hdescription: highlight(description),\n static_url: _this.renkan.options.static_url\n });\n });\n _this.main_$.html(_html);\n if (!search.isempty && count) {\n this.count_$.text(count).show();\n } else {\n this.count_$.hide();\n }\n if (!search.isempty && !count) {\n this.$.hide();\n } else {\n this.$.show();\n }\n this.renkan.resizeBins();\n};\n\nRkns.Wikipedia.Bin.prototype.refresh = function() {\n var _this = this;\n Rkns.$.ajax({\n url: \"http://\" + _this.lang + \".wikipedia.org/w/api.php?action=query&list=search&srsearch=\" + encodeURIComponent(this.search) + \"&format=json\",\n dataType: \"jsonp\",\n success: function(_data) {\n _this.data = _data;\n _this.render();\n }\n });\n};\n","\ndefine('renderer/baserepresentation',['jquery', 'underscore'], function ($, _) {\n \n\n /* Rkns.Renderer._BaseRepresentation Class */\n\n /* In Renkan, a \"Representation\" is a sort of ViewModel (in the MVVM paradigm) and bridges the gap between\n * models (written with Backbone.js) and the view (written with Paper.js)\n * Renkan's representations all inherit from Rkns.Renderer._BaseRepresentation '*/\n\n var _BaseRepresentation = function(_renderer, _model) {\n if (typeof _renderer !== \"undefined\") {\n this.renderer = _renderer;\n this.renkan = _renderer.renkan;\n this.project = _renderer.renkan.project;\n this.options = _renderer.renkan.options;\n this.model = _model;\n if (this.model) {\n var _this = this;\n this._changeBinding = function() {\n _this.redraw();\n };\n this._removeBinding = function() {\n _renderer.removeRepresentation(_this);\n _(function() {\n _renderer.redraw();\n }).defer();\n };\n this._selectBinding = function() {\n _this.select();\n };\n this._unselectBinding = function() {\n _this.unselect();\n };\n this.model.on(\"change\", this._changeBinding );\n this.model.on(\"remove\", this._removeBinding );\n this.model.on(\"select\", this._selectBinding );\n this.model.on(\"unselect\", this._unselectBinding );\n }\n }\n };\n\n /* Rkns.Renderer._BaseRepresentation Methods */\n\n _(_BaseRepresentation.prototype).extend({\n _super: function(_func) {\n return _BaseRepresentation.prototype[_func].apply(this, Array.prototype.slice.call(arguments, 1));\n },\n redraw: function() {},\n moveTo: function() {},\n show: function() { return \"BaseRepresentation.show\"; },\n hide: function() {},\n select: function() {\n if (this.model) {\n this.model.trigger(\"selected\");\n }\n },\n unselect: function() {\n if (this.model) {\n this.model.trigger(\"unselected\");\n }\n },\n highlight: function() {},\n unhighlight: function() {},\n mousedown: function() {},\n mouseup: function() {\n if (this.model) {\n this.model.trigger(\"clicked\");\n }\n },\n destroy: function() {\n if (this.model) {\n this.model.off(\"change\", this._changeBinding );\n this.model.off(\"remove\", this._removeBinding );\n this.model.off(\"select\", this._selectBinding );\n this.model.off(\"unselect\", this._unselectBinding );\n }\n }\n });\n\n /* End of Rkns.Renderer._BaseRepresentation Class */\n\n return _BaseRepresentation;\n\n});\n\ndefine('requtils',[], function ($, _) {\n \n return {\n getUtils: function(){\n return window.Rkns.Utils;\n },\n getRenderer: function(){\n return window.Rkns.Renderer;\n }\n };\n\n});\n\n\ndefine('renderer/basebutton',['jquery', 'underscore', 'requtils', 'renderer/baserepresentation'], function ($, _, requtils, BaseRepresentation) {\n \n\n var Utils = requtils.getUtils();\n\n /* Rkns.Renderer._BaseButton Class */\n\n /* BaseButton is extended by contextual buttons that appear when hovering on nodes and edges */\n\n var _BaseButton = Utils.inherit(BaseRepresentation);\n\n _(_BaseButton.prototype).extend({\n moveTo: function(_pos) {\n this.sector.moveTo(_pos);\n },\n show: function() {\n this.sector.show();\n },\n hide: function() {\n this.sector.hide();\n },\n select: function() {\n this.sector.select();\n },\n unselect: function(_newTarget) {\n this.sector.unselect();\n if (!_newTarget || (_newTarget !== this.source_representation && _newTarget.source_representation !== this.source_representation)) {\n this.source_representation.unselect();\n }\n },\n destroy: function() {\n this.sector.destroy();\n }\n });\n\n return _BaseButton;\n\n});\n\n\ndefine('renderer/shapebuilder',[], function () {\n \n\n /* ShapeBuilder Begin */\n\n var builders = {\n \"circle\":{\n getShape: function() {\n return new paper.Path.Circle([0, 0], 1);\n },\n getImageShape: function(center, radius) {\n return new paper.Path.Circle(center, radius);\n }\n },\n \"rectangle\":{\n getShape: function() {\n return new paper.Path.Rectangle([-2, -2], [2, 2]);\n },\n getImageShape: function(center, radius) {\n return new paper.Path.Rectangle([-radius, -radius], [radius*2, radius*2]);\n }\n },\n \"ellipse\":{\n getShape: function() {\n return new paper.Path.Ellipse(new paper.Rectangle([-2, -1], [2, 1]));\n },\n getImageShape: function(center, radius) {\n return new paper.Path.Ellipse(new paper.Rectangle([-radius, -radius/2], [radius*2, radius]));\n }\n },\n \"polygon\":{\n getShape: function() {\n return new paper.Path.RegularPolygon([0, 0], 6, 1);\n },\n getImageShape: function(center, radius) {\n return new paper.Path.RegularPolygon([0, 0], 6, radius);\n }\n },\n \"diamond\":{\n getShape: function() {\n var d = new paper.Path.Rectangle([-2, -2], [2, 2]);\n d.rotate(45);\n return d;\n },\n getImageShape: function(center, radius) {\n var d = new paper.Path.Rectangle([-radius, -radius], [radius*2, radius*2]);\n d.rotate(45);\n return d;\n }\n },\n \"star\":{\n getShape: function() {\n return new paper.Path.Star([0, 0], 8, 1, 0.7);\n },\n getImageShape: function(center, radius) {\n return new paper.Path.Star([0, 0], 8, radius*1, radius*0.7);\n }\n },\n \"svg\": function(path){\n return {\n getShape: function() {\n return new paper.Path(path);\n },\n getImageShape: function(center, radius) {\n // No calcul for the moment \n return new paper.Path();\n }\n };\n }\n };\n \n var ShapeBuilder = function (shape){\n if(typeof shape===\"undefined\"){\n shape = \"circle\";\n }\n if(shape.substr(0,4)===\"svg:\"){\n return builders.svg(shape.substr(4));\n }\n if(!(shape in builders)){\n shape = \"circle\";\n }\n return builders[shape];\n };\n \n return ShapeBuilder;\n\n});\n\ndefine('renderer/noderepr',['jquery', 'underscore', 'requtils', 'renderer/baserepresentation', 'renderer/shapebuilder'], function ($, _, requtils, BaseRepresentation, ShapeBuilder) {\n \n\n var Utils = requtils.getUtils();\n\n /* Rkns.Renderer.Node Class */\n\n /* The representation for the node : A circle, with an image inside and a text label underneath.\n * The circle and the image are drawn on canvas and managed by Paper.js.\n * The text label is an HTML node, managed by jQuery. */\n\n //var NodeRepr = Renderer.Node = Utils.inherit(Renderer._BaseRepresentation);\n var NodeRepr = Utils.inherit(BaseRepresentation);\n\n _(NodeRepr.prototype).extend({\n _init: function() {\n this.renderer.node_layer.activate();\n this.type = \"Node\";\n this.buildShape();\n if (this.options.show_node_circles) {\n this.circle.strokeWidth = this.options.node_stroke_width;\n this.h_ratio = 1;\n } else {\n this.h_ratio = 0;\n }\n this.title = $('<div class=\"Rk-Label\">').appendTo(this.renderer.labels_$);\n\n if (this.options.editor_mode) {\n var Renderer = requtils.getRenderer();\n this.normal_buttons = [\n new Renderer.NodeEditButton(this.renderer, null),\n new Renderer.NodeRemoveButton(this.renderer, null),\n new Renderer.NodeLinkButton(this.renderer, null),\n new Renderer.NodeEnlargeButton(this.renderer, null),\n new Renderer.NodeShrinkButton(this.renderer, null)\n ];\n this.pending_delete_buttons = [\n new Renderer.NodeRevertButton(this.renderer, null)\n ];\n this.all_buttons = this.normal_buttons.concat(this.pending_delete_buttons);\n\n for (var i = 0; i < this.all_buttons.length; i++) {\n this.all_buttons[i].source_representation = this;\n }\n this.active_buttons = [];\n } else {\n this.active_buttons = this.all_buttons = [];\n }\n this.last_circle_radius = 1;\n\n if (this.renderer.minimap) {\n this.renderer.minimap.node_layer.activate();\n this.minimap_circle = new paper.Path.Circle([0, 0], 1);\n this.minimap_circle.__representation = this.renderer.minimap.miniframe.__representation;\n this.renderer.minimap.node_group.addChild(this.minimap_circle);\n }\n },\n buildShape: function(){\n if(typeof this.model.get(\"shape_changed\")!==\"undefined\" && this.model.get(\"shape_changed\")===true){\n this.model.set(\"shape_changed\", false);\n delete this.img;\n }\n if(this.circle){\n this.circle.remove();\n delete this.circle;\n }\n // \"circle\" \"rectangle\" \"ellipse\" \"polygon\" \"star\" \"diamond\"\n this.shapeBuilder = new ShapeBuilder(this.model.get(\"shape\"));\n this.circle = this.shapeBuilder.getShape();\n this.circle.__representation = this;\n this.last_circle_radius = 1;\n },\n redraw: function(_dontRedrawEdges) {\n if(typeof this.model.get(\"shape_changed\")!==\"undefined\" && this.model.get(\"shape_changed\")===true){\n this.buildShape();\n }\n var _model_coords = new paper.Point(this.model.get(\"position\")),\n _baseRadius = this.options.node_size_base * Math.exp((this.model.get(\"size\") || 0) * Utils._NODE_SIZE_STEP);\n if (!this.is_dragging || !this.paper_coords) {\n this.paper_coords = this.renderer.toPaperCoords(_model_coords);\n }\n this.circle_radius = _baseRadius * this.renderer.scale;\n if (this.last_circle_radius !== this.circle_radius) {\n this.all_buttons.forEach(function(b) {\n b.setSectorSize();\n });\n this.circle.scale(this.circle_radius / this.last_circle_radius);\n if (this.node_image) {\n this.node_image.scale(this.circle_radius / this.last_circle_radius);\n }\n }\n this.circle.position = this.paper_coords;\n if (this.node_image) {\n this.node_image.position = this.paper_coords.subtract(this.image_delta.multiply(this.circle_radius));\n }\n this.last_circle_radius = this.circle_radius;\n\n var old_act_btn = this.active_buttons;\n\n var opacity = 1;\n if (this.model.get(\"delete_scheduled\")) {\n opacity = 0.5;\n this.active_buttons = this.pending_delete_buttons;\n this.circle.dashArray = [2,2];\n } else {\n opacity = 1;\n this.active_buttons = this.normal_buttons;\n this.circle.dashArray = null;\n }\n\n if (this.selected && this.renderer.isEditable()) {\n if (old_act_btn !== this.active_buttons) {\n old_act_btn.forEach(function(b) {\n b.hide();\n });\n }\n this.active_buttons.forEach(function(b) {\n b.show();\n });\n }\n\n if (this.node_image) {\n this.node_image.opacity = this.highlighted ? opacity * 0.5 : (opacity - 0.01);\n }\n\n this.circle.fillColor = this.highlighted ? this.options.highlighted_node_fill_color : this.options.node_fill_color;\n\n this.circle.opacity = this.options.show_node_circles ? opacity : 0.01;\n\n var _text = this.model.get(\"title\") || this.renkan.translate(this.options.label_untitled_nodes) || \"\";\n _text = Utils.shortenText(_text, this.options.node_label_max_length);\n\n if (typeof this.highlighted === \"object\") {\n this.title.html(this.highlighted.replace(_(_text).escape(),'<span class=\"Rk-Highlighted\">$1</span>'));\n } else {\n this.title.text(_text);\n }\n\n this.title.css({\n left: this.paper_coords.x,\n top: this.paper_coords.y + this.circle_radius * this.h_ratio + this.options.node_label_distance,\n opacity: opacity\n });\n var _color = this.model.get(\"color\") || (this.model.get(\"created_by\") || Utils._USER_PLACEHOLDER(this.renkan)).get(\"color\");\n this.circle.strokeColor = _color;\n var _pc = this.paper_coords;\n this.all_buttons.forEach(function(b) {\n b.moveTo(_pc);\n });\n var lastImage = this.img;\n this.img = this.model.get(\"image\");\n if (this.img && this.img !== lastImage) {\n this.showImage();\n }\n if (this.node_image && !this.img) {\n this.node_image.remove();\n delete this.node_image;\n }\n\n if (this.renderer.minimap) {\n this.minimap_circle.fillColor = _color;\n var minipos = this.renderer.toMinimapCoords(_model_coords),\n miniradius = this.renderer.minimap.scale * _baseRadius,\n minisize = new paper.Size([miniradius, miniradius]);\n this.minimap_circle.fitBounds(minipos.subtract(minisize), minisize.multiply(2));\n }\n\n if (!_dontRedrawEdges) {\n var _this = this;\n _.each(\n this.project.get(\"edges\").filter(\n function (ed) {\n return ((ed.get(\"to\") === _this.model) || (ed.get(\"from\") === _this.model));\n }\n ),\n function(edge, index, list) {\n var repr = _this.renderer.getRepresentationByModel(edge);\n if (repr && typeof repr.from_representation !== \"undefined\" && typeof repr.from_representation.paper_coords !== \"undefined\" && typeof repr.to_representation !== \"undefined\" && typeof repr.to_representation.paper_coords !== \"undefined\") {\n repr.redraw();\n }\n }\n );\n }\n\n },\n showImage: function() {\n var _image = null;\n if (typeof this.renderer.image_cache[this.img] === \"undefined\") {\n _image = new Image();\n this.renderer.image_cache[this.img] = _image;\n _image.src = this.img;\n } else {\n _image = this.renderer.image_cache[this.img];\n }\n if (_image.width) {\n if (this.node_image) {\n this.node_image.remove();\n }\n this.renderer.node_layer.activate();\n var width = _image.width,\n height = _image.height,\n clipPath = this.model.get(\"clip_path\"),\n hasClipPath = (typeof clipPath !== \"undefined\" && clipPath),\n _clip = null,\n baseRadius = null,\n centerPoint = null;\n\n if (hasClipPath) {\n _clip = new paper.Path();\n var instructions = clipPath.match(/[a-z][^a-z]+/gi) || [],\n lastCoords = [0,0],\n minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity;\n\n var transformCoords = function(tabc, relative) {\n var newCoords = tabc.slice(1).map(function(v, k) {\n var res = parseFloat(v),\n isY = k % 2;\n if (isY) {\n res = ( res - 0.5 ) * height;\n } else {\n res = ( res - 0.5 ) * width;\n }\n if (relative) {\n res += lastCoords[isY];\n }\n if (isY) {\n minY = Math.min(minY, res);\n maxY = Math.max(maxY, res);\n } else {\n minX = Math.min(minX, res);\n maxX = Math.max(maxX, res);\n }\n return res;\n });\n lastCoords = newCoords.slice(-2);\n return newCoords;\n };\n\n instructions.forEach(function(instr) {\n var coords = instr.match(/([a-z]|[0-9.-]+)/ig) || [\"\"];\n switch(coords[0]) {\n case \"M\":\n _clip.moveTo(transformCoords(coords));\n break;\n case \"m\":\n _clip.moveTo(transformCoords(coords, true));\n break;\n case \"L\":\n _clip.lineTo(transformCoords(coords));\n break;\n case \"l\":\n _clip.lineTo(transformCoords(coords, true));\n break;\n case \"C\":\n _clip.cubicCurveTo(transformCoords(coords));\n break;\n case \"c\":\n _clip.cubicCurveTo(transformCoords(coords, true));\n break;\n case \"Q\":\n _clip.quadraticCurveTo(transformCoords(coords));\n break;\n case \"q\":\n _clip.quadraticCurveTo(transformCoords(coords, true));\n break;\n }\n });\n\n baseRadius = Math[this.options.node_images_fill_mode ? \"min\" : \"max\"](maxX - minX, maxY - minY) / 2;\n centerPoint = new paper.Point((maxX + minX) / 2, (maxY + minY) / 2);\n if (!this.options.show_node_circles) {\n this.h_ratio = (maxY - minY) / (2 * baseRadius);\n }\n } else {\n baseRadius = Math[this.options.node_images_fill_mode ? \"min\" : \"max\"](width, height) / 2;\n centerPoint = new paper.Point(0,0);\n if (!this.options.show_node_circles) {\n this.h_ratio = height / (2 * baseRadius);\n }\n }\n var _raster = new paper.Raster(_image);\n _raster.locked = true; // Disable mouse events on icon\n if (hasClipPath) {\n _raster = new paper.Group(_clip, _raster);\n _raster.opacity = 0.99;\n /* This is a workaround to allow clipping at group level\n * If opacity was set to 1, paper.js would merge all clipping groups in one (known bug).\n */\n _raster.clipped = true;\n _clip.__representation = this;\n }\n if (this.options.clip_node_images) {\n var _circleClip = this.shapeBuilder.getImageShape(centerPoint, baseRadius);\n _raster = new paper.Group(_circleClip, _raster);\n _raster.opacity = 0.99;\n _raster.clipped = true;\n _circleClip.__representation = this;\n }\n this.image_delta = centerPoint.divide(baseRadius);\n this.node_image = _raster;\n this.node_image.__representation = _this;\n this.node_image.scale(this.circle_radius / baseRadius);\n this.node_image.position = this.paper_coords.subtract(this.image_delta.multiply(this.circle_radius));\n this.redraw();\n this.renderer.throttledPaperDraw();\n } else {\n var _this = this;\n $(_image).on(\"load\", function() {\n _this.showImage();\n });\n }\n },\n paperShift: function(_delta) {\n if (this.options.editor_mode) {\n if (!this.renkan.read_only) {\n this.is_dragging = true;\n this.paper_coords = this.paper_coords.add(_delta);\n this.redraw();\n }\n } else {\n this.renderer.paperShift(_delta);\n }\n },\n openEditor: function() {\n this.renderer.removeRepresentationsOfType(\"editor\");\n var _editor = this.renderer.addRepresentation(\"NodeEditor\",null);\n _editor.source_representation = this;\n _editor.draw();\n },\n select: function() {\n this.selected = true;\n this.circle.strokeWidth = this.options.selected_node_stroke_width;\n if (this.renderer.isEditable()) {\n this.active_buttons.forEach(function(b) {\n b.show();\n });\n }\n var _uri = this.model.get(\"uri\");\n if (_uri) {\n $('.Rk-Bin-Item').each(function() {\n var _el = $(this);\n if (_el.attr(\"data-uri\") === _uri) {\n _el.addClass(\"selected\");\n }\n });\n }\n if (!this.options.editor_mode) {\n this.openEditor();\n }\n\n if (this.renderer.minimap) {\n this.minimap_circle.strokeWidth = this.options.minimap_highlight_weight;\n this.minimap_circle.strokeColor = this.options.minimap_highlight_color;\n }\n this._super(\"select\");\n },\n hideButtons: function() {\n this.all_buttons.forEach(function(b) {\n b.hide();\n });\n delete(this.buttonTimeout);\n },\n unselect: function(_newTarget) {\n if (!_newTarget || _newTarget.source_representation !== this) {\n this.selected = false;\n var _this = this;\n this.buttons_timeout = setTimeout(function() { _this.hideButtons(); }, 200);\n this.circle.strokeWidth = this.options.node_stroke_width;\n $('.Rk-Bin-Item').removeClass(\"selected\");\n if (this.renderer.minimap) {\n this.minimap_circle.strokeColor = undefined;\n }\n this._super(\"unselect\");\n }\n },\n highlight: function(textToReplace) {\n var hlvalue = textToReplace || true;\n if (this.highlighted === hlvalue) {\n return;\n }\n this.highlighted = hlvalue;\n this.redraw();\n this.renderer.throttledPaperDraw();\n },\n unhighlight: function() {\n if (!this.highlighted) {\n return;\n }\n this.highlighted = false;\n this.redraw();\n this.renderer.throttledPaperDraw();\n },\n saveCoords: function() {\n var _coords = this.renderer.toModelCoords(this.paper_coords),\n _data = {\n position: {\n x: _coords.x,\n y: _coords.y\n }\n };\n if (this.renderer.isEditable()) {\n this.model.set(_data);\n }\n },\n mousedown: function(_event, _isTouch) {\n if (_isTouch) {\n this.renderer.unselectAll();\n this.select();\n }\n },\n mouseup: function(_event, _isTouch) {\n if (this.renderer.is_dragging && this.renderer.isEditable()) {\n this.saveCoords();\n } else {\n if (!_isTouch && !this.model.get(\"delete_scheduled\")) {\n this.openEditor();\n }\n this.model.trigger(\"clicked\");\n }\n this.renderer.click_target = null;\n this.renderer.is_dragging = false;\n this.is_dragging = false;\n },\n destroy: function(_event) {\n this._super(\"destroy\");\n this.all_buttons.forEach(function(b) {\n b.destroy();\n });\n this.circle.remove();\n this.title.remove();\n if (this.renderer.minimap) {\n this.minimap_circle.remove();\n }\n if (this.node_image) {\n this.node_image.remove();\n }\n }\n });\n\n return NodeRepr;\n\n});\n\n\ndefine('renderer/edge',['jquery', 'underscore', 'requtils', 'renderer/baserepresentation'], function ($, _, requtils, BaseRepresentation) {\n \n\n var Utils = requtils.getUtils();\n\n /* Edge Class Begin */\n\n //var Edge = Renderer.Edge = Utils.inherit(Renderer._BaseRepresentation);\n var Edge = Utils.inherit(BaseRepresentation);\n\n _(Edge.prototype).extend({\n _init: function() {\n this.renderer.edge_layer.activate();\n this.type = \"Edge\";\n this.from_representation = this.renderer.getRepresentationByModel(this.model.get(\"from\"));\n this.to_representation = this.renderer.getRepresentationByModel(this.model.get(\"to\"));\n this.bundle = this.renderer.addToBundles(this);\n this.line = new paper.Path();\n this.line.add([0,0],[0,0],[0,0]);\n this.line.__representation = this;\n this.line.strokeWidth = this.options.edge_stroke_width;\n this.arrow = new paper.Path();\n this.arrow.add(\n [ 0, 0 ],\n [ this.options.edge_arrow_length, this.options.edge_arrow_width / 2 ],\n [ 0, this.options.edge_arrow_width ]\n );\n this.arrow.__representation = this;\n this.text = $('<div class=\"Rk-Label Rk-Edge-Label\">').appendTo(this.renderer.labels_$);\n this.arrow_angle = 0;\n if (this.options.editor_mode) {\n var Renderer = requtils.getRenderer();\n this.normal_buttons = [\n new Renderer.EdgeEditButton(this.renderer, null),\n new Renderer.EdgeRemoveButton(this.renderer, null)\n ];\n this.pending_delete_buttons = [\n new Renderer.EdgeRevertButton(this.renderer, null)\n ];\n this.all_buttons = this.normal_buttons.concat(this.pending_delete_buttons);\n for (var i = 0; i < this.all_buttons.length; i++) {\n this.all_buttons[i].source_representation = this;\n }\n this.active_buttons = [];\n } else {\n this.active_buttons = this.all_buttons = [];\n }\n\n if (this.renderer.minimap) {\n this.renderer.minimap.edge_layer.activate();\n this.minimap_line = new paper.Path();\n this.minimap_line.add([0,0],[0,0]);\n this.minimap_line.__representation = this.renderer.minimap.miniframe.__representation;\n this.minimap_line.strokeWidth = 1;\n }\n },\n redraw: function() {\n var from = this.model.get(\"from\"),\n to = this.model.get(\"to\");\n if (!from || !to) {\n return;\n }\n this.from_representation = this.renderer.getRepresentationByModel(from);\n this.to_representation = this.renderer.getRepresentationByModel(to);\n if (typeof this.from_representation === \"undefined\" || typeof this.to_representation === \"undefined\") {\n return;\n }\n var _p0a = this.from_representation.paper_coords,\n _p1a = this.to_representation.paper_coords,\n _v = _p1a.subtract(_p0a),\n _r = _v.length,\n _u = _v.divide(_r),\n _ortho = new paper.Point([- _u.y, _u.x]),\n _group_pos = this.bundle.getPosition(this),\n _delta = _ortho.multiply( this.options.edge_gap_in_bundles * _group_pos ),\n _p0b = _p0a.add(_delta), /* Adding a 4 px difference */\n _p1b = _p1a.add(_delta), /* to differentiate bundled links */\n _a = _v.angle,\n _textdelta = _ortho.multiply(this.options.edge_label_distance),\n _handle = _v.divide(3),\n _color = this.model.get(\"color\") || this.model.get(\"color\") || (this.model.get(\"created_by\") || Utils._USER_PLACEHOLDER(this.renkan)).get(\"color\"),\n opacity = 1;\n\n if (this.model.get(\"delete_scheduled\") || this.from_representation.model.get(\"delete_scheduled\") || this.to_representation.model.get(\"delete_scheduled\")) {\n opacity = 0.5;\n this.line.dashArray = [2, 2];\n } else {\n opacity = 1;\n this.line.dashArray = null;\n }\n\n var old_act_btn = this.active_buttons;\n\n this.active_buttons = this.model.get(\"delete_scheduled\") ? this.pending_delete_buttons : this.normal_buttons;\n\n if (this.selected && this.renderer.isEditable() && old_act_btn !== this.active_buttons) {\n old_act_btn.forEach(function(b) {\n b.hide();\n });\n this.active_buttons.forEach(function(b) {\n b.show();\n });\n }\n\n this.paper_coords = _p0b.add(_p1b).divide(2);\n this.line.strokeColor = _color;\n this.line.opacity = opacity;\n this.line.segments[0].point = _p0a;\n this.line.segments[1].point = this.paper_coords;\n this.line.segments[1].handleIn = _handle.multiply(-1);\n this.line.segments[1].handleOut = _handle;\n this.line.segments[2].point = _p1a;\n this.arrow.rotate(_a - this.arrow_angle);\n this.arrow.fillColor = _color;\n this.arrow.opacity = opacity;\n this.arrow.position = this.paper_coords;\n this.arrow_angle = _a;\n if (_a > 90) {\n _a -= 180;\n _textdelta = _textdelta.multiply(-1);\n }\n if (_a < -90) {\n _a += 180;\n _textdelta = _textdelta.multiply(-1);\n }\n var _text = this.model.get(\"title\") || this.renkan.translate(this.options.label_untitled_edges) || \"\";\n _text = Utils.shortenText(_text, this.options.node_label_max_length);\n this.text.text(_text);\n var _textpos = this.paper_coords.add(_textdelta);\n this.text.css({\n left: _textpos.x,\n top: _textpos.y,\n transform: \"rotate(\" + _a + \"deg)\",\n \"-moz-transform\": \"rotate(\" + _a + \"deg)\",\n \"-webkit-transform\": \"rotate(\" + _a + \"deg)\",\n opacity: opacity\n });\n this.text_angle = _a;\n\n var _pc = this.paper_coords;\n this.all_buttons.forEach(function(b) {\n b.moveTo(_pc);\n });\n\n if (this.renderer.minimap) {\n this.minimap_line.strokeColor = _color;\n this.minimap_line.segments[0].point = this.renderer.toMinimapCoords(new paper.Point(this.from_representation.model.get(\"position\")));\n this.minimap_line.segments[1].point = this.renderer.toMinimapCoords(new paper.Point(this.to_representation.model.get(\"position\")));\n }\n },\n openEditor: function() {\n this.renderer.removeRepresentationsOfType(\"editor\");\n var _editor = this.renderer.addRepresentation(\"EdgeEditor\",null);\n _editor.source_representation = this;\n _editor.draw();\n },\n select: function() {\n this.selected = true;\n this.line.strokeWidth = this.options.selected_edge_stroke_width;\n if (this.renderer.isEditable()) {\n this.active_buttons.forEach(function(b) {\n b.show();\n });\n }\n if (!this.options.editor_mode) {\n this.openEditor();\n }\n this._super(\"select\");\n },\n unselect: function(_newTarget) {\n if (!_newTarget || _newTarget.source_representation !== this) {\n this.selected = false;\n if (this.options.editor_mode) {\n this.all_buttons.forEach(function(b) {\n b.hide();\n });\n }\n this.line.strokeWidth = this.options.edge_stroke_width;\n this._super(\"unselect\");\n }\n },\n mousedown: function(_event, _isTouch) {\n if (_isTouch) {\n this.renderer.unselectAll();\n this.select();\n }\n },\n mouseup: function(_event, _isTouch) {\n if (!this.renkan.read_only && this.renderer.is_dragging) {\n this.from_representation.saveCoords();\n this.to_representation.saveCoords();\n this.from_representation.is_dragging = false;\n this.to_representation.is_dragging = false;\n } else {\n if (!_isTouch) {\n this.openEditor();\n }\n this.model.trigger(\"clicked\");\n }\n this.renderer.click_target = null;\n this.renderer.is_dragging = false;\n },\n paperShift: function(_delta) {\n if (this.options.editor_mode) {\n if (!this.options.read_only) {\n this.from_representation.paperShift(_delta);\n this.to_representation.paperShift(_delta);\n }\n } else {\n this.renderer.paperShift(_delta);\n }\n },\n destroy: function() {\n this._super(\"destroy\");\n this.line.remove();\n this.arrow.remove();\n this.text.remove();\n if (this.renderer.minimap) {\n this.minimap_line.remove();\n }\n this.all_buttons.forEach(function(b) {\n b.destroy();\n });\n var _this = this;\n this.bundle.edges = _(this.bundle.edges).reject(function(_edge) {\n return _this === _edge;\n });\n }\n });\n\n return Edge;\n\n});\n\n\n\ndefine('renderer/tempedge',['jquery', 'underscore', 'requtils', 'renderer/baserepresentation'], function ($, _, requtils, BaseRepresentation) {\n \n\n var Utils = requtils.getUtils();\n\n /* TempEdge Class Begin */\n\n //var TempEdge = Renderer.TempEdge = Utils.inherit(Renderer._BaseRepresentation);\n var TempEdge = Utils.inherit(BaseRepresentation);\n\n _(TempEdge.prototype).extend({\n _init: function() {\n this.renderer.edge_layer.activate();\n this.type = \"Temp-edge\";\n\n var _color = (this.project.get(\"users\").get(this.renkan.current_user) || Utils._USER_PLACEHOLDER(this.renkan)).get(\"color\");\n this.line = new paper.Path();\n this.line.strokeColor = _color;\n this.line.dashArray = [4, 2];\n this.line.strokeWidth = this.options.selected_edge_stroke_width;\n this.line.add([0,0],[0,0]);\n this.line.__representation = this;\n this.arrow = new paper.Path();\n this.arrow.fillColor = _color;\n this.arrow.add(\n [ 0, 0 ],\n [ this.options.edge_arrow_length, this.options.edge_arrow_width / 2 ],\n [ 0, this.options.edge_arrow_width ]\n );\n this.arrow.__representation = this;\n this.arrow_angle = 0;\n },\n redraw: function() {\n var _p0 = this.from_representation.paper_coords,\n _p1 = this.end_pos,\n _a = _p1.subtract(_p0).angle,\n _c = _p0.add(_p1).divide(2);\n this.line.segments[0].point = _p0;\n this.line.segments[1].point = _p1;\n this.arrow.rotate(_a - this.arrow_angle);\n this.arrow.position = _c;\n this.arrow_angle = _a;\n },\n paperShift: function(_delta) {\n if (!this.renderer.isEditable()) {\n this.renderer.removeRepresentation(_this);\n paper.view.draw();\n return;\n }\n this.end_pos = this.end_pos.add(_delta);\n var _hitResult = paper.project.hitTest(this.end_pos);\n this.renderer.findTarget(_hitResult);\n this.redraw();\n },\n mouseup: function(_event, _isTouch) {\n var _hitResult = paper.project.hitTest(_event.point),\n _model = this.from_representation.model,\n _endDrag = true;\n if (_hitResult && typeof _hitResult.item.__representation !== \"undefined\") {\n var _target = _hitResult.item.__representation;\n if (_target.type.substr(0,4) === \"Node\") {\n var _destmodel = _target.model || _target.source_representation.model;\n if (_model !== _destmodel) {\n var _data = {\n id: Utils.getUID('edge'),\n created_by: this.renkan.current_user,\n from: _model,\n to: _destmodel\n };\n if (this.renderer.isEditable()) {\n this.project.addEdge(_data);\n }\n }\n }\n\n if (_model === _target.model || (_target.source_representation && _target.source_representation.model === _model)) {\n _endDrag = false;\n this.renderer.is_dragging = true;\n }\n }\n if (_endDrag) {\n this.renderer.click_target = null;\n this.renderer.is_dragging = false;\n this.renderer.removeRepresentation(this);\n paper.view.draw();\n }\n },\n destroy: function() {\n this.arrow.remove();\n this.line.remove();\n }\n });\n\n /* TempEdge Class End */\n\n return TempEdge;\n\n});\n\n\ndefine('renderer/baseeditor',['jquery', 'underscore', 'requtils', 'renderer/baserepresentation'], function ($, _, requtils, BaseRepresentation) {\n \n\n var Utils = requtils.getUtils();\n\n /* _BaseEditor Begin */\n //var _BaseEditor = Renderer._BaseEditor = Utils.inherit(Renderer._BaseRepresentation);\n var _BaseEditor = Utils.inherit(BaseRepresentation);\n\n _(_BaseEditor.prototype).extend({\n _init: function() {\n this.renderer.buttons_layer.activate();\n this.type = \"editor\";\n this.editor_block = new paper.Path();\n var _pts = _(_.range(8)).map(function() {return [0,0];});\n this.editor_block.add.apply(this.editor_block, _pts);\n this.editor_block.strokeWidth = this.options.tooltip_border_width;\n this.editor_block.strokeColor = this.options.tooltip_border_color;\n this.editor_block.opacity = 0.8;\n this.editor_$ = $('<div>')\n .appendTo(this.renderer.editor_$)\n .css({\n position: \"absolute\",\n opacity: 0.8\n })\n .hide();\n },\n destroy: function() {\n this.editor_block.remove();\n this.editor_$.remove();\n }\n });\n\n /* _BaseEditor End */\n\n return _BaseEditor;\n\n});\n\n\ndefine('renderer/nodeeditor',['jquery', 'underscore', 'requtils', 'renderer/baseeditor'], function ($, _, requtils, BaseEditor) {\n \n\n var Utils = requtils.getUtils();\n\n /* NodeEditor Begin */\n //var NodeEditor = Renderer.NodeEditor = Utils.inherit(Renderer._BaseEditor);\n var NodeEditor = Utils.inherit(BaseEditor);\n\n _(NodeEditor.prototype).extend({\n \t_init: function() {\n \t\tBaseEditor.prototype._init.apply(this);\n \t\tthis.template = this.options.templates['templates/nodeeditor.html'];\n \t\tthis.readOnlyTemplate = this.options.templates['templates/nodeeditor_readonly.html'];\n \t},\n draw: function() {\n var _model = this.source_representation.model,\n _created_by = _model.get(\"created_by\") || Utils._USER_PLACEHOLDER(this.renkan),\n _template = (this.renderer.isEditable() ? this.template : this.readOnlyTemplate ),\n _image_placeholder = this.options.static_url + \"img/image-placeholder.png\",\n _size = (_model.get(\"size\") || 0);\n this.editor_$\n .html(_template({\n node: {\n has_creator: !!_model.get(\"created_by\"),\n title: _model.get(\"title\"),\n uri: _model.get(\"uri\"),\n short_uri: Utils.shortenText((_model.get(\"uri\") || \"\").replace(/^(https?:\\/\\/)?(www\\.)?/,'').replace(/\\/$/,''),40),\n description: _model.get(\"description\"),\n image: _model.get(\"image\") || \"\",\n image_placeholder: _image_placeholder,\n color: _model.get(\"color\") || _created_by.get(\"color\"),\n clip_path: _model.get(\"clip_path\") || false,\n created_by_color: _created_by.get(\"color\"),\n created_by_title: _created_by.get(\"title\"),\n size: (_size > 0 ? \"+\" : \"\") + _size,\n shape: _model.get(\"shape\") || \"circle\"\n },\n renkan: this.renkan,\n options: this.options,\n shortenText: Utils.shortenText\n }));\n this.redraw();\n var _this = this,\n closeEditor = function() {\n _this.renderer.removeRepresentation(_this);\n paper.view.draw();\n };\n\n this.editor_$.find(\".Rk-CloseX\").click(closeEditor);\n\n this.editor_$.find(\".Rk-Edit-Goto\").click(function() {\n if (!_model.get(\"uri\")) {\n return false;\n }\n });\n\n if (this.renderer.isEditable()) {\n\n var onFieldChange = _(function() {\n _(function() {\n if (_this.renderer.isEditable()) {\n var _data = {\n title: _this.editor_$.find(\".Rk-Edit-Title\").val()\n };\n if (_this.options.show_node_editor_uri) {\n _data.uri = _this.editor_$.find(\".Rk-Edit-URI\").val();\n _this.editor_$.find(\".Rk-Edit-Goto\").attr(\"href\",_data.uri || \"#\");\n }\n if (_this.options.show_node_editor_image) {\n _data.image = _this.editor_$.find(\".Rk-Edit-Image\").val();\n _this.editor_$.find(\".Rk-Edit-ImgPreview\").attr(\"src\", _data.image || _image_placeholder);\n }\n if (_this.options.show_node_editor_description) {\n _data.description = _this.editor_$.find(\".Rk-Edit-Description\").val();\n }\n if (_this.options.change_shapes) {\n if(_model.get(\"shape\")!==_this.editor_$.find(\".Rk-Edit-Shape\").val()){\n _data.shape = _this.editor_$.find(\".Rk-Edit-Shape\").val();\n _data.shape_changed = true;\n }\n }\n _model.set(_data);\n _this.redraw();\n // For an unknown reason, we have to set data twice when we change shape, otherwise the image disappears.\n if(_data.shape_changed===true){\n _model.set(_data);\n }\n } else {\n closeEditor();\n }\n }).defer();\n }).throttle(500);\n \n this.editor_$.on(\"keyup\", function(_e) {\n if (_e.keyCode === 27) {\n closeEditor();\n }\n });\n\n this.editor_$.find(\"input, textarea, select\").on(\"change keyup paste\", onFieldChange);\n\n if(_this.options.allow_image_upload) {\n this.editor_$.find(\".Rk-Edit-Image-File\").change(function() {\n if (this.files.length) {\n var f = this.files[0],\n fr = new FileReader();\n if (f.type.substr(0,5) !== \"image\") {\n alert(_this.renkan.translate(\"This file is not an image\"));\n return;\n }\n if (f.size > (_this.options.uploaded_image_max_kb * 1024)) {\n alert(_this.renkan.translate(\"Image size must be under \") + _this.options.uploaded_image_max_kb + _this.renkan.translate(\"KB\"));\n return;\n }\n fr.onload = function(e) {\n _this.editor_$.find(\".Rk-Edit-Image\").val(e.target.result);\n onFieldChange();\n };\n fr.readAsDataURL(f);\n }\n });\n }\n this.editor_$.find(\".Rk-Edit-Title\")[0].focus();\n\n var _picker = _this.editor_$.find(\".Rk-Edit-ColorPicker\");\n\n this.editor_$.find(\".Rk-Edit-ColorPicker-Wrapper\").hover(\n function(_e) {\n _e.preventDefault();\n _picker.show();\n },\n function(_e) {\n _e.preventDefault();\n _picker.hide();\n }\n );\n\n _picker.find(\"li\").hover(\n function(_e) {\n _e.preventDefault();\n _this.editor_$.find(\".Rk-Edit-Color\").css(\"background\", $(this).attr(\"data-color\"));\n },\n function(_e) {\n _e.preventDefault();\n _this.editor_$.find(\".Rk-Edit-Color\").css(\"background\", _model.get(\"color\") || (_model.get(\"created_by\") || Utils._USER_PLACEHOLDER(_this.renkan)).get(\"color\"));\n }\n ).click(function(_e) {\n _e.preventDefault();\n if (_this.renderer.isEditable()) {\n _model.set(\"color\", $(this).attr(\"data-color\"));\n _picker.hide();\n paper.view.draw();\n } else {\n closeEditor();\n }\n });\n\n var shiftSize = function(n) {\n if (_this.renderer.isEditable()) {\n var _newsize = n+(_model.get(\"size\") || 0);\n _this.editor_$.find(\".Rk-Edit-Size-Value\").text((_newsize > 0 ? \"+\" : \"\") + _newsize);\n _model.set(\"size\", _newsize);\n paper.view.draw();\n } else {\n closeEditor();\n }\n };\n\n this.editor_$.find(\".Rk-Edit-Size-Down\").click(function() {\n shiftSize(-1);\n return false;\n });\n this.editor_$.find(\".Rk-Edit-Size-Up\").click(function() {\n shiftSize(1);\n return false;\n });\n \n this.editor_$.find(\".Rk-Edit-Image-Del\").click(function() {\n \t_this.editor_$.find(\".Rk-Edit-Image\").val('');\n \tonFieldChange();\n return false;\n });\n } else {\n if (typeof this.source_representation.highlighted === \"object\") {\n var titlehtml = this.source_representation.highlighted.replace(_(_model.get(\"title\")).escape(),'<span class=\"Rk-Highlighted\">$1</span>');\n this.editor_$.find(\".Rk-Display-Title\" + (_model.get(\"uri\") ? \" a\" : \"\")).html(titlehtml);\n if (this.options.show_node_tooltip_description) {\n this.editor_$.find(\".Rk-Display-Description\").html(this.source_representation.highlighted.replace(_(_model.get(\"description\")).escape(),'<span class=\"Rk-Highlighted\">$1</span>'));\n }\n }\n }\n this.editor_$.find(\"img\").load(function() {\n _this.redraw();\n });\n },\n redraw: function() {\n var _coords = this.source_representation.paper_coords;\n Utils.drawEditBox(this.options, _coords, this.editor_block, this.source_representation.circle_radius * 0.75, this.editor_$);\n this.editor_$.show();\n paper.view.draw();\n }\n });\n\n /* NodeEditor End */\n\n return NodeEditor;\n\n});\n\n\ndefine('renderer/edgeeditor',['jquery', 'underscore', 'requtils', 'renderer/baseeditor'], function ($, _, requtils, BaseEditor) {\n \n\n var Utils = requtils.getUtils();\n\n /* EdgeEditor Begin */\n\n //var EdgeEditor = Renderer.EdgeEditor = Utils.inherit(Renderer._BaseEditor);\n var EdgeEditor = Utils.inherit(BaseEditor);\n\n _(EdgeEditor.prototype).extend({\n \t_init: function() {\n \t\tBaseEditor.prototype._init.apply(this);\n \t\tthis.template = this.options.templates['templates/edgeeditor.html'];\n \t\tthis.readOnlyTemplate = this.options.templates['templates/edgeeditor_readonly.html'];\n \t},\n draw: function() {\n var _model = this.source_representation.model,\n _from_model = _model.get(\"from\"),\n _to_model = _model.get(\"to\"),\n _created_by = _model.get(\"created_by\") || Utils._USER_PLACEHOLDER(this.renkan),\n _template = (this.renderer.isEditable() ? this.template : this.readOnlyTemplate);\n this.editor_$\n .html(_template({\n edge: {\n has_creator: !!_model.get(\"created_by\"),\n title: _model.get(\"title\"),\n uri: _model.get(\"uri\"),\n short_uri: Utils.shortenText((_model.get(\"uri\") || \"\").replace(/^(https?:\\/\\/)?(www\\.)?/,'').replace(/\\/$/,''),40),\n description: _model.get(\"description\"),\n color: _model.get(\"color\") || _created_by.get(\"color\"),\n from_title: _from_model.get(\"title\"),\n to_title: _to_model.get(\"title\"),\n from_color: _from_model.get(\"color\") || (_from_model.get(\"created_by\") || Utils._USER_PLACEHOLDER(this.renkan)).get(\"color\"),\n to_color: _to_model.get(\"color\") || (_to_model.get(\"created_by\") || Utils._USER_PLACEHOLDER(this.renkan)).get(\"color\"),\n created_by_color: _created_by.get(\"color\"),\n created_by_title: _created_by.get(\"title\")\n },\n renkan: this.renkan,\n shortenText: Utils.shortenText,\n options: this.options\n }));\n this.redraw();\n var _this = this,\n closeEditor = function() {\n _this.renderer.removeRepresentation(_this);\n paper.view.draw();\n };\n this.editor_$.find(\".Rk-CloseX\").click(closeEditor);\n this.editor_$.find(\".Rk-Edit-Goto\").click(function() {\n if (!_model.get(\"uri\")) {\n return false;\n }\n });\n\n if (this.renderer.isEditable()) {\n\n var onFieldChange = _(function() {\n _(function() {\n if (_this.renderer.isEditable()) {\n var _data = {\n title: _this.editor_$.find(\".Rk-Edit-Title\").val()\n };\n if (_this.options.show_edge_editor_uri) {\n _data.uri = _this.editor_$.find(\".Rk-Edit-URI\").val();\n }\n _this.editor_$.find(\".Rk-Edit-Goto\").attr(\"href\",_data.uri || \"#\");\n _model.set(_data);\n paper.view.draw();\n } else {\n closeEditor();\n }\n }).defer();\n }).throttle(500);\n\n this.editor_$.on(\"keyup\", function(_e) {\n if (_e.keyCode === 27) {\n closeEditor();\n }\n });\n\n this.editor_$.find(\"input\").on(\"keyup change paste\", onFieldChange);\n\n this.editor_$.find(\".Rk-Edit-Vocabulary\").change(function() {\n var e = $(this),\n v = e.val();\n if (v) {\n _this.editor_$.find(\".Rk-Edit-Title\").val(e.find(\":selected\").text());\n _this.editor_$.find(\".Rk-Edit-URI\").val(v);\n onFieldChange();\n }\n });\n this.editor_$.find(\".Rk-Edit-Direction\").click(function() {\n if (_this.renderer.isEditable()) {\n _model.set({\n from: _model.get(\"to\"),\n to: _model.get(\"from\")\n });\n _this.draw();\n } else {\n closeEditor();\n }\n });\n\n var _picker = _this.editor_$.find(\".Rk-Edit-ColorPicker\");\n\n this.editor_$.find(\".Rk-Edit-ColorPicker-Wrapper\").hover(\n function(_e) {\n _e.preventDefault();\n _picker.show();\n },\n function(_e) {\n _e.preventDefault();\n _picker.hide();\n }\n );\n\n _picker.find(\"li\").hover(\n function(_e) {\n _e.preventDefault();\n _this.editor_$.find(\".Rk-Edit-Color\").css(\"background\", $(this).attr(\"data-color\"));\n },\n function(_e) {\n _e.preventDefault();\n _this.editor_$.find(\".Rk-Edit-Color\").css(\"background\", _model.get(\"color\") || (_model.get(\"created_by\") || Utils._USER_PLACEHOLDER(_this.renkan)).get(\"color\"));\n }\n ).click(function(_e) {\n _e.preventDefault();\n if (_this.renderer.isEditable()) {\n _model.set(\"color\", $(this).attr(\"data-color\"));\n _picker.hide();\n paper.view.draw();\n } else {\n closeEditor();\n }\n });\n }\n },\n redraw: function() {\n var _coords = this.source_representation.paper_coords;\n Utils.drawEditBox(this.options, _coords, this.editor_block, 5, this.editor_$);\n this.editor_$.show();\n paper.view.draw();\n }\n });\n\n /* EdgeEditor End */\n\n return EdgeEditor;\n\n});\n\n\ndefine('renderer/nodebutton',['jquery', 'underscore', 'requtils', 'renderer/basebutton'], function ($, _, requtils, BaseButton) {\n \n\n var Utils = requtils.getUtils();\n\n /* _NodeButton Begin */\n\n //var _NodeButton = Renderer._NodeButton = Utils.inherit(Renderer._BaseButton);\n var _NodeButton = Utils.inherit(BaseButton);\n\n _(_NodeButton.prototype).extend({\n setSectorSize: function() {\n var sectorInner = this.source_representation.circle_radius;\n if (sectorInner !== this.lastSectorInner) {\n if (this.sector) {\n this.sector.destroy();\n }\n this.sector = this.renderer.drawSector(\n this, 1 + sectorInner,\n Utils._NODE_BUTTON_WIDTH + sectorInner,\n this.startAngle,\n this.endAngle,\n 1,\n this.imageName,\n this.renkan.translate(this.text)\n );\n this.lastSectorInner = sectorInner;\n }\n },\n unselect: function() {\n BaseButton.prototype.unselect.apply(this, Array.prototype.slice.call(arguments, 1));\n if(this.source_representation && this.source_representation.buttons_timeout) {\n clearTimeout(this.source_representation.buttons_timeout);\n this.source_representation.hideButtons();\n }\n },\n select: function() {\n if(this.source_representation && this.source_representation.buttons_timeout) {\n clearTimeout(this.source_representation.buttons_timeout);\n }\n this.sector.select();\n },\n });\n\n /* _NodeButton End */\n\n return _NodeButton;\n\n});\n\n\ndefine('renderer/nodeeditbutton',['jquery', 'underscore', 'requtils', 'renderer/nodebutton'], function ($, _, requtils, NodeButton) {\n \n\n var Utils = requtils.getUtils();\n\n /* NodeEditButton Begin */\n\n //var NodeEditButton = Renderer.NodeEditButton = Utils.inherit(Renderer._NodeButton);\n var NodeEditButton = Utils.inherit(NodeButton);\n\n _(NodeEditButton.prototype).extend({\n _init: function() {\n this.type = \"Node-edit-button\";\n this.lastSectorInner = 0;\n this.startAngle = -135;\n this.endAngle = -45;\n this.imageName = \"edit\";\n this.text = \"Edit\";\n },\n mouseup: function() {\n if (!this.renderer.is_dragging) {\n this.source_representation.openEditor();\n }\n }\n });\n\n /* NodeEditButton End */\n\n return NodeEditButton;\n\n});\n\n\ndefine('renderer/noderemovebutton',['jquery', 'underscore', 'requtils', 'renderer/nodebutton'], function ($, _, requtils, NodeButton) {\n \n \n var Utils = requtils.getUtils();\n\n /* NodeRemoveButton Begin */\n\n //var NodeRemoveButton = Renderer.NodeRemoveButton = Utils.inherit(Renderer._NodeButton);\n var NodeRemoveButton = Utils.inherit(NodeButton);\n\n _(NodeRemoveButton.prototype).extend({\n _init: function() {\n this.type = \"Node-remove-button\";\n this.lastSectorInner = 0;\n this.startAngle = 0;\n this.endAngle = 90;\n this.imageName = \"remove\";\n this.text = \"Remove\";\n },\n mouseup: function() {\n this.renderer.click_target = null;\n this.renderer.is_dragging = false;\n this.renderer.removeRepresentationsOfType(\"editor\");\n if (this.renderer.isEditable()) {\n if (this.options.element_delete_delay) {\n var delid = Utils.getUID(\"delete\");\n this.renderer.delete_list.push({\n id: delid,\n time: new Date().valueOf() + this.options.element_delete_delay\n });\n this.source_representation.model.set(\"delete_scheduled\", delid);\n } else {\n if (confirm(this.renkan.translate('Do you really wish to remove node ') + '\"' + this.source_representation.model.get(\"title\") + '\"?')) {\n this.project.removeNode(this.source_representation.model);\n }\n }\n }\n }\n });\n\n /* NodeRemoveButton End */\n\n return NodeRemoveButton;\n\n});\n\n\ndefine('renderer/noderevertbutton',['jquery', 'underscore', 'requtils', 'renderer/nodebutton'], function ($, _, requtils, NodeButton) {\n \n\n var Utils = requtils.getUtils();\n\n /* NodeRevertButton Begin */\n\n //var NodeRevertButton = Renderer.NodeRevertButton = Utils.inherit(Renderer._NodeButton);\n var NodeRevertButton = Utils.inherit(NodeButton);\n\n _(NodeRevertButton.prototype).extend({\n _init: function() {\n this.type = \"Node-revert-button\";\n this.lastSectorInner = 0;\n this.startAngle = -135;\n this.endAngle = 135;\n this.imageName = \"revert\";\n this.text = \"Cancel deletion\";\n },\n mouseup: function() {\n this.renderer.click_target = null;\n this.renderer.is_dragging = false;\n if (this.renderer.isEditable()) {\n this.source_representation.model.unset(\"delete_scheduled\");\n }\n }\n });\n\n /* NodeRevertButton End */\n\n return NodeRevertButton;\n\n});\n\n\ndefine('renderer/nodelinkbutton',['jquery', 'underscore', 'requtils', 'renderer/nodebutton'], function ($, _, requtils, NodeButton) {\n \n\n var Utils = requtils.getUtils();\n\n /* NodeLinkButton Begin */\n\n //var NodeLinkButton = Renderer.NodeLinkButton = Utils.inherit(Renderer._NodeButton);\n var NodeLinkButton = Utils.inherit(NodeButton);\n\n _(NodeLinkButton.prototype).extend({\n _init: function() {\n this.type = \"Node-link-button\";\n this.lastSectorInner = 0;\n this.startAngle = 90;\n this.endAngle = 180;\n this.imageName = \"link\";\n this.text = \"Link to another node\";\n },\n mousedown: function(_event, _isTouch) {\n if (this.renderer.isEditable()) {\n var _off = this.renderer.canvas_$.offset(),\n _point = new paper.Point([\n _event.pageX - _off.left,\n _event.pageY - _off.top\n ]);\n this.renderer.click_target = null;\n this.renderer.removeRepresentationsOfType(\"editor\");\n this.renderer.addTempEdge(this.source_representation, _point);\n }\n }\n });\n\n /* NodeLinkButton End */\n\n return NodeLinkButton;\n\n});\n\n\n\ndefine('renderer/nodeenlargebutton',['jquery', 'underscore', 'requtils', 'renderer/nodebutton'], function ($, _, requtils, NodeButton) {\n \n \n var Utils = requtils.getUtils();\n\n /* NodeEnlargeButton Begin */\n\n //var NodeEnlargeButton = Renderer.NodeEnlargeButton = Utils.inherit(Renderer._NodeButton);\n var NodeEnlargeButton = Utils.inherit(NodeButton);\n\n _(NodeEnlargeButton.prototype).extend({\n _init: function() {\n this.type = \"Node-enlarge-button\";\n this.lastSectorInner = 0;\n this.startAngle = -45;\n this.endAngle = 0;\n this.imageName = \"enlarge\";\n this.text = \"Enlarge\";\n },\n mouseup: function() {\n var _newsize = 1 + (this.source_representation.model.get(\"size\") || 0);\n this.source_representation.model.set(\"size\", _newsize);\n this.source_representation.select();\n this.select();\n paper.view.draw();\n }\n });\n\n /* NodeEnlargeButton End */\n\n return NodeEnlargeButton;\n\n});\n\n\ndefine('renderer/nodeshrinkbutton',['jquery', 'underscore', 'requtils', 'renderer/nodebutton'], function ($, _, requtils, NodeButton) {\n \n\n var Utils = requtils.getUtils();\n\n /* NodeShrinkButton Begin */\n\n //var NodeShrinkButton = Renderer.NodeShrinkButton = Utils.inherit(Renderer._NodeButton);\n var NodeShrinkButton = Utils.inherit(NodeButton);\n\n _(NodeShrinkButton.prototype).extend({\n _init: function() {\n this.type = \"Node-shrink-button\";\n this.lastSectorInner = 0;\n this.startAngle = -180;\n this.endAngle = -135;\n this.imageName = \"shrink\";\n this.text = \"Shrink\";\n },\n mouseup: function() {\n var _newsize = -1 + (this.source_representation.model.get(\"size\") || 0);\n this.source_representation.model.set(\"size\", _newsize);\n this.source_representation.select();\n this.select();\n paper.view.draw();\n }\n });\n\n /* NodeShrinkButton End */\n\n return NodeShrinkButton;\n\n});\n\n\ndefine('renderer/edgeeditbutton',['jquery', 'underscore', 'requtils', 'renderer/basebutton'], function ($, _, requtils, BaseButton) {\n \n\n var Utils = requtils.getUtils();\n\n /* EdgeEditButton Begin */\n\n //var EdgeEditButton = Renderer.EdgeEditButton = Utils.inherit(Renderer._BaseButton);\n var EdgeEditButton = Utils.inherit(BaseButton);\n\n _(EdgeEditButton.prototype).extend({\n _init: function() {\n this.type = \"Edge-edit-button\";\n this.sector = this.renderer.drawSector(this, Utils._EDGE_BUTTON_INNER, Utils._EDGE_BUTTON_OUTER, -270, -90, 1, \"edit\", this.renkan.translate(\"Edit\"));\n },\n mouseup: function() {\n if (!this.renderer.is_dragging) {\n this.source_representation.openEditor();\n }\n }\n });\n\n /* EdgeEditButton End */\n\n return EdgeEditButton;\n\n});\n\n\ndefine('renderer/edgeremovebutton',['jquery', 'underscore', 'requtils', 'renderer/basebutton'], function ($, _, requtils, BaseButton) {\n \n\n var Utils = requtils.getUtils();\n\n /* EdgeRemoveButton Begin */\n\n //var EdgeRemoveButton = Renderer.EdgeRemoveButton = Utils.inherit(Renderer._BaseButton);\n var EdgeRemoveButton = Utils.inherit(BaseButton);\n\n _(EdgeRemoveButton.prototype).extend({\n _init: function() {\n this.type = \"Edge-remove-button\";\n this.sector = this.renderer.drawSector(this, Utils._EDGE_BUTTON_INNER, Utils._EDGE_BUTTON_OUTER, -90, 90, 1, \"remove\", this.renkan.translate(\"Remove\"));\n },\n mouseup: function() {\n this.renderer.click_target = null;\n this.renderer.is_dragging = false;\n this.renderer.removeRepresentationsOfType(\"editor\");\n if (this.renderer.isEditable()) {\n if (this.options.element_delete_delay) {\n var delid = Utils.getUID(\"delete\");\n this.renderer.delete_list.push({\n id: delid,\n time: new Date().valueOf() + this.options.element_delete_delay\n });\n this.source_representation.model.set(\"delete_scheduled\", delid);\n } else {\n if (confirm(this.renkan.translate('Do you really wish to remove edge ') + '\"' + this.source_representation.model.get(\"title\") + '\"?')) {\n this.project.removeEdge(this.source_representation.model);\n }\n }\n }\n }\n });\n\n /* EdgeRemoveButton End */\n\n return EdgeRemoveButton;\n\n});\n\n\ndefine('renderer/edgerevertbutton',['jquery', 'underscore', 'requtils', 'renderer/basebutton'], function ($, _, requtils, BaseButton) {\n \n\n var Utils = requtils.getUtils();\n\n /* EdgeRevertButton Begin */\n\n //var EdgeRevertButton = Renderer.EdgeRevertButton = Utils.inherit(Renderer._BaseButton);\n var EdgeRevertButton = Utils.inherit(BaseButton);\n\n _(EdgeRevertButton.prototype).extend({\n _init: function() {\n this.type = \"Edge-revert-button\";\n this.sector = this.renderer.drawSector(this, Utils._EDGE_BUTTON_INNER, Utils._EDGE_BUTTON_OUTER, -135, 135, 1, \"revert\", this.renkan.translate(\"Cancel deletion\"));\n },\n mouseup: function() {\n this.renderer.click_target = null;\n this.renderer.is_dragging = false;\n if (this.renderer.isEditable()) {\n this.source_representation.model.unset(\"delete_scheduled\");\n }\n }\n });\n\n /* EdgeRevertButton End */\n\n return EdgeRevertButton;\n\n});\n\n\ndefine('renderer/miniframe',['jquery', 'underscore', 'requtils', 'renderer/baserepresentation'], function ($, _, requtils, BaseRepresentation) {\n \n\n var Utils = requtils.getUtils();\n\n /* MiniFrame Begin */\n\n //var MiniFrame = Renderer.MiniFrame = Utils.inherit(Renderer._BaseRepresentation);\n var MiniFrame = Utils.inherit(BaseRepresentation);\n\n _(MiniFrame.prototype).extend({\n paperShift: function(_delta) {\n this.renderer.offset = this.renderer.offset.subtract(_delta.divide(this.renderer.minimap.scale).multiply(this.renderer.scale));\n this.renderer.redraw();\n },\n mouseup: function(_delta) {\n this.renderer.click_target = null;\n this.renderer.is_dragging = false;\n }\n });\n\n /* MiniFrame End */\n\n return MiniFrame;\n\n});\n\n\ndefine('renderer/scene',['jquery', 'underscore', 'filesaver', 'requtils', 'renderer/miniframe'], function ($, _, filesaver, requtils, MiniFrame) {\n \n\n var Utils = requtils.getUtils();\n\n /* Scene Begin */\n\n var Scene = function(_renkan) {\n this.renkan = _renkan;\n this.$ = $(\".Rk-Render\");\n this.representations = [];\n this.$.html(_renkan.options.templates['templates/scene.html'](_renkan));\n this.onStatusChange();\n this.canvas_$ = this.$.find(\".Rk-Canvas\");\n this.labels_$ = this.$.find(\".Rk-Labels\");\n this.editor_$ = this.$.find(\".Rk-Editor\");\n this.notif_$ = this.$.find(\".Rk-Notifications\");\n paper.setup(this.canvas_$[0]);\n this.scale = 1;\n this.initialScale = 1;\n this.offset = paper.view.center;\n this.totalScroll = 0;\n this.mouse_down = false;\n this.click_target = null;\n this.selected_target = null;\n this.edge_layer = new paper.Layer();\n this.node_layer = new paper.Layer();\n this.buttons_layer = new paper.Layer();\n this.delete_list = [];\n this.redrawActive = true;\n \n if (_renkan.options.show_minimap) {\n this.minimap = {\n background_layer: new paper.Layer(),\n edge_layer: new paper.Layer(),\n node_layer: new paper.Layer(),\n node_group: new paper.Group(),\n size: new paper.Size( _renkan.options.minimap_width, _renkan.options.minimap_height )\n };\n\n this.minimap.background_layer.activate();\n this.minimap.topleft = paper.view.bounds.bottomRight.subtract(this.minimap.size);\n this.minimap.rectangle = new paper.Path.Rectangle(this.minimap.topleft.subtract([2,2]), this.minimap.size.add([4,4]));\n this.minimap.rectangle.fillColor = _renkan.options.minimap_background_color;\n this.minimap.rectangle.strokeColor = _renkan.options.minimap_border_color;\n this.minimap.rectangle.strokeWidth = 4;\n this.minimap.offset = new paper.Point(this.minimap.size.divide(2));\n this.minimap.scale = 0.1;\n\n this.minimap.node_layer.activate();\n this.minimap.cliprectangle = new paper.Path.Rectangle(this.minimap.topleft, this.minimap.size);\n this.minimap.node_group.addChild(this.minimap.cliprectangle);\n this.minimap.node_group.clipped = true;\n this.minimap.miniframe = new paper.Path.Rectangle(this.minimap.topleft, this.minimap.size);\n this.minimap.node_group.addChild(this.minimap.miniframe);\n this.minimap.miniframe.fillColor = '#c0c0ff';\n this.minimap.miniframe.opacity = 0.3;\n this.minimap.miniframe.strokeColor = '#000080';\n this.minimap.miniframe.strokeWidth = 2;\n this.minimap.miniframe.__representation = new MiniFrame(this, null);\n }\n\n this.throttledPaperDraw = _(function() {\n paper.view.draw();\n }).throttle(100);\n\n this.bundles = [];\n this.click_mode = false;\n\n var _this = this,\n _allowScroll = true,\n _originalScale = 1,\n _zooming = false,\n _lastTapX = 0,\n _lastTapY = 0;\n\n this.image_cache = {};\n this.icon_cache = {};\n\n ['edit', 'remove', 'link', 'enlarge', 'shrink', 'revert' ].forEach(function(imgname) {\n var img = new Image();\n img.src = _renkan.options.static_url + 'img/' + imgname + '.png';\n _this.icon_cache[imgname] = img;\n });\n\n var throttledMouseMove = _.throttle(function(_event, _isTouch) {\n _this.onMouseMove(_event, _isTouch);\n }, Utils._MOUSEMOVE_RATE);\n\n this.canvas_$.on({\n mousedown: function(_event) {\n _event.preventDefault();\n _this.onMouseDown(_event, false);\n },\n mousemove: function(_event) {\n _event.preventDefault();\n throttledMouseMove(_event, false);\n },\n mouseup: function(_event) {\n _event.preventDefault();\n _this.onMouseUp(_event, false);\n },\n mousewheel: function(_event, _delta) {\n if(_renkan.options.zoom_on_scroll) {\n _event.preventDefault();\n if (_allowScroll) {\n _this.onScroll(_event, _delta);\n }\n }\n },\n touchstart: function(_event) {\n _event.preventDefault();\n var _touches = _event.originalEvent.touches[0];\n if (\n _renkan.options.allow_double_click &&\n new Date() - _lastTap < Utils._DOUBLETAP_DELAY &&\n ( Math.pow(_lastTapX - _touches.pageX, 2) + Math.pow(_lastTapY - _touches.pageY, 2) < Utils._DOUBLETAP_DISTANCE )\n ) {\n _lastTap = 0;\n _this.onDoubleClick(_touches);\n } else {\n _lastTap = new Date();\n _lastTapX = _touches.pageX;\n _lastTapY = _touches.pageY;\n _originalScale = _this.scale;\n _zooming = false;\n _this.onMouseDown(_touches, true);\n }\n },\n touchmove: function(_event) {\n _event.preventDefault();\n _lastTap = 0;\n if (_event.originalEvent.touches.length === 1) {\n _this.onMouseMove(_event.originalEvent.touches[0], true);\n } else {\n if (!_zooming) {\n _this.onMouseUp(_event.originalEvent.touches[0], true);\n _this.click_target = null;\n _this.is_dragging = false;\n _zooming = true;\n }\n if (_event.originalEvent.scale === \"undefined\") {\n return;\n }\n var _newScale = _event.originalEvent.scale * _originalScale,\n _scaleRatio = _newScale / _this.scale,\n _newOffset = new paper.Point([\n _this.canvas_$.width(),\n _this.canvas_$.height()\n ]).multiply( 0.5 * ( 1 - _scaleRatio ) ).add(_this.offset.multiply( _scaleRatio ));\n _this.setScale(_newScale, _newOffset);\n }\n },\n touchend: function(_event) {\n _event.preventDefault();\n _this.onMouseUp(_event.originalEvent.changedTouches[0], true);\n },\n dblclick: function(_event) {\n _event.preventDefault();\n if (_renkan.options.allow_double_click) {\n _this.onDoubleClick(_event);\n }\n },\n mouseleave: function(_event) {\n _event.preventDefault();\n _this.onMouseUp(_event, false);\n _this.click_target = null;\n _this.is_dragging = false;\n },\n dragover: function(_event) {\n _event.preventDefault();\n },\n dragenter: function(_event) {\n _event.preventDefault();\n _allowScroll = false;\n },\n dragleave: function(_event) {\n _event.preventDefault();\n _allowScroll = true;\n },\n drop: function(_event) {\n _event.preventDefault();\n _allowScroll = true;\n var res = {};\n _(_event.originalEvent.dataTransfer.types).each(function(t) {\n try {\n res[t] = _event.originalEvent.dataTransfer.getData(t);\n } catch(e) {}\n });\n var text = _event.originalEvent.dataTransfer.getData(\"Text\");\n if (typeof text === \"string\") {\n switch(text[0]) {\n case \"{\":\n case \"[\":\n try {\n var data = JSON.parse(text);\n _(res).extend(data);\n }\n catch(e) {\n if (!res[\"text/plain\"]) {\n res[\"text/plain\"] = text;\n }\n }\n break;\n case \"<\":\n if (!res[\"text/html\"]) {\n res[\"text/html\"] = text;\n }\n break;\n default:\n if (!res[\"text/plain\"]) {\n res[\"text/plain\"] = text;\n }\n }\n }\n var url = _event.originalEvent.dataTransfer.getData(\"URL\");\n if (url && !res[\"text/uri-list\"]) {\n res[\"text/uri-list\"] = url;\n }\n _this.dropData(res, _event.originalEvent);\n }\n });\n\n var bindClick = function(selector, fname) {\n _this.$.find(selector).click(function(evt) {\n _this[fname](evt);\n return false;\n });\n };\n\n bindClick(\".Rk-ZoomOut\", \"zoomOut\");\n bindClick(\".Rk-ZoomIn\", \"zoomIn\");\n bindClick(\".Rk-ZoomFit\", \"autoScale\");\n this.$.find(\".Rk-ZoomSave\").click( function() {\n // Save scale and offset point\n _this.renkan.project.addView( { zoom_level:_this.scale, offset:_this.offset } );\n });\n this.$.find(\".Rk-ZoomSetSaved\").click( function() {\n var view = _this.renkan.project.get(\"views\").last();\n if(view){\n _this.setScale(view.get(\"zoom_level\"), new paper.Point(view.get(\"offset\")));\n }\n });\n if(this.renkan.project.get(\"views\").length > 0 && this.renkan.options.save_view){\n this.$.find(\".Rk-ZoomSetSaved\").show();\n }\n this.$.find(\".Rk-CurrentUser\").mouseenter(\n function() { _this.$.find(\".Rk-UserList\").slideDown(); }\n );\n this.$.find(\".Rk-Users\").mouseleave(\n function() { _this.$.find(\".Rk-UserList\").slideUp(); }\n );\n bindClick(\".Rk-FullScreen-Button\", \"fullScreen\");\n bindClick(\".Rk-AddNode-Button\", \"addNodeBtn\");\n bindClick(\".Rk-AddEdge-Button\", \"addEdgeBtn\");\n bindClick(\".Rk-Save-Button\", \"save\");\n bindClick(\".Rk-Open-Button\", \"open\");\n bindClick(\".Rk-Export-Button\", \"exportProject\");\n this.$.find(\".Rk-Bookmarklet-Button\")\n /*jshint scripturl:true */\n .attr(\"href\",\"javascript:\" + Utils._BOOKMARKLET_CODE(_renkan))\n .click(function(){\n _this.notif_$\n .text(_renkan.translate(\"Drag this button to your bookmark bar. When on a third-party website, click it to enable drag-and-drop from the website to Renkan.\"))\n .fadeIn()\n .delay(5000)\n .fadeOut();\n return false;\n });\n this.$.find(\".Rk-TopBar-Button\").mouseover(function() {\n $(this).find(\".Rk-TopBar-Tooltip\").show();\n }).mouseout(function() {\n $(this).find(\".Rk-TopBar-Tooltip\").hide();\n });\n bindClick(\".Rk-Fold-Bins\", \"foldBins\");\n\n paper.view.onResize = function(_event) {\n var _ratio,\n newWidth = _event.width,\n newHeight = _event.height;\n\n if (_this.minimap) {\n _this.minimap.topleft = paper.view.bounds.bottomRight.subtract(_this.minimap.size);\n _this.minimap.rectangle.fitBounds(_this.minimap.topleft.subtract([2,2]), _this.minimap.size.add([4,4]));\n _this.minimap.cliprectangle.fitBounds(_this.minimap.topleft, _this.minimap.size);\n }\n\n var ratioH = newHeight/(newHeight-_event.delta.height),\n ratioW = newWidth/(newWidth-_event.delta.width);\n if (newHeight < newWidth) {\n _ratio = ratioH;\n } else {\n _ratio = ratioW;\n }\n\n _this.resizeZoom(ratioW, ratioH, _ratio);\n\n _this.redraw();\n\n };\n\n var _thRedraw = _.throttle(function() {\n _this.redraw();\n },50);\n\n this.addRepresentations(\"Node\", this.renkan.project.get(\"nodes\"));\n this.addRepresentations(\"Edge\", this.renkan.project.get(\"edges\"));\n this.renkan.project.on(\"change:title\", function() {\n _this.$.find(\".Rk-PadTitle\").val(_renkan.project.get(\"title\"));\n });\n\n this.$.find(\".Rk-PadTitle\").on(\"keyup input paste\", function() {\n _renkan.project.set({\"title\": $(this).val()});\n });\n\n var _thRedrawUsers = _.throttle(function() {\n _this.redrawUsers();\n }, 100);\n\n _thRedrawUsers();\n\n // register model events\n this.renkan.project.on(\"change:save_status\", function(){\n switch (_this.renkan.project.get(\"save_status\")) {\n case 0: //clean\n _this.$.find(\".Rk-Save-Button\").removeClass(\"to-save\");\n _this.$.find(\".Rk-Save-Button\").removeClass(\"saving\");\n _this.$.find(\".Rk-Save-Button\").addClass(\"saved\");\n break;\n case 1: //dirty\n _this.$.find(\".Rk-Save-Button\").removeClass(\"saved\");\n _this.$.find(\".Rk-Save-Button\").removeClass(\"saving\");\n _this.$.find(\".Rk-Save-Button\").addClass(\"to-save\");\n break;\n case 2: //saving\n _this.$.find(\".Rk-Save-Button\").removeClass(\"saved\");\n _this.$.find(\".Rk-Save-Button\").removeClass(\"to-save\");\n _this.$.find(\".Rk-Save-Button\").addClass(\"saving\");\n break;\n }\n });\n\n this.renkan.project.on(\"change:loading_status\", function(){\n if (_this.renkan.project.get(\"loading_status\")){\n var animate = _this.$.find(\".loader\").addClass(\"run\");\n var timer = setTimeout(function(){\n _this.$.find(\".loader\").hide(250);\n }, 3000);\n }\n });\n\n this.renkan.project.on(\"add:users remove:users\", _thRedrawUsers);\n\n this.renkan.project.on(\"add:views remove:views\", function(_node) {\n if(_this.renkan.project.get('views').length > 0) {\n _this.$.find(\".Rk-ZoomSetSaved\").show();\n }\n else {\n _this.$.find(\".Rk-ZoomSetSaved\").hide();\n }\n });\n\n this.renkan.project.on(\"add:nodes\", function(_node) {\n _this.addRepresentation(\"Node\", _node);\n if (!_this.renkan.project.get(\"loading_status\")){\n _thRedraw();\n }\n });\n this.renkan.project.on(\"add:edges\", function(_edge) {\n _this.addRepresentation(\"Edge\", _edge);\n if (!_this.renkan.project.get(\"loading_status\")){\n _thRedraw();\n }\n });\n this.renkan.project.on(\"change:title\", function(_model, _title) {\n var el = _this.$.find(\".Rk-PadTitle\");\n if (el.is(\"input\")) {\n if (el.val() !== _title) {\n el.val(_title);\n }\n } else {\n el.text(_title);\n }\n });\n\n if (_renkan.options.size_bug_fix) {\n var _delay = (\n typeof _renkan.options.size_bug_fix === \"number\" ?\n _renkan.options.size_bug_fix\n : 500\n );\n window.setTimeout(\n function() {\n _this.fixSize();\n },\n _delay\n );\n }\n\n if (_renkan.options.force_resize) {\n $(window).resize(function() {\n _this.autoScale();\n });\n }\n\n if (_renkan.options.show_user_list && _renkan.options.user_color_editable) {\n var $cpwrapper = this.$.find(\".Rk-Users .Rk-Edit-ColorPicker-Wrapper\"),\n $cplist = this.$.find(\".Rk-Users .Rk-Edit-ColorPicker\");\n\n $cpwrapper.hover(\n function(_e) {\n if (_this.isEditable()) {\n _e.preventDefault();\n $cplist.show();\n }\n },\n function(_e) {\n _e.preventDefault();\n $cplist.hide();\n }\n );\n\n $cplist.find(\"li\").mouseenter(\n function(_e) {\n if (_this.isEditable()) {\n _e.preventDefault();\n _this.$.find(\".Rk-CurrentUser-Color\").css(\"background\", $(this).attr(\"data-color\"));\n }\n }\n );\n }\n\n if (_renkan.options.show_search_field) {\n\n var lastval = '';\n\n this.$.find(\".Rk-GraphSearch-Field\").on(\"keyup change paste input\", function() {\n var $this = $(this),\n val = $this.val();\n if (val === lastval) {\n return;\n }\n lastval = val;\n if (val.length < 2) {\n _renkan.project.get(\"nodes\").each(function(n) {\n _this.getRepresentationByModel(n).unhighlight();\n });\n } else {\n var rxs = Utils.regexpFromTextOrArray(val);\n _renkan.project.get(\"nodes\").each(function(n) {\n if (rxs.test(n.get(\"title\")) || rxs.test(n.get(\"description\"))) {\n _this.getRepresentationByModel(n).highlight(rxs);\n } else {\n _this.getRepresentationByModel(n).unhighlight();\n }\n });\n }\n });\n }\n\n this.redraw();\n\n window.setInterval(function() {\n var _now = new Date().valueOf();\n _this.delete_list.forEach(function(d) {\n if (_now >= d.time) {\n var el = _renkan.project.get(\"nodes\").findWhere({\"delete_scheduled\":d.id});\n if (el) {\n project.removeNode(el);\n }\n el = _renkan.project.get(\"edges\").findWhere({\"delete_scheduled\":d.id});\n if (el) {\n project.removeEdge(el);\n }\n }\n });\n _this.delete_list = _this.delete_list.filter(function(d) {\n return _renkan.project.get(\"nodes\").findWhere({\"delete_scheduled\":d.id}) || _renkan.project.get(\"edges\").findWhere({\"delete_scheduled\":d.id});\n });\n }, 500);\n\n if (this.minimap) {\n window.setInterval(function() {\n _this.rescaleMinimap();\n }, 2000);\n }\n\n };\n\n _(Scene.prototype).extend({\n fixSize: function() {\n if( this.renkan.options.default_view && this.renkan.project.get(\"views\").length > 0) {\n var view = this.renkan.project.get(\"views\").last();\n this.setScale(view.get(\"zoom_level\"), new paper.Point(view.get(\"offset\")));\n }\n else{\n this.autoScale();\n }\n },\n drawSector: function(_repr, _inR, _outR, _startAngle, _endAngle, _padding, _imgname, _caption) {\n var _options = this.renkan.options,\n _startRads = _startAngle * Math.PI / 180,\n _endRads = _endAngle * Math.PI / 180,\n _img = this.icon_cache[_imgname],\n _startdx = - Math.sin(_startRads),\n _startdy = Math.cos(_startRads),\n _startXIn = Math.cos(_startRads) * _inR + _padding * _startdx,\n _startYIn = Math.sin(_startRads) * _inR + _padding * _startdy,\n _startXOut = Math.cos(_startRads) * _outR + _padding * _startdx,\n _startYOut = Math.sin(_startRads) * _outR + _padding * _startdy,\n _enddx = - Math.sin(_endRads),\n _enddy = Math.cos(_endRads),\n _endXIn = Math.cos(_endRads) * _inR - _padding * _enddx,\n _endYIn = Math.sin(_endRads) * _inR - _padding * _enddy,\n _endXOut = Math.cos(_endRads) * _outR - _padding * _enddx,\n _endYOut = Math.sin(_endRads) * _outR - _padding * _enddy,\n _centerR = (_inR + _outR) / 2,\n _centerRads = (_startRads + _endRads) / 2,\n _centerX = Math.cos(_centerRads) * _centerR,\n _centerY = Math.sin(_centerRads) * _centerR,\n _centerXIn = Math.cos(_centerRads) * _inR,\n _centerXOut = Math.cos(_centerRads) * _outR,\n _centerYIn = Math.sin(_centerRads) * _inR,\n _centerYOut = Math.sin(_centerRads) * _outR,\n _textX = Math.cos(_centerRads) * (_outR + 3),\n _textY = Math.sin(_centerRads) * (_outR + _options.buttons_label_font_size) + _options.buttons_label_font_size / 2;\n this.buttons_layer.activate();\n var _path = new paper.Path();\n _path.add([_startXIn, _startYIn]);\n _path.arcTo([_centerXIn, _centerYIn], [_endXIn, _endYIn]);\n _path.lineTo([_endXOut, _endYOut]);\n _path.arcTo([_centerXOut, _centerYOut], [_startXOut, _startYOut]);\n _path.fillColor = _options.buttons_background;\n _path.opacity = 0.5;\n _path.closed = true;\n _path.__representation = _repr;\n var _text = new paper.PointText(_textX,_textY);\n _text.characterStyle = {\n fontSize: _options.buttons_label_font_size,\n fillColor: _options.buttons_label_color\n };\n if (_textX > 2) {\n _text.paragraphStyle.justification = 'left';\n } else if (_textX < -2) {\n _text.paragraphStyle.justification = 'right';\n } else {\n _text.paragraphStyle.justification = 'center';\n }\n _text.visible = false;\n var _visible = false,\n _restPos = new paper.Point(-200, -200),\n _grp = new paper.Group([_path, _text]),\n //_grp = new paper.Group([_path]),\n _delta = _grp.position,\n _imgdelta = new paper.Point([_centerX, _centerY]),\n _currentPos = new paper.Point(0,0);\n _text.content = _caption;\n // set group pivot to not depend on text visibility that changes the group bounding box.\n _grp.pivot = _grp.bounds.center;\n _grp.visible = false;\n _grp.position = _restPos;\n var _res = {\n show: function() {\n _visible = true;\n _grp.position = _currentPos.add(_delta);\n _grp.visible = true;\n },\n moveTo: function(_point) {\n _currentPos = _point;\n if (_visible) {\n _grp.position = _point.add(_delta);\n }\n },\n hide: function() {\n _visible = false;\n _grp.visible = false;\n _grp.position = _restPos;\n },\n select: function() {\n _path.opacity = 0.8;\n _text.visible = true;\n },\n unselect: function() {\n _path.opacity = 0.5;\n _text.visible = false;\n },\n destroy: function() {\n _grp.remove();\n }\n };\n var showImage = function() {\n var _raster = new paper.Raster(_img);\n _raster.position = _imgdelta.add(_grp.position).subtract(_delta);\n _raster.locked = true; // Disable mouse events on icon\n _grp.addChild(_raster);\n };\n if (_img.width) {\n showImage();\n } else {\n $(_img).on(\"load\",showImage);\n }\n\n return _res;\n },\n addToBundles: function(_edgeRepr) {\n var _bundle = _(this.bundles).find(function(_bundle) {\n return (\n ( _bundle.from === _edgeRepr.from_representation && _bundle.to === _edgeRepr.to_representation ) ||\n ( _bundle.from === _edgeRepr.to_representation && _bundle.to === _edgeRepr.from_representation )\n );\n });\n if (typeof _bundle !== \"undefined\") {\n _bundle.edges.push(_edgeRepr);\n } else {\n _bundle = {\n from: _edgeRepr.from_representation,\n to: _edgeRepr.to_representation,\n edges: [ _edgeRepr ],\n getPosition: function(_er) {\n var _dir = (_er.from_representation === this.from) ? 1 : -1;\n return _dir * ( _(this.edges).indexOf(_er) - (this.edges.length - 1) / 2 );\n }\n };\n this.bundles.push(_bundle);\n }\n return _bundle;\n },\n isEditable: function() {\n return (this.renkan.options.editor_mode && !this.renkan.read_only);\n },\n onStatusChange: function() {\n var savebtn = this.$.find(\".Rk-Save-Button\"),\n tip = savebtn.find(\".Rk-TopBar-Tooltip-Contents\");\n if (this.renkan.read_only) {\n savebtn.removeClass(\"disabled Rk-Save-Online\").addClass(\"Rk-Save-ReadOnly\");\n tip.text(this.renkan.translate(\"Connection lost\"));\n } else {\n if (this.renkan.options.manual_save) {\n savebtn.removeClass(\"Rk-Save-ReadOnly Rk-Save-Online\");\n tip.text(this.renkan.translate(\"Save Project\"));\n } else {\n savebtn.removeClass(\"disabled Rk-Save-ReadOnly\").addClass(\"Rk-Save-Online\");\n tip.text(this.renkan.translate(\"Auto-save enabled\"));\n }\n }\n this.redrawUsers();\n },\n setScale: function(_newScale, _offset) {\n if ((_newScale/this.initialScale) > Utils._MIN_SCALE && (_newScale/this.initialScale) < Utils._MAX_SCALE) {\n this.scale = _newScale;\n if (_offset) {\n this.offset = _offset;\n }\n this.redraw();\n }\n },\n autoScale: function(force_view) {\n var nodes = this.renkan.project.get(\"nodes\");\n if (nodes.length > 1) {\n var _xx = nodes.map(function(_node) { return _node.get(\"position\").x; }),\n _yy = nodes.map(function(_node) { return _node.get(\"position\").y; }),\n _minx = Math.min.apply(Math, _xx),\n _miny = Math.min.apply(Math, _yy),\n _maxx = Math.max.apply(Math, _xx),\n _maxy = Math.max.apply(Math, _yy);\n var _scale = Math.min( (paper.view.size.width - 2 * this.renkan.options.autoscale_padding) / (_maxx - _minx), (paper.view.size.height - 2 * this.renkan.options.autoscale_padding) / (_maxy - _miny));\n this.initialScale = _scale;\n // Override calculated scale if asked\n if((typeof force_view !== \"undefined\") && parseFloat(force_view.zoom_level)>0 && parseFloat(force_view.offset.x)>0 && parseFloat(force_view.offset.y)>0){\n this.setScale(parseFloat(force_view.zoom_level), new paper.Point(parseFloat(force_view.offset.x), parseFloat(force_view.offset.y)));\n }\n else{\n this.setScale(_scale, paper.view.center.subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(_scale)));\n }\n }\n if (nodes.length === 1) {\n this.setScale(1, paper.view.center.subtract(new paper.Point([nodes.at(0).get(\"position\").x, nodes.at(0).get(\"position\").y])));\n }\n },\n redrawMiniframe: function() {\n var topleft = this.toMinimapCoords(this.toModelCoords(new paper.Point([0,0]))),\n bottomright = this.toMinimapCoords(this.toModelCoords(paper.view.bounds.bottomRight));\n this.minimap.miniframe.fitBounds(topleft, bottomright);\n },\n rescaleMinimap: function() {\n var nodes = this.renkan.project.get(\"nodes\");\n if (nodes.length > 1) {\n var _xx = nodes.map(function(_node) { return _node.get(\"position\").x; }),\n _yy = nodes.map(function(_node) { return _node.get(\"position\").y; }),\n _minx = Math.min.apply(Math, _xx),\n _miny = Math.min.apply(Math, _yy),\n _maxx = Math.max.apply(Math, _xx),\n _maxy = Math.max.apply(Math, _yy);\n var _scale = Math.min(\n this.scale * 0.8 * this.renkan.options.minimap_width / paper.view.bounds.width,\n this.scale * 0.8 * this.renkan.options.minimap_height / paper.view.bounds.height,\n ( this.renkan.options.minimap_width - 2 * this.renkan.options.minimap_padding ) / (_maxx - _minx),\n ( this.renkan.options.minimap_height - 2 * this.renkan.options.minimap_padding ) / (_maxy - _miny)\n );\n this.minimap.offset = this.minimap.size.divide(2).subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(_scale));\n this.minimap.scale = _scale;\n }\n if (nodes.length === 1) {\n this.minimap.scale = 0.1;\n this.minimap.offset = this.minimap.size.divide(2).subtract(new paper.Point([nodes.at(0).get(\"position\").x, nodes.at(0).get(\"position\").y]).multiply(this.minimap.scale));\n }\n this.redraw();\n },\n toPaperCoords: function(_point) {\n return _point.multiply(this.scale).add(this.offset);\n },\n toMinimapCoords: function(_point) {\n return _point.multiply(this.minimap.scale).add(this.minimap.offset).add(this.minimap.topleft);\n },\n toModelCoords: function(_point) {\n return _point.subtract(this.offset).divide(this.scale);\n },\n addRepresentation: function(_type, _model) {\n var RendererType = requtils.getRenderer()[_type];\n var _repr = new RendererType(this, _model);\n this.representations.push(_repr);\n return _repr;\n },\n addRepresentations: function(_type, _collection) {\n var _this = this;\n _collection.forEach(function(_model) {\n _this.addRepresentation(_type, _model);\n });\n },\n userTemplate: _.template(\n '<li class=\"Rk-User\"><span class=\"Rk-UserColor\" style=\"background:<%=background%>;\"></span><%=name%></li>'\n ),\n redrawUsers: function() {\n if (!this.renkan.options.show_user_list) {\n return;\n }\n var allUsers = [].concat((this.renkan.project.current_user_list || {}).models || [], (this.renkan.project.get(\"users\") || {}).models || []),\n ulistHtml = '',\n $userpanel = this.$.find(\".Rk-Users\"),\n $name = $userpanel.find(\".Rk-CurrentUser-Name\"),\n $cpitems = $userpanel.find(\".Rk-Edit-ColorPicker li\"),\n $colorsquare = $userpanel.find(\".Rk-CurrentUser-Color\"),\n _this = this;\n $name.off(\"click\").text(this.renkan.translate(\"<unknown user>\"));\n $cpitems.off(\"mouseleave click\");\n allUsers.forEach(function(_user) {\n if (_user.get(\"_id\") === _this.renkan.current_user) {\n $name.text(_user.get(\"title\"));\n $colorsquare.css(\"background\", _user.get(\"color\"));\n if (_this.isEditable()) {\n\n if (_this.renkan.options.user_name_editable) {\n $name.click(function() {\n var $this = $(this),\n $input = $('<input>').val(_user.get(\"title\")).blur(function() {\n _user.set(\"title\", $(this).val());\n _this.redrawUsers();\n _this.redraw();\n });\n $this.empty().html($input);\n $input.select();\n });\n }\n\n if (_this.renkan.options.user_color_editable) {\n $cpitems.click(\n function(_e) {\n _e.preventDefault();\n if (_this.isEditable()) {\n _user.set(\"color\", $(this).attr(\"data-color\"));\n }\n $(this).parent().hide();\n }\n ).mouseleave(function() {\n $colorsquare.css(\"background\", _user.get(\"color\"));\n });\n }\n }\n\n } else {\n ulistHtml += _this.userTemplate({\n name: _user.get(\"title\"),\n background: _user.get(\"color\")\n });\n }\n });\n $userpanel.find(\".Rk-UserList\").html(ulistHtml);\n },\n removeRepresentation: function(_representation) {\n _representation.destroy();\n this.representations = _(this.representations).reject(\n function(_repr) {\n return _repr === _representation;\n }\n );\n },\n getRepresentationByModel: function(_model) {\n if (!_model) {\n return undefined;\n }\n return _(this.representations).find(function(_repr) {\n return _repr.model === _model;\n });\n },\n removeRepresentationsOfType: function(_type) {\n var _representations = _(this.representations).filter(function(_repr) {\n return _repr.type === _type;\n }),\n _this = this;\n _(_representations).each(function(_repr) {\n _this.removeRepresentation(_repr);\n });\n },\n highlightModel: function(_model) {\n var _repr = this.getRepresentationByModel(_model);\n if (_repr) {\n _repr.highlight();\n }\n },\n unhighlightAll: function(_model) {\n _(this.representations).each(function(_repr) {\n _repr.unhighlight();\n });\n },\n unselectAll: function(_model) {\n _(this.representations).each(function(_repr) {\n _repr.unselect();\n });\n },\n redraw: function() {\n if(! this.redrawActive ) {\n return;\n }\n _(this.representations).each(function(_representation) {\n _representation.redraw(true);\n });\n if (this.minimap) {\n this.redrawMiniframe();\n }\n paper.view.draw();\n },\n addTempEdge: function(_from, _point) {\n var _tmpEdge = this.addRepresentation(\"TempEdge\",null);\n _tmpEdge.end_pos = _point;\n _tmpEdge.from_representation = _from;\n _tmpEdge.redraw();\n this.click_target = _tmpEdge;\n },\n findTarget: function(_hitResult) {\n if (_hitResult && typeof _hitResult.item.__representation !== \"undefined\") {\n var _newTarget = _hitResult.item.__representation;\n if (this.selected_target !== _hitResult.item.__representation) {\n if (this.selected_target) {\n this.selected_target.unselect(_newTarget);\n }\n _newTarget.select(this.selected_target);\n this.selected_target = _newTarget;\n }\n } else {\n if (this.selected_target) {\n this.selected_target.unselect();\n }\n this.selected_target = null;\n }\n },\n paperShift: function(_delta) {\n this.offset = this.offset.add(_delta);\n this.redraw();\n },\n onMouseMove: function(_event) {\n var _off = this.canvas_$.offset(),\n _point = new paper.Point([\n _event.pageX - _off.left,\n _event.pageY - _off.top\n ]),\n _delta = _point.subtract(this.last_point);\n this.last_point = _point;\n if (!this.is_dragging && this.mouse_down && _delta.length > Utils._MIN_DRAG_DISTANCE) {\n this.is_dragging = true;\n }\n var _hitResult = paper.project.hitTest(_point);\n if (this.is_dragging) {\n if (this.click_target && typeof this.click_target.paperShift === \"function\") {\n this.click_target.paperShift(_delta);\n } else {\n this.paperShift(_delta);\n }\n } else {\n this.findTarget(_hitResult);\n }\n paper.view.draw();\n },\n onMouseDown: function(_event, _isTouch) {\n var _off = this.canvas_$.offset(),\n _point = new paper.Point([\n _event.pageX - _off.left,\n _event.pageY - _off.top\n ]);\n this.last_point = _point;\n this.mouse_down = true;\n if (!this.click_target || this.click_target.type !== \"Temp-edge\") {\n this.removeRepresentationsOfType(\"editor\");\n this.is_dragging = false;\n var _hitResult = paper.project.hitTest(_point);\n if (_hitResult && typeof _hitResult.item.__representation !== \"undefined\") {\n this.click_target = _hitResult.item.__representation;\n this.click_target.mousedown(_event, _isTouch);\n } else {\n this.click_target = null;\n if (this.isEditable() && this.click_mode === Utils._CLICKMODE_ADDNODE) {\n var _coords = this.toModelCoords(_point),\n _data = {\n id: Utils.getUID('node'),\n created_by: this.renkan.current_user,\n position: {\n x: _coords.x,\n y: _coords.y\n }\n };\n _node = this.renkan.project.addNode(_data);\n this.getRepresentationByModel(_node).openEditor();\n }\n }\n }\n if (this.click_mode) {\n if (this.isEditable() && this.click_mode === Utils._CLICKMODE_STARTEDGE && this.click_target && this.click_target.type === \"Node\") {\n this.removeRepresentationsOfType(\"editor\");\n this.addTempEdge(this.click_target, _point);\n this.click_mode = Utils._CLICKMODE_ENDEDGE;\n this.notif_$.fadeOut(function() {\n $(this).html(this.renkan.translate(\"Click on a second node to complete the edge\")).fadeIn();\n });\n } else {\n this.notif_$.hide();\n this.click_mode = false;\n }\n }\n paper.view.draw();\n },\n onMouseUp: function(_event, _isTouch) {\n this.mouse_down = false;\n if (this.click_target) {\n var _off = this.canvas_$.offset();\n this.click_target.mouseup(\n {\n point: new paper.Point([\n _event.pageX - _off.left,\n _event.pageY - _off.top\n ])\n },\n _isTouch\n );\n } else {\n this.click_target = null;\n this.is_dragging = false;\n if (_isTouch) {\n this.unselectAll();\n }\n }\n paper.view.draw();\n },\n onScroll: function(_event, _scrolldelta) {\n this.totalScroll += _scrolldelta;\n if (Math.abs(this.totalScroll) >= 1) {\n var _off = this.canvas_$.offset(),\n _delta = new paper.Point([\n _event.pageX - _off.left,\n _event.pageY - _off.top\n ]).subtract(this.offset).multiply( Math.SQRT2 - 1 );\n if (this.totalScroll > 0) {\n this.setScale( this.scale * Math.SQRT2, this.offset.subtract(_delta) );\n } else {\n this.setScale( this.scale * Math.SQRT1_2, this.offset.add(_delta.divide(Math.SQRT2)));\n }\n this.totalScroll = 0;\n }\n },\n onDoubleClick: function(_event) {\n if (!this.isEditable()) {\n return;\n }\n var _off = this.canvas_$.offset(),\n _point = new paper.Point([\n _event.pageX - _off.left,\n _event.pageY - _off.top\n ]);\n var _hitResult = paper.project.hitTest(_point);\n if (this.isEditable() && (!_hitResult || typeof _hitResult.item.__representation === \"undefined\")) {\n var _coords = this.toModelCoords(_point),\n _data = {\n id: Utils.getUID('node'),\n created_by: this.renkan.current_user,\n position: {\n x: _coords.x,\n y: _coords.y\n }\n },\n _node = this.renkan.project.addNode(_data);\n this.getRepresentationByModel(_node).openEditor();\n }\n paper.view.draw();\n },\n defaultDropHandler: function(_data) {\n var newNode = {};\n var snippet = \"\";\n switch(_data[\"text/x-iri-specific-site\"]) {\n case \"twitter\":\n snippet = $('<div>').html(_data[\"text/x-iri-selected-html\"]);\n var tweetdiv = snippet.find(\".tweet\");\n newNode.title = this.renkan.translate(\"Tweet by \") + tweetdiv.attr(\"data-name\");\n newNode.uri = \"http://twitter.com/\" + tweetdiv.attr(\"data-screen-name\") + \"/status/\" + tweetdiv.attr(\"data-tweet-id\");\n newNode.image = tweetdiv.find(\".avatar\").attr(\"src\");\n newNode.description = tweetdiv.find(\".js-tweet-text:first\").text();\n break;\n case \"google\":\n snippet = $('<div>').html(_data[\"text/x-iri-selected-html\"]);\n newNode.title = snippet.find(\"h3:first\").text().trim();\n newNode.uri = snippet.find(\"h3 a\").attr(\"href\");\n newNode.description = snippet.find(\".st:first\").text().trim();\n break;\n default:\n if (_data[\"text/x-iri-source-uri\"]) {\n newNode.uri = _data[\"text/x-iri-source-uri\"];\n }\n }\n if (_data[\"text/plain\"] || _data[\"text/x-iri-selected-text\"]) {\n newNode.description = (_data[\"text/plain\"] || _data[\"text/x-iri-selected-text\"]).replace(/[\\s\\n]+/gm,' ').trim();\n }\n if (_data[\"text/html\"] || _data[\"text/x-iri-selected-html\"]) {\n snippet = $('<div>').html(_data[\"text/html\"] || _data[\"text/x-iri-selected-html\"]);\n var _svgimgs = snippet.find(\"image\");\n if (_svgimgs.length) {\n newNode.image = _svgimgs.attr(\"xlink:href\");\n }\n var _svgpaths = snippet.find(\"path\");\n if (_svgpaths.length) {\n newNode.clipPath = _svgpaths.attr(\"d\");\n }\n var _imgs = snippet.find(\"img\");\n if (_imgs.length) {\n newNode.image = _imgs[0].src;\n }\n var _as = snippet.find(\"a\");\n if (_as.length) {\n newNode.uri = _as[0].href;\n }\n newNode.title = snippet.find(\"[title]\").attr(\"title\") || newNode.title;\n newNode.description = snippet.text().replace(/[\\s\\n]+/gm,' ').trim();\n }\n if (_data[\"text/uri-list\"]) {\n newNode.uri = _data[\"text/uri-list\"];\n }\n if (_data[\"text/x-moz-url\"] && !newNode.title) {\n newNode.title = (_data[\"text/x-moz-url\"].split(\"\\n\")[1] || \"\").trim();\n if (newNode.title === newNode.uri) {\n newNode.title = false;\n }\n }\n if (_data[\"text/x-iri-source-title\"] && !newNode.title) {\n newNode.title = _data[\"text/x-iri-source-title\"];\n }\n if (_data[\"text/html\"] || _data[\"text/x-iri-selected-html\"]) {\n snippet = $('<div>').html(_data[\"text/html\"] || _data[\"text/x-iri-selected-html\"]);\n newNode.image = snippet.find(\"[data-image]\").attr(\"data-image\") || newNode.image;\n newNode.uri = snippet.find(\"[data-uri]\").attr(\"data-uri\") || newNode.uri;\n newNode.title = snippet.find(\"[data-title]\").attr(\"data-title\") || newNode.title;\n newNode.description = snippet.find(\"[data-description]\").attr(\"data-description\") || newNode.description;\n newNode.clipPath = snippet.find(\"[data-clip-path]\").attr(\"data-clip-path\") || newNode.clipPath;\n }\n\n if (!newNode.title) {\n newNode.title = this.renkan.translate(\"Dragged resource\");\n }\n var fields = [\"title\", \"description\", \"uri\", \"image\"];\n for (var i = 0; i < fields.length; i++) {\n var f = fields[i];\n if (_data[\"text/x-iri-\" + f] || _data[f]) {\n newNode[f] = _data[\"text/x-iri-\" + f] || _data[f];\n }\n if (newNode[f] === \"none\" || newNode[f] === \"null\") {\n newNode[f] = undefined;\n }\n }\n\n if(typeof this.renkan.options.drop_enhancer === \"function\"){\n newNode = this.renkan.options.drop_enhancer(newNode, _data);\n }\n\n return newNode;\n\n },\n dropData: function(_data, _event) {\n if (!this.isEditable()) {\n return;\n }\n if (_data[\"text/json\"] || _data[\"application/json\"]) {\n try {\n var jsondata = JSON.parse(_data[\"text/json\"] || _data[\"application/json\"]);\n _(_data).extend(jsondata);\n }\n catch(e) {}\n }\n\n var newNode = (typeof this.renkan.options.drop_handler === \"undefined\")?this.defaultDropHandler(_data):this.renkan.options.drop_handler(_data);\n\n var _off = this.canvas_$.offset(),\n _point = new paper.Point([\n _event.pageX - _off.left,\n _event.pageY - _off.top\n ]),\n _coords = this.toModelCoords(_point),\n _nodedata = {\n id: Utils.getUID('node'),\n created_by: this.renkan.current_user,\n uri: newNode.uri || \"\",\n title: newNode.title || \"\",\n description: newNode.description || \"\",\n image: newNode.image || \"\",\n color: newNode.color || undefined,\n clip_path: newNode.clipPath || undefined,\n position: {\n x: _coords.x,\n y: _coords.y\n }\n };\n var _node = this.renkan.project.addNode(_nodedata),\n _repr = this.getRepresentationByModel(_node);\n if (_event.type === \"drop\") {\n _repr.openEditor();\n }\n },\n fullScreen: function() {\n var _isFull = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen,\n _el = this.renkan.$[0],\n _requestMethods = [\"requestFullScreen\",\"mozRequestFullScreen\",\"webkitRequestFullScreen\"],\n _cancelMethods = [\"cancelFullScreen\",\"mozCancelFullScreen\",\"webkitCancelFullScreen\"],\n i;\n if (_isFull) {\n for (i = 0; i < _cancelMethods.length; i++) {\n if (typeof document[_cancelMethods[i]] === \"function\") {\n document[_cancelMethods[i]]();\n break;\n }\n }\n var widthAft = this.$.width();\n var heightAft = this.$.height();\n\n if (this.renkan.options.show_top_bar) {\n heightAft -= this.$.find(\".Rk-TopBar\").height();\n }\n if (this.renkan.options.show_bins && (this.renkan.$.find(\".Rk-Bins\").position().left > 0)) {\n widthAft -= this.renkan.$.find(\".Rk-Bins\").width();\n }\n\n paper.view.viewSize = new paper.Size([widthAft, heightAft]);\n\n } else {\n for (i = 0; i < _requestMethods.length; i++) {\n if (typeof _el[_requestMethods[i]] === \"function\") {\n _el[_requestMethods[i]]();\n break;\n }\n }\n this.redraw();\n }\n },\n zoomOut: function() {\n var _newScale = this.scale * Math.SQRT1_2,\n _offset = new paper.Point([\n this.canvas_$.width(),\n this.canvas_$.height()\n ]).multiply( 0.5 * ( 1 - Math.SQRT1_2 ) ).add(this.offset.multiply( Math.SQRT1_2 ));\n this.setScale( _newScale, _offset );\n },\n zoomIn: function() {\n var _newScale = this.scale * Math.SQRT2,\n _offset = new paper.Point([\n this.canvas_$.width(),\n this.canvas_$.height()\n ]).multiply( 0.5 * ( 1 - Math.SQRT2 ) ).add(this.offset.multiply( Math.SQRT2 ));\n this.setScale( _newScale, _offset );\n },\n resizeZoom: function(_scaleWidth, _scaleHeight, _ratio) {\n var _newScale = this.scale * _ratio,\n _offset = new paper.Point([\n (this.offset.x * _scaleWidth),\n (this.offset.y * _scaleHeight)\n ]);\n this.setScale( _newScale, _offset );\n },\n addNodeBtn: function() {\n if (this.click_mode === Utils._CLICKMODE_ADDNODE) {\n this.click_mode = false;\n this.notif_$.hide();\n } else {\n this.click_mode = Utils._CLICKMODE_ADDNODE;\n this.notif_$.text(this.renkan.translate(\"Click on the background canvas to add a node\")).fadeIn();\n }\n return false;\n },\n addEdgeBtn: function() {\n if (this.click_mode === Utils._CLICKMODE_STARTEDGE || this.click_mode === Utils._CLICKMODE_ENDEDGE) {\n this.click_mode = false;\n this.notif_$.hide();\n } else {\n this.click_mode = Utils._CLICKMODE_STARTEDGE;\n this.notif_$.text(this.renkan.translate(\"Click on a first node to start the edge\")).fadeIn();\n }\n return false;\n },\n exportProject: function() {\n var projectJSON = this.renkan.project.toJSON(),\n downloadLink = document.createElement(\"a\"),\n projectId = projectJSON.id,\n fileNameToSaveAs = projectId + \".json\";\n\n // clean ids\n delete projectJSON.id;\n delete projectJSON._id;\n delete projectJSON.space_id;\n\n var objId;\n var idsMap = {};\n\n _.each(projectJSON.nodes, function(e,i,l) {\n objId = e.id || e._id;\n delete e._id;\n delete e.id;\n idsMap[objId] = e['@id'] = Utils.getUUID4();\n });\n _.each(projectJSON.edges, function(e,i,l) {\n delete e._id;\n delete e.id;\n e.to = idsMap[e.to];\n e.from = idsMap[e.from];\n });\n _.each(projectJSON.views, function(e,i,l) {\n objId = e.id || e._id;\n delete e._id;\n delete e.id;\n });\n projectJSON.users = [];\n\n var projectJSONStr = JSON.stringify(projectJSON, null, 2);\n var blob = new Blob([projectJSONStr], {type: \"application/json;charset=utf-8\"});\n filesaver(blob,fileNameToSaveAs);\n\n },\n foldBins: function() {\n var foldBinsButton = this.$.find(\".Rk-Fold-Bins\"),\n bins = this.renkan.$.find(\".Rk-Bins\");\n var _this = this,\n sizeBef = _this.canvas_$.width(),\n sizeAft;\n if (bins.position().left < 0) {\n bins.animate({left: 0},250);\n this.$.animate({left: 300},250,function() {\n var w = _this.$.width();\n paper.view.viewSize = new paper.Size([w, _this.canvas_$.height()]);\n });\n if ((sizeBef - bins.width()) < bins.height()){\n sizeAft = sizeBef;\n } else {\n sizeAft = sizeBef - bins.width();\n }\n foldBinsButton.html(\"«\");\n } else {\n bins.animate({left: -300},250);\n this.$.animate({left: 0},250,function() {\n var w = _this.$.width();\n paper.view.viewSize = new paper.Size([w, _this.canvas_$.height()]);\n });\n sizeAft = sizeBef+300;\n foldBinsButton.html(\"»\");\n }\n _this.resizeZoom(1, 1, (sizeAft/sizeBef));\n },\n save: function() { },\n open: function() { }\n });\n\n /* Scene End */\n\n return Scene;\n\n});\n\n\n//Load modules and use them\nif( typeof require.config === \"function\" ) {\n require.config({\n paths: {\n 'jquery':'../lib/jquery/jquery',\n 'underscore':'../lib/underscore/underscore',\n 'filesaver' :'../lib/FileSaver/FileSaver',\n 'requtils':'require-utils'\n }\n });\n}\n\nrequire(['renderer/baserepresentation',\n 'renderer/basebutton',\n 'renderer/noderepr',\n 'renderer/edge',\n 'renderer/tempedge',\n 'renderer/baseeditor',\n 'renderer/nodeeditor',\n 'renderer/edgeeditor',\n 'renderer/nodebutton',\n 'renderer/nodeeditbutton',\n 'renderer/noderemovebutton',\n 'renderer/noderevertbutton',\n 'renderer/nodelinkbutton',\n 'renderer/nodeenlargebutton',\n 'renderer/nodeshrinkbutton',\n 'renderer/edgeeditbutton',\n 'renderer/edgeremovebutton',\n 'renderer/edgerevertbutton',\n 'renderer/miniframe',\n 'renderer/scene'\n ], function(BaseRepresentation, BaseButton, NodeRepr, Edge, TempEdge, BaseEditor, NodeEditor, EdgeEditor, NodeButton, NodeEditButton, NodeRemoveButton, NodeRevertButton, NodeLinkButton, NodeEnlargeButton, NodeShrinkButton, EdgeEditButton, EdgeRemoveButton, EdgeRevertButton, MiniFrame, Scene){\n\n \n\n var Rkns = window.Rkns;\n\n if(typeof Rkns.Renderer === \"undefined\"){\n Rkns.Renderer = {};\n }\n var Renderer = Rkns.Renderer;\n\n Renderer._BaseRepresentation = BaseRepresentation;\n Renderer._BaseButton = BaseButton;\n Renderer.Node = NodeRepr;\n Renderer.Edge = Edge;\n Renderer.TempEdge = TempEdge;\n Renderer._BaseEditor = BaseEditor;\n Renderer.NodeEditor = NodeEditor;\n Renderer.EdgeEditor = EdgeEditor;\n Renderer._NodeButton = NodeButton;\n Renderer.NodeEditButton = NodeEditButton;\n Renderer.NodeRemoveButton = NodeRemoveButton;\n Renderer.NodeRevertButton = NodeRevertButton;\n Renderer.NodeLinkButton = NodeLinkButton;\n Renderer.NodeEnlargeButton = NodeEnlargeButton;\n Renderer.NodeShrinkButton = NodeShrinkButton;\n Renderer.EdgeEditButton = EdgeEditButton;\n Renderer.EdgeRemoveButton = EdgeRemoveButton;\n Renderer.EdgeRevertButton = EdgeRevertButton;\n Renderer.MiniFrame = MiniFrame;\n Renderer.Scene = Scene;\n\n startRenkan();\n});\n\ndefine(\"main-renderer\", function(){});\n\n"]} \ No newline at end of file +{"version":3,"file":"renkan.min.js","sources":["templates.js","../../js/main.js","../../js/models.js","../../js/defaults.js","../../js/i18n.js","../../js/full-json.js","../../js/save-once.js","../../js/ldtjson-bin.js","../../js/list-bin.js","../../js/wikipedia-bin.js","paper-renderer.js"],"names":["this","obj","__t","__p","_","escape","__e","Array","prototype","join","renkan","translate","edge","title","options","show_edge_editor_uri","uri","properties","length","each","ontology","label","property","show_edge_editor_color","show_edge_editor_direction","show_edge_editor_nodes","from_color","shortenText","from_title","to_title","show_edge_editor_creator","has_creator","created_by_title","show_edge_tooltip_color","color","show_edge_tooltip_uri","short_uri","description","show_edge_tooltip_nodes","to_color","show_edge_tooltip_creator","created_by_color","Rkns","Utils","getFullURL","image","static_url","url","show_bins","show_editor","node","show_node_editor_uri","show_node_editor_description","show_node_editor_size","size","show_node_editor_color","show_node_editor_image","image_placeholder","clip_path","allow_image_upload","show_node_editor_creator","change_shapes","shape","show_node_tooltip_color","show_node_tooltip_uri","show_node_tooltip_description","show_node_tooltip_image","show_node_tooltip_creator","print","__j","call","arguments","show_top_bar","editor_mode","project","get","show_user_list","show_user_color","user_color_editable","colorPicker","home_button_url","home_button_title","show_fullscreen_button","show_addnode_button","show_addedge_button","show_export_button","show_save_button","show_open_button","show_bookmarklet","show_search_field","resize","show_zoom","save_view","root","$","jQuery","pickerColors","__renkans","_BaseBin","_renkan","_opts","find","hide","addClass","appendTo","title_icon_$","_this","attr","href","html","click","destroy","slideDown","resizeBins","refresh","count_$","title_$","main_$","auto_refresh","window","setInterval","detach","Renkan","push","defaults","templates","renkanJST","template","property_files","f","getJSON","data","concat","read_only","Models","Project","setCurrentUser","user_id","user_name","addUser","_id","current_user","renderer","redrawUsers","container","tabs","search_engines","current_user_list","UsersList","on","_tmpl","map","c","Renderer","Scene","search","_select","_input","_form","_search","type","Search","_key","key","getSearchTitle","className","getBgClass","_el","setSearchEngine","submit","val","search_engine","mouseenter","mouseleave","bins","_bin","Bin","elementDropped","_mainDiv","siblings","is","slideUp","_t","_models","where","_model","highlightModel","mouseout","unhighlightAll","dragDrop","err","e","preventDefault","touch","originalEvent","changedTouches","off","canvas_$","offset","w","width","h","height","pageX","left","pageY","top","onMouseMove","div","document","createElement","appendChild","cloneNode","dropData","text/html","innerHTML","onMouseDown","onMouseUp","dataTransfer","setData","lastsearch","lastval","regexpFromTextOrArray","source","tab","render","_text","i18n","language","substr","onStatusChange","listClasses","split","classes","i","_d","outerHeight","css","getUUID4","replace","r","Math","random","v","toString","getUID","pad","n","Date","ID_AUTO_INCREMENT","ID_BASE","getUTCFullYear","getUTCMonth","getUTCDate","_base","_n","_uidbase","test","img","Image","src","res","inherit","_baseClass","_callbefore","_class","apply","slice","_init","_initialized","extend","replaceText","makeReplaceFunc","l","k","charsrx","txt","toLowerCase","remrx","j","remsrc","charsub","getSource","inp","removeChars","String","fromCharCode","RegExp","_textOrArray","testrx","replacerx","isempty","_replace","text","_MIN_DRAG_DISTANCE","_NODE_BUTTON_WIDTH","_EDGE_BUTTON_INNER","_EDGE_BUTTON_OUTER","_CLICKMODE_ADDNODE","_CLICKMODE_STARTEDGE","_CLICKMODE_ENDEDGE","_NODE_SIZE_STEP","LN2","_MIN_SCALE","_MAX_SCALE","_MOUSEMOVE_RATE","_DOUBLETAP_DELAY","_DOUBLETAP_DISTANCE","_USER_PLACEHOLDER","default_user_color","_BOOKMARKLET_CODE","_maxlength","drawEditBox","_options","_coords","_path","_xmargin","_selector","tooltip_width","tooltip_padding","_height","_isLeft","x","paper","view","center","_left","tooltip_arrow_length","_right","_top","y","tooltip_margin","max","tooltip_arrow_width","min","_bottom","segments","point","add","closed","fillColor","GradientColor","Gradient","tooltip_top_color","tooltip_bottom_color","Backbone","guid","RenkanModel","RelationalModel","idAttribute","constructor","id","prepare","validate","addReference","_propName","_list","_default","_element","User","toJSON","Node","relations","HasOne","relatedModel","created_by","position","hidden","Edge","from","to","View","isArray","zoom_level","RosterUser","blacklist","HasMany","reverseRelation","includeInJSON","_props","_user","findOrCreate","addNode","_node","addEdge","_edge","addView","_view","removeNode","remove","removeEdge","_project","users","nodes","edges","views","_item","initialize","filter","json","clone","attributes","Model","Collection","omit","site_id","model","navigator","userLanguage","manual_save","size_bug_fix","force_resize","allow_double_click","zoom_on_scroll","element_delete_delay","autoscale_padding","default_view","user_name_editable","show_minimap","minimap_width","minimap_height","minimap_padding","minimap_background_color","minimap_border_color","minimap_highlight_color","minimap_highlight_weight","buttons_background","buttons_label_color","buttons_label_font_size","show_node_circles","clip_node_images","node_images_fill_mode","node_size_base","node_stroke_width","selected_node_stroke_width","node_fill_color","highlighted_node_fill_color","node_label_distance","node_label_max_length","label_untitled_nodes","edge_stroke_width","selected_edge_stroke_width","edge_label_distance","edge_label_max_length","edge_arrow_length","edge_arrow_width","edge_gap_in_bundles","label_untitled_edges","tooltip_border_color","tooltip_border_width","uploaded_image_max_kb","fr","Edit Node","Edit Edge","Title:","URI:","Description:","From:","To:","Image URL:","Choose Image File:","Full Screen","Add Node","Add Edge","Save Project","Open Project","Auto-save enabled","Connection lost","Created by:","Zoom In","Zoom Out","Edit","Remove","Cancel deletion","Link to another node","Enlarge","Shrink","Click on the background canvas to add a node","Click on a first node to start the edge","Click on a second node to complete the edge","Wikipedia","Wikipedia in ","French","English","Japanese","Untitled project","Lignes de Temps","Loading, please wait","Edge color:","Node color:","Choose color","Change edge direction","Do you really wish to remove node ","Do you really wish to remove edge ","This file is not an image","Image size must be under ","Size:","KB","Choose from vocabulary:","SKOS Documentation properties","has note","has example","has definition","SKOS Semantic relations","has broader","has narrower","has related","Dublin Core Metadata","has contributor","covers","created by","has date","published by","has source","has subject","Dragged resource","Search the Web","Search in Bins","Close bin","Refresh bin","(untitled)","Select contents:","Drag items from this website, drop them in Renkan","Drag this button to your bookmark bar. When on a third-party website, click it to enable drag-and-drop from the website to Renkan.","Shapes available","Circle","Square","Diamond","Hexagone","Ellipse","Star","Zoom Fit","Download Project","Zoom Save","View saved zoom","Renkan 'Drag-to-Add' bookmarklet","(unknown user)","<unknown user>","Search in graph","Search in ","jsonIO","_proj","http_method","_load","redrawActive","set","loading_status","_data","save_status","fixSize","_save","ajax","contentType","JSON","stringify","success","_thrSave","throttle","setTimeout","changedAttributes","hasChanged","jsonIOSaveOnClick","_saveWarn","_onLeave","getdata","rx","matches","location","hash","match","beforeSend","autoScale","_checkLeave","removeClass","save","hasClass","Ldt","ProjectBin","ldt_type","Resclass","console","error","tagTemplate","annotationTemplate","proj_id","project_id","ldt_platform","searchbase","highlight","_e","convertTC","_ms","_res","_totalSeconds","abs","floor","_hours","_minutes","_seconds","_html","_projtitle","meta","count","tags","_tag","_title","htitle","encodedtitle","encodeURIComponent","annotations","_annotation","_description","content","_duration","end","begin","_img","hdescription","start","duration","mediaid","media","annotationid","show","dataType","lang","_q","ResultsBin","segmentTemplate","max_results","highlightrx","objects","_segment","_begin","start_ts","_end","iri_id","element_id","format","q","limit","ResourceList","resultTemplate","list","trim","_match","langs","en","ja","query","_result","encodeURI","snippet","define","_BaseRepresentation","_renderer","_changeBinding","redraw","change","_removeBinding","removeRepresentation","defer","_selectBinding","select","_unselectBinding","unselect","_super","_func","moveTo","trigger","unhighlight","mousedown","mouseup","value","getUtils","getRenderer","requtils","BaseRepresentation","_BaseButton","_pos","sector","_newTarget","source_representation","builders","circle","getShape","Path","getImageShape","radius","rectangle","Rectangle","ellipse","polygon","RegularPolygon","diamond","d","SQRT2","rotate","star","svg","path","ShapeBuilder","NodeRepr","node_layer","activate","buildShape","strokeWidth","h_ratio","labels_$","normal_buttons","NodeEditButton","NodeRemoveButton","NodeLinkButton","NodeEnlargeButton","NodeShrinkButton","pending_delete_buttons","NodeRevertButton","all_buttons","active_buttons","last_circle_radius","minimap","minimap_circle","__representation","miniframe","node_group","addChild","changed","shapeBuilder","sendToBack","_model_coords","Point","_baseRadius","exp","is_dragging","paper_coords","toPaperCoords","circle_radius","scale","forEach","b","setSectorSize","node_image","subtract","image_delta","multiply","old_act_btn","opacity","dashArray","selected","isEditable","highlighted","_color","strokeColor","_pc","lastImage","showImage","minipos","toMinimapCoords","miniradius","minisize","Size","fitBounds","dontRedrawEdges","ed","repr","getRepresentationByModel","from_representation","to_representation","_image","image_cache","clipPath","hasClipPath","_clip","baseRadius","centerPoint","instructions","lastCoords","minX","Infinity","minY","maxX","maxY","transformCoords","tabc","relative","newCoords","parseFloat","isY","instr","coords","lineTo","cubicCurveTo","quadraticCurveTo","_raster","Raster","locked","Group","clipped","_circleClip","divide","insertAbove","paperShift","_delta","openEditor","removeRepresentationsOfType","_editor","addRepresentation","draw","_uri","hideButtons","buttons_timeout","undefined","textToReplace","hlvalue","throttledPaperDraw","saveCoords","toModelCoords","_event","_isTouch","unselectAll","click_target","edge_layer","bundle","addToBundles","line","arrow","arrow_angle","EdgeEditButton","EdgeRemoveButton","EdgeRevertButton","minimap_line","_p0a","_p1a","_v","_r","_u","_ortho","_group_pos","getPosition","_p0b","_p1b","_a","angle","_textdelta","_handle","handleIn","handleOut","_textpos","transform","-moz-transform","-webkit-transform","text_angle","reject","TempEdge","_p0","_p1","end_pos","_c","_hitResult","hitTest","findTarget","_endDrag","item","_target","_destmodel","_BaseEditor","buttons_layer","editor_block","_pts","range","editor_$","BaseEditor","NodeEditor","readOnlyTemplate","_created_by","_template","_image_placeholder","_size","closeEditor","onFieldChange","keyCode","files","FileReader","alert","onload","target","result","readAsDataURL","focus","_picker","hover","shiftSize","_newsize","titlehtml","load","EdgeEditor","_from_model","_to_model","BaseButton","_NodeButton","sectorInner","lastSectorInner","drawSector","startAngle","endAngle","imageName","clearTimeout","NodeButton","delid","delete_list","time","valueOf","confirm","unset","_off","_point","addTempEdge","MiniFrame","filesaver","representations","notif_$","setup","initialScale","totalScroll","mouse_down","selected_target","Layer","background_layer","topleft","bounds","bottomRight","cliprectangle","bundles","click_mode","_allowScroll","_originalScale","_zooming","_lastTapX","_lastTapY","icon_cache","imgname","throttledMouseMove","mousemove","mousewheel","onScroll","touchstart","_touches","touches","_lastTap","pow","onDoubleClick","touchmove","_newScale","_scaleRatio","_newOffset","setScale","touchend","dblclick","dragover","dragenter","dragleave","drop","types","t","getData","parse","bindClick","selector","fname","evt","last","fadeIn","delay","fadeOut","mouseover","onResize","_ratio","newWidth","newHeight","ratioH","delta","ratioW","resizeZoom","_thRedraw","addRepresentations","_thRedrawUsers","el","_delay","$cpwrapper","$cplist","$this","rxs","_now","findWhere","delete_scheduled","rescaleMinimap","_repr","_inR","_outR","_startAngle","_endAngle","_padding","_imgname","_caption","_startRads","PI","_endRads","_startdx","sin","_startdy","cos","_startXIn","_startYIn","_startXOut","_startYOut","_enddx","_enddy","_endXIn","_endYIn","_endXOut","_endYOut","_centerR","_centerRads","_centerX","_centerY","_centerXIn","_centerXOut","_centerYIn","_centerYOut","_textX","_textY","arcTo","PointText","characterStyle","fontSize","paragraphStyle","justification","visible","_visible","_restPos","_grp","_imgdelta","_currentPos","pivot","_edgeRepr","_bundle","_er","_dir","indexOf","savebtn","tip","_offset","force_view","_xx","_yy","_minx","_miny","_maxx","_maxy","_scale","at","redrawMiniframe","bottomright","_type","RendererType","_collection","userTemplate","allUsers","models","ulistHtml","$userpanel","$name","$cpitems","$colorsquare","$input","blur","empty","parent","name","background","_representation","_representations","_from","_tmpEdge","last_point","_scrolldelta","SQRT1_2","defaultDropHandler","newNode","tweetdiv","_svgimgs","_svgpaths","_imgs","_as","fields","drop_enhancer","jsondata","drop_handler","_nodedata","fullScreen","_isFull","mozFullScreen","webkitIsFullScreen","_requestMethods","_cancelMethods","widthAft","heightAft","viewSize","zoomOut","zoomIn","_scaleWidth","_scaleHeight","addNodeBtn","addEdgeBtn","exportProject","projectJSON","projectId","fileNameToSaveAs","space_id","objId","idsMap","projectJSONStr","blob","Blob","foldBins","sizeAft","foldBinsButton","sizeBef","animate","open","require","config","paths","jquery","underscore","startRenkan"],"mappings":"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","sourcesContent":["this[\"renkanJST\"] = this[\"renkanJST\"] || {};\n\nthis[\"renkanJST\"][\"templates/colorpicker.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape;\nwith (obj) {\n__p += '<li data-color=\"' +\n((__t = (c)) == null ? '' : __t) +\n'\" style=\"background: ' +\n((__t = (c)) == null ? '' : __t) +\n'\"></li>';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/edgeeditor.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape, __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\nwith (obj) {\n__p += '<h2>\\n <span class=\"Rk-CloseX\">×</span>' +\n__e(renkan.translate(\"Edit Edge\")) +\n'</span>\\n</h2>\\n<p>\\n <label>' +\n__e(renkan.translate(\"Title:\")) +\n'</label>\\n <input class=\"Rk-Edit-Title\" type=\"text\" value=\"' +\n__e(edge.title) +\n'\" />\\n</p>\\n';\n if (options.show_edge_editor_uri) { ;\n__p += '\\n <p>\\n <label>' +\n__e(renkan.translate(\"URI:\")) +\n'</label>\\n <input class=\"Rk-Edit-URI\" type=\"text\" value=\"' +\n__e(edge.uri) +\n'\" />\\n <a class=\"Rk-Edit-Goto\" href=\"' +\n__e(edge.uri) +\n'\" target=\"_blank\"></a>\\n </p>\\n ';\n if (options.properties.length) { ;\n__p += '\\n <p>\\n <label>' +\n__e(renkan.translate(\"Choose from vocabulary:\")) +\n'</label>\\n <select class=\"Rk-Edit-Vocabulary\">\\n ';\n _.each(options.properties, function(ontology) { ;\n__p += '\\n <option class=\"Rk-Edit-Vocabulary-Class\" value=\"\">\\n ' +\n__e( renkan.translate(ontology.label) ) +\n'\\n </option>\\n ';\n _.each(ontology.properties, function(property) { var uri = ontology[\"base-uri\"] + property.uri; ;\n__p += '\\n <option class=\"Rk-Edit-Vocabulary-Property\" value=\"' +\n__e( uri ) +\n'\"\\n ';\n if (uri === edge.uri) { ;\n__p += ' selected';\n } ;\n__p += '>\\n ' +\n__e( renkan.translate(property.label) ) +\n'\\n </option>\\n ';\n }) ;\n__p += '\\n ';\n }) ;\n__p += '\\n </select>\\n </p>\\n';\n } } ;\n__p += '\\n';\n if (options.show_edge_editor_color) { ;\n__p += '\\n <div class=\"Rk-Editor-p\">\\n <span class=\"Rk-Editor-Label\">' +\n__e(renkan.translate(\"Edge color:\")) +\n'</span>\\n <div class=\"Rk-Edit-ColorPicker-Wrapper\">\\n <span class=\"Rk-Edit-Color\" style=\"background: <%-edge.color%>;\">\\n <span class=\"Rk-Edit-ColorTip\"></span>\\n </span>\\n ' +\n((__t = ( renkan.colorPicker )) == null ? '' : __t) +\n'\\n <span class=\"Rk-Edit-ColorPicker-Text\">' +\n__e( renkan.translate(\"Choose color\") ) +\n'</span>\\n </div>\\n </div>\\n';\n } ;\n__p += '\\n';\n if (options.show_edge_editor_direction) { ;\n__p += '\\n <p>\\n <span class=\"Rk-Edit-Direction\">' +\n__e( renkan.translate(\"Change edge direction\") ) +\n'</span>\\n </p>\\n';\n } ;\n__p += '\\n';\n if (options.show_edge_editor_nodes) { ;\n__p += '\\n <p>\\n <span class=\"Rk-Editor-Label\">' +\n__e(renkan.translate(\"From:\")) +\n'</span>\\n <span class=\"Rk-UserColor\" style=\"background: ' +\n__e(edge.from_color) +\n';\"></span>\\n ' +\n__e( shortenText(edge.from_title, 25) ) +\n'\\n </p>\\n <p>\\n <span class=\"Rk-Editor-Label\">' +\n__e(renkan.translate(\"To:\")) +\n'</span>\\n <span class=\"Rk-UserColor\" style=\"background: >%-edge.to_color%>;\"></span>\\n ' +\n__e( shortenText(edge.to_title, 25) ) +\n'\\n </p>\\n';\n } ;\n__p += '\\n';\n if (options.show_edge_editor_creator && edge.has_creator) { ;\n__p += '\\n <p>\\n <span class=\"Rk-Editor-Label\">' +\n__e(renkan.translate(\"Created by:\")) +\n'</span>\\n <span class=\"Rk-UserColor\" style=\"background: <%-edge.created_by_color%>;\"></span>\\n ' +\n__e( shortenText(edge.created_by_title, 25) ) +\n'\\n </p>\\n';\n } ;\n__p += '\\n';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/edgeeditor_readonly.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape, __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\nwith (obj) {\n__p += '<h2>\\n <span class=\"Rk-CloseX\">×</span>\\n ';\n if (options.show_edge_tooltip_color) { ;\n__p += '\\n <span class=\"Rk-UserColor\" style=\"background: ' +\n__e( edge.color ) +\n';\"></span>\\n ';\n } ;\n__p += '\\n <span class=\"Rk-Display-Title\">\\n ';\n if (edge.uri) { ;\n__p += '\\n <a href=\"' +\n__e(edge.uri) +\n'\" target=\"_blank\">\\n ';\n } ;\n__p += '\\n ' +\n__e(edge.title) +\n'\\n ';\n if (edge.uri) { ;\n__p += ' </a> ';\n } ;\n__p += '\\n </span>\\n</h2>\\n';\n if (options.show_edge_tooltip_uri && edge.uri) { ;\n__p += '\\n <p class=\"Rk-Display-URI\">\\n <a href=\"' +\n__e(edge.uri) +\n'\" target=\"_blank\">' +\n__e( edge.short_uri ) +\n'</a>\\n </p>\\n';\n } ;\n__p += '\\n<p>' +\n__e(edge.description) +\n'</p>\\n';\n if (options.show_edge_tooltip_nodes) { ;\n__p += '\\n <p>\\n <span class=\"Rk-Editor-Label\">' +\n__e(renkan.translate(\"From:\")) +\n'</span>\\n <span class=\"Rk-UserColor\" style=\"background: ' +\n__e( edge.from_color ) +\n';\"></span>\\n ' +\n__e( shortenText(edge.from_title, 25) ) +\n'\\n </p>\\n <p>\\n <span class=\"Rk-Editor-Label\">' +\n__e(renkan.translate(\"To:\")) +\n'</span>\\n <span class=\"Rk-UserColor\" style=\"background: ' +\n__e( edge.to_color ) +\n';\"></span>\\n ' +\n__e( shortenText(edge.to_title, 25) ) +\n'\\n </p>\\n';\n } ;\n__p += '\\n';\n if (options.show_edge_tooltip_creator && edge.has_creator) { ;\n__p += '\\n <p>\\n <span class=\"Rk-Editor-Label\">' +\n__e(renkan.translate(\"Created by:\")) +\n'</span>\\n <span class=\"Rk-UserColor\" style=\"background: ' +\n__e( edge.created_by_color ) +\n';\"></span>\\n ' +\n__e( shortenText(edge.created_by_title, 25) ) +\n'\\n </p>\\n';\n } ;\n__p += '\\n';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/ldtjson-bin/annotationtemplate.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape;\nwith (obj) {\n__p += '<li class=\"Rk-Bin-Item\" draggable=\"true\"\\n data-image=\"' +\n__e( Rkns.Utils.getFullURL(image) ) +\n'\"\\n data-uri=\"' +\n((__t = (ldt_platform)) == null ? '' : __t) +\n'ldtplatform/ldt/front/player/' +\n((__t = (mediaid)) == null ? '' : __t) +\n'/#id=' +\n((__t = (annotationid)) == null ? '' : __t) +\n'\"\\n data-title=\"' +\n__e(title) +\n'\" data-description=\"' +\n__e(description) +\n'\">\\n\\n <img class=\"Rk-Ldt-Annotation-Icon\" src=\"' +\n((__t = (image)) == null ? '' : __t) +\n'\" />\\n <h4>' +\n((__t = (htitle)) == null ? '' : __t) +\n'</h4>\\n <p>' +\n((__t = (hdescription)) == null ? '' : __t) +\n'</p>\\n <p>Start: ' +\n((__t = (start)) == null ? '' : __t) +\n', End: ' +\n((__t = (end)) == null ? '' : __t) +\n', Duration: ' +\n((__t = (duration)) == null ? '' : __t) +\n'</p>\\n <div class=\"Rk-Clear\"></div>\\n</li>\\n';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/ldtjson-bin/segmenttemplate.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape;\nwith (obj) {\n__p += '<li class=\"Rk-Bin-Item\" draggable=\"true\"\\n data-image=\"' +\n__e( Rkns.Utils.getFullURL(image) ) +\n'\"\\n data-uri=\"' +\n((__t = (ldt_platform)) == null ? '' : __t) +\n'ldtplatform/ldt/front/player/' +\n((__t = (mediaid)) == null ? '' : __t) +\n'/#id=' +\n((__t = (annotationid)) == null ? '' : __t) +\n'\"\\n data-title=\"' +\n__e(title) +\n'\" data-description=\"' +\n__e(description) +\n'\">\\n\\n <img class=\"Rk-Ldt-Annotation-Icon\" src=\"' +\n((__t = (image)) == null ? '' : __t) +\n'\" />\\n <h4>' +\n((__t = (htitle)) == null ? '' : __t) +\n'</h4>\\n <p>' +\n((__t = (hdescription)) == null ? '' : __t) +\n'</p>\\n <p>Start: ' +\n((__t = (start)) == null ? '' : __t) +\n', End: ' +\n((__t = (end)) == null ? '' : __t) +\n', Duration: ' +\n((__t = (duration)) == null ? '' : __t) +\n'</p>\\n <div class=\"Rk-Clear\"></div>\\n</li>\\n';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/ldtjson-bin/tagtemplate.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape;\nwith (obj) {\n__p += '<li class=\"Rk-Bin-Item\" draggable=\"true\"\\n data-image=\"' +\n__e( Rkns.Utils.getFullURL(static_url+'img/ldt-tag.png') ) +\n'\"\\n data-uri=\"' +\n((__t = (ldt_platform)) == null ? '' : __t) +\n'ldtplatform/ldt/front/search/?search=' +\n((__t = (encodedtitle)) == null ? '' : __t) +\n'&field=all\"\\n data-title=\"' +\n__e(title) +\n'\" data-description=\"Tag \\'' +\n__e(title) +\n'\\'\">\\n\\n <img class=\"Rk-Ldt-Tag-Icon\" src=\"' +\n__e(static_url) +\n'img/ldt-tag.png\" />\\n <h4>' +\n((__t = (htitle)) == null ? '' : __t) +\n'</h4>\\n <div class=\"Rk-Clear\"></div>\\n</li>\\n';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/list-bin.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape, __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\nwith (obj) {\n__p += '<li class=\"Rk-Bin-Item Rk-ResourceList-Item\" draggable=\"true\"\\n data-uri=\"' +\n__e(url) +\n'\" data-title=\"' +\n__e(title) +\n'\"\\n data-description=\"' +\n__e(description) +\n'\"\\n ';\n if (image) { ;\n__p += '\\n data-image=\"' +\n__e( Rkns.Utils.getFullURL(image) ) +\n'\"\\n ';\n } else { ;\n__p += '\\n data-image=\"\"\\n ';\n } ;\n__p += '\\n>';\n if (image) { ;\n__p += '\\n <img class=\"Rk-ResourceList-Image\" src=\"' +\n__e(image) +\n'\" />\\n';\n } ;\n__p += '\\n<h4 class=\"Rk-ResourceList-Title\">\\n ';\n if (url) { ;\n__p += '\\n <a href=\"' +\n__e(url) +\n'\" target=\"_blank\">\\n ';\n } ;\n__p += '\\n ' +\n((__t = (htitle)) == null ? '' : __t) +\n'\\n ';\n if (url) { ;\n__p += '</a>';\n } ;\n__p += '\\n </h4>\\n ';\n if (description) { ;\n__p += '\\n <p class=\"Rk-ResourceList-Description\">' +\n((__t = (hdescription)) == null ? '' : __t) +\n'</p>\\n ';\n } ;\n__p += '\\n ';\n if (image) { ;\n__p += '\\n <div style=\"clear: both;\"></div>\\n ';\n } ;\n__p += '\\n</li>\\n';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/main.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape, __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\nwith (obj) {\n\n if (options.show_bins) { ;\n__p += '\\n <div class=\"Rk-Bins\">\\n <div class=\"Rk-Bins-Head\">\\n <h2 class=\"Rk-Bins-Title\">' +\n__e( translate(\"Select contents:\")) +\n'</h2>\\n <form class=\"Rk-Web-Search-Form Rk-Search-Form\">\\n <input class=\"Rk-Web-Search-Input Rk-Search-Input\" type=\"search\"\\n placeholder=\"' +\n__e( translate('Search the Web') ) +\n'\" />\\n <div class=\"Rk-Search-Select\">\\n <div class=\"Rk-Search-Current\"></div>\\n <ul class=\"Rk-Search-List\"></ul>\\n </div>\\n <input type=\"submit\" value=\"\"\\n class=\"Rk-Web-Search-Submit Rk-Search-Submit\" title=\"' +\n__e( translate('Search the Web') ) +\n'\" />\\n </form>\\n <form class=\"Rk-Bins-Search-Form Rk-Search-Form\">\\n <input class=\"Rk-Bins-Search-Input Rk-Search-Input\" type=\"search\"\\n placeholder=\"' +\n__e( translate('Search in Bins') ) +\n'\" /> <input\\n type=\"submit\" value=\"\"\\n class=\"Rk-Bins-Search-Submit Rk-Search-Submit\"\\n title=\"' +\n__e( translate('Search in Bins') ) +\n'\" />\\n </form>\\n </div>\\n <ul class=\"Rk-Bin-List\"></ul>\\n </div>\\n';\n } ;\n__p += ' ';\n if (options.show_editor) { ;\n__p += '\\n <div class=\"Rk-Render Rk-Render-';\n if (options.show_bins) { ;\n__p += 'Panel';\n } else { ;\n__p += 'Full';\n } ;\n__p += '\"></div>\\n';\n } ;\n__p += '\\n';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/nodeeditor.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape, __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\nwith (obj) {\n__p += '<h2>\\n <span class=\"Rk-CloseX\">×</span>' +\n__e(renkan.translate(\"Edit Node\")) +\n'</span>\\n</h2>\\n<p>\\n <label>' +\n__e(renkan.translate(\"Title:\")) +\n'</label>\\n <input class=\"Rk-Edit-Title\" type=\"text\" value=\"' +\n__e(node.title) +\n'\" />\\n</p>\\n';\n if (options.show_node_editor_uri) { ;\n__p += '\\n <p>\\n <label>' +\n__e(renkan.translate(\"URI:\")) +\n'</label>\\n <input class=\"Rk-Edit-URI\" type=\"text\" value=\"' +\n__e(node.uri) +\n'\" />\\n <a class=\"Rk-Edit-Goto\" href=\"' +\n__e(node.uri) +\n'\" target=\"_blank\"></a>\\n </p>\\n';\n } ;\n__p += ' ';\n if (options.show_node_editor_description) { ;\n__p += '\\n <p>\\n <label>' +\n__e(renkan.translate(\"Description:\")) +\n'</label>\\n <textarea class=\"Rk-Edit-Description\">' +\n__e(node.description) +\n'</textarea>\\n </p>\\n';\n } ;\n__p += ' ';\n if (options.show_node_editor_size) { ;\n__p += '\\n <p>\\n <span class=\"Rk-Editor-Label\">' +\n__e(renkan.translate(\"Size:\")) +\n'</span>\\n <a href=\"#\" class=\"Rk-Edit-Size-Down\">-</a>\\n <span class=\"Rk-Edit-Size-Value\">' +\n__e(node.size) +\n'</span>\\n <a href=\"#\" class=\"Rk-Edit-Size-Up\">+</a>\\n </p>\\n';\n } ;\n__p += ' ';\n if (options.show_node_editor_color) { ;\n__p += '\\n <div class=\"Rk-Editor-p\">\\n <span class=\"Rk-Editor-Label\">\\n ' +\n__e(renkan.translate(\"Node color:\")) +\n'</span>\\n <div class=\"Rk-Edit-ColorPicker-Wrapper\">\\n <span class=\"Rk-Edit-Color\" style=\"background: ' +\n__e(node.color) +\n';\">\\n <span class=\"Rk-Edit-ColorTip\"></span>\\n </span>\\n ' +\n((__t = ( renkan.colorPicker )) == null ? '' : __t) +\n'\\n <span class=\"Rk-Edit-ColorPicker-Text\">' +\n__e( renkan.translate(\"Choose color\") ) +\n'</span>\\n </div>\\n </div>\\n';\n } ;\n__p += ' ';\n if (options.show_node_editor_image) { ;\n__p += '\\n <div class=\"Rk-Edit-ImgWrap\">\\n <div class=\"Rk-Edit-ImgPreview\">\\n <img src=\"' +\n__e(node.image || node.image_placeholder) +\n'\" />\\n ';\n if (node.clip_path) { ;\n__p += '\\n <svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewbox=\"0 0 1 1\" preserveAspectRatio=\"none\">\\n <path style=\"stroke-width: .02; stroke:red; fill-opacity:.3; fill:red;\" d=\"' +\n__e( node.clip_path ) +\n'\" />\\n </svg>\\n ';\n };\n__p += '\\n </div>\\n </div>\\n <p>\\n <label>' +\n__e(renkan.translate(\"Image URL:\")) +\n'</label>\\n <div>\\n <a class=\"Rk-Edit-Image-Del\" href=\"#\"></a>\\n <input class=\"Rk-Edit-Image\" type=\"text\" value=\\'' +\n__e(node.image) +\n'\\' />\\n </div>\\n </p>\\n';\n if (options.allow_image_upload) { ;\n__p += '\\n <p>\\n <label>' +\n__e(renkan.translate(\"Choose Image File:\")) +\n'</label>\\n <input class=\"Rk-Edit-Image-File\" type=\"file\" accept=\"image/*\" />\\n </p>\\n';\n };\n\n } ;\n__p += ' ';\n if (options.show_node_editor_creator && node.has_creator) { ;\n__p += '\\n <p>\\n <span class=\"Rk-Editor-Label\">' +\n__e(renkan.translate(\"Created by:\")) +\n'</span>\\n <span class=\"Rk-UserColor\" style=\"background: ' +\n__e(node.created_by_color) +\n';\"></span>\\n ' +\n__e( shortenText(node.created_by_title, 25) ) +\n'\\n </p>\\n';\n } ;\n__p += ' ';\n if (options.change_shapes) { ;\n__p += '\\n <p>\\n <label>' +\n__e(renkan.translate(\"Shapes available\")) +\n':</label>\\n <select class=\"Rk-Edit-Shape\">\\n <option class=\"Rk-Edit-Vocabulary-Property\" value=\"circle\"';\n if (node.shape === \"circle\") { ;\n__p += ' selected';\n } ;\n__p += '>\\n ' +\n__e( renkan.translate(\"Circle\") ) +\n'\\n </option>\\n <option class=\"Rk-Edit-Vocabulary-Property\" value=\"rectangle\"';\n if (node.shape === \"rectangle\") { ;\n__p += ' selected';\n } ;\n__p += '>\\n ' +\n__e( renkan.translate(\"Square\") ) +\n'\\n </option>\\n <option class=\"Rk-Edit-Vocabulary-Property\" value=\"diamond\"';\n if (node.shape === \"diamond\") { ;\n__p += ' selected';\n } ;\n__p += '>\\n ' +\n__e( renkan.translate(\"Diamond\") ) +\n'\\n </option>\\n <option class=\"Rk-Edit-Vocabulary-Property\" value=\"polygon\"';\n if (node.shape === \"polygon\") { ;\n__p += ' selected';\n } ;\n__p += '>\\n ' +\n__e( renkan.translate(\"Hexagone\") ) +\n'\\n </option>\\n <option class=\"Rk-Edit-Vocabulary-Property\" value=\"ellipse\"';\n if (node.shape === \"ellipse\") { ;\n__p += ' selected';\n } ;\n__p += '>\\n ' +\n__e( renkan.translate(\"Ellipse\") ) +\n'\\n </option>\\n <option class=\"Rk-Edit-Vocabulary-Property\" value=\"star\"';\n if (node.shape === \"star\") { ;\n__p += ' selected';\n } ;\n__p += '>\\n ' +\n__e( renkan.translate(\"Star\") ) +\n'\\n </option>\\n </select>\\n </p>\\n';\n } ;\n__p += '\\n';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/nodeeditor_readonly.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape, __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\nwith (obj) {\n__p += '<h2>\\n <span class=\"Rk-CloseX\">×</span>\\n ';\n if (options.show_node_tooltip_color) { ;\n__p += '\\n <span class=\"Rk-UserColor\" style=\"background: ' +\n__e(node.color) +\n';\"></span>\\n ';\n } ;\n__p += '\\n <span class=\"Rk-Display-Title\">\\n ';\n if (node.uri) { ;\n__p += '\\n <a href=\"' +\n__e(node.uri) +\n'\" target=\"_blank\">\\n ';\n } ;\n__p += '\\n ' +\n__e(node.title) +\n'\\n ';\n if (node.uri) { ;\n__p += '</a>';\n } ;\n__p += '\\n </span>\\n</h2>\\n';\n if (node.uri && options.show_node_tooltip_uri) { ;\n__p += '\\n <p class=\"Rk-Display-URI\">\\n <a href=\"' +\n__e(node.uri) +\n'\" target=\"_blank\">' +\n__e(node.short_uri) +\n'</a>\\n </p>\\n';\n } ;\n__p += ' ';\n if (options.show_node_tooltip_description) { ;\n__p += '\\n <p class=\"Rk-Display-Description\">' +\n__e(node.description) +\n'</p>\\n';\n } ;\n__p += ' ';\n if (node.image && options.show_node_tooltip_image) { ;\n__p += '\\n <img class=\"Rk-Display-ImgPreview\" src=\"' +\n__e(node.image) +\n'\" />\\n';\n } ;\n__p += ' ';\n if (node.has_creator && options.show_node_tooltip_creator) { ;\n__p += '\\n <p>\\n <span class=\"Rk-Editor-Label\">' +\n__e(renkan.translate(\"Created by:\")) +\n'</span>\\n <span class=\"Rk-UserColor\" style=\"background: ' +\n__e(node.created_by_color) +\n';\"></span>\\n ' +\n__e( shortenText(node.created_by_title, 25) ) +\n'\\n </p>\\n';\n } ;\n__p += '\\n';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/scene.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape, __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\nwith (obj) {\n\n if (options.show_top_bar) { ;\n__p += '\\n <div class=\"Rk-TopBar\">\\n <div class=\"loader\"></div>\\n ';\n if (!options.editor_mode) { ;\n__p += '\\n <h2 class=\"Rk-PadTitle\">\\n ' +\n__e( project.get(\"title\") || translate(\"Untitled project\")) +\n'\\n </h2>\\n ';\n } else { ;\n__p += '\\n <input type=\"text\" class=\"Rk-PadTitle\" value=\"' +\n__e( project.get('title') || '' ) +\n'\" placeholder=\"' +\n__e(translate('Untitled project')) +\n'\" />\\n ';\n } ;\n__p += '\\n ';\n if (options.show_user_list) { ;\n__p += '\\n <div class=\"Rk-Users\">\\n <div class=\"Rk-CurrentUser\">\\n ';\n if (options.show_user_color) { ;\n__p += '\\n <div class=\"Rk-Edit-ColorPicker-Wrapper\">\\n <span class=\"Rk-CurrentUser-Color\">\\n ';\n if (options.user_color_editable) { ;\n__p += '\\n <span class=\"Rk-Edit-ColorTip\"></span>\\n ';\n } ;\n__p += '\\n </span>\\n ';\n if (options.user_color_editable) { print(colorPicker) } ;\n__p += '\\n </div>\\n ';\n } ;\n__p += '\\n <span class=\"Rk-CurrentUser-Name\"><unknown user></span>\\n </div>\\n <ul class=\"Rk-UserList\"></ul>\\n </div>\\n ';\n } ;\n__p += '\\n ';\n if (options.home_button_url) {;\n__p += '\\n <div class=\"Rk-TopBar-Separator\"></div>\\n <a class=\"Rk-TopBar-Button Rk-Home-Button\" href=\"' +\n__e( options.home_button_url ) +\n'\">\\n <div class=\"Rk-TopBar-Tooltip\">\\n <div class=\"Rk-TopBar-Tooltip-Contents\">\\n ' +\n__e( translate(options.home_button_title) ) +\n'\\n </div>\\n </div>\\n </a>\\n ';\n } ;\n__p += '\\n ';\n if (options.show_fullscreen_button) { ;\n__p += '\\n <div class=\"Rk-TopBar-Separator\"></div>\\n <div class=\"Rk-TopBar-Button Rk-FullScreen-Button\">\\n <div class=\"Rk-TopBar-Tooltip\">\\n <div class=\"Rk-TopBar-Tooltip-Contents\">\\n ' +\n__e(translate(\"Full Screen\")) +\n'\\n </div>\\n </div>\\n </div>\\n ';\n } ;\n__p += '\\n ';\n if (options.editor_mode) { ;\n__p += '\\n ';\n if (options.show_addnode_button) { ;\n__p += '\\n <div class=\"Rk-TopBar-Separator\"></div>\\n <div class=\"Rk-TopBar-Button Rk-AddNode-Button\">\\n <div class=\"Rk-TopBar-Tooltip\">\\n <div class=\"Rk-TopBar-Tooltip-Contents\">\\n ' +\n__e(translate(\"Add Node\")) +\n'\\n </div>\\n </div>\\n </div>\\n ';\n } ;\n__p += '\\n ';\n if (options.show_addedge_button) { ;\n__p += '\\n <div class=\"Rk-TopBar-Separator\"></div>\\n <div class=\"Rk-TopBar-Button Rk-AddEdge-Button\">\\n <div class=\"Rk-TopBar-Tooltip\">\\n <div class=\"Rk-TopBar-Tooltip-Contents\">\\n ' +\n__e(translate(\"Add Edge\")) +\n'\\n </div>\\n </div>\\n </div>\\n ';\n } ;\n__p += '\\n ';\n if (options.show_export_button) { ;\n__p += '\\n <div class=\"Rk-TopBar-Separator\"></div>\\n <div class=\"Rk-TopBar-Button Rk-Export-Button\">\\n <div class=\"Rk-TopBar-Tooltip\">\\n <div class=\"Rk-TopBar-Tooltip-Contents\">\\n ' +\n__e(translate(\"Download Project\")) +\n'\\n </div>\\n </div>\\n </div>\\n ';\n } ;\n__p += '\\n ';\n if (options.show_save_button) { ;\n__p += '\\n <div class=\"Rk-TopBar-Separator\"></div>\\n <div class=\"Rk-TopBar-Button Rk-Save-Button\">\\n <div class=\"Rk-TopBar-Tooltip\">\\n <div class=\"Rk-TopBar-Tooltip-Contents\"></div>\\n </div>\\n </div>\\n ';\n } ;\n__p += '\\n ';\n if (options.show_open_button) { ;\n__p += '\\n <div class=\"Rk-TopBar-Separator\"></div>\\n <div class=\"Rk-TopBar-Button Rk-Open-Button\">\\n <div class=\"Rk-TopBar-Tooltip\">\\n <div class=\"Rk-TopBar-Tooltip-Contents\">\\n ' +\n__e(translate(\"Open Project\")) +\n'\\n </div>\\n </div>\\n </div>\\n ';\n } ;\n__p += '\\n ';\n if (options.show_bookmarklet) { ;\n__p += '\\n <div class=\"Rk-TopBar-Separator\"></div>\\n <a class=\"Rk-TopBar-Button Rk-Bookmarklet-Button\" href=\"#\">\\n <div class=\"Rk-TopBar-Tooltip\">\\n <div class=\"Rk-TopBar-Tooltip-Contents\">\\n ' +\n__e(translate(\"Renkan \\'Drag-to-Add\\' bookmarklet\")) +\n'\\n </div>\\n </div>\\n </a>\\n <div class=\"Rk-TopBar-Separator\"></div>\\n ';\n } ;\n__p += '\\n ';\n } else { ;\n__p += '\\n ';\n if (options.show_export_button) { ;\n__p += '\\n <div class=\"Rk-TopBar-Separator\"></div>\\n <div class=\"Rk-TopBar-Button Rk-Export-Button\">\\n <div class=\"Rk-TopBar-Tooltip\">\\n <div class=\"Rk-TopBar-Tooltip-Contents\">\\n ' +\n__e(translate(\"Download Project\")) +\n'\\n </div>\\n </div>\\n </div>\\n <div class=\"Rk-TopBar-Separator\"></div>\\n ';\n } ;\n__p += '\\n ';\n }; ;\n__p += '\\n ';\n if (options.show_search_field) { ;\n__p += '\\n <form action=\"#\" class=\"Rk-GraphSearch-Form\">\\n <input type=\"search\" class=\"Rk-GraphSearch-Field\" placeholder=\"' +\n__e( translate('Search in graph') ) +\n'\" />\\n </form>\\n <div class=\"Rk-TopBar-Separator\"></div>\\n ';\n } ;\n__p += '\\n </div>\\n';\n } ;\n__p += '\\n<div class=\"Rk-Editing-Space';\n if (!options.show_top_bar) { ;\n__p += ' Rk-Editing-Space-Full';\n } ;\n__p += '\">\\n <div class=\"Rk-Labels\"></div>\\n <canvas class=\"Rk-Canvas\" ';\n if (options.resize) { ;\n__p += ' resize=\"\" ';\n } ;\n__p += '></canvas>\\n <div class=\"Rk-Notifications\"></div>\\n <div class=\"Rk-Editor\">\\n ';\n if (options.show_bins) { ;\n__p += '\\n <div class=\"Rk-Fold-Bins\">«</div>\\n ';\n } ;\n__p += '\\n ';\n if (options.show_zoom) { ;\n__p += '\\n <div class=\"Rk-ZoomButtons\">\\n <div class=\"Rk-ZoomIn\" title=\"' +\n__e(translate('Zoom In')) +\n'\"></div>\\n <div class=\"Rk-ZoomFit\" title=\"' +\n__e(translate('Zoom Fit')) +\n'\"></div>\\n <div class=\"Rk-ZoomOut\" title=\"' +\n__e(translate('Zoom Out')) +\n'\"></div>\\n ';\n if (options.editor_mode && options.save_view) { ;\n__p += '\\n <div class=\"Rk-ZoomSave\" title=\"' +\n__e(translate('Zoom Save')) +\n'\"></div>\\n ';\n } ;\n__p += '\\n ';\n if (options.save_view) { ;\n__p += '\\n <div class=\"Rk-ZoomSetSaved\" title=\"' +\n__e(translate('View saved zoom')) +\n'\"></div>\\n ';\n } ;\n__p += '\\n </div>\\n ';\n } ;\n__p += '\\n </div>\\n</div>\\n';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/search.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape;\nwith (obj) {\n__p += '<li class=\"' +\n((__t = ( className )) == null ? '' : __t) +\n'\" data-key=\"' +\n((__t = ( key )) == null ? '' : __t) +\n'\">' +\n((__t = ( title )) == null ? '' : __t) +\n'</li>';\n\n}\nreturn __p\n};\n\nthis[\"renkanJST\"][\"templates/wikipedia-bin/resulttemplate.html\"] = function(obj) {\nobj || (obj = {});\nvar __t, __p = '', __e = _.escape;\nwith (obj) {\n__p += '<li class=\"Rk-Wikipedia-Result Rk-Bin-Item\" draggable=\"true\"\\n data-uri=\"' +\n__e(url) +\n'\" data-title=\"Wikipedia: ' +\n__e(title) +\n'\"\\n data-description=\"' +\n__e(description) +\n'\"\\n data-image=\"' +\n__e( Rkns.Utils.getFullURL( static_url + 'img/wikipedia.png' ) ) +\n'\">\\n\\n <img class=\"Rk-Wikipedia-Icon\" src=\"' +\n__e(static_url) +\n'img/wikipedia.png\">\\n <h4 class=\"Rk-Wikipedia-Title\">\\n <a href=\"' +\n__e(url) +\n'\" target=\"_blank\">' +\n((__t = (htitle)) == null ? '' : __t) +\n'</a>\\n </h4>\\n <p class=\"Rk-Wikipedia-Snippet\">' +\n((__t = (hdescription)) == null ? '' : __t) +\n'</p>\\n</li>\\n';\n\n}\nreturn __p\n};","\n/* Declaring the Renkan Namespace Rkns and Default values */\n\n(function(root) {\n\n\"use strict\";\n\nif (typeof root.Rkns !== \"object\") {\n root.Rkns = {};\n}\n\nvar Rkns = root.Rkns;\nvar $ = Rkns.$ = root.jQuery;\nvar _ = Rkns._ = root._;\n\nRkns.pickerColors = [\"#8f1919\", \"#a80000\", \"#d82626\", \"#ff0000\", \"#e87c7c\", \"#ff6565\", \"#f7d3d3\", \"#fecccc\",\n \"#8f5419\", \"#a85400\", \"#d87f26\", \"#ff7f00\", \"#e8b27c\", \"#ffb265\", \"#f7e5d3\", \"#fee5cc\",\n \"#8f8f19\", \"#a8a800\", \"#d8d826\", \"#feff00\", \"#e8e87c\", \"#feff65\", \"#f7f7d3\", \"#fefecc\",\n \"#198f19\", \"#00a800\", \"#26d826\", \"#00ff00\", \"#7ce87c\", \"#65ff65\", \"#d3f7d3\", \"#ccfecc\",\n \"#198f8f\", \"#00a8a8\", \"#26d8d8\", \"#00feff\", \"#7ce8e8\", \"#65feff\", \"#d3f7f7\", \"#ccfefe\",\n \"#19198f\", \"#0000a8\", \"#2626d8\", \"#0000ff\", \"#7c7ce8\", \"#6565ff\", \"#d3d3f7\", \"#ccccfe\",\n \"#8f198f\", \"#a800a8\", \"#d826d8\", \"#ff00fe\", \"#e87ce8\", \"#ff65fe\", \"#f7d3f7\", \"#feccfe\",\n \"#000000\", \"#242424\", \"#484848\", \"#6d6d6d\", \"#919191\", \"#b6b6b6\", \"#dadada\", \"#ffffff\"];\n\nRkns.__renkans = [];\n\nvar _BaseBin = Rkns._BaseBin = function(_renkan, _opts) {\n if (typeof _renkan !== \"undefined\") {\n this.renkan = _renkan;\n this.renkan.$.find(\".Rk-Bin-Main\").hide();\n this.$ = Rkns.$('<li>')\n .addClass(\"Rk-Bin\")\n .appendTo(_renkan.$.find(\".Rk-Bin-List\"));\n this.title_icon_$ = Rkns.$('<span>')\n .addClass(\"Rk-Bin-Title-Icon\")\n .appendTo(this.$);\n\n var _this = this;\n\n Rkns.$('<a>')\n .attr({\n href: \"#\",\n title: _renkan.translate(\"Close bin\")\n })\n .addClass(\"Rk-Bin-Close\")\n .html('×')\n .appendTo(this.$)\n .click(function() {\n _this.destroy();\n if (!_renkan.$.find(\".Rk-Bin-Main:visible\").length) {\n _renkan.$.find(\".Rk-Bin-Main:last\").slideDown();\n }\n _renkan.resizeBins();\n return false;\n });\n Rkns.$('<a>')\n .attr({\n href: \"#\",\n title: _renkan.translate(\"Refresh bin\")\n })\n .addClass(\"Rk-Bin-Refresh\")\n .appendTo(this.$)\n .click(function() {\n _this.refresh();\n return false;\n });\n this.count_$ = Rkns.$('<div>')\n .addClass(\"Rk-Bin-Count\")\n .appendTo(this.$);\n this.title_$ = Rkns.$('<h2>')\n .addClass(\"Rk-Bin-Title\")\n .appendTo(this.$);\n this.main_$ = Rkns.$('<div>')\n .addClass(\"Rk-Bin-Main\")\n .appendTo(this.$)\n .html('<h4 class=\"Rk-Bin-Loading\">' + _renkan.translate(\"Loading, please wait\") + '</h4>');\n this.title_$.html(_opts.title || '(new bin)');\n this.renkan.resizeBins();\n\n if (_opts.auto_refresh) {\n window.setInterval(function() {\n _this.refresh();\n },_opts.auto_refresh);\n }\n }\n};\n\n_BaseBin.prototype.destroy = function() {\n this.$.detach();\n this.renkan.resizeBins();\n};\n\n/* Point of entry */\n\nvar Renkan = Rkns.Renkan = function(_opts) {\n var _this = this;\n\n Rkns.__renkans.push(this);\n\n this.options = _.defaults(_opts, Rkns.defaults, {templates: renkanJST});\n this.template = renkanJST['templates/main.html'];\n\n _.each(this.options.property_files,function(f) {\n Rkns.$.getJSON(f, function(data) {\n _this.options.properties = _this.options.properties.concat(data);\n });\n });\n\n this.read_only = this.options.read_only || !this.options.editor_mode;\n\n this.project = new Rkns.Models.Project();\n\n this.setCurrentUser = function (user_id, user_name) {\n \tthis.project.addUser({\n \t\t_id:user_id,\n \t\ttitle: user_name\n \t});\n \tthis.current_user = user_id;\n \tthis.renderer.redrawUsers();\n };\n\n if (typeof this.options.user_id !== \"undefined\") {\n this.current_user = this.options.user_id;\n }\n this.$ = Rkns.$(\"#\" + this.options.container);\n this.$\n .addClass(\"Rk-Main\")\n .html(this.template(this));\n\n this.tabs = [];\n this.search_engines = [];\n\n this.current_user_list = new Rkns.Models.UsersList();\n\n this.current_user_list.on(\"add remove\", function() {\n if (this.renderer) {\n this.renderer.redrawUsers();\n }\n });\n\n this.colorPicker = (function() {\n var _tmpl = renkanJST['templates/colorpicker.html'];\n return '<ul class=\"Rk-Edit-ColorPicker\">' + Rkns.pickerColors.map(function(c) { return _tmpl({c:c});}).join(\"\") + '</ul>';\n })();\n\n if (this.options.show_editor) {\n this.renderer = new Rkns.Renderer.Scene(this);\n }\n\n if (!this.options.search.length) {\n this.$.find(\".Rk-Web-Search-Form\").detach();\n } else {\n var _tmpl = renkanJST['templates/search.html'],\n _select = this.$.find(\".Rk-Search-List\"),\n _input = this.$.find(\".Rk-Web-Search-Input\"),\n _form = this.$.find(\".Rk-Web-Search-Form\");\n _.each(this.options.search, function(_search, _key) {\n if (Rkns[_search.type] && Rkns[_search.type].Search) {\n _this.search_engines.push(new Rkns[_search.type].Search(_this, _search));\n }\n });\n _select.html(\n _(this.search_engines).map(function(_search, _key) {\n return _tmpl({\n key: _key,\n title: _search.getSearchTitle(),\n className: _search.getBgClass()\n });\n }).join(\"\")\n );\n _select.find(\"li\").click(function() {\n var _el = Rkns.$(this);\n _this.setSearchEngine(_el.attr(\"data-key\"));\n _form.submit();\n });\n _form.submit(function() {\n if (_input.val()) {\n var _search = _this.search_engine;\n _search.search(_input.val());\n }\n return false;\n });\n this.$.find(\".Rk-Search-Current\").mouseenter(\n function() { _select.slideDown(); }\n );\n this.$.find(\".Rk-Search-Select\").mouseleave(\n function() { _select.hide(); }\n );\n this.setSearchEngine(0);\n }\n _.each(this.options.bins, function(_bin) {\n if (Rkns[_bin.type] && Rkns[_bin.type].Bin) {\n _this.tabs.push(new Rkns[_bin.type].Bin(_this, _bin));\n }\n });\n\n var elementDropped = false;\n\n this.$.find(\".Rk-Bins\")\n .on(\"click\",\".Rk-Bin-Title,.Rk-Bin-Title-Icon\", function() {\n var _mainDiv = Rkns.$(this).siblings(\".Rk-Bin-Main\");\n if (_mainDiv.is(\":hidden\")) {\n _this.$.find(\".Rk-Bin-Main\").slideUp();\n _mainDiv.slideDown();\n }\n });\n\n if (this.options.show_editor) {\n\n this.$.find(\".Rk-Bins\").on(\"mouseover\", \".Rk-Bin-Item\", function(_e) {\n var _t = Rkns.$(this);\n if (_t && $(_t).attr(\"data-uri\")) {\n var _models = _this.project.get(\"nodes\").where({\n uri: $(_t).attr(\"data-uri\")\n });\n _.each(_models, function(_model) {\n _this.renderer.highlightModel(_model);\n });\n }\n }).mouseout(function() {\n _this.renderer.unhighlightAll();\n }).on(\"mousemove\", \".Rk-Bin-Item\", function(e) {\n try {\n this.dragDrop();\n }\n catch(err) {}\n }).on(\"touchstart\", \".Rk-Bin-Item\", function(e) {\n elementDropped = false;\n }).on(\"touchmove\", \".Rk-Bin-Item\", function(e) {\n e.preventDefault();\n var touch = e.originalEvent.changedTouches[0],\n off = _this.renderer.canvas_$.offset(),\n w = _this.renderer.canvas_$.width(),\n h = _this.renderer.canvas_$.height();\n if (touch.pageX >= off.left && touch.pageX < (off.left + w) && touch.pageY >= off.top && touch.pageY < (off.top + h)) {\n if (elementDropped) {\n _this.renderer.onMouseMove(touch, true);\n } else {\n elementDropped = true;\n var div = document.createElement('div');\n div.appendChild(this.cloneNode(true));\n _this.renderer.dropData({\"text/html\": div.innerHTML}, touch);\n _this.renderer.onMouseDown(touch, true);\n }\n }\n }).on(\"touchend\", \".Rk-Bin-Item\", function(e) {\n if (elementDropped) {\n _this.renderer.onMouseUp(e.originalEvent.changedTouches[0], true);\n }\n elementDropped = false;\n }).on(\"dragstart\", \".Rk-Bin-Item\", function(e) {\n var div = document.createElement('div');\n div.appendChild(this.cloneNode(true));\n try {\n e.originalEvent.dataTransfer.setData(\"text/html\",div.innerHTML);\n }\n catch(err) {\n e.originalEvent.dataTransfer.setData(\"text\",div.innerHTML);\n }\n });\n\n }\n\n Rkns.$(window).resize(function() {\n _this.resizeBins();\n });\n\n var lastsearch = false, lastval = '';\n\n this.$.find(\".Rk-Bins-Search-Input\").on(\"change keyup paste input\", function() {\n var val = Rkns.$(this).val();\n if (val === lastval) {\n return;\n }\n var search = Rkns.Utils.regexpFromTextOrArray(val.length > 1 ? val: null);\n if (search.source === lastsearch) {\n return;\n }\n lastsearch = search.source;\n _.each(_this.tabs, function(tab) {\n tab.render(search);\n });\n\n });\n this.$.find(\".Rk-Bins-Search-Form\").submit(function() {\n return false;\n });\n\n};\n\nRenkan.prototype.translate = function(_text) {\n if (Rkns.i18n[this.options.language] && Rkns.i18n[this.options.language][_text]) {\n return Rkns.i18n[this.options.language][_text];\n }\n if (this.options.language.length > 2 && Rkns.i18n[this.options.language.substr(0,2)] && Rkns.i18n[this.options.language.substr(0,2)][_text]) {\n return Rkns.i18n[this.options.language.substr(0,2)][_text];\n }\n return _text;\n};\n\nRenkan.prototype.onStatusChange = function() {\n this.renderer.onStatusChange();\n};\n\nRenkan.prototype.setSearchEngine = function(_key) {\n this.search_engine = this.search_engines[_key];\n this.$.find(\".Rk-Search-Current\").attr(\"class\",\"Rk-Search-Current \" + this.search_engine.getBgClass());\n var listClasses = this.search_engine.getBgClass().split(\" \");\n var classes = \"\";\n for\t(var i= 0; i < listClasses.length; i++) {\n classes += \".\" + listClasses[i];\n }\n this.$.find(\".Rk-Web-Search-Input.Rk-Search-Input\").attr(\"placeholder\", this.translate(\"Search in \") + this.$.find(\".Rk-Search-List \"+ classes).html());\n};\n\nRenkan.prototype.resizeBins = function() {\n var _d = + this.$.find(\".Rk-Bins-Head\").outerHeight();\n this.$.find(\".Rk-Bin-Title:visible\").each(function() {\n _d += Rkns.$(this).outerHeight();\n });\n this.$.find(\".Rk-Bin-Main\").css({\n height: this.$.find(\".Rk-Bins\").height() - _d\n });\n};\n\n/* Utility functions */\nvar getUUID4 = function() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {\n var r = Math.random()*16|0, v = c === 'x' ? r : (r&0x3|0x8);\n return v.toString(16);\n });\n};\n\nRkns.Utils = {\n getUUID4 : getUUID4,\n getUID : (function() {\n function pad(n){\n return n<10 ? '0'+n : n;\n }\n var _d = new Date(),\n ID_AUTO_INCREMENT = 0,\n ID_BASE = _d.getUTCFullYear() + '-' +\n pad(_d.getUTCMonth()+1) + '-' +\n pad(_d.getUTCDate()) + '-' +\n getUUID4();\n return function(_base) {\n var _n = (++ID_AUTO_INCREMENT).toString(16),\n _uidbase = (typeof _base === \"undefined\" ? \"\" : _base + \"-\" );\n while (_n.length < 4) { _n = '0' + _n; }\n return _uidbase + ID_BASE + '-' + _n;\n };\n })(),\n getFullURL : function(url) {\n\n if(typeof(url) === 'undefined' || url == null ) {\n return \"\";\n }\n if(/https?:\\/\\//.test(url)) {\n return url;\n }\n var img = new Image();\n img.src = url;\n var res = img.src;\n img.src = null;\n return res;\n\n },\n inherit : function(_baseClass, _callbefore) {\n\n var _class = function(_arg) {\n if (typeof _callbefore === \"function\") {\n _callbefore.apply(this, Array.prototype.slice.call(arguments, 0));\n }\n _baseClass.apply(this, Array.prototype.slice.call(arguments, 0));\n if (typeof this._init === \"function\" && !this._initialized) {\n this._init.apply(this, Array.prototype.slice.call(arguments, 0));\n this._initialized = true;\n }\n };\n _.extend(_class.prototype,_baseClass.prototype);\n\n return _class;\n\n },\n regexpFromTextOrArray: (function() {\n var charsub = [\n '[aÔà âä]',\n '[cƧ]',\n '[eéèêë]',\n '[iĆìîï]',\n '[oóòÓö]',\n '[uùûü]'\n ],\n removeChars = [\n String.fromCharCode(768), String.fromCharCode(769), String.fromCharCode(770), String.fromCharCode(771), String.fromCharCode(807),\n \"ļ½\", \"ļ½\", \"ļ¼\", \"ļ¼\", \"ļ¼»\", \"ļ¼½\", \"ć\", \"ć\", \"ć\", \"ć»\", \"ā„\", \"ć\", \"ć\", \"ć\", \"ć\", \"ć\", \"ć\", \"ļ¼\", \"ļ¼\", \"ļ¼\", \"ć\",\n \",\", \" \", \";\", \"(\", \")\", \".\", \"*\", \"+\", \"\\\\\", \"?\", \"|\", \"{\", \"}\", \"[\", \"]\", \"^\", \"#\", \"/\"\n ],\n remsrc = \"[\\\\\" + removeChars.join(\"\\\\\") + \"]\",\n remrx = new RegExp(remsrc, \"gm\"),\n charsrx = _.map(charsub, function(c) {\n return new RegExp(c);\n });\n\n function replaceText(_text) {\n var txt = _text.toLowerCase().replace(remrx,\"\"), src = \"\";\n function makeReplaceFunc(l) {\n return function(k,v) {\n l = l.replace(charsrx[k], v);\n };\n }\n for (var j = 0; j < txt.length; j++) {\n if (j) {\n src += remsrc + \"*\";\n }\n var l = txt[j];\n _.each(charsub, makeReplaceFunc(l));\n src += l;\n }\n return src;\n }\n\n function getSource(inp) {\n switch (typeof inp) {\n case \"string\":\n return replaceText(inp);\n case \"object\":\n var src = '';\n _.each(inp, function(v) {\n var res = getSource(v);\n if (res) {\n if (src) {\n src += '|';\n }\n src += res;\n }\n });\n return src;\n }\n return '';\n }\n\n return function(_textOrArray) {\n var source = getSource(_textOrArray);\n if (source) {\n var testrx = new RegExp( source, \"im\"),\n replacerx = new RegExp( '(' + source + ')', \"igm\");\n return {\n isempty: false,\n source: source,\n test: function(_t) { return testrx.test(_t); },\n replace: function(_text, _replace) { return _text.replace(replacerx, _replace); }\n };\n } else {\n return {\n isempty: true,\n source: '',\n test: function() { return true; },\n replace: function(_text) { return text; }\n };\n }\n };\n })(),\n /* The minimum distance (in pixels) the mouse has to move to consider an element was dragged */\n _MIN_DRAG_DISTANCE: 2,\n /* Distance between the inner and outer radius of buttons that appear when hovering on a node */\n _NODE_BUTTON_WIDTH: 40,\n\n _EDGE_BUTTON_INNER: 2,\n _EDGE_BUTTON_OUTER: 40,\n /* Constants used to know if a specific action is to be performed when clicking on the canvas */\n _CLICKMODE_ADDNODE: 1,\n _CLICKMODE_STARTEDGE: 2,\n _CLICKMODE_ENDEDGE: 3,\n /* Node size step: Used to calculate the size change when clicking the +/- buttons */\n _NODE_SIZE_STEP: Math.LN2/4,\n _MIN_SCALE: 1/20,\n _MAX_SCALE: 20,\n _MOUSEMOVE_RATE: 80,\n _DOUBLETAP_DELAY: 800,\n /* Maximum distance in pixels (squared, to reduce calculations)\n * between two taps when double-tapping on a touch terminal */\n _DOUBLETAP_DISTANCE: 20*20,\n /* A placeholder so a default colour is displayed when a node has a null value for its user property */\n _USER_PLACEHOLDER: function(_renkan) {\n return {\n color: _renkan.options.default_user_color,\n title: _renkan.translate(\"(unknown user)\"),\n get: function(attr) {\n return this[attr] || false;\n }\n };\n },\n /* The code for the \"Drag and Add Bookmarklet\", slightly minified and with whitespaces removed, though\n * it doesn't seem that it's still a requirement in newer browsers (i.e. the ones compatibles with canvas drawing)\n */\n _BOOKMARKLET_CODE: function(_renkan) {\n return \"(function(a,b,c,d,e,f,h,i,j,k,l,m,n,o,p,q,r){a=document;b=a.body;c=a.location.href;j='draggable';m='text/x-iri-';d=a.createElement('div');d.innerHTML='<p_style=\\\"position:fixed;top:0;right:0;font:bold_18px_sans-serif;color:#fff;background:#909;padding:10px;z-index:100000;\\\">\" +\n _renkan.translate(\"Drag items from this website, drop them in Renkan\").replace(/ /g,\"_\") +\n \"</p>'.replace(/_/g,String.fromCharCode(32));b.appendChild(d);e=[{r:/https?:\\\\/\\\\/[^\\\\/]*twitter\\\\.com\\\\//,s:'.tweet',n:'twitter'},{r:/https?:\\\\/\\\\/[^\\\\/]*google\\\\.[^\\\\/]+\\\\//,s:'.g',n:'google'},{r:/https?:\\\\/\\\\/[^\\\\/]*lemonde\\\\.fr\\\\//,s:'[data-vr-contentbox]',n:'lemonde'}];f=false;e.forEach(function(g){if(g.r.test(c)){f=g;}});if(f){h=function(){Array.prototype.forEach.call(a.querySelectorAll(f.s),function(i){i[j]=true;k=i.style;k.borderWidth='2px';k.borderColor='#909';k.borderStyle='solid';k.backgroundColor='rgba(200,0,180,.1)';})};window.setInterval(h,500);h();};a.addEventListener('dragstart',function(k){l=k.dataTransfer;l.setData(m+'source-uri',c);l.setData(m+'source-title',a.title);n=k.target;if(f){o=n;while(!o.attributes[j]){o=o.parentNode;if(o==b){break;}}}if(f&&o.attributes[j]){p=o.cloneNode(true);l.setData(m+'specific-site',f.n)}else{q=a.getSelection();if(q.type==='Range'||!q.type){p=q.getRangeAt(0).cloneContents();}else{p=n.cloneNode();}}r=a.createElement('div');r.appendChild(p);l.setData('text/x-iri-selected-text',r.textContent.trim());l.setData('text/x-iri-selected-html',r.innerHTML);},false);})();\";\n },\n /* Shortens text to the required length then adds ellipsis */\n shortenText: function(_text, _maxlength) {\n return (_text.length > _maxlength ? (_text.substr(0,_maxlength) + 'ā¦') : _text);\n },\n /* Drawing an edit box with an arrow and positioning the edit box according to the position of the node/edge being edited\n * Called by Rkns.Renderer.NodeEditor and Rkns.Renderer.EdgeEditor */\n drawEditBox: function(_options, _coords, _path, _xmargin, _selector) {\n _selector.css({\n width: ( _options.tooltip_width - 2* _options.tooltip_padding )\n });\n var _height = _selector.outerHeight() + 2* _options.tooltip_padding,\n _isLeft = (_coords.x < paper.view.center.x ? 1 : -1),\n _left = _coords.x + _isLeft * ( _xmargin + _options.tooltip_arrow_length ),\n _right = _coords.x + _isLeft * ( _xmargin + _options.tooltip_arrow_length + _options.tooltip_width ),\n _top = _coords.y - _height / 2;\n if (_top + _height > (paper.view.size.height - _options.tooltip_margin)) {\n _top = Math.max( paper.view.size.height - _options.tooltip_margin, _coords.y + _options.tooltip_arrow_width / 2 ) - _height;\n }\n if (_top < _options.tooltip_margin) {\n _top = Math.min( _options.tooltip_margin, _coords.y - _options.tooltip_arrow_width / 2 );\n }\n var _bottom = _top + _height;\n /* jshint laxbreak:true */\n _path.segments[0].point\n = _path.segments[7].point\n = _coords.add([_isLeft * _xmargin, 0]);\n _path.segments[1].point.x\n = _path.segments[2].point.x\n = _path.segments[5].point.x\n = _path.segments[6].point.x\n = _left;\n _path.segments[3].point.x\n = _path.segments[4].point.x\n = _right;\n _path.segments[2].point.y\n = _path.segments[3].point.y\n = _top;\n _path.segments[4].point.y\n = _path.segments[5].point.y\n = _bottom;\n _path.segments[1].point.y = _coords.y - _options.tooltip_arrow_width / 2;\n _path.segments[6].point.y = _coords.y + _options.tooltip_arrow_width / 2;\n _path.closed = true;\n _path.fillColor = new paper.GradientColor(new paper.Gradient([_options.tooltip_top_color, _options.tooltip_bottom_color]), [0,_top], [0, _bottom]);\n _selector.css({\n left: (_options.tooltip_padding + Math.min(_left, _right)),\n top: (_options.tooltip_padding + _top)\n });\n return _path;\n }\n};\n})(window);\n\n/* END main.js */\n","(function() {\n \"use strict\";\n var root = this;\n\n var Backbone = root.Backbone;\n\n var Models = root.Rkns.Models = {};\n\n Models.getUID = function(obj) {\n var guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,\n function(c) {\n var r = Math.random() * 16 | 0, v = c === 'x' ? r\n : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n if (typeof obj !== 'undefined') {\n return obj.type + \"-\" + guid;\n }\n else {\n return guid;\n }\n };\n\n var RenkanModel = Backbone.RelationalModel.extend({\n idAttribute : \"_id\",\n constructor : function(options) {\n\n if (typeof options !== \"undefined\") {\n options._id = options._id || options.id || Models.getUID(this);\n options.title = options.title || \"\";\n options.description = options.description || \"\";\n options.uri = options.uri || \"\";\n\n if (typeof this.prepare === \"function\") {\n options = this.prepare(options);\n }\n }\n Backbone.RelationalModel.prototype.constructor.call(this, options);\n },\n validate : function() {\n if (!this.type) {\n return \"object has no type\";\n }\n },\n addReference : function(_options, _propName, _list, _id, _default) {\n var _element = _list.get(_id);\n if (typeof _element === \"undefined\" &&\n typeof _default !== \"undefined\") {\n _options[_propName] = _default;\n }\n else {\n _options[_propName] = _element;\n }\n }\n });\n\n // USER\n var User = Models.User = RenkanModel.extend({\n type : \"user\",\n prepare : function(options) {\n options.color = options.color || \"#666666\";\n return options;\n },\n toJSON : function() {\n return {\n _id : this.get(\"_id\"),\n title : this.get(\"title\"),\n uri : this.get(\"uri\"),\n description : this.get(\"description\"),\n color : this.get(\"color\")\n };\n }\n });\n\n // NODE\n var Node = Models.Node = RenkanModel.extend({\n type : \"node\",\n relations : [ {\n type : Backbone.HasOne,\n key : \"created_by\",\n relatedModel : User\n } ],\n prepare : function(options) {\n var project = options.project;\n this.addReference(options, \"created_by\", project.get(\"users\"),\n options.created_by, project.current_user);\n options.description = options.description || \"\";\n return options;\n },\n toJSON : function() {\n return {\n _id : this.get(\"_id\"),\n title : this.get(\"title\"),\n uri : this.get(\"uri\"),\n description : this.get(\"description\"),\n position : this.get(\"position\"),\n image : this.get(\"image\"),\n color : this.get(\"color\"),\n created_by : this.get(\"created_by\") ? this.get(\"created_by\")\n .get(\"_id\") : null,\n size : this.get(\"size\"),\n clip_path : this.get(\"clip_path\"),\n shape : this.get(\"shape\"),\n type : this.get(\"type\"),\n hidden : this.get(\"hidden\")\n };\n }\n });\n\n // EDGE\n var Edge = Models.Edge = RenkanModel.extend({\n type : \"edge\",\n relations : [ {\n type : Backbone.HasOne,\n key : \"created_by\",\n relatedModel : User\n }, {\n type : Backbone.HasOne,\n key : \"from\",\n relatedModel : Node\n }, {\n type : Backbone.HasOne,\n key : \"to\",\n relatedModel : Node\n } ],\n prepare : function(options) {\n var project = options.project;\n this.addReference(options, \"created_by\", project.get(\"users\"),\n options.created_by, project.current_user);\n this.addReference(options, \"from\", project.get(\"nodes\"),\n options.from);\n this.addReference(options, \"to\", project.get(\"nodes\"), options.to);\n return options;\n },\n toJSON : function() {\n return {\n _id : this.get(\"_id\"),\n title : this.get(\"title\"),\n uri : this.get(\"uri\"),\n description : this.get(\"description\"),\n from : this.get(\"from\") ? this.get(\"from\").get(\"_id\") : null,\n to : this.get(\"to\") ? this.get(\"to\").get(\"_id\") : null,\n color : this.get(\"color\"),\n created_by : this.get(\"created_by\") ? this.get(\"created_by\")\n .get(\"_id\") : null\n };\n }\n });\n\n // View\n var View = Models.View = RenkanModel.extend({\n type : \"view\",\n relations : [ {\n type : Backbone.HasOne,\n key : \"created_by\",\n relatedModel : User\n } ],\n prepare : function(options) {\n var project = options.project;\n this.addReference(options, \"created_by\", project.get(\"users\"),\n options.created_by, project.current_user);\n options.description = options.description || \"\";\n if (typeof options.offset !== \"undefined\") {\n var offset = {};\n if (Array.isArray(options.offset)) {\n offset.x = options.offset[0];\n offset.y = options.offset.length > 1 ? options.offset[1]\n : options.offset[0];\n }\n else if (options.offset.x != null) {\n offset.x = options.offset.x;\n offset.y = options.offset.y;\n }\n options.offset = offset;\n }\n return options;\n },\n toJSON : function() {\n return {\n _id : this.get(\"_id\"),\n zoom_level : this.get(\"zoom_level\"),\n offset : this.get(\"offset\"),\n title : this.get(\"title\"),\n description : this.get(\"description\"),\n created_by : this.get(\"created_by\") ? this.get(\"created_by\")\n .get(\"_id\") : null\n // Don't need project id\n };\n }\n });\n\n // PROJECT\n var Project = Models.Project = RenkanModel.extend({\n type : \"project\",\n blacklist : [ 'save_status', ],\n relations : [ {\n type : Backbone.HasMany,\n key : \"users\",\n relatedModel : User,\n reverseRelation : {\n key : 'project',\n includeInJSON : '_id'\n }\n }, {\n type : Backbone.HasMany,\n key : \"nodes\",\n relatedModel : Node,\n reverseRelation : {\n key : 'project',\n includeInJSON : '_id'\n }\n }, {\n type : Backbone.HasMany,\n key : \"edges\",\n relatedModel : Edge,\n reverseRelation : {\n key : 'project',\n includeInJSON : '_id'\n }\n }, {\n type : Backbone.HasMany,\n key : \"views\",\n relatedModel : View,\n reverseRelation : {\n key : 'project',\n includeInJSON : '_id'\n }\n } ],\n addUser : function(_props, _options) {\n _props.project = this;\n var _user = User.findOrCreate(_props);\n this.get(\"users\").push(_user, _options);\n return _user;\n },\n addNode : function(_props, _options) {\n _props.project = this;\n var _node = Node.findOrCreate(_props);\n this.get(\"nodes\").push(_node, _options);\n return _node;\n },\n addEdge : function(_props, _options) {\n _props.project = this;\n var _edge = Edge.findOrCreate(_props);\n this.get(\"edges\").push(_edge, _options);\n return _edge;\n },\n addView : function(_props, _options) {\n _props.project = this;\n // TODO: check if need to replace with create only\n var _view = View.findOrCreate(_props);\n // TODO: Should we remember only one view?\n this.get(\"views\").push(_view, _options);\n return _view;\n },\n removeNode : function(_model) {\n this.get(\"nodes\").remove(_model);\n },\n removeEdge : function(_model) {\n this.get(\"edges\").remove(_model);\n },\n validate : function(options) {\n var _project = this;\n _.each(\n [].concat(options.users, options.nodes, options.edges,options.views),\n function(_item) {\n if (_item) {\n _item.project = _project;\n }\n }\n );\n },\n // Add event handler to remove edges when a node is removed\n initialize : function() {\n var _this = this;\n this.on(\"remove:nodes\", function(_node) {\n _this.get(\"edges\").remove(\n _this.get(\"edges\").filter(\n function(_edge) {\n return _edge.get(\"from\") === _node ||\n _edge.get(\"to\") === _node;\n }));\n });\n },\n toJSON : function() {\n var json = _.clone(this.attributes);\n for ( var attr in json) {\n if ((json[attr] instanceof Backbone.Model) ||\n (json[attr] instanceof Backbone.Collection) ||\n (json[attr] instanceof RenkanModel)) {\n json[attr] = json[attr].toJSON();\n }\n }\n return _.omit(json, this.blacklist);\n }\n });\n\n var RosterUser = Models.RosterUser = Backbone.Model\n .extend({\n type : \"roster_user\",\n idAttribute : \"_id\",\n\n constructor : function(options) {\n\n if (typeof options !== \"undefined\") {\n options._id = options._id ||\n options.id ||\n Models.getUID(this);\n options.title = options.title || \"(untitled \" + this.type + \")\";\n options.description = options.description || \"\";\n options.uri = options.uri || \"\";\n options.project = options.project || null;\n options.site_id = options.site_id || 0;\n\n if (typeof this.prepare === \"function\") {\n options = this.prepare(options);\n }\n }\n Backbone.Model.prototype.constructor.call(this, options);\n },\n\n validate : function() {\n if (!this.type) {\n return \"object has no type\";\n }\n },\n\n prepare : function(options) {\n options.color = options.color || \"#666666\";\n return options;\n },\n\n toJSON : function() {\n return {\n _id : this.get(\"_id\"),\n title : this.get(\"title\"),\n uri : this.get(\"uri\"),\n description : this.get(\"description\"),\n color : this.get(\"color\"),\n project : (this.get(\"project\") != null) ? this.get(\n \"project\").get(\"id\") : null,\n site_id : this.get(\"site_id\")\n };\n }\n });\n\n var UsersList = Models.UsersList = Backbone.Collection.extend({\n model : RosterUser\n });\n\n}).call(window);\n","Rkns.defaults = {\n\n language: (navigator.language || navigator.userLanguage || \"en\"),\n /* GUI Language */\n container: \"renkan\",\n /* GUI Container DOM element ID */\n search: [],\n /* List of Search Engines */\n bins: [],\n /* List of Bins */\n static_url: \"\",\n /* URL for static resources */\n show_bins: true,\n /* Show bins in left column */\n properties: [],\n /* Semantic properties for edges */\n show_editor: true,\n /* Show the graph editor... Setting this to \"false\" only shows the bins part ! */\n read_only: false,\n /* Allows editing of renkan without changing the rest of the GUI. Can be switched on/off on the fly to block/enable editing */\n editor_mode: true,\n /* Switch for Publish/Edit GUI. If editor_mode is false, read_only will be true. */\n manual_save: false,\n /* In snapshot mode, clicking on the floppy will save a snapshot. Otherwise, it will show the connection status */\n show_top_bar: true,\n /* Show the top bar, (title, buttons, users) */\n default_user_color: \"#303030\",\n size_bug_fix: true,\n /* Resize the canvas after load (fixes a bug on iPad and FF Mac) */\n force_resize: false,\n allow_double_click: true,\n /* Allows Double Click to create a node on an empty background */\n zoom_on_scroll: true,\n /* Allows to use the scrollwheel to zoom */\n element_delete_delay: 0,\n /* Delay between clicking on the bin on an element and really deleting it\n Set to 0 for delete confirm */\n autoscale_padding: 50,\n resize: true,\n \n /* zoom options */\n show_zoom: true,\n /* show zoom buttons */\n save_view: true,\n /* show buttons to save view */\n default_view: false,\n /* Allows to load default view (zoom+offset) at start on read_only mode, instead of autoScale. the default_view will be the last */\n \n \n /* TOP BAR BUTTONS */\n show_search_field: true,\n show_user_list: true,\n user_name_editable: true,\n user_color_editable: true,\n show_user_color: true,\n show_save_button: true,\n show_export_button: true,\n show_open_button: false,\n show_addnode_button: true,\n show_addedge_button: true,\n show_bookmarklet: true,\n show_fullscreen_button: true,\n home_button_url: false,\n home_button_title: \"Home\",\n\n /* MINI-MAP OPTIONS */\n\n show_minimap: true,\n /* Show a small map at the bottom right */\n minimap_width: 160,\n minimap_height: 120,\n minimap_padding: 20,\n minimap_background_color: \"#ffffff\",\n minimap_border_color: \"#cccccc\",\n minimap_highlight_color: \"#ffff00\",\n minimap_highlight_weight: 5,\n \n\n /* EDGE/NODE COMMON OPTIONS */\n\n buttons_background: \"#202020\",\n buttons_label_color: \"#c000c0\",\n buttons_label_font_size: 9,\n\n /* NODE DISPLAY OPTIONS */\n\n show_node_circles: true,\n /* Show circles for nodes */\n clip_node_images: true,\n /* Constraint node images to circles */\n node_images_fill_mode: false,\n /* Set to false for \"letterboxing\" (height/width of node adapted to show full image)\n Set to true for \"crop\" (adapted to fill circle) */\n node_size_base: 25,\n node_stroke_width: 2,\n selected_node_stroke_width: 4,\n node_fill_color: \"#ffffff\",\n highlighted_node_fill_color: \"#ffff00\",\n node_label_distance: 5,\n /* Vertical distance between node and label */\n node_label_max_length: 60,\n /* Maximum displayed text length */\n label_untitled_nodes: \"(untitled)\",\n /* Label to display on untitled nodes */\n change_shapes: true,\n /* Change shapes enabled */\n\n /* EDGE DISPLAY OPTIONS */\n\n edge_stroke_width: 2,\n selected_edge_stroke_width: 4,\n edge_label_distance: 0,\n edge_label_max_length: 20,\n edge_arrow_length: 18,\n edge_arrow_width: 12,\n edge_gap_in_bundles: 12,\n label_untitled_edges: \"\",\n\n /* CONTEXTUAL DISPLAY (TOOLTIP OR EDITOR) OPTIONS */\n\n tooltip_width: 275,\n tooltip_padding: 10,\n tooltip_margin: 15,\n tooltip_arrow_length : 20,\n tooltip_arrow_width : 40,\n tooltip_top_color: \"#f0f0f0\",\n tooltip_bottom_color: \"#d0d0d0\",\n tooltip_border_color: \"#808080\",\n tooltip_border_width: 1,\n\n /* NODE EDITOR OPTIONS */\n\n show_node_editor_uri: true,\n show_node_editor_description: true,\n show_node_editor_size: true,\n show_node_editor_color: true,\n show_node_editor_image: true,\n show_node_editor_creator: true,\n allow_image_upload: true,\n uploaded_image_max_kb: 500,\n\n /* NODE TOOLTIP OPTIONS */\n\n show_node_tooltip_uri: true,\n show_node_tooltip_description: true,\n show_node_tooltip_color: true,\n show_node_tooltip_image: true,\n show_node_tooltip_creator: true,\n\n /* EDGE EDITOR OPTIONS */\n\n show_edge_editor_uri: true,\n show_edge_editor_color: true,\n show_edge_editor_direction: true,\n show_edge_editor_nodes: true,\n show_edge_editor_creator: true,\n\n /* EDGE TOOLTIP OPTIONS */\n\n show_edge_tooltip_uri: true,\n show_edge_tooltip_color: true,\n show_edge_tooltip_nodes: true,\n show_edge_tooltip_creator: true\n\n /* */\n\n};\n","Rkns.i18n = {\n fr: {\n \"Edit Node\": \"Ćdition dāun nÅud\",\n \"Edit Edge\": \"Ćdition dāun lien\",\n \"Title:\": \"Titre :\",\n \"URI:\": \"URI :\",\n \"Description:\": \"Description :\",\n \"From:\": \"De :\",\n \"To:\": \"Vers :\",\n \"Image\": \"Image\",\n \"Image URL:\": \"URL d'Image\",\n \"Choose Image File:\": \"Choisir un fichier image\",\n \"Full Screen\": \"Mode plein Ć©cran\",\n \"Add Node\": \"Ajouter un nÅud\",\n \"Add Edge\": \"Ajouter un lien\",\n \"Save Project\": \"Enregistrer le projet\",\n \"Open Project\": \"Ouvrir un projet\",\n \"Auto-save enabled\": \"Enregistrement automatique activĆ©\",\n \"Connection lost\": \"Connexion perdue\",\n \"Created by:\": \"CrƩƩ par :\",\n \"Zoom In\": \"Agrandir lāĆ©chelle\",\n \"Zoom Out\": \"Rapetisser lāĆ©chelle\",\n \"Edit\": \"Ćditer\",\n \"Remove\": \"Supprimer\",\n \"Cancel deletion\": \"Annuler la suppression\",\n \"Link to another node\": \"CrĆ©er un lien\",\n \"Enlarge\": \"Agrandir\",\n \"Shrink\": \"RĆ©trĆ©cir\",\n \"Click on the background canvas to add a node\": \"Cliquer sur le fond du graphe pour rajouter un nÅud\",\n \"Click on a first node to start the edge\": \"Cliquer sur un premier nÅud pour commencer le lien\",\n \"Click on a second node to complete the edge\": \"Cliquer sur un second nÅud pour terminer le lien\",\n \"Wikipedia\": \"WikipĆ©dia\",\n \"Wikipedia in \": \"WikipĆ©dia en \",\n \"French\": \"FranƧais\",\n \"English\": \"Anglais\",\n \"Japanese\": \"Japonais\",\n \"Untitled project\": \"Projet sans titre\",\n \"Lignes de Temps\": \"Lignes de Temps\",\n \"Loading, please wait\": \"Chargement en cours, merci de patienter\",\n \"Edge color:\": \"Couleur :\",\n \"Node color:\": \"Couleur :\",\n \"Choose color\": \"Choisir une couleur\",\n \"Change edge direction\": \"Changer le sens du lien\",\n \"Do you really wish to remove node \": \"Voulez-vous rĆ©ellement supprimer le nÅud \",\n \"Do you really wish to remove edge \": \"Voulez-vous rĆ©ellement supprimer le lien \",\n \"This file is not an image\": \"Ce fichier n'est pas une image\",\n \"Image size must be under \": \"L'image doit peser moins de \",\n \"Size:\": \"Taille :\",\n \"KB\": \"ko\",\n \"Choose from vocabulary:\": \"Choisir dans un vocabulaire :\",\n \"SKOS Documentation properties\": \"SKOS: PropriĆ©tĆ©s documentaires\",\n \"has note\": \"a pour note\",\n \"has example\": \"a pour exemple\",\n \"has definition\": \"a pour dĆ©finition\",\n \"SKOS Semantic relations\": \"SKOS: Relations sĆ©mantiques\",\n \"has broader\": \"a pour concept plus large\",\n \"has narrower\": \"a pour concept plus Ć©troit\",\n \"has related\": \"a pour concept apparentĆ©\",\n \"Dublin Core Metadata\": \"MĆ©tadonnĆ©es Dublin Core\",\n \"has contributor\": \"a pour contributeur\",\n \"covers\": \"couvre\",\n \"created by\": \"crƩƩ par\",\n \"has date\": \"a pour date\",\n \"published by\": \"Ć©ditĆ© par\",\n \"has source\": \"a pour source\",\n \"has subject\": \"a pour sujet\",\n \"Dragged resource\": \"Ressource glisĆ©e-dĆ©posĆ©e\",\n \"Search the Web\": \"Rechercher en ligne\",\n \"Search in Bins\": \"Rechercher dans les chutiers\",\n \"Close bin\": \"Fermer le chutier\",\n \"Refresh bin\": \"RafraĆ®chir le chutier\",\n \"(untitled)\": \"(sans titre)\",\n \"Select contents:\": \"SĆ©lectionner des contenus :\",\n \"Drag items from this website, drop them in Renkan\": \"Glissez des Ć©lĆ©ments de ce site web vers Renkan\",\n \"Drag this button to your bookmark bar. When on a third-party website, click it to enable drag-and-drop from the website to Renkan.\": \"Glissez ce bouton vers votre barre de favoris. Ensuite, depuis un site tiers, cliquez dessus pour activer 'Drag-to-Add' puis glissez des Ć©lĆ©ments de ce site vers Renkan\",\n \"Shapes available\": \"Formes disponibles\",\n \"Circle\": \"Cercle\",\n \"Square\": \"CarrĆ©\",\n \"Diamond\": \"Losange\",\n \"Hexagone\": \"Hexagone\",\n \"Ellipse\": \"Ellipse\",\n \"Star\": \"Ćtoile\",\n \"Zoom Fit\": \"Ajuster le Zoom\",\n \"Download Project\": \"TĆ©lĆ©charger le projet\",\n \"Zoom Save\": \"Sauver le Zoom\",\n \"View saved zoom\": \"Restaurer le Zoom\",\n \"Renkan \\'Drag-to-Add\\' bookmarklet\": \"Renkan \\'Deplacer-Pour-Ajouter\\' Signet\",\n \"(unknown user)\":\"(non authentifiĆ©)\",\n \"<unknown user>\":\"<non authentifiĆ©>\",\n \"Search in graph\":\"Rechercher dans carte\",\n \"Search in \" : \"Chercher dans \"\n }\n};\n","/* Saves the Full JSON at each modification */\n\nRkns.jsonIO = function(_renkan, _opts) {\n var _proj = _renkan.project;\n if (typeof _opts.http_method === \"undefined\") {\n _opts.http_method = 'PUT';\n }\n var _load = function() {\n _renkan.renderer.redrawActive = false;\n _proj.set({\n loading_status : true\n });\n Rkns.$.getJSON(_opts.url, function(_data) {\n _proj.set(_data, {\n validate : true\n });\n _proj.set({\n loading_status : false\n });\n _proj.set({\n save_status : 0\n });\n _renkan.renderer.redrawActive = true;\n _renkan.renderer.fixSize();\n });\n };\n var _save = function() {\n _proj.set({\n save_status : 2\n });\n var _data = _proj.toJSON();\n if (!_renkan.read_only) {\n Rkns.$.ajax({\n type : _opts.http_method,\n url : _opts.url,\n contentType : \"application/json\",\n data : JSON.stringify(_data),\n success : function(data, textStatus, jqXHR) {\n _proj.set({\n save_status : 0\n });\n }\n });\n }\n\n };\n var _thrSave = Rkns._.throttle(function() {\n setTimeout(_save, 100);\n }, 1000);\n _proj.on(\"add:nodes add:edges add:users add:views\", function(_model) {\n _model.on(\"change remove\", function(_model) {\n _thrSave();\n });\n _thrSave();\n });\n _proj.on(\"change\", function() {\n if (!(_proj.changedAttributes.length === 1 && _proj\n .hasChanged('save_status'))) {\n _thrSave();\n }\n });\n\n _load();\n};\n","/* Saves the Full JSON once */\n\nRkns.jsonIOSaveOnClick = function(_renkan, _opts) {\n var _proj = _renkan.project,\n _saveWarn = false,\n _onLeave = function() {\n return \"Project not saved\";\n };\n if (typeof _opts.http_method === \"undefined\") {\n _opts.http_method = 'POST';\n }\n var _load = function() {\n var getdata = {},\n rx = /id=([^&#?=]+)/,\n matches = document.location.hash.match(rx);\n if (matches) {\n getdata.id = matches[1];\n }\n Rkns.$.ajax({\n url: _opts.url,\n data: getdata,\n beforeSend: function(){\n \t_proj.set({loading_status:true});\n },\n success: function(_data) {\n _proj.set(_data, {validate: true});\n \t_proj.set({loading_status:false});\n _proj.set({save_status:0});\n \t_renkan.renderer.autoScale();\n }\n });\n };\n var _save = function() {\n _proj.set(\"saved_at\", new Date());\n var _data = _proj.toJSON();\n Rkns.$.ajax({\n type: _opts.http_method,\n url: _opts.url,\n contentType: \"application/json\",\n data: JSON.stringify(_data),\n beforeSend: function(){\n \t_proj.set({save_status:2});\n },\n success: function(data, textStatus, jqXHR) {\n $(window).off(\"beforeunload\", _onLeave);\n _saveWarn = false;\n _proj.set({save_status:0});\n //document.location.hash = \"#id=\" + data.id;\n //$(\".Rk-Notifications\").text(\"Saved as \"+document.location.href).fadeIn().delay(2000).fadeOut();\n }\n });\n };\n var _checkLeave = function() {\n \t_proj.set({save_status:1});\n \t\n var title = _proj.get(\"title\");\n if (title && _proj.get(\"nodes\").length) {\n $(\".Rk-Save-Button\").removeClass(\"disabled\");\n } else {\n $(\".Rk-Save-Button\").addClass(\"disabled\");\n }\n if (title) {\n $(\".Rk-PadTitle\").css(\"border-color\",\"#333333\");\n }\n if (!_saveWarn) {\n _saveWarn = true;\n $(window).on(\"beforeunload\", _onLeave);\n }\n };\n _load();\n _proj.on(\"add:nodes add:edges add:users change\", function(_model) {\n\t _model.on(\"change remove\", function(_model) {\n\t \tif(!(_model.changedAttributes.length === 1 && _model.hasChanged('save_status'))) {\n\t \t\t_checkLeave();\n\t \t}\n\t });\n\t\tif(!(_proj.changedAttributes.length === 1 && _proj.hasChanged('save_status'))) {\n\t\t _checkLeave();\n \t}\n });\n _renkan.renderer.save = function() {\n if ($(\".Rk-Save-Button\").hasClass(\"disabled\")) {\n if (!_proj.get(\"title\")) {\n $(\".Rk-PadTitle\").css(\"border-color\",\"#ff0000\");\n }\n } else {\n _save();\n }\n };\n};\n","(function(Rkns) {\n\"use strict\";\n\nvar _ = Rkns._;\n\nvar Ldt = Rkns.Ldt = {};\n\nvar Bin = Ldt.Bin = function(_renkan, _opts) {\n if (_opts.ldt_type) {\n var Resclass = Ldt[_opts.ldt_type+\"Bin\"];\n if (Resclass) {\n return new Resclass(_renkan, _opts);\n }\n }\n console.error(\"No such LDT Bin Type\");\n};\n\nvar ProjectBin = Ldt.ProjectBin = Rkns.Utils.inherit(Rkns._BaseBin);\n\nProjectBin.prototype.tagTemplate = renkanJST['templates/ldtjson-bin/tagtemplate.html'];\n\nProjectBin.prototype.annotationTemplate = renkanJST['templates/ldtjson-bin/annotationtemplate.html'];\n\nProjectBin.prototype._init = function(_renkan, _opts) {\n this.renkan = _renkan;\n this.proj_id = _opts.project_id;\n this.ldt_platform = _opts.ldt_platform || \"http://ldt.iri.centrepompidou.fr/\";\n this.title_$.html(_opts.title);\n this.title_icon_$.addClass('Rk-Ldt-Title-Icon');\n this.refresh();\n};\n\nProjectBin.prototype.render = function(searchbase) {\n var search = searchbase || Rkns.Utils.regexpFromTextOrArray();\n function highlight(_text) {\n var _e = _(_text).escape();\n return search.isempty ? _e : search.replace(_e, \"<span class='searchmatch'>$1</span>\");\n }\n function convertTC(_ms) {\n function pad(_n) {\n var _res = _n.toString();\n while (_res.length < 2) {\n _res = '0' + _res;\n }\n return _res;\n }\n var _totalSeconds = Math.abs(Math.floor(_ms/1000)),\n _hours = Math.floor(_totalSeconds / 3600),\n _minutes = (Math.floor(_totalSeconds / 60) % 60),\n _seconds = _totalSeconds % 60,\n _res = '';\n if (_hours) {\n _res += pad(_hours) + ':';\n }\n _res += pad(_minutes) + ':' + pad(_seconds);\n return _res;\n }\n\n var _html = '<li><h3>Tags</h3></li>',\n _projtitle = this.data.meta[\"dc:title\"],\n _this = this,\n count = 0;\n _this.title_$.text('LDT Project: \"' + _projtitle + '\"');\n _.map(_this.data.tags,function(_tag) {\n var _title = _tag.meta[\"dc:title\"];\n if (!search.isempty && !search.test(_title)) {\n return;\n }\n count++;\n _html += _this.tagTemplate({\n ldt_platform: _this.ldt_platform,\n title: _title,\n htitle: highlight(_title),\n encodedtitle : encodeURIComponent(_title),\n static_url: _this.renkan.options.static_url\n });\n });\n _html += '<li><h3>Annotations</h3></li>';\n _.map(_this.data.annotations,function(_annotation) {\n var _description = _annotation.content.description,\n _title = _annotation.content.title.replace(_description,\"\");\n if (!search.isempty && !search.test(_title) && !search.test(_description)) {\n return;\n }\n count++;\n var _duration = _annotation.end - _annotation.begin,\n _img = (\n (_annotation.content && _annotation.content.img && _annotation.content.img.src) ?\n _annotation.content.img.src :\n ( _duration ? _this.renkan.options.static_url+\"img/ldt-segment.png\" : _this.renkan.options.static_url+\"img/ldt-point.png\" )\n );\n _html += _this.annotationTemplate({\n ldt_platform: _this.ldt_platform,\n title: _title,\n htitle: highlight(_title),\n description: _description,\n hdescription: highlight(_description),\n start: convertTC(_annotation.begin),\n end: convertTC(_annotation.end),\n duration: convertTC(_duration),\n mediaid: _annotation.media,\n annotationid: _annotation.id,\n image: _img,\n static_url: _this.renkan.options.static_url\n });\n });\n\n this.main_$.html(_html);\n if (!search.isempty && count) {\n this.count_$.text(count).show();\n } else {\n this.count_$.hide();\n }\n if (!search.isempty && !count) {\n this.$.hide();\n } else {\n this.$.show();\n }\n this.renkan.resizeBins();\n};\n\nProjectBin.prototype.refresh = function() {\n var _this = this;\n Rkns.$.ajax({\n url: this.ldt_platform + 'ldtplatform/ldt/cljson/id/' + this.proj_id,\n dataType: \"jsonp\",\n success: function(_data) {\n _this.data = _data;\n _this.render();\n }\n });\n};\n\nvar Search = Ldt.Search = function(_renkan, _opts) {\n this.renkan = _renkan;\n this.lang = _opts.lang || \"en\";\n};\n\nSearch.prototype.getBgClass = function() {\n return \"Rk-Ldt-Icon\";\n};\n\nSearch.prototype.getSearchTitle = function() {\n return this.renkan.translate(\"Lignes de Temps\");\n};\n\nSearch.prototype.search = function(_q) {\n this.renkan.tabs.push(\n new ResultsBin(this.renkan, {\n search: _q\n })\n );\n};\n\nvar ResultsBin = Ldt.ResultsBin = Rkns.Utils.inherit(Rkns._BaseBin);\n\nResultsBin.prototype.segmentTemplate = renkanJST['templates/ldtjson-bin/segmenttemplate.html'];\n\nResultsBin.prototype._init = function(_renkan, _opts) {\n this.renkan = _renkan;\n this.ldt_platform = _opts.ldt_platform || \"http://ldt.iri.centrepompidou.fr/\";\n this.max_results = _opts.max_results || 50;\n this.search = _opts.search;\n this.title_$.html('Lignes de Temps: \"' + _opts.search + '\"');\n this.title_icon_$.addClass('Rk-Ldt-Title-Icon');\n this.refresh();\n};\n\nResultsBin.prototype.render = function(searchbase) {\n if (!this.data) {\n return;\n }\n var search = searchbase || Rkns.Utils.regexpFromTextOrArray();\n var highlightrx = (search.isempty ? Rkns.Utils.regexpFromTextOrArray(this.search) : search);\n function highlight(_text) {\n return highlightrx.replace(_(_text).escape(), \"<span class='searchmatch'>$1</span>\");\n }\n function convertTC(_ms) {\n function pad(_n) {\n var _res = _n.toString();\n while (_res.length < 2) {\n _res = '0' + _res;\n }\n return _res;\n }\n var _totalSeconds = Math.abs(Math.floor(_ms/1000)),\n _hours = Math.floor(_totalSeconds / 3600),\n _minutes = (Math.floor(_totalSeconds / 60) % 60),\n _seconds = _totalSeconds % 60,\n _res = '';\n if (_hours) {\n _res += pad(_hours) + ':';\n }\n _res += pad(_minutes) + ':' + pad(_seconds);\n return _res;\n }\n\n var _html = '',\n _this = this,\n count = 0;\n _.each(this.data.objects,function(_segment) {\n var _description = _segment.abstract,\n _title = _segment.title;\n if (!search.isempty && !search.test(_title) && !search.test(_description)) {\n return;\n }\n count++;\n var _duration = _segment.duration,\n _begin = _segment.start_ts,\n _end = + _segment.duration + _begin,\n _img = (\n _duration ?\n _this.renkan.options.static_url + \"img/ldt-segment.png\" :\n _this.renkan.options.static_url + \"img/ldt-point.png\"\n );\n _html += _this.segmentTemplate({\n ldt_platform: _this.ldt_platform,\n title: _title,\n htitle: highlight(_title),\n description: _description,\n hdescription: highlight(_description),\n start: convertTC(_begin),\n end: convertTC(_end),\n duration: convertTC(_duration),\n mediaid: _segment.iri_id,\n //projectid: _segment.project_id,\n //cuttingid: _segment.cutting_id,\n annotationid: _segment.element_id,\n image: _img\n });\n });\n\n this.main_$.html(_html);\n if (!search.isempty && count) {\n this.count_$.text(count).show();\n } else {\n this.count_$.hide();\n }\n if (!search.isempty && !count) {\n this.$.hide();\n } else {\n this.$.show();\n }\n this.renkan.resizeBins();\n};\n\nResultsBin.prototype.refresh = function() {\n var _this = this;\n Rkns.$.ajax({\n url: this.ldt_platform + 'ldtplatform/api/ldt/1.0/segments/search/',\n data: {\n format: \"jsonp\",\n q: this.search,\n limit: this.max_results\n },\n dataType: \"jsonp\",\n success: function(_data) {\n _this.data = _data;\n _this.render();\n }\n });\n};\n\n})(window.Rkns);\n","Rkns.ResourceList = {};\n\nRkns.ResourceList.Bin = Rkns.Utils.inherit(Rkns._BaseBin);\n\nRkns.ResourceList.Bin.prototype.resultTemplate = renkanJST['templates/list-bin.html'];\n\nRkns.ResourceList.Bin.prototype._init = function(_renkan, _opts) {\n this.renkan = _renkan;\n this.title_$.html(_opts.title);\n if (_opts.list) {\n this.data = _opts.list;\n }\n this.refresh();\n};\n\nRkns.ResourceList.Bin.prototype.render = function(searchbase) {\n var search = searchbase || Rkns.Utils.regexpFromTextOrArray();\n function highlight(_text) {\n var _e = _(_text).escape();\n return search.isempty ? _e : search.replace(_e, \"<span class='searchmatch'>$1</span>\");\n }\n var _html = \"\",\n _this = this,\n count = 0;\n Rkns._.each(this.data,function(_item) {\n var _element;\n if (typeof _item === \"string\") {\n if (/^(https?:\\/\\/|www)/.test(_item)) {\n _element = { url: _item };\n } else {\n _element = { title: _item.replace(/[:,]?\\s?(https?:\\/\\/|www)[\\d\\w\\/.&?=#%-_]+\\s?/,'').trim() };\n var _match = _item.match(/(https?:\\/\\/|www)[\\d\\w\\/.&?=#%-_]+/);\n if (_match) {\n _element.url = _match[0];\n }\n if (_element.title.length > 80) {\n _element.description = _element.title;\n _element.title = _element.title.replace(/^(.{30,60})\\s.+$/,'$1ā¦');\n }\n }\n } else {\n _element = _item;\n }\n var title = _element.title || (_element.url || \"\").replace(/^https?:\\/\\/(www\\.)?/,'').replace(/^(.{40}).+$/,'$1ā¦'),\n url = _element.url || \"\",\n description = _element.description || \"\",\n image = _element.image || \"\";\n if (url && !/^https?:\\/\\//.test(url)) {\n url = 'http://' + url;\n }\n if (!search.isempty && !search.test(title) && !search.test(description)) {\n return;\n }\n count++;\n _html += _this.resultTemplate({\n url: url,\n title: title,\n htitle: highlight(title),\n image: image,\n description: description,\n hdescription: highlight(description),\n static_url: _this.renkan.options.static_url\n });\n });\n _this.main_$.html(_html);\n if (!search.isempty && count) {\n this.count_$.text(count).show();\n } else {\n this.count_$.hide();\n }\n if (!search.isempty && !count) {\n this.$.hide();\n } else {\n this.$.show();\n }\n this.renkan.resizeBins();\n};\n\nRkns.ResourceList.Bin.prototype.refresh = function() {\n if (this.data) {\n this.render();\n }\n};\n","Rkns.Wikipedia = {\n};\n\nRkns.Wikipedia.Search = function(_renkan, _opts) {\n this.renkan = _renkan;\n this.lang = _opts.lang || \"en\";\n};\n\nRkns.Wikipedia.Search.prototype.getBgClass = function() {\n return \"Rk-Wikipedia-Search-Icon Rk-Wikipedia-Lang-\" + this.lang;\n};\n\nRkns.Wikipedia.Search.prototype.getSearchTitle = function() {\n var langs = {\n \"fr\": \"French\",\n \"en\": \"English\",\n \"ja\": \"Japanese\"\n };\n if (langs[this.lang]) {\n return this.renkan.translate(\"Wikipedia in \") + this.renkan.translate(langs[this.lang]);\n } else {\n return this.renkan.translate(\"Wikipedia\") + \" [\" + this.lang + \"]\";\n }\n};\n\nRkns.Wikipedia.Search.prototype.search = function(_q) {\n this.renkan.tabs.push(\n new Rkns.Wikipedia.Bin(this.renkan, {\n lang: this.lang,\n search: _q\n })\n );\n};\n\nRkns.Wikipedia.Bin = Rkns.Utils.inherit(Rkns._BaseBin);\n\nRkns.Wikipedia.Bin.prototype.resultTemplate = renkanJST['templates/wikipedia-bin/resulttemplate.html'];\n\nRkns.Wikipedia.Bin.prototype._init = function(_renkan, _opts) {\n this.renkan = _renkan;\n this.search = _opts.search;\n this.lang = _opts.lang || \"en\";\n this.title_icon_$.addClass('Rk-Wikipedia-Title-Icon Rk-Wikipedia-Lang-' + this.lang);\n this.title_$.html(this.search).addClass(\"Rk-Wikipedia-Title\");\n this.refresh();\n};\n\nRkns.Wikipedia.Bin.prototype.render = function(searchbase) {\n var search = searchbase || Rkns.Utils.regexpFromTextOrArray();\n var highlightrx = (search.isempty ? Rkns.Utils.regexpFromTextOrArray(this.search) : search);\n function highlight(_text) {\n return highlightrx.replace(_(_text).escape(), \"<span class='searchmatch'>$1</span>\");\n }\n var _html = \"\",\n _this = this,\n count = 0;\n Rkns._.each(this.data.query.search, function(_result) {\n var title = _result.title,\n url = \"http://\" + _this.lang + \".wikipedia.org/wiki/\" + encodeURI(title.replace(/ /g,\"_\")),\n description = Rkns.$('<div>').html(_result.snippet).text();\n if (!search.isempty && !search.test(title) && !search.test(description)) {\n return;\n }\n count++;\n _html += _this.resultTemplate({\n url: url,\n title: title,\n htitle: highlight(title),\n description: description,\n hdescription: highlight(description),\n static_url: _this.renkan.options.static_url\n });\n });\n _this.main_$.html(_html);\n if (!search.isempty && count) {\n this.count_$.text(count).show();\n } else {\n this.count_$.hide();\n }\n if (!search.isempty && !count) {\n this.$.hide();\n } else {\n this.$.show();\n }\n this.renkan.resizeBins();\n};\n\nRkns.Wikipedia.Bin.prototype.refresh = function() {\n var _this = this;\n Rkns.$.ajax({\n url: \"http://\" + _this.lang + \".wikipedia.org/w/api.php?action=query&list=search&srsearch=\" + encodeURIComponent(this.search) + \"&format=json\",\n dataType: \"jsonp\",\n success: function(_data) {\n _this.data = _data;\n _this.render();\n }\n });\n};\n","\ndefine('renderer/baserepresentation',['jquery', 'underscore'], function ($, _) {\n \n\n /* Rkns.Renderer._BaseRepresentation Class */\n\n /* In Renkan, a \"Representation\" is a sort of ViewModel (in the MVVM paradigm) and bridges the gap between\n * models (written with Backbone.js) and the view (written with Paper.js)\n * Renkan's representations all inherit from Rkns.Renderer._BaseRepresentation '*/\n\n var _BaseRepresentation = function(_renderer, _model) {\n if (typeof _renderer !== \"undefined\") {\n this.renderer = _renderer;\n this.renkan = _renderer.renkan;\n this.project = _renderer.renkan.project;\n this.options = _renderer.renkan.options;\n this.model = _model;\n if (this.model) {\n var _this = this;\n this._changeBinding = function() {\n _this.redraw({change: true});\n };\n this._removeBinding = function() {\n _renderer.removeRepresentation(_this);\n _.defer(function() {\n _renderer.redraw();\n });\n };\n this._selectBinding = function() {\n _this.select();\n };\n this._unselectBinding = function() {\n _this.unselect();\n };\n this.model.on(\"change\", this._changeBinding );\n this.model.on(\"remove\", this._removeBinding );\n this.model.on(\"select\", this._selectBinding );\n this.model.on(\"unselect\", this._unselectBinding );\n }\n }\n };\n\n /* Rkns.Renderer._BaseRepresentation Methods */\n\n _(_BaseRepresentation.prototype).extend({\n _super: function(_func) {\n return _BaseRepresentation.prototype[_func].apply(this, Array.prototype.slice.call(arguments, 1));\n },\n redraw: function() {},\n moveTo: function() {},\n show: function() { return \"BaseRepresentation.show\"; },\n hide: function() {},\n select: function() {\n if (this.model) {\n this.model.trigger(\"selected\");\n }\n },\n unselect: function() {\n if (this.model) {\n this.model.trigger(\"unselected\");\n }\n },\n highlight: function() {},\n unhighlight: function() {},\n mousedown: function() {},\n mouseup: function() {\n if (this.model) {\n this.model.trigger(\"clicked\");\n }\n },\n destroy: function() {\n if (this.model) {\n this.model.off(\"change\", this._changeBinding );\n this.model.off(\"remove\", this._removeBinding );\n this.model.off(\"select\", this._selectBinding );\n this.model.off(\"unselect\", this._unselectBinding );\n }\n }\n }).value();\n\n /* End of Rkns.Renderer._BaseRepresentation Class */\n\n return _BaseRepresentation;\n\n});\n\ndefine('requtils',[], function ($, _) {\n \n return {\n getUtils: function(){\n return window.Rkns.Utils;\n },\n getRenderer: function(){\n return window.Rkns.Renderer;\n }\n };\n\n});\n\n\ndefine('renderer/basebutton',['jquery', 'underscore', 'requtils', 'renderer/baserepresentation'], function ($, _, requtils, BaseRepresentation) {\n \n\n var Utils = requtils.getUtils();\n\n /* Rkns.Renderer._BaseButton Class */\n\n /* BaseButton is extended by contextual buttons that appear when hovering on nodes and edges */\n\n var _BaseButton = Utils.inherit(BaseRepresentation);\n\n _(_BaseButton.prototype).extend({\n moveTo: function(_pos) {\n this.sector.moveTo(_pos);\n },\n show: function() {\n this.sector.show();\n },\n hide: function() {\n this.sector.hide();\n },\n select: function() {\n this.sector.select();\n },\n unselect: function(_newTarget) {\n this.sector.unselect();\n if (!_newTarget || (_newTarget !== this.source_representation && _newTarget.source_representation !== this.source_representation)) {\n this.source_representation.unselect();\n }\n },\n destroy: function() {\n this.sector.destroy();\n }\n }).value();\n\n return _BaseButton;\n\n});\n\n\ndefine('renderer/shapebuilder',[], function () {\n \n\n /* ShapeBuilder Begin */\n\n var builders = {\n \"circle\":{\n getShape: function() {\n return new paper.Path.Circle([0, 0], 1);\n },\n getImageShape: function(center, radius) {\n return new paper.Path.Circle(center, radius);\n }\n },\n \"rectangle\":{\n getShape: function() {\n return new paper.Path.Rectangle([-2, -2], [2, 2]);\n },\n getImageShape: function(center, radius) {\n return new paper.Path.Rectangle([-radius, -radius], [radius*2, radius*2]);\n }\n },\n \"ellipse\":{\n getShape: function() {\n return new paper.Path.Ellipse(new paper.Rectangle([-2, -1], [2, 1]));\n },\n getImageShape: function(center, radius) {\n return new paper.Path.Ellipse(new paper.Rectangle([-radius, -radius/2], [radius*2, radius]));\n }\n },\n \"polygon\":{\n getShape: function() {\n return new paper.Path.RegularPolygon([0, 0], 6, 1);\n },\n getImageShape: function(center, radius) {\n return new paper.Path.RegularPolygon([0, 0], 6, radius);\n }\n },\n \"diamond\":{\n getShape: function() {\n var d = new paper.Path.Rectangle([-Math.SQRT2, -Math.SQRT2], [Math.SQRT2, Math.SQRT2]);\n d.rotate(45);\n return d;\n },\n getImageShape: function(center, radius) {\n var d = new paper.Path.Rectangle([-radius*Math.SQRT2/2, -radius*Math.SQRT2/2], [radius*Math.SQRT2, radius*Math.SQRT2]);\n d.rotate(45);\n return d;\n }\n },\n \"star\":{\n getShape: function() {\n return new paper.Path.Star([0, 0], 8, 1, 0.7);\n },\n getImageShape: function(center, radius) {\n return new paper.Path.Star([0, 0], 8, radius*1, radius*0.7);\n }\n },\n \"svg\": function(path){\n return {\n getShape: function() {\n return new paper.Path(path);\n },\n getImageShape: function(center, radius) {\n // No calcul for the moment\n return new paper.Path();\n }\n };\n }\n };\n\n var ShapeBuilder = function (shape){\n if(shape === null || typeof shape === \"undefined\"){\n shape = \"circle\";\n }\n if(shape.substr(0,4)===\"svg:\"){\n return builders.svg(shape.substr(4));\n }\n if(!(shape in builders)){\n shape = \"circle\";\n }\n return builders[shape];\n };\n\n return ShapeBuilder;\n\n});\n\ndefine('renderer/noderepr',['jquery', 'underscore', 'requtils', 'renderer/baserepresentation', 'renderer/shapebuilder'], function ($, _, requtils, BaseRepresentation, ShapeBuilder) {\n \n\n var Utils = requtils.getUtils();\n\n /* Rkns.Renderer.Node Class */\n\n /* The representation for the node : A circle, with an image inside and a text label underneath.\n * The circle and the image are drawn on canvas and managed by Paper.js.\n * The text label is an HTML node, managed by jQuery. */\n\n //var NodeRepr = Renderer.Node = Utils.inherit(Renderer._BaseRepresentation);\n var NodeRepr = Utils.inherit(BaseRepresentation);\n\n _(NodeRepr.prototype).extend({\n _init: function() {\n this.renderer.node_layer.activate();\n this.type = \"Node\";\n this.buildShape();\n if (this.options.show_node_circles) {\n this.circle.strokeWidth = this.options.node_stroke_width;\n this.h_ratio = 1;\n } else {\n this.h_ratio = 0;\n }\n this.title = $('<div class=\"Rk-Label\">').appendTo(this.renderer.labels_$);\n\n if (this.options.editor_mode) {\n var Renderer = requtils.getRenderer();\n this.normal_buttons = [\n new Renderer.NodeEditButton(this.renderer, null),\n new Renderer.NodeRemoveButton(this.renderer, null),\n new Renderer.NodeLinkButton(this.renderer, null),\n new Renderer.NodeEnlargeButton(this.renderer, null),\n new Renderer.NodeShrinkButton(this.renderer, null)\n ];\n this.pending_delete_buttons = [\n new Renderer.NodeRevertButton(this.renderer, null)\n ];\n this.all_buttons = this.normal_buttons.concat(this.pending_delete_buttons);\n\n for (var i = 0; i < this.all_buttons.length; i++) {\n this.all_buttons[i].source_representation = this;\n }\n this.active_buttons = [];\n } else {\n this.active_buttons = this.all_buttons = [];\n }\n this.last_circle_radius = 1;\n\n if (this.renderer.minimap) {\n this.renderer.minimap.node_layer.activate();\n this.minimap_circle = new paper.Path.Circle([0, 0], 1);\n this.minimap_circle.__representation = this.renderer.minimap.miniframe.__representation;\n this.renderer.minimap.node_group.addChild(this.minimap_circle);\n }\n },\n buildShape: function(){\n if( 'shape' in this.model.changed ) {\n delete this.img;\n }\n if(this.circle){\n this.circle.remove();\n delete this.circle;\n }\n // \"circle\" \"rectangle\" \"ellipse\" \"polygon\" \"star\" \"diamond\"\n this.shapeBuilder = new ShapeBuilder(this.model.get(\"shape\"));\n this.circle = this.shapeBuilder.getShape();\n this.circle.__representation = this;\n this.circle.sendToBack();\n this.last_circle_radius = 1;\n },\n redraw: function(options) {\n if( 'shape' in this.model.changed && 'change' in options && options.change ) {\n //if( 'shape' in this.model.changed ) {\n this.buildShape();\n }\n var _model_coords = new paper.Point(this.model.get(\"position\")),\n _baseRadius = this.options.node_size_base * Math.exp((this.model.get(\"size\") || 0) * Utils._NODE_SIZE_STEP);\n if (!this.is_dragging || !this.paper_coords) {\n this.paper_coords = this.renderer.toPaperCoords(_model_coords);\n }\n this.circle_radius = _baseRadius * this.renderer.scale;\n if (this.last_circle_radius !== this.circle_radius) {\n this.all_buttons.forEach(function(b) {\n b.setSectorSize();\n });\n this.circle.scale(this.circle_radius / this.last_circle_radius);\n if (this.node_image) {\n this.node_image.scale(this.circle_radius / this.last_circle_radius);\n }\n }\n this.circle.position = this.paper_coords;\n if (this.node_image) {\n this.node_image.position = this.paper_coords.subtract(this.image_delta.multiply(this.circle_radius));\n }\n this.last_circle_radius = this.circle_radius;\n\n var old_act_btn = this.active_buttons;\n\n var opacity = 1;\n if (this.model.get(\"delete_scheduled\")) {\n opacity = 0.5;\n this.active_buttons = this.pending_delete_buttons;\n this.circle.dashArray = [2,2];\n } else {\n opacity = 1;\n this.active_buttons = this.normal_buttons;\n this.circle.dashArray = null;\n }\n\n if (this.selected && this.renderer.isEditable()) {\n if (old_act_btn !== this.active_buttons) {\n old_act_btn.forEach(function(b) {\n b.hide();\n });\n }\n this.active_buttons.forEach(function(b) {\n b.show();\n });\n }\n\n if (this.node_image) {\n this.node_image.opacity = this.highlighted ? opacity * 0.5 : (opacity - 0.01);\n }\n\n this.circle.fillColor = this.highlighted ? this.options.highlighted_node_fill_color : this.options.node_fill_color;\n\n this.circle.opacity = this.options.show_node_circles ? opacity : 0.01;\n\n var _text = this.model.get(\"title\") || this.renkan.translate(this.options.label_untitled_nodes) || \"\";\n _text = Utils.shortenText(_text, this.options.node_label_max_length);\n\n if (typeof this.highlighted === \"object\") {\n this.title.html(this.highlighted.replace(_(_text).escape(),'<span class=\"Rk-Highlighted\">$1</span>'));\n } else {\n this.title.text(_text);\n }\n\n this.title.css({\n left: this.paper_coords.x,\n top: this.paper_coords.y + this.circle_radius * this.h_ratio + this.options.node_label_distance,\n opacity: opacity\n });\n var _color = this.model.get(\"color\") || (this.model.get(\"created_by\") || Utils._USER_PLACEHOLDER(this.renkan)).get(\"color\");\n this.circle.strokeColor = _color;\n var _pc = this.paper_coords;\n this.all_buttons.forEach(function(b) {\n b.moveTo(_pc);\n });\n var lastImage = this.img;\n this.img = this.model.get(\"image\");\n if (this.img && this.img !== lastImage) {\n this.showImage();\n if(this.circle) {\n this.circle.sendToBack();\n }\n }\n if (this.node_image && !this.img) {\n this.node_image.remove();\n delete this.node_image;\n }\n\n if (this.renderer.minimap) {\n this.minimap_circle.fillColor = _color;\n var minipos = this.renderer.toMinimapCoords(_model_coords),\n miniradius = this.renderer.minimap.scale * _baseRadius,\n minisize = new paper.Size([miniradius, miniradius]);\n this.minimap_circle.fitBounds(minipos.subtract(minisize), minisize.multiply(2));\n }\n\n if (typeof options === 'undefined' || !('dontRedrawEdges' in options) || !options.dontRedrawEdges) {\n var _this = this;\n _.each(\n this.project.get(\"edges\").filter(\n function (ed) {\n return ((ed.get(\"to\") === _this.model) || (ed.get(\"from\") === _this.model));\n }\n ),\n function(edge, index, list) {\n var repr = _this.renderer.getRepresentationByModel(edge);\n if (repr && typeof repr.from_representation !== \"undefined\" && typeof repr.from_representation.paper_coords !== \"undefined\" && typeof repr.to_representation !== \"undefined\" && typeof repr.to_representation.paper_coords !== \"undefined\") {\n repr.redraw();\n }\n }\n );\n }\n\n },\n showImage: function() {\n var _image = null;\n if (typeof this.renderer.image_cache[this.img] === \"undefined\") {\n _image = new Image();\n this.renderer.image_cache[this.img] = _image;\n _image.src = this.img;\n } else {\n _image = this.renderer.image_cache[this.img];\n }\n if (_image.width) {\n if (this.node_image) {\n this.node_image.remove();\n }\n this.renderer.node_layer.activate();\n var width = _image.width,\n height = _image.height,\n clipPath = this.model.get(\"clip_path\"),\n hasClipPath = (typeof clipPath !== \"undefined\" && clipPath),\n _clip = null,\n baseRadius = null,\n centerPoint = null;\n\n if (hasClipPath) {\n _clip = new paper.Path();\n var instructions = clipPath.match(/[a-z][^a-z]+/gi) || [],\n lastCoords = [0,0],\n minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity;\n\n var transformCoords = function(tabc, relative) {\n var newCoords = tabc.slice(1).map(function(v, k) {\n var res = parseFloat(v),\n isY = k % 2;\n if (isY) {\n res = ( res - 0.5 ) * height;\n } else {\n res = ( res - 0.5 ) * width;\n }\n if (relative) {\n res += lastCoords[isY];\n }\n if (isY) {\n minY = Math.min(minY, res);\n maxY = Math.max(maxY, res);\n } else {\n minX = Math.min(minX, res);\n maxX = Math.max(maxX, res);\n }\n return res;\n });\n lastCoords = newCoords.slice(-2);\n return newCoords;\n };\n\n instructions.forEach(function(instr) {\n var coords = instr.match(/([a-z]|[0-9.-]+)/ig) || [\"\"];\n switch(coords[0]) {\n case \"M\":\n _clip.moveTo(transformCoords(coords));\n break;\n case \"m\":\n _clip.moveTo(transformCoords(coords, true));\n break;\n case \"L\":\n _clip.lineTo(transformCoords(coords));\n break;\n case \"l\":\n _clip.lineTo(transformCoords(coords, true));\n break;\n case \"C\":\n _clip.cubicCurveTo(transformCoords(coords));\n break;\n case \"c\":\n _clip.cubicCurveTo(transformCoords(coords, true));\n break;\n case \"Q\":\n _clip.quadraticCurveTo(transformCoords(coords));\n break;\n case \"q\":\n _clip.quadraticCurveTo(transformCoords(coords, true));\n break;\n }\n });\n\n baseRadius = Math[this.options.node_images_fill_mode ? \"min\" : \"max\"](maxX - minX, maxY - minY) / 2;\n centerPoint = new paper.Point((maxX + minX) / 2, (maxY + minY) / 2);\n if (!this.options.show_node_circles) {\n this.h_ratio = (maxY - minY) / (2 * baseRadius);\n }\n } else {\n baseRadius = Math[this.options.node_images_fill_mode ? \"min\" : \"max\"](width, height) / 2;\n centerPoint = new paper.Point(0,0);\n if (!this.options.show_node_circles) {\n this.h_ratio = height / (2 * baseRadius);\n }\n }\n var _raster = new paper.Raster(_image);\n _raster.locked = true; // Disable mouse events on icon\n if (hasClipPath) {\n _raster = new paper.Group(_clip, _raster);\n _raster.opacity = 0.99;\n /* This is a workaround to allow clipping at group level\n * If opacity was set to 1, paper.js would merge all clipping groups in one (known bug).\n */\n _raster.clipped = true;\n _clip.__representation = this;\n }\n if (this.options.clip_node_images) {\n var _circleClip = this.shapeBuilder.getImageShape(centerPoint, baseRadius);\n _raster = new paper.Group(_circleClip, _raster);\n _raster.opacity = 0.99;\n _raster.clipped = true;\n _circleClip.__representation = this;\n }\n this.image_delta = centerPoint.divide(baseRadius);\n this.node_image = _raster;\n this.node_image.__representation = _this;\n this.node_image.scale(this.circle_radius / baseRadius);\n this.node_image.position = this.paper_coords.subtract(this.image_delta.multiply(this.circle_radius));\n this.node_image.insertAbove(this.circle);\n } else {\n var _this = this;\n $(_image).on(\"load\", function() {\n _this.showImage();\n });\n }\n },\n paperShift: function(_delta) {\n if (this.options.editor_mode) {\n if (!this.renkan.read_only) {\n this.is_dragging = true;\n this.paper_coords = this.paper_coords.add(_delta);\n this.redraw();\n }\n } else {\n this.renderer.paperShift(_delta);\n }\n },\n openEditor: function() {\n this.renderer.removeRepresentationsOfType(\"editor\");\n var _editor = this.renderer.addRepresentation(\"NodeEditor\",null);\n _editor.source_representation = this;\n _editor.draw();\n },\n select: function() {\n this.selected = true;\n this.circle.strokeWidth = this.options.selected_node_stroke_width;\n if (this.renderer.isEditable()) {\n this.active_buttons.forEach(function(b) {\n b.show();\n });\n }\n var _uri = this.model.get(\"uri\");\n if (_uri) {\n $('.Rk-Bin-Item').each(function() {\n var _el = $(this);\n if (_el.attr(\"data-uri\") === _uri) {\n _el.addClass(\"selected\");\n }\n });\n }\n if (!this.options.editor_mode) {\n this.openEditor();\n }\n\n if (this.renderer.minimap) {\n this.minimap_circle.strokeWidth = this.options.minimap_highlight_weight;\n this.minimap_circle.strokeColor = this.options.minimap_highlight_color;\n }\n this._super(\"select\");\n },\n hideButtons: function() {\n this.all_buttons.forEach(function(b) {\n b.hide();\n });\n delete(this.buttonTimeout);\n },\n unselect: function(_newTarget) {\n if (!_newTarget || _newTarget.source_representation !== this) {\n this.selected = false;\n var _this = this;\n this.buttons_timeout = setTimeout(function() { _this.hideButtons(); }, 200);\n this.circle.strokeWidth = this.options.node_stroke_width;\n $('.Rk-Bin-Item').removeClass(\"selected\");\n if (this.renderer.minimap) {\n this.minimap_circle.strokeColor = undefined;\n }\n this._super(\"unselect\");\n }\n },\n highlight: function(textToReplace) {\n var hlvalue = textToReplace || true;\n if (this.highlighted === hlvalue) {\n return;\n }\n this.highlighted = hlvalue;\n this.redraw();\n this.renderer.throttledPaperDraw();\n },\n unhighlight: function() {\n if (!this.highlighted) {\n return;\n }\n this.highlighted = false;\n this.redraw();\n this.renderer.throttledPaperDraw();\n },\n saveCoords: function() {\n var _coords = this.renderer.toModelCoords(this.paper_coords),\n _data = {\n position: {\n x: _coords.x,\n y: _coords.y\n }\n };\n if (this.renderer.isEditable()) {\n this.model.set(_data);\n }\n },\n mousedown: function(_event, _isTouch) {\n if (_isTouch) {\n this.renderer.unselectAll();\n this.select();\n }\n },\n mouseup: function(_event, _isTouch) {\n if (this.renderer.is_dragging && this.renderer.isEditable()) {\n this.saveCoords();\n } else {\n if (!_isTouch && !this.model.get(\"delete_scheduled\")) {\n this.openEditor();\n }\n this.model.trigger(\"clicked\");\n }\n this.renderer.click_target = null;\n this.renderer.is_dragging = false;\n this.is_dragging = false;\n },\n destroy: function(_event) {\n this._super(\"destroy\");\n this.all_buttons.forEach(function(b) {\n b.destroy();\n });\n this.circle.remove();\n this.title.remove();\n if (this.renderer.minimap) {\n this.minimap_circle.remove();\n }\n if (this.node_image) {\n this.node_image.remove();\n }\n }\n }).value();\n\n return NodeRepr;\n\n});\n\n\ndefine('renderer/edge',['jquery', 'underscore', 'requtils', 'renderer/baserepresentation'], function ($, _, requtils, BaseRepresentation) {\n \n\n var Utils = requtils.getUtils();\n\n /* Edge Class Begin */\n\n //var Edge = Renderer.Edge = Utils.inherit(Renderer._BaseRepresentation);\n var Edge = Utils.inherit(BaseRepresentation);\n\n _(Edge.prototype).extend({\n _init: function() {\n this.renderer.edge_layer.activate();\n this.type = \"Edge\";\n this.from_representation = this.renderer.getRepresentationByModel(this.model.get(\"from\"));\n this.to_representation = this.renderer.getRepresentationByModel(this.model.get(\"to\"));\n this.bundle = this.renderer.addToBundles(this);\n this.line = new paper.Path();\n this.line.add([0,0],[0,0],[0,0]);\n this.line.__representation = this;\n this.line.strokeWidth = this.options.edge_stroke_width;\n this.arrow = new paper.Path();\n this.arrow.add(\n [ 0, 0 ],\n [ this.options.edge_arrow_length, this.options.edge_arrow_width / 2 ],\n [ 0, this.options.edge_arrow_width ]\n );\n this.arrow.__representation = this;\n this.text = $('<div class=\"Rk-Label Rk-Edge-Label\">').appendTo(this.renderer.labels_$);\n this.arrow_angle = 0;\n if (this.options.editor_mode) {\n var Renderer = requtils.getRenderer();\n this.normal_buttons = [\n new Renderer.EdgeEditButton(this.renderer, null),\n new Renderer.EdgeRemoveButton(this.renderer, null)\n ];\n this.pending_delete_buttons = [\n new Renderer.EdgeRevertButton(this.renderer, null)\n ];\n this.all_buttons = this.normal_buttons.concat(this.pending_delete_buttons);\n for (var i = 0; i < this.all_buttons.length; i++) {\n this.all_buttons[i].source_representation = this;\n }\n this.active_buttons = [];\n } else {\n this.active_buttons = this.all_buttons = [];\n }\n\n if (this.renderer.minimap) {\n this.renderer.minimap.edge_layer.activate();\n this.minimap_line = new paper.Path();\n this.minimap_line.add([0,0],[0,0]);\n this.minimap_line.__representation = this.renderer.minimap.miniframe.__representation;\n this.minimap_line.strokeWidth = 1;\n }\n },\n redraw: function() {\n var from = this.model.get(\"from\"),\n to = this.model.get(\"to\");\n if (!from || !to) {\n return;\n }\n this.from_representation = this.renderer.getRepresentationByModel(from);\n this.to_representation = this.renderer.getRepresentationByModel(to);\n if (typeof this.from_representation === \"undefined\" || typeof this.to_representation === \"undefined\") {\n return;\n }\n var _p0a = this.from_representation.paper_coords,\n _p1a = this.to_representation.paper_coords,\n _v = _p1a.subtract(_p0a),\n _r = _v.length,\n _u = _v.divide(_r),\n _ortho = new paper.Point([- _u.y, _u.x]),\n _group_pos = this.bundle.getPosition(this),\n _delta = _ortho.multiply( this.options.edge_gap_in_bundles * _group_pos ),\n _p0b = _p0a.add(_delta), /* Adding a 4 px difference */\n _p1b = _p1a.add(_delta), /* to differentiate bundled links */\n _a = _v.angle,\n _textdelta = _ortho.multiply(this.options.edge_label_distance),\n _handle = _v.divide(3),\n _color = this.model.get(\"color\") || this.model.get(\"color\") || (this.model.get(\"created_by\") || Utils._USER_PLACEHOLDER(this.renkan)).get(\"color\"),\n opacity = 1;\n\n if (this.model.get(\"delete_scheduled\") || this.from_representation.model.get(\"delete_scheduled\") || this.to_representation.model.get(\"delete_scheduled\")) {\n opacity = 0.5;\n this.line.dashArray = [2, 2];\n } else {\n opacity = 1;\n this.line.dashArray = null;\n }\n\n var old_act_btn = this.active_buttons;\n\n this.active_buttons = this.model.get(\"delete_scheduled\") ? this.pending_delete_buttons : this.normal_buttons;\n\n if (this.selected && this.renderer.isEditable() && old_act_btn !== this.active_buttons) {\n old_act_btn.forEach(function(b) {\n b.hide();\n });\n this.active_buttons.forEach(function(b) {\n b.show();\n });\n }\n\n this.paper_coords = _p0b.add(_p1b).divide(2);\n this.line.strokeColor = _color;\n this.line.opacity = opacity;\n this.line.segments[0].point = _p0a;\n this.line.segments[1].point = this.paper_coords;\n this.line.segments[1].handleIn = _handle.multiply(-1);\n this.line.segments[1].handleOut = _handle;\n this.line.segments[2].point = _p1a;\n this.arrow.rotate(_a - this.arrow_angle);\n this.arrow.fillColor = _color;\n this.arrow.opacity = opacity;\n this.arrow.position = this.paper_coords;\n this.arrow_angle = _a;\n if (_a > 90) {\n _a -= 180;\n _textdelta = _textdelta.multiply(-1);\n }\n if (_a < -90) {\n _a += 180;\n _textdelta = _textdelta.multiply(-1);\n }\n var _text = this.model.get(\"title\") || this.renkan.translate(this.options.label_untitled_edges) || \"\";\n _text = Utils.shortenText(_text, this.options.node_label_max_length);\n this.text.text(_text);\n var _textpos = this.paper_coords.add(_textdelta);\n this.text.css({\n left: _textpos.x,\n top: _textpos.y,\n transform: \"rotate(\" + _a + \"deg)\",\n \"-moz-transform\": \"rotate(\" + _a + \"deg)\",\n \"-webkit-transform\": \"rotate(\" + _a + \"deg)\",\n opacity: opacity\n });\n this.text_angle = _a;\n\n var _pc = this.paper_coords;\n this.all_buttons.forEach(function(b) {\n b.moveTo(_pc);\n });\n\n if (this.renderer.minimap) {\n this.minimap_line.strokeColor = _color;\n this.minimap_line.segments[0].point = this.renderer.toMinimapCoords(new paper.Point(this.from_representation.model.get(\"position\")));\n this.minimap_line.segments[1].point = this.renderer.toMinimapCoords(new paper.Point(this.to_representation.model.get(\"position\")));\n }\n },\n openEditor: function() {\n this.renderer.removeRepresentationsOfType(\"editor\");\n var _editor = this.renderer.addRepresentation(\"EdgeEditor\",null);\n _editor.source_representation = this;\n _editor.draw();\n },\n select: function() {\n this.selected = true;\n this.line.strokeWidth = this.options.selected_edge_stroke_width;\n if (this.renderer.isEditable()) {\n this.active_buttons.forEach(function(b) {\n b.show();\n });\n }\n if (!this.options.editor_mode) {\n this.openEditor();\n }\n this._super(\"select\");\n },\n unselect: function(_newTarget) {\n if (!_newTarget || _newTarget.source_representation !== this) {\n this.selected = false;\n if (this.options.editor_mode) {\n this.all_buttons.forEach(function(b) {\n b.hide();\n });\n }\n this.line.strokeWidth = this.options.edge_stroke_width;\n this._super(\"unselect\");\n }\n },\n mousedown: function(_event, _isTouch) {\n if (_isTouch) {\n this.renderer.unselectAll();\n this.select();\n }\n },\n mouseup: function(_event, _isTouch) {\n if (!this.renkan.read_only && this.renderer.is_dragging) {\n this.from_representation.saveCoords();\n this.to_representation.saveCoords();\n this.from_representation.is_dragging = false;\n this.to_representation.is_dragging = false;\n } else {\n if (!_isTouch) {\n this.openEditor();\n }\n this.model.trigger(\"clicked\");\n }\n this.renderer.click_target = null;\n this.renderer.is_dragging = false;\n },\n paperShift: function(_delta) {\n if (this.options.editor_mode) {\n if (!this.options.read_only) {\n this.from_representation.paperShift(_delta);\n this.to_representation.paperShift(_delta);\n }\n } else {\n this.renderer.paperShift(_delta);\n }\n },\n destroy: function() {\n this._super(\"destroy\");\n this.line.remove();\n this.arrow.remove();\n this.text.remove();\n if (this.renderer.minimap) {\n this.minimap_line.remove();\n }\n this.all_buttons.forEach(function(b) {\n b.destroy();\n });\n var _this = this;\n this.bundle.edges = _.reject(this.bundle.edges, function(_edge) {\n return _this === _edge;\n });\n }\n }).value();\n\n return Edge;\n\n});\n\n\n\ndefine('renderer/tempedge',['jquery', 'underscore', 'requtils', 'renderer/baserepresentation'], function ($, _, requtils, BaseRepresentation) {\n \n\n var Utils = requtils.getUtils();\n\n /* TempEdge Class Begin */\n\n //var TempEdge = Renderer.TempEdge = Utils.inherit(Renderer._BaseRepresentation);\n var TempEdge = Utils.inherit(BaseRepresentation);\n\n _(TempEdge.prototype).extend({\n _init: function() {\n this.renderer.edge_layer.activate();\n this.type = \"Temp-edge\";\n\n var _color = (this.project.get(\"users\").get(this.renkan.current_user) || Utils._USER_PLACEHOLDER(this.renkan)).get(\"color\");\n this.line = new paper.Path();\n this.line.strokeColor = _color;\n this.line.dashArray = [4, 2];\n this.line.strokeWidth = this.options.selected_edge_stroke_width;\n this.line.add([0,0],[0,0]);\n this.line.__representation = this;\n this.arrow = new paper.Path();\n this.arrow.fillColor = _color;\n this.arrow.add(\n [ 0, 0 ],\n [ this.options.edge_arrow_length, this.options.edge_arrow_width / 2 ],\n [ 0, this.options.edge_arrow_width ]\n );\n this.arrow.__representation = this;\n this.arrow_angle = 0;\n },\n redraw: function() {\n var _p0 = this.from_representation.paper_coords,\n _p1 = this.end_pos,\n _a = _p1.subtract(_p0).angle,\n _c = _p0.add(_p1).divide(2);\n this.line.segments[0].point = _p0;\n this.line.segments[1].point = _p1;\n this.arrow.rotate(_a - this.arrow_angle);\n this.arrow.position = _c;\n this.arrow_angle = _a;\n },\n paperShift: function(_delta) {\n if (!this.renderer.isEditable()) {\n this.renderer.removeRepresentation(_this);\n paper.view.draw();\n return;\n }\n this.end_pos = this.end_pos.add(_delta);\n var _hitResult = paper.project.hitTest(this.end_pos);\n this.renderer.findTarget(_hitResult);\n this.redraw();\n },\n mouseup: function(_event, _isTouch) {\n var _hitResult = paper.project.hitTest(_event.point),\n _model = this.from_representation.model,\n _endDrag = true;\n if (_hitResult && typeof _hitResult.item.__representation !== \"undefined\") {\n var _target = _hitResult.item.__representation;\n if (_target.type.substr(0,4) === \"Node\") {\n var _destmodel = _target.model || _target.source_representation.model;\n if (_model !== _destmodel) {\n var _data = {\n id: Utils.getUID('edge'),\n created_by: this.renkan.current_user,\n from: _model,\n to: _destmodel\n };\n if (this.renderer.isEditable()) {\n this.project.addEdge(_data);\n }\n }\n }\n\n if (_model === _target.model || (_target.source_representation && _target.source_representation.model === _model)) {\n _endDrag = false;\n this.renderer.is_dragging = true;\n }\n }\n if (_endDrag) {\n this.renderer.click_target = null;\n this.renderer.is_dragging = false;\n this.renderer.removeRepresentation(this);\n paper.view.draw();\n }\n },\n destroy: function() {\n this.arrow.remove();\n this.line.remove();\n }\n }).value();\n\n /* TempEdge Class End */\n\n return TempEdge;\n\n});\n\n\ndefine('renderer/baseeditor',['jquery', 'underscore', 'requtils', 'renderer/baserepresentation'], function ($, _, requtils, BaseRepresentation) {\n \n\n var Utils = requtils.getUtils();\n\n /* _BaseEditor Begin */\n //var _BaseEditor = Renderer._BaseEditor = Utils.inherit(Renderer._BaseRepresentation);\n var _BaseEditor = Utils.inherit(BaseRepresentation);\n\n _(_BaseEditor.prototype).extend({\n _init: function() {\n this.renderer.buttons_layer.activate();\n this.type = \"editor\";\n this.editor_block = new paper.Path();\n var _pts = _.map(_.range(8), function() {return [0,0];});\n this.editor_block.add.apply(this.editor_block, _pts);\n this.editor_block.strokeWidth = this.options.tooltip_border_width;\n this.editor_block.strokeColor = this.options.tooltip_border_color;\n this.editor_block.opacity = 0.8;\n this.editor_$ = $('<div>')\n .appendTo(this.renderer.editor_$)\n .css({\n position: \"absolute\",\n opacity: 0.8\n })\n .hide();\n },\n destroy: function() {\n this.editor_block.remove();\n this.editor_$.remove();\n }\n }).value();\n\n /* _BaseEditor End */\n\n return _BaseEditor;\n\n});\n\n\ndefine('renderer/nodeeditor',['jquery', 'underscore', 'requtils', 'renderer/baseeditor'], function ($, _, requtils, BaseEditor) {\n \n\n var Utils = requtils.getUtils();\n\n /* NodeEditor Begin */\n //var NodeEditor = Renderer.NodeEditor = Utils.inherit(Renderer._BaseEditor);\n var NodeEditor = Utils.inherit(BaseEditor);\n\n _(NodeEditor.prototype).extend({\n _init: function() {\n BaseEditor.prototype._init.apply(this);\n this.template = this.options.templates['templates/nodeeditor.html'];\n this.readOnlyTemplate = this.options.templates['templates/nodeeditor_readonly.html'];\n },\n draw: function() {\n var _model = this.source_representation.model,\n _created_by = _model.get(\"created_by\") || Utils._USER_PLACEHOLDER(this.renkan),\n _template = (this.renderer.isEditable() ? this.template : this.readOnlyTemplate ),\n _image_placeholder = this.options.static_url + \"img/image-placeholder.png\",\n _size = (_model.get(\"size\") || 0);\n this.editor_$\n .html(_template({\n node: {\n has_creator: !!_model.get(\"created_by\"),\n title: _model.get(\"title\"),\n uri: _model.get(\"uri\"),\n short_uri: Utils.shortenText((_model.get(\"uri\") || \"\").replace(/^(https?:\\/\\/)?(www\\.)?/,'').replace(/\\/$/,''),40),\n description: _model.get(\"description\"),\n image: _model.get(\"image\") || \"\",\n image_placeholder: _image_placeholder,\n color: _model.get(\"color\") || _created_by.get(\"color\"),\n clip_path: _model.get(\"clip_path\") || false,\n created_by_color: _created_by.get(\"color\"),\n created_by_title: _created_by.get(\"title\"),\n size: (_size > 0 ? \"+\" : \"\") + _size,\n shape: _model.get(\"shape\") || \"circle\"\n },\n renkan: this.renkan,\n options: this.options,\n shortenText: Utils.shortenText\n }));\n this.redraw();\n var _this = this,\n closeEditor = function() {\n _this.editor_$.off(\"keyup\");\n _this.editor_$.find(\"input, textarea, select\").off(\"change keyup paste\");\n _this.editor_$.find(\".Rk-Edit-Image-File\").off('change');\n _this.editor_$.find(\".Rk-Edit-ColorPicker-Wrapper\").off('hover');\n _this.editor_$.find(\".Rk-Edit-Size-Down\").off('click');\n _this.editor_$.find(\".Rk-Edit-Size-Up\").off('click');\n _this.editor_$.find(\".Rk-Edit-Image-Del\").off('click');\n _this.editor_$.find(\".Rk-Edit-ColorPicker\").find(\"li\").off('hover click');\n _this.editor_$.find(\".Rk-CloseX\").off('click');\n _this.editor_$.find(\".Rk-Edit-Goto\").off('click');\n\n _this.renderer.removeRepresentation(_this);\n paper.view.draw();\n };\n\n this.editor_$.find(\".Rk-CloseX\").click(closeEditor);\n\n this.editor_$.find(\".Rk-Edit-Goto\").click(function() {\n if (!_model.get(\"uri\")) {\n return false;\n }\n });\n\n if (this.renderer.isEditable()) {\n\n var onFieldChange = _.throttle(function() {\n _.defer(function() {\n if (_this.renderer.isEditable()) {\n var _data = {\n title: _this.editor_$.find(\".Rk-Edit-Title\").val()\n };\n if (_this.options.show_node_editor_uri) {\n _data.uri = _this.editor_$.find(\".Rk-Edit-URI\").val();\n _this.editor_$.find(\".Rk-Edit-Goto\").attr(\"href\",_data.uri || \"#\");\n }\n if (_this.options.show_node_editor_image) {\n _data.image = _this.editor_$.find(\".Rk-Edit-Image\").val();\n _this.editor_$.find(\".Rk-Edit-ImgPreview\").attr(\"src\", _data.image || _image_placeholder);\n }\n if (_this.options.show_node_editor_description) {\n _data.description = _this.editor_$.find(\".Rk-Edit-Description\").val();\n }\n if (_this.options.change_shapes) {\n if(_model.get(\"shape\")!==_this.editor_$.find(\".Rk-Edit-Shape\").val()){\n _data.shape = _this.editor_$.find(\".Rk-Edit-Shape\").val();\n }\n }\n _model.set(_data);\n _this.redraw();\n } else {\n closeEditor();\n }\n });\n }, 500);\n\n this.editor_$.on(\"keyup\", function(_e) {\n if (_e.keyCode === 27) {\n closeEditor();\n }\n });\n\n this.editor_$.find(\"input, textarea, select\").on(\"change keyup paste\", onFieldChange);\n\n if(_this.options.allow_image_upload) {\n this.editor_$.find(\".Rk-Edit-Image-File\").change(function() {\n if (this.files.length) {\n var f = this.files[0],\n fr = new FileReader();\n if (f.type.substr(0,5) !== \"image\") {\n alert(_this.renkan.translate(\"This file is not an image\"));\n return;\n }\n if (f.size > (_this.options.uploaded_image_max_kb * 1024)) {\n alert(_this.renkan.translate(\"Image size must be under \") + _this.options.uploaded_image_max_kb + _this.renkan.translate(\"KB\"));\n return;\n }\n fr.onload = function(e) {\n _this.editor_$.find(\".Rk-Edit-Image\").val(e.target.result);\n onFieldChange();\n };\n fr.readAsDataURL(f);\n }\n });\n }\n this.editor_$.find(\".Rk-Edit-Title\")[0].focus();\n\n var _picker = _this.editor_$.find(\".Rk-Edit-ColorPicker\");\n\n this.editor_$.find(\".Rk-Edit-ColorPicker-Wrapper\").hover(\n function(_e) {\n _e.preventDefault();\n _picker.show();\n },\n function(_e) {\n _e.preventDefault();\n _picker.hide();\n }\n );\n\n _picker.find(\"li\").hover(\n function(_e) {\n _e.preventDefault();\n _this.editor_$.find(\".Rk-Edit-Color\").css(\"background\", $(this).attr(\"data-color\"));\n },\n function(_e) {\n _e.preventDefault();\n _this.editor_$.find(\".Rk-Edit-Color\").css(\"background\", _model.get(\"color\") || (_model.get(\"created_by\") || Utils._USER_PLACEHOLDER(_this.renkan)).get(\"color\"));\n }\n ).click(function(_e) {\n _e.preventDefault();\n if (_this.renderer.isEditable()) {\n _model.set(\"color\", $(this).attr(\"data-color\"));\n _picker.hide();\n paper.view.draw();\n } else {\n closeEditor();\n }\n });\n\n var shiftSize = function(n) {\n if (_this.renderer.isEditable()) {\n var _newsize = n+(_model.get(\"size\") || 0);\n _this.editor_$.find(\".Rk-Edit-Size-Value\").text((_newsize > 0 ? \"+\" : \"\") + _newsize);\n _model.set(\"size\", _newsize);\n paper.view.draw();\n } else {\n closeEditor();\n }\n };\n\n this.editor_$.find(\".Rk-Edit-Size-Down\").click(function() {\n shiftSize(-1);\n return false;\n });\n this.editor_$.find(\".Rk-Edit-Size-Up\").click(function() {\n shiftSize(1);\n return false;\n });\n\n this.editor_$.find(\".Rk-Edit-Image-Del\").click(function() {\n _this.editor_$.find(\".Rk-Edit-Image\").val('');\n onFieldChange();\n return false;\n });\n } else {\n if (typeof this.source_representation.highlighted === \"object\") {\n var titlehtml = this.source_representation.highlighted.replace(_(_model.get(\"title\")).escape(),'<span class=\"Rk-Highlighted\">$1</span>');\n this.editor_$.find(\".Rk-Display-Title\" + (_model.get(\"uri\") ? \" a\" : \"\")).html(titlehtml);\n if (this.options.show_node_tooltip_description) {\n this.editor_$.find(\".Rk-Display-Description\").html(this.source_representation.highlighted.replace(_(_model.get(\"description\")).escape(),'<span class=\"Rk-Highlighted\">$1</span>'));\n }\n }\n }\n this.editor_$.find(\"img\").load(function() {\n _this.redraw();\n });\n },\n redraw: function() {\n var _coords = this.source_representation.paper_coords;\n Utils.drawEditBox(this.options, _coords, this.editor_block, this.source_representation.circle_radius * 0.75, this.editor_$);\n this.editor_$.show();\n paper.view.draw();\n }\n }).value();\n\n /* NodeEditor End */\n\n return NodeEditor;\n\n});\n\n\ndefine('renderer/edgeeditor',['jquery', 'underscore', 'requtils', 'renderer/baseeditor'], function ($, _, requtils, BaseEditor) {\n \n\n var Utils = requtils.getUtils();\n\n /* EdgeEditor Begin */\n\n //var EdgeEditor = Renderer.EdgeEditor = Utils.inherit(Renderer._BaseEditor);\n var EdgeEditor = Utils.inherit(BaseEditor);\n\n _(EdgeEditor.prototype).extend({\n _init: function() {\n BaseEditor.prototype._init.apply(this);\n this.template = this.options.templates['templates/edgeeditor.html'];\n this.readOnlyTemplate = this.options.templates['templates/edgeeditor_readonly.html'];\n },\n draw: function() {\n var _model = this.source_representation.model,\n _from_model = _model.get(\"from\"),\n _to_model = _model.get(\"to\"),\n _created_by = _model.get(\"created_by\") || Utils._USER_PLACEHOLDER(this.renkan),\n _template = (this.renderer.isEditable() ? this.template : this.readOnlyTemplate);\n this.editor_$\n .html(_template({\n edge: {\n has_creator: !!_model.get(\"created_by\"),\n title: _model.get(\"title\"),\n uri: _model.get(\"uri\"),\n short_uri: Utils.shortenText((_model.get(\"uri\") || \"\").replace(/^(https?:\\/\\/)?(www\\.)?/,'').replace(/\\/$/,''),40),\n description: _model.get(\"description\"),\n color: _model.get(\"color\") || _created_by.get(\"color\"),\n from_title: _from_model.get(\"title\"),\n to_title: _to_model.get(\"title\"),\n from_color: _from_model.get(\"color\") || (_from_model.get(\"created_by\") || Utils._USER_PLACEHOLDER(this.renkan)).get(\"color\"),\n to_color: _to_model.get(\"color\") || (_to_model.get(\"created_by\") || Utils._USER_PLACEHOLDER(this.renkan)).get(\"color\"),\n created_by_color: _created_by.get(\"color\"),\n created_by_title: _created_by.get(\"title\")\n },\n renkan: this.renkan,\n shortenText: Utils.shortenText,\n options: this.options\n }));\n this.redraw();\n var _this = this,\n closeEditor = function() {\n _this.renderer.removeRepresentation(_this);\n paper.view.draw();\n };\n this.editor_$.find(\".Rk-CloseX\").click(closeEditor);\n this.editor_$.find(\".Rk-Edit-Goto\").click(function() {\n if (!_model.get(\"uri\")) {\n return false;\n }\n });\n\n if (this.renderer.isEditable()) {\n\n var onFieldChange = _.throttle(function() {\n _.defer(function() {\n if (_this.renderer.isEditable()) {\n var _data = {\n title: _this.editor_$.find(\".Rk-Edit-Title\").val()\n };\n if (_this.options.show_edge_editor_uri) {\n _data.uri = _this.editor_$.find(\".Rk-Edit-URI\").val();\n }\n _this.editor_$.find(\".Rk-Edit-Goto\").attr(\"href\",_data.uri || \"#\");\n _model.set(_data);\n paper.view.draw();\n } else {\n closeEditor();\n }\n });\n },500);\n\n this.editor_$.on(\"keyup\", function(_e) {\n if (_e.keyCode === 27) {\n closeEditor();\n }\n });\n\n this.editor_$.find(\"input\").on(\"keyup change paste\", onFieldChange);\n\n this.editor_$.find(\".Rk-Edit-Vocabulary\").change(function() {\n var e = $(this),\n v = e.val();\n if (v) {\n _this.editor_$.find(\".Rk-Edit-Title\").val(e.find(\":selected\").text());\n _this.editor_$.find(\".Rk-Edit-URI\").val(v);\n onFieldChange();\n }\n });\n this.editor_$.find(\".Rk-Edit-Direction\").click(function() {\n if (_this.renderer.isEditable()) {\n _model.set({\n from: _model.get(\"to\"),\n to: _model.get(\"from\")\n });\n _this.draw();\n } else {\n closeEditor();\n }\n });\n\n var _picker = _this.editor_$.find(\".Rk-Edit-ColorPicker\");\n\n this.editor_$.find(\".Rk-Edit-ColorPicker-Wrapper\").hover(\n function(_e) {\n _e.preventDefault();\n _picker.show();\n },\n function(_e) {\n _e.preventDefault();\n _picker.hide();\n }\n );\n\n _picker.find(\"li\").hover(\n function(_e) {\n _e.preventDefault();\n _this.editor_$.find(\".Rk-Edit-Color\").css(\"background\", $(this).attr(\"data-color\"));\n },\n function(_e) {\n _e.preventDefault();\n _this.editor_$.find(\".Rk-Edit-Color\").css(\"background\", _model.get(\"color\") || (_model.get(\"created_by\") || Utils._USER_PLACEHOLDER(_this.renkan)).get(\"color\"));\n }\n ).click(function(_e) {\n _e.preventDefault();\n if (_this.renderer.isEditable()) {\n _model.set(\"color\", $(this).attr(\"data-color\"));\n _picker.hide();\n paper.view.draw();\n } else {\n closeEditor();\n }\n });\n }\n },\n redraw: function() {\n var _coords = this.source_representation.paper_coords;\n Utils.drawEditBox(this.options, _coords, this.editor_block, 5, this.editor_$);\n this.editor_$.show();\n paper.view.draw();\n }\n }).value();\n\n /* EdgeEditor End */\n\n return EdgeEditor;\n\n});\n\n\ndefine('renderer/nodebutton',['jquery', 'underscore', 'requtils', 'renderer/basebutton'], function ($, _, requtils, BaseButton) {\n \n\n var Utils = requtils.getUtils();\n\n /* _NodeButton Begin */\n\n //var _NodeButton = Renderer._NodeButton = Utils.inherit(Renderer._BaseButton);\n var _NodeButton = Utils.inherit(BaseButton);\n\n _(_NodeButton.prototype).extend({\n setSectorSize: function() {\n var sectorInner = this.source_representation.circle_radius;\n if (sectorInner !== this.lastSectorInner) {\n if (this.sector) {\n this.sector.destroy();\n }\n this.sector = this.renderer.drawSector(\n this, 1 + sectorInner,\n Utils._NODE_BUTTON_WIDTH + sectorInner,\n this.startAngle,\n this.endAngle,\n 1,\n this.imageName,\n this.renkan.translate(this.text)\n );\n this.lastSectorInner = sectorInner;\n }\n },\n unselect: function() {\n BaseButton.prototype.unselect.apply(this, Array.prototype.slice.call(arguments, 1));\n if(this.source_representation && this.source_representation.buttons_timeout) {\n clearTimeout(this.source_representation.buttons_timeout);\n this.source_representation.hideButtons();\n }\n },\n select: function() {\n if(this.source_representation && this.source_representation.buttons_timeout) {\n clearTimeout(this.source_representation.buttons_timeout);\n }\n this.sector.select();\n },\n }).value();\n\n\n /* _NodeButton End */\n\n return _NodeButton;\n\n});\n\n\ndefine('renderer/nodeeditbutton',['jquery', 'underscore', 'requtils', 'renderer/nodebutton'], function ($, _, requtils, NodeButton) {\n \n\n var Utils = requtils.getUtils();\n\n /* NodeEditButton Begin */\n\n //var NodeEditButton = Renderer.NodeEditButton = Utils.inherit(Renderer._NodeButton);\n var NodeEditButton = Utils.inherit(NodeButton);\n\n _(NodeEditButton.prototype).extend({\n _init: function() {\n this.type = \"Node-edit-button\";\n this.lastSectorInner = 0;\n this.startAngle = -135;\n this.endAngle = -45;\n this.imageName = \"edit\";\n this.text = \"Edit\";\n },\n mouseup: function() {\n if (!this.renderer.is_dragging) {\n this.source_representation.openEditor();\n }\n }\n }).value();\n\n /* NodeEditButton End */\n\n return NodeEditButton;\n\n});\n\n\ndefine('renderer/noderemovebutton',['jquery', 'underscore', 'requtils', 'renderer/nodebutton'], function ($, _, requtils, NodeButton) {\n \n\n var Utils = requtils.getUtils();\n\n /* NodeRemoveButton Begin */\n\n //var NodeRemoveButton = Renderer.NodeRemoveButton = Utils.inherit(Renderer._NodeButton);\n var NodeRemoveButton = Utils.inherit(NodeButton);\n\n _(NodeRemoveButton.prototype).extend({\n _init: function() {\n this.type = \"Node-remove-button\";\n this.lastSectorInner = 0;\n this.startAngle = 0;\n this.endAngle = 90;\n this.imageName = \"remove\";\n this.text = \"Remove\";\n },\n mouseup: function() {\n this.renderer.click_target = null;\n this.renderer.is_dragging = false;\n this.renderer.removeRepresentationsOfType(\"editor\");\n if (this.renderer.isEditable()) {\n if (this.options.element_delete_delay) {\n var delid = Utils.getUID(\"delete\");\n this.renderer.delete_list.push({\n id: delid,\n time: new Date().valueOf() + this.options.element_delete_delay\n });\n this.source_representation.model.set(\"delete_scheduled\", delid);\n } else {\n if (confirm(this.renkan.translate('Do you really wish to remove node ') + '\"' + this.source_representation.model.get(\"title\") + '\"?')) {\n this.project.removeNode(this.source_representation.model);\n }\n }\n }\n }\n }).value();\n\n /* NodeRemoveButton End */\n\n return NodeRemoveButton;\n\n});\n\n\ndefine('renderer/noderevertbutton',['jquery', 'underscore', 'requtils', 'renderer/nodebutton'], function ($, _, requtils, NodeButton) {\n \n\n var Utils = requtils.getUtils();\n\n /* NodeRevertButton Begin */\n\n //var NodeRevertButton = Renderer.NodeRevertButton = Utils.inherit(Renderer._NodeButton);\n var NodeRevertButton = Utils.inherit(NodeButton);\n\n _(NodeRevertButton.prototype).extend({\n _init: function() {\n this.type = \"Node-revert-button\";\n this.lastSectorInner = 0;\n this.startAngle = -135;\n this.endAngle = 135;\n this.imageName = \"revert\";\n this.text = \"Cancel deletion\";\n },\n mouseup: function() {\n this.renderer.click_target = null;\n this.renderer.is_dragging = false;\n if (this.renderer.isEditable()) {\n this.source_representation.model.unset(\"delete_scheduled\");\n }\n }\n }).value();\n\n /* NodeRevertButton End */\n\n return NodeRevertButton;\n\n});\n\n\ndefine('renderer/nodelinkbutton',['jquery', 'underscore', 'requtils', 'renderer/nodebutton'], function ($, _, requtils, NodeButton) {\n \n\n var Utils = requtils.getUtils();\n\n /* NodeLinkButton Begin */\n\n //var NodeLinkButton = Renderer.NodeLinkButton = Utils.inherit(Renderer._NodeButton);\n var NodeLinkButton = Utils.inherit(NodeButton);\n\n _(NodeLinkButton.prototype).extend({\n _init: function() {\n this.type = \"Node-link-button\";\n this.lastSectorInner = 0;\n this.startAngle = 90;\n this.endAngle = 180;\n this.imageName = \"link\";\n this.text = \"Link to another node\";\n },\n mousedown: function(_event, _isTouch) {\n if (this.renderer.isEditable()) {\n var _off = this.renderer.canvas_$.offset(),\n _point = new paper.Point([\n _event.pageX - _off.left,\n _event.pageY - _off.top\n ]);\n this.renderer.click_target = null;\n this.renderer.removeRepresentationsOfType(\"editor\");\n this.renderer.addTempEdge(this.source_representation, _point);\n }\n }\n }).value();\n\n /* NodeLinkButton End */\n\n return NodeLinkButton;\n\n});\n\n\n\ndefine('renderer/nodeenlargebutton',['jquery', 'underscore', 'requtils', 'renderer/nodebutton'], function ($, _, requtils, NodeButton) {\n \n\n var Utils = requtils.getUtils();\n\n /* NodeEnlargeButton Begin */\n\n //var NodeEnlargeButton = Renderer.NodeEnlargeButton = Utils.inherit(Renderer._NodeButton);\n var NodeEnlargeButton = Utils.inherit(NodeButton);\n\n _(NodeEnlargeButton.prototype).extend({\n _init: function() {\n this.type = \"Node-enlarge-button\";\n this.lastSectorInner = 0;\n this.startAngle = -45;\n this.endAngle = 0;\n this.imageName = \"enlarge\";\n this.text = \"Enlarge\";\n },\n mouseup: function() {\n var _newsize = 1 + (this.source_representation.model.get(\"size\") || 0);\n this.source_representation.model.set(\"size\", _newsize);\n this.source_representation.select();\n this.select();\n paper.view.draw();\n }\n }).value();\n\n /* NodeEnlargeButton End */\n\n return NodeEnlargeButton;\n\n});\n\n\ndefine('renderer/nodeshrinkbutton',['jquery', 'underscore', 'requtils', 'renderer/nodebutton'], function ($, _, requtils, NodeButton) {\n \n\n var Utils = requtils.getUtils();\n\n /* NodeShrinkButton Begin */\n\n //var NodeShrinkButton = Renderer.NodeShrinkButton = Utils.inherit(Renderer._NodeButton);\n var NodeShrinkButton = Utils.inherit(NodeButton);\n\n _(NodeShrinkButton.prototype).extend({\n _init: function() {\n this.type = \"Node-shrink-button\";\n this.lastSectorInner = 0;\n this.startAngle = -180;\n this.endAngle = -135;\n this.imageName = \"shrink\";\n this.text = \"Shrink\";\n },\n mouseup: function() {\n var _newsize = -1 + (this.source_representation.model.get(\"size\") || 0);\n this.source_representation.model.set(\"size\", _newsize);\n this.source_representation.select();\n this.select();\n paper.view.draw();\n }\n }).value();\n\n /* NodeShrinkButton End */\n\n return NodeShrinkButton;\n\n});\n\n\ndefine('renderer/edgeeditbutton',['jquery', 'underscore', 'requtils', 'renderer/basebutton'], function ($, _, requtils, BaseButton) {\n \n\n var Utils = requtils.getUtils();\n\n /* EdgeEditButton Begin */\n\n //var EdgeEditButton = Renderer.EdgeEditButton = Utils.inherit(Renderer._BaseButton);\n var EdgeEditButton = Utils.inherit(BaseButton);\n\n _(EdgeEditButton.prototype).extend({\n _init: function() {\n this.type = \"Edge-edit-button\";\n this.sector = this.renderer.drawSector(this, Utils._EDGE_BUTTON_INNER, Utils._EDGE_BUTTON_OUTER, -270, -90, 1, \"edit\", this.renkan.translate(\"Edit\"));\n },\n mouseup: function() {\n if (!this.renderer.is_dragging) {\n this.source_representation.openEditor();\n }\n }\n }).value();\n\n /* EdgeEditButton End */\n\n return EdgeEditButton;\n\n});\n\n\ndefine('renderer/edgeremovebutton',['jquery', 'underscore', 'requtils', 'renderer/basebutton'], function ($, _, requtils, BaseButton) {\n \n\n var Utils = requtils.getUtils();\n\n /* EdgeRemoveButton Begin */\n\n //var EdgeRemoveButton = Renderer.EdgeRemoveButton = Utils.inherit(Renderer._BaseButton);\n var EdgeRemoveButton = Utils.inherit(BaseButton);\n\n _(EdgeRemoveButton.prototype).extend({\n _init: function() {\n this.type = \"Edge-remove-button\";\n this.sector = this.renderer.drawSector(this, Utils._EDGE_BUTTON_INNER, Utils._EDGE_BUTTON_OUTER, -90, 90, 1, \"remove\", this.renkan.translate(\"Remove\"));\n },\n mouseup: function() {\n this.renderer.click_target = null;\n this.renderer.is_dragging = false;\n this.renderer.removeRepresentationsOfType(\"editor\");\n if (this.renderer.isEditable()) {\n if (this.options.element_delete_delay) {\n var delid = Utils.getUID(\"delete\");\n this.renderer.delete_list.push({\n id: delid,\n time: new Date().valueOf() + this.options.element_delete_delay\n });\n this.source_representation.model.set(\"delete_scheduled\", delid);\n } else {\n if (confirm(this.renkan.translate('Do you really wish to remove edge ') + '\"' + this.source_representation.model.get(\"title\") + '\"?')) {\n this.project.removeEdge(this.source_representation.model);\n }\n }\n }\n }\n }).value();\n\n /* EdgeRemoveButton End */\n\n return EdgeRemoveButton;\n\n});\n\n\ndefine('renderer/edgerevertbutton',['jquery', 'underscore', 'requtils', 'renderer/basebutton'], function ($, _, requtils, BaseButton) {\n \n\n var Utils = requtils.getUtils();\n\n /* EdgeRevertButton Begin */\n\n //var EdgeRevertButton = Renderer.EdgeRevertButton = Utils.inherit(Renderer._BaseButton);\n var EdgeRevertButton = Utils.inherit(BaseButton);\n\n _(EdgeRevertButton.prototype).extend({\n _init: function() {\n this.type = \"Edge-revert-button\";\n this.sector = this.renderer.drawSector(this, Utils._EDGE_BUTTON_INNER, Utils._EDGE_BUTTON_OUTER, -135, 135, 1, \"revert\", this.renkan.translate(\"Cancel deletion\"));\n },\n mouseup: function() {\n this.renderer.click_target = null;\n this.renderer.is_dragging = false;\n if (this.renderer.isEditable()) {\n this.source_representation.model.unset(\"delete_scheduled\");\n }\n }\n }).value();\n\n /* EdgeRevertButton End */\n\n return EdgeRevertButton;\n\n});\n\n\ndefine('renderer/miniframe',['jquery', 'underscore', 'requtils', 'renderer/baserepresentation'], function ($, _, requtils, BaseRepresentation) {\n \n\n var Utils = requtils.getUtils();\n\n /* MiniFrame Begin */\n\n //var MiniFrame = Renderer.MiniFrame = Utils.inherit(Renderer._BaseRepresentation);\n var MiniFrame = Utils.inherit(BaseRepresentation);\n\n _(MiniFrame.prototype).extend({\n paperShift: function(_delta) {\n this.renderer.offset = this.renderer.offset.subtract(_delta.divide(this.renderer.minimap.scale).multiply(this.renderer.scale));\n this.renderer.redraw();\n },\n mouseup: function(_delta) {\n this.renderer.click_target = null;\n this.renderer.is_dragging = false;\n }\n }).value();\n\n\n /* MiniFrame End */\n\n return MiniFrame;\n\n});\n\n\ndefine('renderer/scene',['jquery', 'underscore', 'filesaver', 'requtils', 'renderer/miniframe'], function ($, _, filesaver, requtils, MiniFrame) {\n \n\n var Utils = requtils.getUtils();\n\n /* Scene Begin */\n\n var Scene = function(_renkan) {\n this.renkan = _renkan;\n this.$ = $(\".Rk-Render\");\n this.representations = [];\n this.$.html(_renkan.options.templates['templates/scene.html'](_renkan));\n this.onStatusChange();\n this.canvas_$ = this.$.find(\".Rk-Canvas\");\n this.labels_$ = this.$.find(\".Rk-Labels\");\n this.editor_$ = this.$.find(\".Rk-Editor\");\n this.notif_$ = this.$.find(\".Rk-Notifications\");\n paper.setup(this.canvas_$[0]);\n this.scale = 1;\n this.initialScale = 1;\n this.offset = paper.view.center;\n this.totalScroll = 0;\n this.mouse_down = false;\n this.click_target = null;\n this.selected_target = null;\n this.edge_layer = new paper.Layer();\n this.node_layer = new paper.Layer();\n this.buttons_layer = new paper.Layer();\n this.delete_list = [];\n this.redrawActive = true;\n\n if (_renkan.options.show_minimap) {\n this.minimap = {\n background_layer: new paper.Layer(),\n edge_layer: new paper.Layer(),\n node_layer: new paper.Layer(),\n node_group: new paper.Group(),\n size: new paper.Size( _renkan.options.minimap_width, _renkan.options.minimap_height )\n };\n\n this.minimap.background_layer.activate();\n this.minimap.topleft = paper.view.bounds.bottomRight.subtract(this.minimap.size);\n this.minimap.rectangle = new paper.Path.Rectangle(this.minimap.topleft.subtract([2,2]), this.minimap.size.add([4,4]));\n this.minimap.rectangle.fillColor = _renkan.options.minimap_background_color;\n this.minimap.rectangle.strokeColor = _renkan.options.minimap_border_color;\n this.minimap.rectangle.strokeWidth = 4;\n this.minimap.offset = new paper.Point(this.minimap.size.divide(2));\n this.minimap.scale = 0.1;\n\n this.minimap.node_layer.activate();\n this.minimap.cliprectangle = new paper.Path.Rectangle(this.minimap.topleft, this.minimap.size);\n this.minimap.node_group.addChild(this.minimap.cliprectangle);\n this.minimap.node_group.clipped = true;\n this.minimap.miniframe = new paper.Path.Rectangle(this.minimap.topleft, this.minimap.size);\n this.minimap.node_group.addChild(this.minimap.miniframe);\n this.minimap.miniframe.fillColor = '#c0c0ff';\n this.minimap.miniframe.opacity = 0.3;\n this.minimap.miniframe.strokeColor = '#000080';\n this.minimap.miniframe.strokeWidth = 2;\n this.minimap.miniframe.__representation = new MiniFrame(this, null);\n }\n\n this.throttledPaperDraw = _(function() {\n paper.view.draw();\n }).throttle(100).value();\n\n this.bundles = [];\n this.click_mode = false;\n\n var _this = this,\n _allowScroll = true,\n _originalScale = 1,\n _zooming = false,\n _lastTapX = 0,\n _lastTapY = 0;\n\n this.image_cache = {};\n this.icon_cache = {};\n\n ['edit', 'remove', 'link', 'enlarge', 'shrink', 'revert' ].forEach(function(imgname) {\n var img = new Image();\n img.src = _renkan.options.static_url + 'img/' + imgname + '.png';\n _this.icon_cache[imgname] = img;\n });\n\n var throttledMouseMove = _.throttle(function(_event, _isTouch) {\n _this.onMouseMove(_event, _isTouch);\n }, Utils._MOUSEMOVE_RATE);\n\n this.canvas_$.on({\n mousedown: function(_event) {\n _event.preventDefault();\n _this.onMouseDown(_event, false);\n },\n mousemove: function(_event) {\n _event.preventDefault();\n throttledMouseMove(_event, false);\n },\n mouseup: function(_event) {\n _event.preventDefault();\n _this.onMouseUp(_event, false);\n },\n mousewheel: function(_event, _delta) {\n if(_renkan.options.zoom_on_scroll) {\n _event.preventDefault();\n if (_allowScroll) {\n _this.onScroll(_event, _delta);\n }\n }\n },\n touchstart: function(_event) {\n _event.preventDefault();\n var _touches = _event.originalEvent.touches[0];\n if (\n _renkan.options.allow_double_click &&\n new Date() - _lastTap < Utils._DOUBLETAP_DELAY &&\n ( Math.pow(_lastTapX - _touches.pageX, 2) + Math.pow(_lastTapY - _touches.pageY, 2) < Utils._DOUBLETAP_DISTANCE )\n ) {\n _lastTap = 0;\n _this.onDoubleClick(_touches);\n } else {\n _lastTap = new Date();\n _lastTapX = _touches.pageX;\n _lastTapY = _touches.pageY;\n _originalScale = _this.scale;\n _zooming = false;\n _this.onMouseDown(_touches, true);\n }\n },\n touchmove: function(_event) {\n _event.preventDefault();\n _lastTap = 0;\n if (_event.originalEvent.touches.length === 1) {\n _this.onMouseMove(_event.originalEvent.touches[0], true);\n } else {\n if (!_zooming) {\n _this.onMouseUp(_event.originalEvent.touches[0], true);\n _this.click_target = null;\n _this.is_dragging = false;\n _zooming = true;\n }\n if (_event.originalEvent.scale === \"undefined\") {\n return;\n }\n var _newScale = _event.originalEvent.scale * _originalScale,\n _scaleRatio = _newScale / _this.scale,\n _newOffset = new paper.Point([\n _this.canvas_$.width(),\n _this.canvas_$.height()\n ]).multiply( 0.5 * ( 1 - _scaleRatio ) ).add(_this.offset.multiply( _scaleRatio ));\n _this.setScale(_newScale, _newOffset);\n }\n },\n touchend: function(_event) {\n _event.preventDefault();\n _this.onMouseUp(_event.originalEvent.changedTouches[0], true);\n },\n dblclick: function(_event) {\n _event.preventDefault();\n if (_renkan.options.allow_double_click) {\n _this.onDoubleClick(_event);\n }\n },\n mouseleave: function(_event) {\n _event.preventDefault();\n _this.onMouseUp(_event, false);\n _this.click_target = null;\n _this.is_dragging = false;\n },\n dragover: function(_event) {\n _event.preventDefault();\n },\n dragenter: function(_event) {\n _event.preventDefault();\n _allowScroll = false;\n },\n dragleave: function(_event) {\n _event.preventDefault();\n _allowScroll = true;\n },\n drop: function(_event) {\n _event.preventDefault();\n _allowScroll = true;\n var res = {};\n _.each(_event.originalEvent.dataTransfer.types, function(t) {\n try {\n res[t] = _event.originalEvent.dataTransfer.getData(t);\n } catch(e) {}\n });\n var text = _event.originalEvent.dataTransfer.getData(\"Text\");\n if (typeof text === \"string\") {\n switch(text[0]) {\n case \"{\":\n case \"[\":\n try {\n var data = JSON.parse(text);\n _.extend(res,data);\n }\n catch(e) {\n if (!res[\"text/plain\"]) {\n res[\"text/plain\"] = text;\n }\n }\n break;\n case \"<\":\n if (!res[\"text/html\"]) {\n res[\"text/html\"] = text;\n }\n break;\n default:\n if (!res[\"text/plain\"]) {\n res[\"text/plain\"] = text;\n }\n }\n }\n var url = _event.originalEvent.dataTransfer.getData(\"URL\");\n if (url && !res[\"text/uri-list\"]) {\n res[\"text/uri-list\"] = url;\n }\n _this.dropData(res, _event.originalEvent);\n }\n });\n\n var bindClick = function(selector, fname) {\n _this.$.find(selector).click(function(evt) {\n _this[fname](evt);\n return false;\n });\n };\n\n bindClick(\".Rk-ZoomOut\", \"zoomOut\");\n bindClick(\".Rk-ZoomIn\", \"zoomIn\");\n bindClick(\".Rk-ZoomFit\", \"autoScale\");\n this.$.find(\".Rk-ZoomSave\").click( function() {\n // Save scale and offset point\n _this.renkan.project.addView( { zoom_level:_this.scale, offset:_this.offset } );\n });\n this.$.find(\".Rk-ZoomSetSaved\").click( function() {\n var view = _this.renkan.project.get(\"views\").last();\n if(view){\n _this.setScale(view.get(\"zoom_level\"), new paper.Point(view.get(\"offset\")));\n }\n });\n if(this.renkan.project.get(\"views\").length > 0 && this.renkan.options.save_view){\n this.$.find(\".Rk-ZoomSetSaved\").show();\n }\n this.$.find(\".Rk-CurrentUser\").mouseenter(\n function() { _this.$.find(\".Rk-UserList\").slideDown(); }\n );\n this.$.find(\".Rk-Users\").mouseleave(\n function() { _this.$.find(\".Rk-UserList\").slideUp(); }\n );\n bindClick(\".Rk-FullScreen-Button\", \"fullScreen\");\n bindClick(\".Rk-AddNode-Button\", \"addNodeBtn\");\n bindClick(\".Rk-AddEdge-Button\", \"addEdgeBtn\");\n bindClick(\".Rk-Save-Button\", \"save\");\n bindClick(\".Rk-Open-Button\", \"open\");\n bindClick(\".Rk-Export-Button\", \"exportProject\");\n this.$.find(\".Rk-Bookmarklet-Button\")\n /*jshint scripturl:true */\n .attr(\"href\",\"javascript:\" + Utils._BOOKMARKLET_CODE(_renkan))\n .click(function(){\n _this.notif_$\n .text(_renkan.translate(\"Drag this button to your bookmark bar. When on a third-party website, click it to enable drag-and-drop from the website to Renkan.\"))\n .fadeIn()\n .delay(5000)\n .fadeOut();\n return false;\n });\n this.$.find(\".Rk-TopBar-Button\").mouseover(function() {\n $(this).find(\".Rk-TopBar-Tooltip\").show();\n }).mouseout(function() {\n $(this).find(\".Rk-TopBar-Tooltip\").hide();\n });\n bindClick(\".Rk-Fold-Bins\", \"foldBins\");\n\n paper.view.onResize = function(_event) {\n var _ratio,\n newWidth = _event.width,\n newHeight = _event.height;\n\n if (_this.minimap) {\n _this.minimap.topleft = paper.view.bounds.bottomRight.subtract(_this.minimap.size);\n _this.minimap.rectangle.fitBounds(_this.minimap.topleft.subtract([2,2]), _this.minimap.size.add([4,4]));\n _this.minimap.cliprectangle.fitBounds(_this.minimap.topleft, _this.minimap.size);\n }\n\n var ratioH = newHeight/(newHeight-_event.delta.height),\n ratioW = newWidth/(newWidth-_event.delta.width);\n if (newHeight < newWidth) {\n _ratio = ratioH;\n } else {\n _ratio = ratioW;\n }\n\n _this.resizeZoom(ratioW, ratioH, _ratio);\n\n _this.redraw();\n\n };\n\n var _thRedraw = _.throttle(function() {\n _this.redraw();\n },50);\n\n this.addRepresentations(\"Node\", this.renkan.project.get(\"nodes\"));\n this.addRepresentations(\"Edge\", this.renkan.project.get(\"edges\"));\n this.renkan.project.on(\"change:title\", function() {\n _this.$.find(\".Rk-PadTitle\").val(_renkan.project.get(\"title\"));\n });\n\n this.$.find(\".Rk-PadTitle\").on(\"keyup input paste\", function() {\n _renkan.project.set({\"title\": $(this).val()});\n });\n\n var _thRedrawUsers = _.throttle(function() {\n _this.redrawUsers();\n }, 100);\n\n _thRedrawUsers();\n\n // register model events\n this.renkan.project.on(\"change:save_status\", function(){\n switch (_this.renkan.project.get(\"save_status\")) {\n case 0: //clean\n _this.$.find(\".Rk-Save-Button\").removeClass(\"to-save\");\n _this.$.find(\".Rk-Save-Button\").removeClass(\"saving\");\n _this.$.find(\".Rk-Save-Button\").addClass(\"saved\");\n break;\n case 1: //dirty\n _this.$.find(\".Rk-Save-Button\").removeClass(\"saved\");\n _this.$.find(\".Rk-Save-Button\").removeClass(\"saving\");\n _this.$.find(\".Rk-Save-Button\").addClass(\"to-save\");\n break;\n case 2: //saving\n _this.$.find(\".Rk-Save-Button\").removeClass(\"saved\");\n _this.$.find(\".Rk-Save-Button\").removeClass(\"to-save\");\n _this.$.find(\".Rk-Save-Button\").addClass(\"saving\");\n break;\n }\n });\n\n this.renkan.project.on(\"change:loading_status\", function(){\n if (_this.renkan.project.get(\"loading_status\")){\n var animate = _this.$.find(\".loader\").addClass(\"run\");\n var timer = setTimeout(function(){\n _this.$.find(\".loader\").hide(250);\n }, 3000);\n }\n });\n\n this.renkan.project.on(\"add:users remove:users\", _thRedrawUsers);\n\n this.renkan.project.on(\"add:views remove:views\", function(_node) {\n if(_this.renkan.project.get('views').length > 0) {\n _this.$.find(\".Rk-ZoomSetSaved\").show();\n }\n else {\n _this.$.find(\".Rk-ZoomSetSaved\").hide();\n }\n });\n\n this.renkan.project.on(\"add:nodes\", function(_node) {\n _this.addRepresentation(\"Node\", _node);\n if (!_this.renkan.project.get(\"loading_status\")){\n _thRedraw();\n }\n });\n this.renkan.project.on(\"add:edges\", function(_edge) {\n _this.addRepresentation(\"Edge\", _edge);\n if (!_this.renkan.project.get(\"loading_status\")){\n _thRedraw();\n }\n });\n this.renkan.project.on(\"change:title\", function(_model, _title) {\n var el = _this.$.find(\".Rk-PadTitle\");\n if (el.is(\"input\")) {\n if (el.val() !== _title) {\n el.val(_title);\n }\n } else {\n el.text(_title);\n }\n });\n\n if (_renkan.options.size_bug_fix) {\n var _delay = (\n typeof _renkan.options.size_bug_fix === \"number\" ?\n _renkan.options.size_bug_fix\n : 500\n );\n window.setTimeout(\n function() {\n _this.fixSize();\n },\n _delay\n );\n }\n\n if (_renkan.options.force_resize) {\n $(window).resize(function() {\n _this.autoScale();\n });\n }\n\n if (_renkan.options.show_user_list && _renkan.options.user_color_editable) {\n var $cpwrapper = this.$.find(\".Rk-Users .Rk-Edit-ColorPicker-Wrapper\"),\n $cplist = this.$.find(\".Rk-Users .Rk-Edit-ColorPicker\");\n\n $cpwrapper.hover(\n function(_e) {\n if (_this.isEditable()) {\n _e.preventDefault();\n $cplist.show();\n }\n },\n function(_e) {\n _e.preventDefault();\n $cplist.hide();\n }\n );\n\n $cplist.find(\"li\").mouseenter(\n function(_e) {\n if (_this.isEditable()) {\n _e.preventDefault();\n _this.$.find(\".Rk-CurrentUser-Color\").css(\"background\", $(this).attr(\"data-color\"));\n }\n }\n );\n }\n\n if (_renkan.options.show_search_field) {\n\n var lastval = '';\n\n this.$.find(\".Rk-GraphSearch-Field\").on(\"keyup change paste input\", function() {\n var $this = $(this),\n val = $this.val();\n if (val === lastval) {\n return;\n }\n lastval = val;\n if (val.length < 2) {\n _renkan.project.get(\"nodes\").each(function(n) {\n _this.getRepresentationByModel(n).unhighlight();\n });\n } else {\n var rxs = Utils.regexpFromTextOrArray(val);\n _renkan.project.get(\"nodes\").each(function(n) {\n if (rxs.test(n.get(\"title\")) || rxs.test(n.get(\"description\"))) {\n _this.getRepresentationByModel(n).highlight(rxs);\n } else {\n _this.getRepresentationByModel(n).unhighlight();\n }\n });\n }\n });\n }\n\n this.redraw();\n\n window.setInterval(function() {\n var _now = new Date().valueOf();\n _this.delete_list.forEach(function(d) {\n if (_now >= d.time) {\n var el = _renkan.project.get(\"nodes\").findWhere({\"delete_scheduled\":d.id});\n if (el) {\n project.removeNode(el);\n }\n el = _renkan.project.get(\"edges\").findWhere({\"delete_scheduled\":d.id});\n if (el) {\n project.removeEdge(el);\n }\n }\n });\n _this.delete_list = _this.delete_list.filter(function(d) {\n return _renkan.project.get(\"nodes\").findWhere({\"delete_scheduled\":d.id}) || _renkan.project.get(\"edges\").findWhere({\"delete_scheduled\":d.id});\n });\n }, 500);\n\n if (this.minimap) {\n window.setInterval(function() {\n _this.rescaleMinimap();\n }, 2000);\n }\n\n };\n\n _(Scene.prototype).extend({\n fixSize: function() {\n if( this.renkan.options.default_view && this.renkan.project.get(\"views\").length > 0) {\n var view = this.renkan.project.get(\"views\").last();\n this.setScale(view.get(\"zoom_level\"), new paper.Point(view.get(\"offset\")));\n }\n else{\n this.autoScale();\n }\n },\n drawSector: function(_repr, _inR, _outR, _startAngle, _endAngle, _padding, _imgname, _caption) {\n var _options = this.renkan.options,\n _startRads = _startAngle * Math.PI / 180,\n _endRads = _endAngle * Math.PI / 180,\n _img = this.icon_cache[_imgname],\n _startdx = - Math.sin(_startRads),\n _startdy = Math.cos(_startRads),\n _startXIn = Math.cos(_startRads) * _inR + _padding * _startdx,\n _startYIn = Math.sin(_startRads) * _inR + _padding * _startdy,\n _startXOut = Math.cos(_startRads) * _outR + _padding * _startdx,\n _startYOut = Math.sin(_startRads) * _outR + _padding * _startdy,\n _enddx = - Math.sin(_endRads),\n _enddy = Math.cos(_endRads),\n _endXIn = Math.cos(_endRads) * _inR - _padding * _enddx,\n _endYIn = Math.sin(_endRads) * _inR - _padding * _enddy,\n _endXOut = Math.cos(_endRads) * _outR - _padding * _enddx,\n _endYOut = Math.sin(_endRads) * _outR - _padding * _enddy,\n _centerR = (_inR + _outR) / 2,\n _centerRads = (_startRads + _endRads) / 2,\n _centerX = Math.cos(_centerRads) * _centerR,\n _centerY = Math.sin(_centerRads) * _centerR,\n _centerXIn = Math.cos(_centerRads) * _inR,\n _centerXOut = Math.cos(_centerRads) * _outR,\n _centerYIn = Math.sin(_centerRads) * _inR,\n _centerYOut = Math.sin(_centerRads) * _outR,\n _textX = Math.cos(_centerRads) * (_outR + 3),\n _textY = Math.sin(_centerRads) * (_outR + _options.buttons_label_font_size) + _options.buttons_label_font_size / 2;\n this.buttons_layer.activate();\n var _path = new paper.Path();\n _path.add([_startXIn, _startYIn]);\n _path.arcTo([_centerXIn, _centerYIn], [_endXIn, _endYIn]);\n _path.lineTo([_endXOut, _endYOut]);\n _path.arcTo([_centerXOut, _centerYOut], [_startXOut, _startYOut]);\n _path.fillColor = _options.buttons_background;\n _path.opacity = 0.5;\n _path.closed = true;\n _path.__representation = _repr;\n var _text = new paper.PointText(_textX,_textY);\n _text.characterStyle = {\n fontSize: _options.buttons_label_font_size,\n fillColor: _options.buttons_label_color\n };\n if (_textX > 2) {\n _text.paragraphStyle.justification = 'left';\n } else if (_textX < -2) {\n _text.paragraphStyle.justification = 'right';\n } else {\n _text.paragraphStyle.justification = 'center';\n }\n _text.visible = false;\n var _visible = false,\n _restPos = new paper.Point(-200, -200),\n _grp = new paper.Group([_path, _text]),\n //_grp = new paper.Group([_path]),\n _delta = _grp.position,\n _imgdelta = new paper.Point([_centerX, _centerY]),\n _currentPos = new paper.Point(0,0);\n _text.content = _caption;\n // set group pivot to not depend on text visibility that changes the group bounding box.\n _grp.pivot = _grp.bounds.center;\n _grp.visible = false;\n _grp.position = _restPos;\n var _res = {\n show: function() {\n _visible = true;\n _grp.position = _currentPos.add(_delta);\n _grp.visible = true;\n },\n moveTo: function(_point) {\n _currentPos = _point;\n if (_visible) {\n _grp.position = _point.add(_delta);\n }\n },\n hide: function() {\n _visible = false;\n _grp.visible = false;\n _grp.position = _restPos;\n },\n select: function() {\n _path.opacity = 0.8;\n _text.visible = true;\n },\n unselect: function() {\n _path.opacity = 0.5;\n _text.visible = false;\n },\n destroy: function() {\n _grp.remove();\n }\n };\n var showImage = function() {\n var _raster = new paper.Raster(_img);\n _raster.position = _imgdelta.add(_grp.position).subtract(_delta);\n _raster.locked = true; // Disable mouse events on icon\n _grp.addChild(_raster);\n };\n if (_img.width) {\n showImage();\n } else {\n $(_img).on(\"load\",showImage);\n }\n\n return _res;\n },\n addToBundles: function(_edgeRepr) {\n var _bundle = _(this.bundles).find(function(_bundle) {\n return (\n ( _bundle.from === _edgeRepr.from_representation && _bundle.to === _edgeRepr.to_representation ) ||\n ( _bundle.from === _edgeRepr.to_representation && _bundle.to === _edgeRepr.from_representation )\n );\n });\n if (typeof _bundle !== \"undefined\") {\n _bundle.edges.push(_edgeRepr);\n } else {\n _bundle = {\n from: _edgeRepr.from_representation,\n to: _edgeRepr.to_representation,\n edges: [ _edgeRepr ],\n getPosition: function(_er) {\n var _dir = (_er.from_representation === this.from) ? 1 : -1;\n return _dir * ( _(this.edges).indexOf(_er) - (this.edges.length - 1) / 2 );\n }\n };\n this.bundles.push(_bundle);\n }\n return _bundle;\n },\n isEditable: function() {\n return (this.renkan.options.editor_mode && !this.renkan.read_only);\n },\n onStatusChange: function() {\n var savebtn = this.$.find(\".Rk-Save-Button\"),\n tip = savebtn.find(\".Rk-TopBar-Tooltip-Contents\");\n if (this.renkan.read_only) {\n savebtn.removeClass(\"disabled Rk-Save-Online\").addClass(\"Rk-Save-ReadOnly\");\n tip.text(this.renkan.translate(\"Connection lost\"));\n } else {\n if (this.renkan.options.manual_save) {\n savebtn.removeClass(\"Rk-Save-ReadOnly Rk-Save-Online\");\n tip.text(this.renkan.translate(\"Save Project\"));\n } else {\n savebtn.removeClass(\"disabled Rk-Save-ReadOnly\").addClass(\"Rk-Save-Online\");\n tip.text(this.renkan.translate(\"Auto-save enabled\"));\n }\n }\n this.redrawUsers();\n },\n setScale: function(_newScale, _offset) {\n if ((_newScale/this.initialScale) > Utils._MIN_SCALE && (_newScale/this.initialScale) < Utils._MAX_SCALE) {\n this.scale = _newScale;\n if (_offset) {\n this.offset = _offset;\n }\n this.redraw();\n }\n },\n autoScale: function(force_view) {\n var nodes = this.renkan.project.get(\"nodes\");\n if (nodes.length > 1) {\n var _xx = nodes.map(function(_node) { return _node.get(\"position\").x; }),\n _yy = nodes.map(function(_node) { return _node.get(\"position\").y; }),\n _minx = Math.min.apply(Math, _xx),\n _miny = Math.min.apply(Math, _yy),\n _maxx = Math.max.apply(Math, _xx),\n _maxy = Math.max.apply(Math, _yy);\n var _scale = Math.min( (paper.view.size.width - 2 * this.renkan.options.autoscale_padding) / (_maxx - _minx), (paper.view.size.height - 2 * this.renkan.options.autoscale_padding) / (_maxy - _miny));\n this.initialScale = _scale;\n // Override calculated scale if asked\n if((typeof force_view !== \"undefined\") && parseFloat(force_view.zoom_level)>0 && parseFloat(force_view.offset.x)>0 && parseFloat(force_view.offset.y)>0){\n this.setScale(parseFloat(force_view.zoom_level), new paper.Point(parseFloat(force_view.offset.x), parseFloat(force_view.offset.y)));\n }\n else{\n this.setScale(_scale, paper.view.center.subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(_scale)));\n }\n }\n if (nodes.length === 1) {\n this.setScale(1, paper.view.center.subtract(new paper.Point([nodes.at(0).get(\"position\").x, nodes.at(0).get(\"position\").y])));\n }\n },\n redrawMiniframe: function() {\n var topleft = this.toMinimapCoords(this.toModelCoords(new paper.Point([0,0]))),\n bottomright = this.toMinimapCoords(this.toModelCoords(paper.view.bounds.bottomRight));\n this.minimap.miniframe.fitBounds(topleft, bottomright);\n },\n rescaleMinimap: function() {\n var nodes = this.renkan.project.get(\"nodes\");\n if (nodes.length > 1) {\n var _xx = nodes.map(function(_node) { return _node.get(\"position\").x; }),\n _yy = nodes.map(function(_node) { return _node.get(\"position\").y; }),\n _minx = Math.min.apply(Math, _xx),\n _miny = Math.min.apply(Math, _yy),\n _maxx = Math.max.apply(Math, _xx),\n _maxy = Math.max.apply(Math, _yy);\n var _scale = Math.min(\n this.scale * 0.8 * this.renkan.options.minimap_width / paper.view.bounds.width,\n this.scale * 0.8 * this.renkan.options.minimap_height / paper.view.bounds.height,\n ( this.renkan.options.minimap_width - 2 * this.renkan.options.minimap_padding ) / (_maxx - _minx),\n ( this.renkan.options.minimap_height - 2 * this.renkan.options.minimap_padding ) / (_maxy - _miny)\n );\n this.minimap.offset = this.minimap.size.divide(2).subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(_scale));\n this.minimap.scale = _scale;\n }\n if (nodes.length === 1) {\n this.minimap.scale = 0.1;\n this.minimap.offset = this.minimap.size.divide(2).subtract(new paper.Point([nodes.at(0).get(\"position\").x, nodes.at(0).get(\"position\").y]).multiply(this.minimap.scale));\n }\n this.redraw();\n },\n toPaperCoords: function(_point) {\n return _point.multiply(this.scale).add(this.offset);\n },\n toMinimapCoords: function(_point) {\n return _point.multiply(this.minimap.scale).add(this.minimap.offset).add(this.minimap.topleft);\n },\n toModelCoords: function(_point) {\n return _point.subtract(this.offset).divide(this.scale);\n },\n addRepresentation: function(_type, _model) {\n var RendererType = requtils.getRenderer()[_type];\n var _repr = new RendererType(this, _model);\n this.representations.push(_repr);\n return _repr;\n },\n addRepresentations: function(_type, _collection) {\n var _this = this;\n _collection.forEach(function(_model) {\n _this.addRepresentation(_type, _model);\n });\n },\n userTemplate: _.template(\n '<li class=\"Rk-User\"><span class=\"Rk-UserColor\" style=\"background:<%=background%>;\"></span><%=name%></li>'\n ),\n redrawUsers: function() {\n if (!this.renkan.options.show_user_list) {\n return;\n }\n var allUsers = [].concat((this.renkan.project.current_user_list || {}).models || [], (this.renkan.project.get(\"users\") || {}).models || []),\n ulistHtml = '',\n $userpanel = this.$.find(\".Rk-Users\"),\n $name = $userpanel.find(\".Rk-CurrentUser-Name\"),\n $cpitems = $userpanel.find(\".Rk-Edit-ColorPicker li\"),\n $colorsquare = $userpanel.find(\".Rk-CurrentUser-Color\"),\n _this = this;\n $name.off(\"click\").text(this.renkan.translate(\"<unknown user>\"));\n $cpitems.off(\"mouseleave click\");\n allUsers.forEach(function(_user) {\n if (_user.get(\"_id\") === _this.renkan.current_user) {\n $name.text(_user.get(\"title\"));\n $colorsquare.css(\"background\", _user.get(\"color\"));\n if (_this.isEditable()) {\n\n if (_this.renkan.options.user_name_editable) {\n $name.click(function() {\n var $this = $(this),\n $input = $('<input>').val(_user.get(\"title\")).blur(function() {\n _user.set(\"title\", $(this).val());\n _this.redrawUsers();\n _this.redraw();\n });\n $this.empty().html($input);\n $input.select();\n });\n }\n\n if (_this.renkan.options.user_color_editable) {\n $cpitems.click(\n function(_e) {\n _e.preventDefault();\n if (_this.isEditable()) {\n _user.set(\"color\", $(this).attr(\"data-color\"));\n }\n $(this).parent().hide();\n }\n ).mouseleave(function() {\n $colorsquare.css(\"background\", _user.get(\"color\"));\n });\n }\n }\n\n } else {\n ulistHtml += _this.userTemplate({\n name: _user.get(\"title\"),\n background: _user.get(\"color\")\n });\n }\n });\n $userpanel.find(\".Rk-UserList\").html(ulistHtml);\n },\n removeRepresentation: function(_representation) {\n _representation.destroy();\n this.representations = _.reject(this.representations,\n function(_repr) {\n return _repr === _representation;\n }\n );\n },\n getRepresentationByModel: function(_model) {\n if (!_model) {\n return undefined;\n }\n return _.find(this.representations, function(_repr) {\n return _repr.model === _model;\n });\n },\n removeRepresentationsOfType: function(_type) {\n var _representations = _.filter(this.representations,function(_repr) {\n return _repr.type === _type;\n }),\n _this = this;\n _.each(_representations, function(_repr) {\n _this.removeRepresentation(_repr);\n });\n },\n highlightModel: function(_model) {\n var _repr = this.getRepresentationByModel(_model);\n if (_repr) {\n _repr.highlight();\n }\n },\n unhighlightAll: function(_model) {\n _.each(this.representations, function(_repr) {\n _repr.unhighlight();\n });\n },\n unselectAll: function(_model) {\n _.each(this.representations, function(_repr) {\n _repr.unselect();\n });\n },\n redraw: function() {\n if(! this.redrawActive ) {\n return;\n }\n _.each(this.representations, function(_representation) {\n _representation.redraw({ dontRedrawEdges:true });\n });\n if (this.minimap) {\n this.redrawMiniframe();\n }\n paper.view.draw();\n },\n addTempEdge: function(_from, _point) {\n var _tmpEdge = this.addRepresentation(\"TempEdge\",null);\n _tmpEdge.end_pos = _point;\n _tmpEdge.from_representation = _from;\n _tmpEdge.redraw();\n this.click_target = _tmpEdge;\n },\n findTarget: function(_hitResult) {\n if (_hitResult && typeof _hitResult.item.__representation !== \"undefined\") {\n var _newTarget = _hitResult.item.__representation;\n if (this.selected_target !== _hitResult.item.__representation) {\n if (this.selected_target) {\n this.selected_target.unselect(_newTarget);\n }\n _newTarget.select(this.selected_target);\n this.selected_target = _newTarget;\n }\n } else {\n if (this.selected_target) {\n this.selected_target.unselect();\n }\n this.selected_target = null;\n }\n },\n paperShift: function(_delta) {\n this.offset = this.offset.add(_delta);\n this.redraw();\n },\n onMouseMove: function(_event) {\n var _off = this.canvas_$.offset(),\n _point = new paper.Point([\n _event.pageX - _off.left,\n _event.pageY - _off.top\n ]),\n _delta = _point.subtract(this.last_point);\n this.last_point = _point;\n if (!this.is_dragging && this.mouse_down && _delta.length > Utils._MIN_DRAG_DISTANCE) {\n this.is_dragging = true;\n }\n var _hitResult = paper.project.hitTest(_point);\n if (this.is_dragging) {\n if (this.click_target && typeof this.click_target.paperShift === \"function\") {\n this.click_target.paperShift(_delta);\n } else {\n this.paperShift(_delta);\n }\n } else {\n this.findTarget(_hitResult);\n }\n paper.view.draw();\n },\n onMouseDown: function(_event, _isTouch) {\n var _off = this.canvas_$.offset(),\n _point = new paper.Point([\n _event.pageX - _off.left,\n _event.pageY - _off.top\n ]);\n this.last_point = _point;\n this.mouse_down = true;\n if (!this.click_target || this.click_target.type !== \"Temp-edge\") {\n this.removeRepresentationsOfType(\"editor\");\n this.is_dragging = false;\n var _hitResult = paper.project.hitTest(_point);\n if (_hitResult && typeof _hitResult.item.__representation !== \"undefined\") {\n this.click_target = _hitResult.item.__representation;\n this.click_target.mousedown(_event, _isTouch);\n } else {\n this.click_target = null;\n if (this.isEditable() && this.click_mode === Utils._CLICKMODE_ADDNODE) {\n var _coords = this.toModelCoords(_point),\n _data = {\n id: Utils.getUID('node'),\n created_by: this.renkan.current_user,\n position: {\n x: _coords.x,\n y: _coords.y\n }\n };\n _node = this.renkan.project.addNode(_data);\n this.getRepresentationByModel(_node).openEditor();\n }\n }\n }\n if (this.click_mode) {\n if (this.isEditable() && this.click_mode === Utils._CLICKMODE_STARTEDGE && this.click_target && this.click_target.type === \"Node\") {\n this.removeRepresentationsOfType(\"editor\");\n this.addTempEdge(this.click_target, _point);\n this.click_mode = Utils._CLICKMODE_ENDEDGE;\n this.notif_$.fadeOut(function() {\n $(this).html(this.renkan.translate(\"Click on a second node to complete the edge\")).fadeIn();\n });\n } else {\n this.notif_$.hide();\n this.click_mode = false;\n }\n }\n paper.view.draw();\n },\n onMouseUp: function(_event, _isTouch) {\n this.mouse_down = false;\n if (this.click_target) {\n var _off = this.canvas_$.offset();\n this.click_target.mouseup(\n {\n point: new paper.Point([\n _event.pageX - _off.left,\n _event.pageY - _off.top\n ])\n },\n _isTouch\n );\n } else {\n this.click_target = null;\n this.is_dragging = false;\n if (_isTouch) {\n this.unselectAll();\n }\n }\n paper.view.draw();\n },\n onScroll: function(_event, _scrolldelta) {\n this.totalScroll += _scrolldelta;\n if (Math.abs(this.totalScroll) >= 1) {\n var _off = this.canvas_$.offset(),\n _delta = new paper.Point([\n _event.pageX - _off.left,\n _event.pageY - _off.top\n ]).subtract(this.offset).multiply( Math.SQRT2 - 1 );\n if (this.totalScroll > 0) {\n this.setScale( this.scale * Math.SQRT2, this.offset.subtract(_delta) );\n } else {\n this.setScale( this.scale * Math.SQRT1_2, this.offset.add(_delta.divide(Math.SQRT2)));\n }\n this.totalScroll = 0;\n }\n },\n onDoubleClick: function(_event) {\n if (!this.isEditable()) {\n return;\n }\n var _off = this.canvas_$.offset(),\n _point = new paper.Point([\n _event.pageX - _off.left,\n _event.pageY - _off.top\n ]);\n var _hitResult = paper.project.hitTest(_point);\n if (this.isEditable() && (!_hitResult || typeof _hitResult.item.__representation === \"undefined\")) {\n var _coords = this.toModelCoords(_point),\n _data = {\n id: Utils.getUID('node'),\n created_by: this.renkan.current_user,\n position: {\n x: _coords.x,\n y: _coords.y\n }\n },\n _node = this.renkan.project.addNode(_data);\n this.getRepresentationByModel(_node).openEditor();\n }\n paper.view.draw();\n },\n defaultDropHandler: function(_data) {\n var newNode = {};\n var snippet = \"\";\n switch(_data[\"text/x-iri-specific-site\"]) {\n case \"twitter\":\n snippet = $('<div>').html(_data[\"text/x-iri-selected-html\"]);\n var tweetdiv = snippet.find(\".tweet\");\n newNode.title = this.renkan.translate(\"Tweet by \") + tweetdiv.attr(\"data-name\");\n newNode.uri = \"http://twitter.com/\" + tweetdiv.attr(\"data-screen-name\") + \"/status/\" + tweetdiv.attr(\"data-tweet-id\");\n newNode.image = tweetdiv.find(\".avatar\").attr(\"src\");\n newNode.description = tweetdiv.find(\".js-tweet-text:first\").text();\n break;\n case \"google\":\n snippet = $('<div>').html(_data[\"text/x-iri-selected-html\"]);\n newNode.title = snippet.find(\"h3:first\").text().trim();\n newNode.uri = snippet.find(\"h3 a\").attr(\"href\");\n newNode.description = snippet.find(\".st:first\").text().trim();\n break;\n default:\n if (_data[\"text/x-iri-source-uri\"]) {\n newNode.uri = _data[\"text/x-iri-source-uri\"];\n }\n }\n if (_data[\"text/plain\"] || _data[\"text/x-iri-selected-text\"]) {\n newNode.description = (_data[\"text/plain\"] || _data[\"text/x-iri-selected-text\"]).replace(/[\\s\\n]+/gm,' ').trim();\n }\n if (_data[\"text/html\"] || _data[\"text/x-iri-selected-html\"]) {\n snippet = $('<div>').html(_data[\"text/html\"] || _data[\"text/x-iri-selected-html\"]);\n var _svgimgs = snippet.find(\"image\");\n if (_svgimgs.length) {\n newNode.image = _svgimgs.attr(\"xlink:href\");\n }\n var _svgpaths = snippet.find(\"path\");\n if (_svgpaths.length) {\n newNode.clipPath = _svgpaths.attr(\"d\");\n }\n var _imgs = snippet.find(\"img\");\n if (_imgs.length) {\n newNode.image = _imgs[0].src;\n }\n var _as = snippet.find(\"a\");\n if (_as.length) {\n newNode.uri = _as[0].href;\n }\n newNode.title = snippet.find(\"[title]\").attr(\"title\") || newNode.title;\n newNode.description = snippet.text().replace(/[\\s\\n]+/gm,' ').trim();\n }\n if (_data[\"text/uri-list\"]) {\n newNode.uri = _data[\"text/uri-list\"];\n }\n if (_data[\"text/x-moz-url\"] && !newNode.title) {\n newNode.title = (_data[\"text/x-moz-url\"].split(\"\\n\")[1] || \"\").trim();\n if (newNode.title === newNode.uri) {\n newNode.title = false;\n }\n }\n if (_data[\"text/x-iri-source-title\"] && !newNode.title) {\n newNode.title = _data[\"text/x-iri-source-title\"];\n }\n if (_data[\"text/html\"] || _data[\"text/x-iri-selected-html\"]) {\n snippet = $('<div>').html(_data[\"text/html\"] || _data[\"text/x-iri-selected-html\"]);\n newNode.image = snippet.find(\"[data-image]\").attr(\"data-image\") || newNode.image;\n newNode.uri = snippet.find(\"[data-uri]\").attr(\"data-uri\") || newNode.uri;\n newNode.title = snippet.find(\"[data-title]\").attr(\"data-title\") || newNode.title;\n newNode.description = snippet.find(\"[data-description]\").attr(\"data-description\") || newNode.description;\n newNode.clipPath = snippet.find(\"[data-clip-path]\").attr(\"data-clip-path\") || newNode.clipPath;\n }\n\n if (!newNode.title) {\n newNode.title = this.renkan.translate(\"Dragged resource\");\n }\n var fields = [\"title\", \"description\", \"uri\", \"image\"];\n for (var i = 0; i < fields.length; i++) {\n var f = fields[i];\n if (_data[\"text/x-iri-\" + f] || _data[f]) {\n newNode[f] = _data[\"text/x-iri-\" + f] || _data[f];\n }\n if (newNode[f] === \"none\" || newNode[f] === \"null\") {\n newNode[f] = undefined;\n }\n }\n\n if(typeof this.renkan.options.drop_enhancer === \"function\"){\n newNode = this.renkan.options.drop_enhancer(newNode, _data);\n }\n\n return newNode;\n\n },\n dropData: function(_data, _event) {\n if (!this.isEditable()) {\n return;\n }\n if (_data[\"text/json\"] || _data[\"application/json\"]) {\n try {\n var jsondata = JSON.parse(_data[\"text/json\"] || _data[\"application/json\"]);\n _.extend(_data,jsondata);\n }\n catch(e) {}\n }\n\n var newNode = (typeof this.renkan.options.drop_handler === \"undefined\")?this.defaultDropHandler(_data):this.renkan.options.drop_handler(_data);\n\n var _off = this.canvas_$.offset(),\n _point = new paper.Point([\n _event.pageX - _off.left,\n _event.pageY - _off.top\n ]),\n _coords = this.toModelCoords(_point),\n _nodedata = {\n id: Utils.getUID('node'),\n created_by: this.renkan.current_user,\n uri: newNode.uri || \"\",\n title: newNode.title || \"\",\n description: newNode.description || \"\",\n image: newNode.image || \"\",\n color: newNode.color || undefined,\n clip_path: newNode.clipPath || undefined,\n position: {\n x: _coords.x,\n y: _coords.y\n }\n };\n var _node = this.renkan.project.addNode(_nodedata),\n _repr = this.getRepresentationByModel(_node);\n if (_event.type === \"drop\") {\n _repr.openEditor();\n }\n },\n fullScreen: function() {\n var _isFull = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen,\n _el = this.renkan.$[0],\n _requestMethods = [\"requestFullScreen\",\"mozRequestFullScreen\",\"webkitRequestFullScreen\"],\n _cancelMethods = [\"cancelFullScreen\",\"mozCancelFullScreen\",\"webkitCancelFullScreen\"],\n i;\n if (_isFull) {\n for (i = 0; i < _cancelMethods.length; i++) {\n if (typeof document[_cancelMethods[i]] === \"function\") {\n document[_cancelMethods[i]]();\n break;\n }\n }\n var widthAft = this.$.width();\n var heightAft = this.$.height();\n\n if (this.renkan.options.show_top_bar) {\n heightAft -= this.$.find(\".Rk-TopBar\").height();\n }\n if (this.renkan.options.show_bins && (this.renkan.$.find(\".Rk-Bins\").position().left > 0)) {\n widthAft -= this.renkan.$.find(\".Rk-Bins\").width();\n }\n\n paper.view.viewSize = new paper.Size([widthAft, heightAft]);\n\n } else {\n for (i = 0; i < _requestMethods.length; i++) {\n if (typeof _el[_requestMethods[i]] === \"function\") {\n _el[_requestMethods[i]]();\n break;\n }\n }\n this.redraw();\n }\n },\n zoomOut: function() {\n var _newScale = this.scale * Math.SQRT1_2,\n _offset = new paper.Point([\n this.canvas_$.width(),\n this.canvas_$.height()\n ]).multiply( 0.5 * ( 1 - Math.SQRT1_2 ) ).add(this.offset.multiply( Math.SQRT1_2 ));\n this.setScale( _newScale, _offset );\n },\n zoomIn: function() {\n var _newScale = this.scale * Math.SQRT2,\n _offset = new paper.Point([\n this.canvas_$.width(),\n this.canvas_$.height()\n ]).multiply( 0.5 * ( 1 - Math.SQRT2 ) ).add(this.offset.multiply( Math.SQRT2 ));\n this.setScale( _newScale, _offset );\n },\n resizeZoom: function(_scaleWidth, _scaleHeight, _ratio) {\n var _newScale = this.scale * _ratio,\n _offset = new paper.Point([\n (this.offset.x * _scaleWidth),\n (this.offset.y * _scaleHeight)\n ]);\n this.setScale( _newScale, _offset );\n },\n addNodeBtn: function() {\n if (this.click_mode === Utils._CLICKMODE_ADDNODE) {\n this.click_mode = false;\n this.notif_$.hide();\n } else {\n this.click_mode = Utils._CLICKMODE_ADDNODE;\n this.notif_$.text(this.renkan.translate(\"Click on the background canvas to add a node\")).fadeIn();\n }\n return false;\n },\n addEdgeBtn: function() {\n if (this.click_mode === Utils._CLICKMODE_STARTEDGE || this.click_mode === Utils._CLICKMODE_ENDEDGE) {\n this.click_mode = false;\n this.notif_$.hide();\n } else {\n this.click_mode = Utils._CLICKMODE_STARTEDGE;\n this.notif_$.text(this.renkan.translate(\"Click on a first node to start the edge\")).fadeIn();\n }\n return false;\n },\n exportProject: function() {\n var projectJSON = this.renkan.project.toJSON(),\n downloadLink = document.createElement(\"a\"),\n projectId = projectJSON.id,\n fileNameToSaveAs = projectId + \".json\";\n\n // clean ids\n delete projectJSON.id;\n delete projectJSON._id;\n delete projectJSON.space_id;\n\n var objId;\n var idsMap = {};\n\n _.each(projectJSON.nodes, function(e,i,l) {\n objId = e.id || e._id;\n delete e._id;\n delete e.id;\n idsMap[objId] = e['@id'] = Utils.getUUID4();\n });\n _.each(projectJSON.edges, function(e,i,l) {\n delete e._id;\n delete e.id;\n e.to = idsMap[e.to];\n e.from = idsMap[e.from];\n });\n _.each(projectJSON.views, function(e,i,l) {\n objId = e.id || e._id;\n delete e._id;\n delete e.id;\n });\n projectJSON.users = [];\n\n var projectJSONStr = JSON.stringify(projectJSON, null, 2);\n var blob = new Blob([projectJSONStr], {type: \"application/json;charset=utf-8\"});\n filesaver(blob,fileNameToSaveAs);\n\n },\n foldBins: function() {\n var foldBinsButton = this.$.find(\".Rk-Fold-Bins\"),\n bins = this.renkan.$.find(\".Rk-Bins\");\n var _this = this,\n sizeBef = _this.canvas_$.width(),\n sizeAft;\n if (bins.position().left < 0) {\n bins.animate({left: 0},250);\n this.$.animate({left: 300},250,function() {\n var w = _this.$.width();\n paper.view.viewSize = new paper.Size([w, _this.canvas_$.height()]);\n });\n if ((sizeBef - bins.width()) < bins.height()){\n sizeAft = sizeBef;\n } else {\n sizeAft = sizeBef - bins.width();\n }\n foldBinsButton.html(\"«\");\n } else {\n bins.animate({left: -300},250);\n this.$.animate({left: 0},250,function() {\n var w = _this.$.width();\n paper.view.viewSize = new paper.Size([w, _this.canvas_$.height()]);\n });\n sizeAft = sizeBef+300;\n foldBinsButton.html(\"»\");\n }\n _this.resizeZoom(1, 1, (sizeAft/sizeBef));\n },\n save: function() { },\n open: function() { }\n }).value();\n\n /* Scene End */\n\n return Scene;\n\n});\n\n\n//Load modules and use them\nif( typeof require.config === \"function\" ) {\n require.config({\n paths: {\n 'jquery':'../lib/jquery/jquery',\n// 'underscore':'../lib/underscore/underscore',\n// 'underscore':'../lib/lodash-compat/lodash',\n 'underscore':'../lib/lodash/lodash',\n 'filesaver' :'../lib/FileSaver/FileSaver',\n 'requtils':'require-utils'\n }\n });\n}\n\nrequire(['renderer/baserepresentation',\n 'renderer/basebutton',\n 'renderer/noderepr',\n 'renderer/edge',\n 'renderer/tempedge',\n 'renderer/baseeditor',\n 'renderer/nodeeditor',\n 'renderer/edgeeditor',\n 'renderer/nodebutton',\n 'renderer/nodeeditbutton',\n 'renderer/noderemovebutton',\n 'renderer/noderevertbutton',\n 'renderer/nodelinkbutton',\n 'renderer/nodeenlargebutton',\n 'renderer/nodeshrinkbutton',\n 'renderer/edgeeditbutton',\n 'renderer/edgeremovebutton',\n 'renderer/edgerevertbutton',\n 'renderer/miniframe',\n 'renderer/scene'\n ], function(BaseRepresentation, BaseButton, NodeRepr, Edge, TempEdge, BaseEditor, NodeEditor, EdgeEditor, NodeButton, NodeEditButton, NodeRemoveButton, NodeRevertButton, NodeLinkButton, NodeEnlargeButton, NodeShrinkButton, EdgeEditButton, EdgeRemoveButton, EdgeRevertButton, MiniFrame, Scene){\n\n \n\n var Rkns = window.Rkns;\n\n if(typeof Rkns.Renderer === \"undefined\"){\n Rkns.Renderer = {};\n }\n var Renderer = Rkns.Renderer;\n\n Renderer._BaseRepresentation = BaseRepresentation;\n Renderer._BaseButton = BaseButton;\n Renderer.Node = NodeRepr;\n Renderer.Edge = Edge;\n Renderer.TempEdge = TempEdge;\n Renderer._BaseEditor = BaseEditor;\n Renderer.NodeEditor = NodeEditor;\n Renderer.EdgeEditor = EdgeEditor;\n Renderer._NodeButton = NodeButton;\n Renderer.NodeEditButton = NodeEditButton;\n Renderer.NodeRemoveButton = NodeRemoveButton;\n Renderer.NodeRevertButton = NodeRevertButton;\n Renderer.NodeLinkButton = NodeLinkButton;\n Renderer.NodeEnlargeButton = NodeEnlargeButton;\n Renderer.NodeShrinkButton = NodeShrinkButton;\n Renderer.EdgeEditButton = EdgeEditButton;\n Renderer.EdgeRemoveButton = EdgeRemoveButton;\n Renderer.EdgeRevertButton = EdgeRevertButton;\n Renderer.MiniFrame = MiniFrame;\n Renderer.Scene = Scene;\n\n startRenkan();\n});\n\ndefine(\"main-renderer\", function(){});\n\n"]} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/python/django/renkanmanager/static/renkanmanager/lib/renkan/js/templates.js Mon Apr 27 17:22:46 2015 +0200 @@ -0,0 +1,718 @@ +this["renkanJST"] = this["renkanJST"] || {}; + +this["renkanJST"]["templates/colorpicker.html"] = function(obj) { +obj || (obj = {}); +var __t, __p = '', __e = _.escape; +with (obj) { +__p += '<li data-color="' + +((__t = (c)) == null ? '' : __t) + +'" style="background: ' + +((__t = (c)) == null ? '' : __t) + +'"></li>'; + +} +return __p +}; + +this["renkanJST"]["templates/edgeeditor.html"] = function(obj) { +obj || (obj = {}); +var __t, __p = '', __e = _.escape, __j = Array.prototype.join; +function print() { __p += __j.call(arguments, '') } +with (obj) { +__p += '<h2>\n <span class="Rk-CloseX">×</span>' + +__e(renkan.translate("Edit Edge")) + +'</span>\n</h2>\n<p>\n <label>' + +__e(renkan.translate("Title:")) + +'</label>\n <input class="Rk-Edit-Title" type="text" value="' + +__e(edge.title) + +'" />\n</p>\n'; + if (options.show_edge_editor_uri) { ; +__p += '\n <p>\n <label>' + +__e(renkan.translate("URI:")) + +'</label>\n <input class="Rk-Edit-URI" type="text" value="' + +__e(edge.uri) + +'" />\n <a class="Rk-Edit-Goto" href="' + +__e(edge.uri) + +'" target="_blank"></a>\n </p>\n '; + if (options.properties.length) { ; +__p += '\n <p>\n <label>' + +__e(renkan.translate("Choose from vocabulary:")) + +'</label>\n <select class="Rk-Edit-Vocabulary">\n '; + _.each(options.properties, function(ontology) { ; +__p += '\n <option class="Rk-Edit-Vocabulary-Class" value="">\n ' + +__e( renkan.translate(ontology.label) ) + +'\n </option>\n '; + _.each(ontology.properties, function(property) { var uri = ontology["base-uri"] + property.uri; ; +__p += '\n <option class="Rk-Edit-Vocabulary-Property" value="' + +__e( uri ) + +'"\n '; + if (uri === edge.uri) { ; +__p += ' selected'; + } ; +__p += '>\n ' + +__e( renkan.translate(property.label) ) + +'\n </option>\n '; + }) ; +__p += '\n '; + }) ; +__p += '\n </select>\n </p>\n'; + } } ; +__p += '\n'; + if (options.show_edge_editor_color) { ; +__p += '\n <div class="Rk-Editor-p">\n <span class="Rk-Editor-Label">' + +__e(renkan.translate("Edge color:")) + +'</span>\n <div class="Rk-Edit-ColorPicker-Wrapper">\n <span class="Rk-Edit-Color" style="background: <%-edge.color%>;">\n <span class="Rk-Edit-ColorTip"></span>\n </span>\n ' + +((__t = ( renkan.colorPicker )) == null ? '' : __t) + +'\n <span class="Rk-Edit-ColorPicker-Text">' + +__e( renkan.translate("Choose color") ) + +'</span>\n </div>\n </div>\n'; + } ; +__p += '\n'; + if (options.show_edge_editor_direction) { ; +__p += '\n <p>\n <span class="Rk-Edit-Direction">' + +__e( renkan.translate("Change edge direction") ) + +'</span>\n </p>\n'; + } ; +__p += '\n'; + if (options.show_edge_editor_nodes) { ; +__p += '\n <p>\n <span class="Rk-Editor-Label">' + +__e(renkan.translate("From:")) + +'</span>\n <span class="Rk-UserColor" style="background: ' + +__e(edge.from_color) + +';"></span>\n ' + +__e( shortenText(edge.from_title, 25) ) + +'\n </p>\n <p>\n <span class="Rk-Editor-Label">' + +__e(renkan.translate("To:")) + +'</span>\n <span class="Rk-UserColor" style="background: >%-edge.to_color%>;"></span>\n ' + +__e( shortenText(edge.to_title, 25) ) + +'\n </p>\n'; + } ; +__p += '\n'; + if (options.show_edge_editor_creator && edge.has_creator) { ; +__p += '\n <p>\n <span class="Rk-Editor-Label">' + +__e(renkan.translate("Created by:")) + +'</span>\n <span class="Rk-UserColor" style="background: <%-edge.created_by_color%>;"></span>\n ' + +__e( shortenText(edge.created_by_title, 25) ) + +'\n </p>\n'; + } ; +__p += '\n'; + +} +return __p +}; + +this["renkanJST"]["templates/edgeeditor_readonly.html"] = function(obj) { +obj || (obj = {}); +var __t, __p = '', __e = _.escape, __j = Array.prototype.join; +function print() { __p += __j.call(arguments, '') } +with (obj) { +__p += '<h2>\n <span class="Rk-CloseX">×</span>\n '; + if (options.show_edge_tooltip_color) { ; +__p += '\n <span class="Rk-UserColor" style="background: ' + +__e( edge.color ) + +';"></span>\n '; + } ; +__p += '\n <span class="Rk-Display-Title">\n '; + if (edge.uri) { ; +__p += '\n <a href="' + +__e(edge.uri) + +'" target="_blank">\n '; + } ; +__p += '\n ' + +__e(edge.title) + +'\n '; + if (edge.uri) { ; +__p += ' </a> '; + } ; +__p += '\n </span>\n</h2>\n'; + if (options.show_edge_tooltip_uri && edge.uri) { ; +__p += '\n <p class="Rk-Display-URI">\n <a href="' + +__e(edge.uri) + +'" target="_blank">' + +__e( edge.short_uri ) + +'</a>\n </p>\n'; + } ; +__p += '\n<p>' + +__e(edge.description) + +'</p>\n'; + if (options.show_edge_tooltip_nodes) { ; +__p += '\n <p>\n <span class="Rk-Editor-Label">' + +__e(renkan.translate("From:")) + +'</span>\n <span class="Rk-UserColor" style="background: ' + +__e( edge.from_color ) + +';"></span>\n ' + +__e( shortenText(edge.from_title, 25) ) + +'\n </p>\n <p>\n <span class="Rk-Editor-Label">' + +__e(renkan.translate("To:")) + +'</span>\n <span class="Rk-UserColor" style="background: ' + +__e( edge.to_color ) + +';"></span>\n ' + +__e( shortenText(edge.to_title, 25) ) + +'\n </p>\n'; + } ; +__p += '\n'; + if (options.show_edge_tooltip_creator && edge.has_creator) { ; +__p += '\n <p>\n <span class="Rk-Editor-Label">' + +__e(renkan.translate("Created by:")) + +'</span>\n <span class="Rk-UserColor" style="background: ' + +__e( edge.created_by_color ) + +';"></span>\n ' + +__e( shortenText(edge.created_by_title, 25) ) + +'\n </p>\n'; + } ; +__p += '\n'; + +} +return __p +}; + +this["renkanJST"]["templates/ldtjson-bin/annotationtemplate.html"] = function(obj) { +obj || (obj = {}); +var __t, __p = '', __e = _.escape; +with (obj) { +__p += '<li class="Rk-Bin-Item" draggable="true"\n data-image="' + +__e( Rkns.Utils.getFullURL(image) ) + +'"\n data-uri="' + +((__t = (ldt_platform)) == null ? '' : __t) + +'ldtplatform/ldt/front/player/' + +((__t = (mediaid)) == null ? '' : __t) + +'/#id=' + +((__t = (annotationid)) == null ? '' : __t) + +'"\n data-title="' + +__e(title) + +'" data-description="' + +__e(description) + +'">\n\n <img class="Rk-Ldt-Annotation-Icon" src="' + +((__t = (image)) == null ? '' : __t) + +'" />\n <h4>' + +((__t = (htitle)) == null ? '' : __t) + +'</h4>\n <p>' + +((__t = (hdescription)) == null ? '' : __t) + +'</p>\n <p>Start: ' + +((__t = (start)) == null ? '' : __t) + +', End: ' + +((__t = (end)) == null ? '' : __t) + +', Duration: ' + +((__t = (duration)) == null ? '' : __t) + +'</p>\n <div class="Rk-Clear"></div>\n</li>\n'; + +} +return __p +}; + +this["renkanJST"]["templates/ldtjson-bin/segmenttemplate.html"] = function(obj) { +obj || (obj = {}); +var __t, __p = '', __e = _.escape; +with (obj) { +__p += '<li class="Rk-Bin-Item" draggable="true"\n data-image="' + +__e( Rkns.Utils.getFullURL(image) ) + +'"\n data-uri="' + +((__t = (ldt_platform)) == null ? '' : __t) + +'ldtplatform/ldt/front/player/' + +((__t = (mediaid)) == null ? '' : __t) + +'/#id=' + +((__t = (annotationid)) == null ? '' : __t) + +'"\n data-title="' + +__e(title) + +'" data-description="' + +__e(description) + +'">\n\n <img class="Rk-Ldt-Annotation-Icon" src="' + +((__t = (image)) == null ? '' : __t) + +'" />\n <h4>' + +((__t = (htitle)) == null ? '' : __t) + +'</h4>\n <p>' + +((__t = (hdescription)) == null ? '' : __t) + +'</p>\n <p>Start: ' + +((__t = (start)) == null ? '' : __t) + +', End: ' + +((__t = (end)) == null ? '' : __t) + +', Duration: ' + +((__t = (duration)) == null ? '' : __t) + +'</p>\n <div class="Rk-Clear"></div>\n</li>\n'; + +} +return __p +}; + +this["renkanJST"]["templates/ldtjson-bin/tagtemplate.html"] = function(obj) { +obj || (obj = {}); +var __t, __p = '', __e = _.escape; +with (obj) { +__p += '<li class="Rk-Bin-Item" draggable="true"\n data-image="' + +__e( Rkns.Utils.getFullURL(static_url+'img/ldt-tag.png') ) + +'"\n data-uri="' + +((__t = (ldt_platform)) == null ? '' : __t) + +'ldtplatform/ldt/front/search/?search=' + +((__t = (encodedtitle)) == null ? '' : __t) + +'&field=all"\n data-title="' + +__e(title) + +'" data-description="Tag \'' + +__e(title) + +'\'">\n\n <img class="Rk-Ldt-Tag-Icon" src="' + +__e(static_url) + +'img/ldt-tag.png" />\n <h4>' + +((__t = (htitle)) == null ? '' : __t) + +'</h4>\n <div class="Rk-Clear"></div>\n</li>\n'; + +} +return __p +}; + +this["renkanJST"]["templates/list-bin.html"] = function(obj) { +obj || (obj = {}); +var __t, __p = '', __e = _.escape, __j = Array.prototype.join; +function print() { __p += __j.call(arguments, '') } +with (obj) { +__p += '<li class="Rk-Bin-Item Rk-ResourceList-Item" draggable="true"\n data-uri="' + +__e(url) + +'" data-title="' + +__e(title) + +'"\n data-description="' + +__e(description) + +'"\n '; + if (image) { ; +__p += '\n data-image="' + +__e( Rkns.Utils.getFullURL(image) ) + +'"\n '; + } else { ; +__p += '\n data-image=""\n '; + } ; +__p += '\n>'; + if (image) { ; +__p += '\n <img class="Rk-ResourceList-Image" src="' + +__e(image) + +'" />\n'; + } ; +__p += '\n<h4 class="Rk-ResourceList-Title">\n '; + if (url) { ; +__p += '\n <a href="' + +__e(url) + +'" target="_blank">\n '; + } ; +__p += '\n ' + +((__t = (htitle)) == null ? '' : __t) + +'\n '; + if (url) { ; +__p += '</a>'; + } ; +__p += '\n </h4>\n '; + if (description) { ; +__p += '\n <p class="Rk-ResourceList-Description">' + +((__t = (hdescription)) == null ? '' : __t) + +'</p>\n '; + } ; +__p += '\n '; + if (image) { ; +__p += '\n <div style="clear: both;"></div>\n '; + } ; +__p += '\n</li>\n'; + +} +return __p +}; + +this["renkanJST"]["templates/main.html"] = function(obj) { +obj || (obj = {}); +var __t, __p = '', __e = _.escape, __j = Array.prototype.join; +function print() { __p += __j.call(arguments, '') } +with (obj) { + + if (options.show_bins) { ; +__p += '\n <div class="Rk-Bins">\n <div class="Rk-Bins-Head">\n <h2 class="Rk-Bins-Title">' + +__e( translate("Select contents:")) + +'</h2>\n <form class="Rk-Web-Search-Form Rk-Search-Form">\n <input class="Rk-Web-Search-Input Rk-Search-Input" type="search"\n placeholder="' + +__e( translate('Search the Web') ) + +'" />\n <div class="Rk-Search-Select">\n <div class="Rk-Search-Current"></div>\n <ul class="Rk-Search-List"></ul>\n </div>\n <input type="submit" value=""\n class="Rk-Web-Search-Submit Rk-Search-Submit" title="' + +__e( translate('Search the Web') ) + +'" />\n </form>\n <form class="Rk-Bins-Search-Form Rk-Search-Form">\n <input class="Rk-Bins-Search-Input Rk-Search-Input" type="search"\n placeholder="' + +__e( translate('Search in Bins') ) + +'" /> <input\n type="submit" value=""\n class="Rk-Bins-Search-Submit Rk-Search-Submit"\n title="' + +__e( translate('Search in Bins') ) + +'" />\n </form>\n </div>\n <ul class="Rk-Bin-List"></ul>\n </div>\n'; + } ; +__p += ' '; + if (options.show_editor) { ; +__p += '\n <div class="Rk-Render Rk-Render-'; + if (options.show_bins) { ; +__p += 'Panel'; + } else { ; +__p += 'Full'; + } ; +__p += '"></div>\n'; + } ; +__p += '\n'; + +} +return __p +}; + +this["renkanJST"]["templates/nodeeditor.html"] = function(obj) { +obj || (obj = {}); +var __t, __p = '', __e = _.escape, __j = Array.prototype.join; +function print() { __p += __j.call(arguments, '') } +with (obj) { +__p += '<h2>\n <span class="Rk-CloseX">×</span>' + +__e(renkan.translate("Edit Node")) + +'</span>\n</h2>\n<p>\n <label>' + +__e(renkan.translate("Title:")) + +'</label>\n <input class="Rk-Edit-Title" type="text" value="' + +__e(node.title) + +'" />\n</p>\n'; + if (options.show_node_editor_uri) { ; +__p += '\n <p>\n <label>' + +__e(renkan.translate("URI:")) + +'</label>\n <input class="Rk-Edit-URI" type="text" value="' + +__e(node.uri) + +'" />\n <a class="Rk-Edit-Goto" href="' + +__e(node.uri) + +'" target="_blank"></a>\n </p>\n'; + } ; +__p += ' '; + if (options.show_node_editor_description) { ; +__p += '\n <p>\n <label>' + +__e(renkan.translate("Description:")) + +'</label>\n <textarea class="Rk-Edit-Description">' + +__e(node.description) + +'</textarea>\n </p>\n'; + } ; +__p += ' '; + if (options.show_node_editor_size) { ; +__p += '\n <p>\n <span class="Rk-Editor-Label">' + +__e(renkan.translate("Size:")) + +'</span>\n <a href="#" class="Rk-Edit-Size-Down">-</a>\n <span class="Rk-Edit-Size-Value">' + +__e(node.size) + +'</span>\n <a href="#" class="Rk-Edit-Size-Up">+</a>\n </p>\n'; + } ; +__p += ' '; + if (options.show_node_editor_color) { ; +__p += '\n <div class="Rk-Editor-p">\n <span class="Rk-Editor-Label">\n ' + +__e(renkan.translate("Node color:")) + +'</span>\n <div class="Rk-Edit-ColorPicker-Wrapper">\n <span class="Rk-Edit-Color" style="background: ' + +__e(node.color) + +';">\n <span class="Rk-Edit-ColorTip"></span>\n </span>\n ' + +((__t = ( renkan.colorPicker )) == null ? '' : __t) + +'\n <span class="Rk-Edit-ColorPicker-Text">' + +__e( renkan.translate("Choose color") ) + +'</span>\n </div>\n </div>\n'; + } ; +__p += ' '; + if (options.show_node_editor_image) { ; +__p += '\n <div class="Rk-Edit-ImgWrap">\n <div class="Rk-Edit-ImgPreview">\n <img src="' + +__e(node.image || node.image_placeholder) + +'" />\n '; + if (node.clip_path) { ; +__p += '\n <svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewbox="0 0 1 1" preserveAspectRatio="none">\n <path style="stroke-width: .02; stroke:red; fill-opacity:.3; fill:red;" d="' + +__e( node.clip_path ) + +'" />\n </svg>\n '; + }; +__p += '\n </div>\n </div>\n <p>\n <label>' + +__e(renkan.translate("Image URL:")) + +'</label>\n <div>\n <a class="Rk-Edit-Image-Del" href="#"></a>\n <input class="Rk-Edit-Image" type="text" value=\'' + +__e(node.image) + +'\' />\n </div>\n </p>\n'; + if (options.allow_image_upload) { ; +__p += '\n <p>\n <label>' + +__e(renkan.translate("Choose Image File:")) + +'</label>\n <input class="Rk-Edit-Image-File" type="file" accept="image/*" />\n </p>\n'; + }; + + } ; +__p += ' '; + if (options.show_node_editor_creator && node.has_creator) { ; +__p += '\n <p>\n <span class="Rk-Editor-Label">' + +__e(renkan.translate("Created by:")) + +'</span>\n <span class="Rk-UserColor" style="background: ' + +__e(node.created_by_color) + +';"></span>\n ' + +__e( shortenText(node.created_by_title, 25) ) + +'\n </p>\n'; + } ; +__p += ' '; + if (options.change_shapes) { ; +__p += '\n <p>\n <label>' + +__e(renkan.translate("Shapes available")) + +':</label>\n <select class="Rk-Edit-Shape">\n <option class="Rk-Edit-Vocabulary-Property" value="circle"'; + if (node.shape === "circle") { ; +__p += ' selected'; + } ; +__p += '>\n ' + +__e( renkan.translate("Circle") ) + +'\n </option>\n <option class="Rk-Edit-Vocabulary-Property" value="rectangle"'; + if (node.shape === "rectangle") { ; +__p += ' selected'; + } ; +__p += '>\n ' + +__e( renkan.translate("Square") ) + +'\n </option>\n <option class="Rk-Edit-Vocabulary-Property" value="diamond"'; + if (node.shape === "diamond") { ; +__p += ' selected'; + } ; +__p += '>\n ' + +__e( renkan.translate("Diamond") ) + +'\n </option>\n <option class="Rk-Edit-Vocabulary-Property" value="polygon"'; + if (node.shape === "polygon") { ; +__p += ' selected'; + } ; +__p += '>\n ' + +__e( renkan.translate("Hexagone") ) + +'\n </option>\n <option class="Rk-Edit-Vocabulary-Property" value="ellipse"'; + if (node.shape === "ellipse") { ; +__p += ' selected'; + } ; +__p += '>\n ' + +__e( renkan.translate("Ellipse") ) + +'\n </option>\n <option class="Rk-Edit-Vocabulary-Property" value="star"'; + if (node.shape === "star") { ; +__p += ' selected'; + } ; +__p += '>\n ' + +__e( renkan.translate("Star") ) + +'\n </option>\n </select>\n </p>\n'; + } ; +__p += '\n'; + +} +return __p +}; + +this["renkanJST"]["templates/nodeeditor_readonly.html"] = function(obj) { +obj || (obj = {}); +var __t, __p = '', __e = _.escape, __j = Array.prototype.join; +function print() { __p += __j.call(arguments, '') } +with (obj) { +__p += '<h2>\n <span class="Rk-CloseX">×</span>\n '; + if (options.show_node_tooltip_color) { ; +__p += '\n <span class="Rk-UserColor" style="background: ' + +__e(node.color) + +';"></span>\n '; + } ; +__p += '\n <span class="Rk-Display-Title">\n '; + if (node.uri) { ; +__p += '\n <a href="' + +__e(node.uri) + +'" target="_blank">\n '; + } ; +__p += '\n ' + +__e(node.title) + +'\n '; + if (node.uri) { ; +__p += '</a>'; + } ; +__p += '\n </span>\n</h2>\n'; + if (node.uri && options.show_node_tooltip_uri) { ; +__p += '\n <p class="Rk-Display-URI">\n <a href="' + +__e(node.uri) + +'" target="_blank">' + +__e(node.short_uri) + +'</a>\n </p>\n'; + } ; +__p += ' '; + if (options.show_node_tooltip_description) { ; +__p += '\n <p class="Rk-Display-Description">' + +__e(node.description) + +'</p>\n'; + } ; +__p += ' '; + if (node.image && options.show_node_tooltip_image) { ; +__p += '\n <img class="Rk-Display-ImgPreview" src="' + +__e(node.image) + +'" />\n'; + } ; +__p += ' '; + if (node.has_creator && options.show_node_tooltip_creator) { ; +__p += '\n <p>\n <span class="Rk-Editor-Label">' + +__e(renkan.translate("Created by:")) + +'</span>\n <span class="Rk-UserColor" style="background: ' + +__e(node.created_by_color) + +';"></span>\n ' + +__e( shortenText(node.created_by_title, 25) ) + +'\n </p>\n'; + } ; +__p += '\n'; + +} +return __p +}; + +this["renkanJST"]["templates/scene.html"] = function(obj) { +obj || (obj = {}); +var __t, __p = '', __e = _.escape, __j = Array.prototype.join; +function print() { __p += __j.call(arguments, '') } +with (obj) { + + if (options.show_top_bar) { ; +__p += '\n <div class="Rk-TopBar">\n <div class="loader"></div>\n '; + if (!options.editor_mode) { ; +__p += '\n <h2 class="Rk-PadTitle">\n ' + +__e( project.get("title") || translate("Untitled project")) + +'\n </h2>\n '; + } else { ; +__p += '\n <input type="text" class="Rk-PadTitle" value="' + +__e( project.get('title') || '' ) + +'" placeholder="' + +__e(translate('Untitled project')) + +'" />\n '; + } ; +__p += '\n '; + if (options.show_user_list) { ; +__p += '\n <div class="Rk-Users">\n <div class="Rk-CurrentUser">\n '; + if (options.show_user_color) { ; +__p += '\n <div class="Rk-Edit-ColorPicker-Wrapper">\n <span class="Rk-CurrentUser-Color">\n '; + if (options.user_color_editable) { ; +__p += '\n <span class="Rk-Edit-ColorTip"></span>\n '; + } ; +__p += '\n </span>\n '; + if (options.user_color_editable) { print(colorPicker) } ; +__p += '\n </div>\n '; + } ; +__p += '\n <span class="Rk-CurrentUser-Name"><unknown user></span>\n </div>\n <ul class="Rk-UserList"></ul>\n </div>\n '; + } ; +__p += '\n '; + if (options.home_button_url) {; +__p += '\n <div class="Rk-TopBar-Separator"></div>\n <a class="Rk-TopBar-Button Rk-Home-Button" href="' + +__e( options.home_button_url ) + +'">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n ' + +__e( translate(options.home_button_title) ) + +'\n </div>\n </div>\n </a>\n '; + } ; +__p += '\n '; + if (options.show_fullscreen_button) { ; +__p += '\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-FullScreen-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n ' + +__e(translate("Full Screen")) + +'\n </div>\n </div>\n </div>\n '; + } ; +__p += '\n '; + if (options.editor_mode) { ; +__p += '\n '; + if (options.show_addnode_button) { ; +__p += '\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-AddNode-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n ' + +__e(translate("Add Node")) + +'\n </div>\n </div>\n </div>\n '; + } ; +__p += '\n '; + if (options.show_addedge_button) { ; +__p += '\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-AddEdge-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n ' + +__e(translate("Add Edge")) + +'\n </div>\n </div>\n </div>\n '; + } ; +__p += '\n '; + if (options.show_export_button) { ; +__p += '\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-Export-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n ' + +__e(translate("Download Project")) + +'\n </div>\n </div>\n </div>\n '; + } ; +__p += '\n '; + if (options.show_save_button) { ; +__p += '\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-Save-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents"></div>\n </div>\n </div>\n '; + } ; +__p += '\n '; + if (options.show_open_button) { ; +__p += '\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-Open-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n ' + +__e(translate("Open Project")) + +'\n </div>\n </div>\n </div>\n '; + } ; +__p += '\n '; + if (options.show_bookmarklet) { ; +__p += '\n <div class="Rk-TopBar-Separator"></div>\n <a class="Rk-TopBar-Button Rk-Bookmarklet-Button" href="#">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n ' + +__e(translate("Renkan \'Drag-to-Add\' bookmarklet")) + +'\n </div>\n </div>\n </a>\n <div class="Rk-TopBar-Separator"></div>\n '; + } ; +__p += '\n '; + } else { ; +__p += '\n '; + if (options.show_export_button) { ; +__p += '\n <div class="Rk-TopBar-Separator"></div>\n <div class="Rk-TopBar-Button Rk-Export-Button">\n <div class="Rk-TopBar-Tooltip">\n <div class="Rk-TopBar-Tooltip-Contents">\n ' + +__e(translate("Download Project")) + +'\n </div>\n </div>\n </div>\n <div class="Rk-TopBar-Separator"></div>\n '; + } ; +__p += '\n '; + }; ; +__p += '\n '; + if (options.show_search_field) { ; +__p += '\n <form action="#" class="Rk-GraphSearch-Form">\n <input type="search" class="Rk-GraphSearch-Field" placeholder="' + +__e( translate('Search in graph') ) + +'" />\n </form>\n <div class="Rk-TopBar-Separator"></div>\n '; + } ; +__p += '\n </div>\n'; + } ; +__p += '\n<div class="Rk-Editing-Space'; + if (!options.show_top_bar) { ; +__p += ' Rk-Editing-Space-Full'; + } ; +__p += '">\n <div class="Rk-Labels"></div>\n <canvas class="Rk-Canvas" '; + if (options.resize) { ; +__p += ' resize="" '; + } ; +__p += '></canvas>\n <div class="Rk-Notifications"></div>\n <div class="Rk-Editor">\n '; + if (options.show_bins) { ; +__p += '\n <div class="Rk-Fold-Bins">«</div>\n '; + } ; +__p += '\n '; + if (options.show_zoom) { ; +__p += '\n <div class="Rk-ZoomButtons">\n <div class="Rk-ZoomIn" title="' + +__e(translate('Zoom In')) + +'"></div>\n <div class="Rk-ZoomFit" title="' + +__e(translate('Zoom Fit')) + +'"></div>\n <div class="Rk-ZoomOut" title="' + +__e(translate('Zoom Out')) + +'"></div>\n '; + if (options.editor_mode && options.save_view) { ; +__p += '\n <div class="Rk-ZoomSave" title="' + +__e(translate('Zoom Save')) + +'"></div>\n '; + } ; +__p += '\n '; + if (options.save_view) { ; +__p += '\n <div class="Rk-ZoomSetSaved" title="' + +__e(translate('View saved zoom')) + +'"></div>\n '; + } ; +__p += '\n </div>\n '; + } ; +__p += '\n </div>\n</div>\n'; + +} +return __p +}; + +this["renkanJST"]["templates/search.html"] = function(obj) { +obj || (obj = {}); +var __t, __p = '', __e = _.escape; +with (obj) { +__p += '<li class="' + +((__t = ( className )) == null ? '' : __t) + +'" data-key="' + +((__t = ( key )) == null ? '' : __t) + +'">' + +((__t = ( title )) == null ? '' : __t) + +'</li>'; + +} +return __p +}; + +this["renkanJST"]["templates/wikipedia-bin/resulttemplate.html"] = function(obj) { +obj || (obj = {}); +var __t, __p = '', __e = _.escape; +with (obj) { +__p += '<li class="Rk-Wikipedia-Result Rk-Bin-Item" draggable="true"\n data-uri="' + +__e(url) + +'" data-title="Wikipedia: ' + +__e(title) + +'"\n data-description="' + +__e(description) + +'"\n data-image="' + +__e( Rkns.Utils.getFullURL( static_url + 'img/wikipedia.png' ) ) + +'">\n\n <img class="Rk-Wikipedia-Icon" src="' + +__e(static_url) + +'img/wikipedia.png">\n <h4 class="Rk-Wikipedia-Title">\n <a href="' + +__e(url) + +'" target="_blank">' + +((__t = (htitle)) == null ? '' : __t) + +'</a>\n </h4>\n <p class="Rk-Wikipedia-Snippet">' + +((__t = (hdescription)) == null ? '' : __t) + +'</p>\n</li>\n'; + +} +return __p +}; \ No newline at end of file
--- a/server/python/django/renkanmanager/static/renkanmanager/lib/requirejs/require.js Sat Apr 25 04:37:06 2015 +0200 +++ b/server/python/django/renkanmanager/static/renkanmanager/lib/requirejs/require.js Mon Apr 27 17:22:46 2015 +0200 @@ -1,5 +1,5 @@ /** vim: et:ts=4:sw=4:sts=4 - * @license RequireJS 2.1.15 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved. + * @license RequireJS 2.1.17 Copyright (c) 2010-2015, The Dojo Foundation All Rights Reserved. * Available via the MIT or new BSD license. * see: http://github.com/jrburke/requirejs for details */ @@ -12,7 +12,7 @@ (function (global) { var req, s, head, baseElement, dataMain, src, interactiveScript, currentlyAddingScript, mainScript, subPath, - version = '2.1.15', + version = '2.1.17', commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g, jsSuffixRegExp = /\.js$/, @@ -244,7 +244,7 @@ // still work when converted to a path, even though // as an ID it is less than ideal. In larger point // releases, may be better to just kick out an error. - if (i === 0 || (i == 1 && ary[2] === '..') || ary[i - 1] === '..') { + if (i === 0 || (i === 1 && ary[2] === '..') || ary[i - 1] === '..') { continue; } else if (i > 0) { ary.splice(i - 1, 2); @@ -1123,6 +1123,13 @@ if (this.errback) { on(depMap, 'error', bind(this, this.errback)); + } else if (this.events.error) { + // No direct errback on this module, but something + // else is listening for errors, so be sure to + // propagate the error correctly. + on(depMap, 'error', bind(this, function(err) { + this.emit('error', err); + })); } }