You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2015/01/05 18:34:11 UTC
[32/51] [abbrv] [partial] jena git commit: Maven modules for Fuseki2
http://git-wip-us.apache.org/repos/asf/jena/blob/470ee4d7/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/app/views/file-upload.js
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/app/views/file-upload.js b/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/app/views/file-upload.js
new file mode 100644
index 0000000..f16e544
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/app/views/file-upload.js
@@ -0,0 +1,225 @@
+/**
+ * This view presents a control to upload files to the current dataset, and a recently-uploaded
+ * log to track what has been done.
+ */
+
+define(
+ function( require ) {
+ var Backbone = require( "backbone" ),
+ _ = require( "underscore" ),
+ sprintf = require( "sprintf" ),
+ fui = require( "app/fui" ),
+ fileUploadTemplate = require( "plugins/text!app/templates/file-upload.tpl" ),
+ UploadableFileView = require( "app/views/uploadable-file" );
+
+ var FileUploadView = Backbone.Marionette.CompositeView.extend( {
+ initialize: function(){
+ _.bindAll( this,
+ "onUploadAdd", "onRemoveUpload", "onUploadAll",
+ "onProgress", "onUploadDone", "onUploadFail",
+ "onPerformUpload" );
+
+ fui.vent.on( "upload.remove", this.onRemoveUpload );
+ fui.vent.on( "upload.perform", this.onPerformUpload );
+ },
+
+ template: _.template( fileUploadTemplate ),
+
+ el: "#file-upload",
+
+ itemViewContainer: "ul",
+ itemView: UploadableFileView,
+ collection: new Backbone.Collection(),
+
+ ui: {
+ fileUpload: '#fileuploadForm',
+ graphLabel: '.graph-label input'
+ },
+
+ events: {
+ "click .action-upload-all": "onUploadAll"
+ },
+
+ templateHelpers: {
+ },
+
+ onRender: function() {
+ // initialise the file upload widget
+ this.ui.fileUpload.fileupload( {
+ dataType: 'json',
+ add: this.onUploadAdd,
+ progress: this.onProgress
+ } );
+ },
+
+ /** User has added a file */
+ onUploadAdd: function( e, data ) {
+ var collection = this.collection;
+ var self = this;
+
+ _.each( data.files, function( file ) {
+ file.readableFileSize = self.readableFileSize( file );
+ collection.add( new Backbone.Model( {file: file} ) );
+ } );
+
+ this.enableUploadAll( true );
+ },
+
+ /** Return file size in bytes in a human-readable form */
+ readableFileSize: function( file ) {
+ var k = 1024;
+ var m = k * k;
+
+ if (file.size >= m) {
+ return sprintf( "%.1fmb", file.size / m );
+ }
+ else if (file.size >= k) {
+ return sprintf( "%.1fkb", file.size / k );
+ }
+ else {
+ return sprintf( "%d bytes", file.size );
+ }
+ },
+
+ /** User has requested to remove a selected upload */
+ onRemoveUpload: function( file ) {
+ this.collection.remove( file );
+ this.enableUploadAll( this.collection.size() > 0 )
+ },
+
+ /** User has requested to perform a selected upload */
+ onPerformUpload: function( model ) {
+ this.loadAll = false;
+ this.uploadFileFromModel( model );
+ },
+
+ /** Return the list of active files waiting for upload */
+ activeFiles: function() {
+ var activeModels = _.filter( this.collection.models, function( m ) {
+ return !m.completed;
+ } );
+
+ return _.map( activeModels, function( m ) {
+ return m.get( "file" );
+ } );
+ },
+
+ /** User action to upload all active files */
+ onUploadAll: function( e ) {
+ if (e) {
+ e.preventDefault();
+ }
+
+ this.$el.find( ".file-description .action" ).attr( 'disabled', 'disabled' );
+ this.loadNextAvailableFile( true );
+ },
+
+ /** Load the next file in the sequence */
+ loadNextAvailableFile: function( all ) {
+ this.loadAll = all;
+ var files = this.activeFiles();
+
+ if (files.length > 0) {
+ this.uploadFile( files.shift() );
+ }
+ else {
+ this.enableUploadAll( false );
+ }
+ },
+
+ /** Upload the given file to the server */
+ uploadFile: function( file ) {
+ this.uploadFileFromModel( this.collection.findWhere( {file: file} ) );
+ },
+
+ /** Upload the file attached to a given model */
+ uploadFileFromModel: function( model ) {
+ this.cacheModel( model );
+
+ var file = model.get( "file" );
+ var ds = fui.models.fusekiServer.selectedDataset();
+ var url = ds.uploadURL( this.destinationGraphName() );
+
+ this.ui.fileUpload.fileupload( 'send', {
+ files: [file],
+ url: url
+ })
+ .success( this.onUploadDone )
+ .fail( this.onUploadFail );
+ },
+
+ /** Return the selected graph name, or 'default' */
+ destinationGraphName: function() {
+ var gName = this.ui.graphLabel.val();
+ return (gName && gName !== "") ? gName : 'default';
+ },
+
+ /** Callback on progress against an upload */
+ onProgress: function( e, data ) {
+ var complete = Math.round( 100.0 * data.loaded/ data.total);
+ $(this.activeView.el).find( ".progress-bar" )
+ .attr( 'aria-valuenow', complete )
+ .css( 'width', sprintf( "%s%%", complete ));
+ },
+
+ /** Callback on successful completion */
+ onUploadDone: function( data, response ) {
+ var label = "Data file was empty.";
+ if ((data.count) > 0) {
+ var s = (data.count === 1) ? "" : "s";
+ label = sprintf( "%d %s%s", data.count, ((data.tripleCount > 0) ? "triple" : "quad"), s );
+ }
+
+ this.displayUploadResult( sprintf( "<p><small>Result: <strong>success</strong>. %s</small></p>", label ), "" );
+
+ if (this.loadAll) {
+ this.loadNextAvailableFile( true );
+ }
+ },
+
+ /** Callback on error */
+ onUploadFail: function( jqxhr, error, msg ) {
+ $(this.activeView.el).find( ".progress-bar" )
+ .removeClass( "progress-bar-success" )
+ .addClass( "progress-bar-warning" );
+ this.displayUploadResult( sprintf( "<p><small>Result: <strong>failed</strong> with message "%s"</small></p>", msg ), "text-danger" );
+
+ if (this.loadAll) {
+ this.loadNextAvailableFile( true );
+ }
+ },
+
+ /** Show the result of uploading a file */
+ displayUploadResult: function( html, cls ) {
+ var el = $(this.activeView.el);
+ this.activeModel.completed = true;
+ el.find( ".action" ).hide();
+
+ el.find( ".result" )
+ .addClass( cls )
+ .append( html );
+ },
+
+ /** Cache the currently active model so that we can attach actions to the corresponding view */
+ cacheModel: function( model ) {
+ this.activeModel = model;
+ this.activeView = this.children.findByModel( model );
+ },
+
+ /** Enable or disable the upload all button */
+ enableUploadAll: function( enabled ) {
+ if (enabled) {
+ $(".action-upload-all").removeAttr( 'disabled' );
+ }
+ else {
+ $(".action-upload-all").attr( 'disabled', 'disabled' );
+ }
+ }
+
+
+ });
+
+
+ return FileUploadView;
+ }
+);
http://git-wip-us.apache.org/repos/asf/jena/blob/470ee4d7/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/app/views/tabbed-view-manager.js
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/app/views/tabbed-view-manager.js b/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/app/views/tabbed-view-manager.js
new file mode 100644
index 0000000..5bba26d
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/app/views/tabbed-view-manager.js
@@ -0,0 +1,63 @@
+/**
+ * Reusable component that encapsulates managing a collection of sub-views as
+ * tabs, with the active tab being selected via the URL query param `tab`.
+ **/
+
+define(
+ function( require ) {
+ "use strict";
+
+ var Marionette = require( "marionette" ),
+ Backbone = require( "backbone" ),
+ _ = require( "underscore" ),
+ fui = require( "app/fui" ),
+ sprintf = require( "sprintf" ),
+ PageUtils = require( "app/util/page-utils" );
+
+ var TabbedViewManagerView = Backbone.View.extend( {
+
+ initialize: function(){
+ this._tab = PageUtils.queryParam( "tab" );
+ this._firstRender = false;
+ },
+
+ render: function() {
+ if (!this._firstRender) {
+ this._firstRender = true;
+ this.activateCurrentTab();
+
+ $(".nav-tabs").on( "shown.bs.tab", function( e ) {
+ fui.vent.trigger( "shown.bs.tab", $(e.target) );
+ } );
+ }
+ },
+
+ /**
+ * Make the tab named as the current tab active. If no named tab, make
+ * the first tab active by default.
+ */
+ activateCurrentTab: function() {
+ var tabs = $(".nav-tabs");
+ var tab = tabs.children().first();
+
+ if (this._tab) {
+ tab = tabs.find( sprintf( "a[href=#%s]", this._tab ) )
+ .parent();
+ }
+
+ if (!tab.is(".active")) {
+ tabs.children( "li" ).removeClass( "active" );
+ tabs.parent().children(".tab-pane").removeClass("active");
+
+ tab.addClass( "active" );
+ $( tab.children( "a" ).attr( "href" ) ).addClass("active");
+ }
+ }
+
+
+ });
+
+
+ return TabbedViewManagerView;
+ }
+);
http://git-wip-us.apache.org/repos/asf/jena/blob/470ee4d7/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/app/views/uploadable-file.js
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/app/views/uploadable-file.js b/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/app/views/uploadable-file.js
new file mode 100644
index 0000000..382a92f
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/app/views/uploadable-file.js
@@ -0,0 +1,39 @@
+/**
+ * This view encapsulates a single uploadable file
+ */
+
+define(
+ function( require ) {
+ var Backbone = require( "backbone" ),
+ _ = require( "underscore" ),
+ fui = require( "app/fui" ),
+ uploadableFileTemplate = require( "plugins/text!app/templates/uploadable-file.tpl" );
+
+ var UploadableFileView = Backbone.Marionette.ItemView.extend( {
+ initialize: function(){
+ },
+
+ tagName: "li",
+
+ template: _.template( uploadableFileTemplate ),
+
+ events: {
+ "click .action-remove-upload": "onActionRemoveUpload",
+ "click .action-upload-file": "onActionUploadFile"
+ },
+
+ onActionRemoveUpload: function( e ) {
+ e.preventDefault();
+ fui.vent.trigger( "upload.remove", this.model );
+ },
+
+ onActionUploadFile: function( e ) {
+ e.preventDefault();
+ fui.vent.trigger( "upload.perform", this.model );
+ }
+
+ });
+
+ return UploadableFileView;
+ }
+);
http://git-wip-us.apache.org/repos/asf/jena/blob/470ee4d7/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/app/views/validation-options.js
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/app/views/validation-options.js b/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/app/views/validation-options.js
new file mode 100644
index 0000000..ef0f723
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/app/views/validation-options.js
@@ -0,0 +1,54 @@
+define(
+ function( require ) {
+ var Backbone = require( "backbone" ),
+ _ = require( "underscore" ),
+ fui = require( "app/fui" );
+
+ var ValidationOptions = Backbone.Marionette.ItemView.extend( {
+ initialize: function(){
+ _.bindAll( this, "onValidateAs", "onOutputFormat", "onModelChange" );
+ this.listenTo( this.model, "change", this.onModelChange, this );
+ },
+
+ el: ".validation",
+
+ events: {
+ "click .validate-as-options a": "onValidateAs",
+ "click .output-format-options a": "onOutputFormat",
+ },
+
+ templateHelpers: {
+ },
+
+ onValidateAs: function( e ) {
+ e.preventDefault();
+ var elem = $(e.currentTarget);
+ this.model.setValidateAs( elem.data( "validate-as" ) );
+ this.$el.find(".validate-as-options a").removeClass("active");
+ elem.addClass("active");
+
+ if (this.model.validateAsQuery()) {
+ this.$el.find(".output-format-options").removeClass("hidden");
+ }
+ else {
+ this.$el.find(".output-format-options").addClass("hidden");
+ }
+ },
+
+ onOutputFormat: function( e ) {
+ e.preventDefault();
+ var elem = $(e.currentTarget);
+ this.model.setOutputFormat( elem.data( "output-format" ) );
+ this.$el.find(".output-format-options a").removeClass("active");
+ elem.addClass("active");
+ },
+
+ onModelChange: function( event ) {
+ }
+
+ });
+
+
+ return ValidationOptions;
+ }
+);
http://git-wip-us.apache.org/repos/asf/jena/blob/470ee4d7/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/common-config.js
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/common-config.js b/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/common-config.js
new file mode 100644
index 0000000..d715670
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/common-config.js
@@ -0,0 +1,93 @@
+require.config({
+ baseUrl: 'js/lib',
+ paths: {
+ 'app': '../app',
+ // lib paths
+ 'bootstrap': 'bootstrap.min',
+ 'jquery': 'jquery-1.10.2.min',
+ 'marionette': 'backbone.marionette',
+ 'sprintf': 'sprintf-0.7-beta1',
+ 'datatables': 'jquery.dataTables.min',
+ 'yasqe': 'yasqe.min',
+ 'yasr': 'yasr.min',
+ 'pivottable': 'pivot.min',
+ 'jquery-ui': 'jquery-ui.min'
+ },
+ map: {
+ '*': {
+ 'codemirror': 'lib/codemirror',
+ 'jquery.dataTables.min' : 'datatables',
+ 'jquery-ui': 'jquery-ui'
+ },
+ },
+ shim: {
+ 'underscore': {
+ exports: '_'
+ },
+ 'backbone': {
+ deps: ['underscore', 'jquery'],
+ exports: 'Backbone'
+ },
+ 'bootstrap': {
+ deps: ['jquery']
+ },
+ 'bootstrap-select.min': {
+ deps: ['bootstrap']
+ },
+ 'jquery.xdomainrequest': {
+ deps: ['jquery']
+ },
+ 'jquery.dataTables.min': {
+ deps: ['jquery']
+ },
+ 'jquery.form': {
+ deps: ['jquery']
+ },
+ 'jquery.ui.widget': {
+ deps: ['jquery']
+ },
+ 'qonsole': {
+ deps: ['yasqe', 'yasr'],
+ exports: 'qonsole'
+ },
+ 'yasqe': {
+ deps: ['jquery', 'lib/codemirror'],
+ exports: 'YASQE'
+ },
+ 'yasr': {
+ deps: ['pivottable', 'jquery', 'lib/codemirror', 'datatables'],
+ exports: 'YASR'
+ },
+ 'pivottable': {
+ deps: ['jquery-ui']
+ },
+ 'jquery-ui': {
+ deps: ['jquery']
+ },
+ 'jquery.fileupload': {
+ deps: ['jquery.fileupload.local', 'jquery.iframe-transport', 'jquery.ui.widget']
+ },
+ 'jquery.fileupload.local': {
+ deps: ['jquery']
+ },
+ 'jquery.iframe-transport': {
+ deps: ['jquery']
+ },
+ 'sprintf': {
+ exports: 'sprintf'
+ },
+ 'marionette': {
+ deps: ['backbone'],
+ exports: 'Marionette'
+ },
+ 'addon/fold/foldcode': {deps: ['lib/codemirror']},
+ 'addon/fold/brace-fold': {deps: ['addon/fold/foldcode']},
+ 'addon/fold/comment-fold': {deps: ['addon/fold/foldcode']},
+ 'addon/fold/foldgutter': {deps: ['addon/fold/foldcode']},
+ 'addon/fold/xml-fold': {deps: ['addon/fold/foldcode']},
+ 'mode/javascript/javascript': {deps: ['lib/codemirror']},
+ 'mode/sparql/sparql': {deps: ['lib/codemirror']},
+ 'mode/xml/xml': {deps: ['lib/codemirror']},
+ 'mode/turtle/turtle': {deps: ['lib/codemirror']}
+ }
+});
http://git-wip-us.apache.org/repos/asf/jena/blob/470ee4d7/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/addon/fold/brace-fold.js
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/addon/fold/brace-fold.js b/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/addon/fold/brace-fold.js
new file mode 100644
index 0000000..1605f6c
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/addon/fold/brace-fold.js
@@ -0,0 +1,105 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.registerHelper("fold", "brace", function(cm, start) {
+ var line = start.line, lineText = cm.getLine(line);
+ var startCh, tokenType;
+
+ function findOpening(openCh) {
+ for (var at = start.ch, pass = 0;;) {
+ var found = at <= 0 ? -1 : lineText.lastIndexOf(openCh, at - 1);
+ if (found == -1) {
+ if (pass == 1) break;
+ pass = 1;
+ at = lineText.length;
+ continue;
+ }
+ if (pass == 1 && found < start.ch) break;
+ tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));
+ if (!/^(comment|string)/.test(tokenType)) return found + 1;
+ at = found - 1;
+ }
+ }
+
+ var startToken = "{", endToken = "}", startCh = findOpening("{");
+ if (startCh == null) {
+ startToken = "[", endToken = "]";
+ startCh = findOpening("[");
+ }
+
+ if (startCh == null) return;
+ var count = 1, lastLine = cm.lastLine(), end, endCh;
+ outer: for (var i = line; i <= lastLine; ++i) {
+ var text = cm.getLine(i), pos = i == line ? startCh : 0;
+ for (;;) {
+ var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos);
+ if (nextOpen < 0) nextOpen = text.length;
+ if (nextClose < 0) nextClose = text.length;
+ pos = Math.min(nextOpen, nextClose);
+ if (pos == text.length) break;
+ if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == tokenType) {
+ if (pos == nextOpen) ++count;
+ else if (!--count) { end = i; endCh = pos; break outer; }
+ }
+ ++pos;
+ }
+ }
+ if (end == null || line == end && endCh == startCh) return;
+ return {from: CodeMirror.Pos(line, startCh),
+ to: CodeMirror.Pos(end, endCh)};
+});
+
+CodeMirror.registerHelper("fold", "import", function(cm, start) {
+ function hasImport(line) {
+ if (line < cm.firstLine() || line > cm.lastLine()) return null;
+ var start = cm.getTokenAt(CodeMirror.Pos(line, 1));
+ if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1));
+ if (start.type != "keyword" || start.string != "import") return null;
+ // Now find closing semicolon, return its position
+ for (var i = line, e = Math.min(cm.lastLine(), line + 10); i <= e; ++i) {
+ var text = cm.getLine(i), semi = text.indexOf(";");
+ if (semi != -1) return {startCh: start.end, end: CodeMirror.Pos(i, semi)};
+ }
+ }
+
+ var start = start.line, has = hasImport(start), prev;
+ if (!has || hasImport(start - 1) || ((prev = hasImport(start - 2)) && prev.end.line == start - 1))
+ return null;
+ for (var end = has.end;;) {
+ var next = hasImport(end.line + 1);
+ if (next == null) break;
+ end = next.end;
+ }
+ return {from: cm.clipPos(CodeMirror.Pos(start, has.startCh + 1)), to: end};
+});
+
+CodeMirror.registerHelper("fold", "include", function(cm, start) {
+ function hasInclude(line) {
+ if (line < cm.firstLine() || line > cm.lastLine()) return null;
+ var start = cm.getTokenAt(CodeMirror.Pos(line, 1));
+ if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1));
+ if (start.type == "meta" && start.string.slice(0, 8) == "#include") return start.start + 8;
+ }
+
+ var start = start.line, has = hasInclude(start);
+ if (has == null || hasInclude(start - 1) != null) return null;
+ for (var end = start;;) {
+ var next = hasInclude(end + 1);
+ if (next == null) break;
+ ++end;
+ }
+ return {from: CodeMirror.Pos(start, has + 1),
+ to: cm.clipPos(CodeMirror.Pos(end))};
+});
+
+});
http://git-wip-us.apache.org/repos/asf/jena/blob/470ee4d7/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/addon/fold/comment-fold.js
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/addon/fold/comment-fold.js b/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/addon/fold/comment-fold.js
new file mode 100644
index 0000000..b75db7e
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/addon/fold/comment-fold.js
@@ -0,0 +1,57 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.registerGlobalHelper("fold", "comment", function(mode) {
+ return mode.blockCommentStart && mode.blockCommentEnd;
+}, function(cm, start) {
+ var mode = cm.getModeAt(start), startToken = mode.blockCommentStart, endToken = mode.blockCommentEnd;
+ if (!startToken || !endToken) return;
+ var line = start.line, lineText = cm.getLine(line);
+
+ var startCh;
+ for (var at = start.ch, pass = 0;;) {
+ var found = at <= 0 ? -1 : lineText.lastIndexOf(startToken, at - 1);
+ if (found == -1) {
+ if (pass == 1) return;
+ pass = 1;
+ at = lineText.length;
+ continue;
+ }
+ if (pass == 1 && found < start.ch) return;
+ if (/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1)))) {
+ startCh = found + startToken.length;
+ break;
+ }
+ at = found - 1;
+ }
+
+ var depth = 1, lastLine = cm.lastLine(), end, endCh;
+ outer: for (var i = line; i <= lastLine; ++i) {
+ var text = cm.getLine(i), pos = i == line ? startCh : 0;
+ for (;;) {
+ var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos);
+ if (nextOpen < 0) nextOpen = text.length;
+ if (nextClose < 0) nextClose = text.length;
+ pos = Math.min(nextOpen, nextClose);
+ if (pos == text.length) break;
+ if (pos == nextOpen) ++depth;
+ else if (!--depth) { end = i; endCh = pos; break outer; }
+ ++pos;
+ }
+ }
+ if (end == null || line == end && endCh == startCh) return;
+ return {from: CodeMirror.Pos(line, startCh),
+ to: CodeMirror.Pos(end, endCh)};
+});
+
+});
http://git-wip-us.apache.org/repos/asf/jena/blob/470ee4d7/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/addon/fold/foldcode.js
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/addon/fold/foldcode.js b/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/addon/fold/foldcode.js
new file mode 100644
index 0000000..3abeb83
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/addon/fold/foldcode.js
@@ -0,0 +1,145 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+ "use strict";
+
+ function doFold(cm, pos, options, force) {
+ if (options && options.call) {
+ var finder = options;
+ options = null;
+ } else {
+ var finder = getOption(cm, options, "rangeFinder");
+ }
+ if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0);
+ var minSize = getOption(cm, options, "minFoldSize");
+
+ function getRange(allowFolded) {
+ var range = finder(cm, pos);
+ if (!range || range.to.line - range.from.line < minSize) return null;
+ var marks = cm.findMarksAt(range.from);
+ for (var i = 0; i < marks.length; ++i) {
+ if (marks[i].__isFold && force !== "fold") {
+ if (!allowFolded) return null;
+ range.cleared = true;
+ marks[i].clear();
+ }
+ }
+ return range;
+ }
+
+ var range = getRange(true);
+ if (getOption(cm, options, "scanUp")) while (!range && pos.line > cm.firstLine()) {
+ pos = CodeMirror.Pos(pos.line - 1, 0);
+ range = getRange(false);
+ }
+ if (!range || range.cleared || force === "unfold") return;
+
+ var myWidget = makeWidget(cm, options);
+ CodeMirror.on(myWidget, "mousedown", function(e) {
+ myRange.clear();
+ CodeMirror.e_preventDefault(e);
+ });
+ var myRange = cm.markText(range.from, range.to, {
+ replacedWith: myWidget,
+ clearOnEnter: true,
+ __isFold: true
+ });
+ myRange.on("clear", function(from, to) {
+ CodeMirror.signal(cm, "unfold", cm, from, to);
+ });
+ CodeMirror.signal(cm, "fold", cm, range.from, range.to);
+ }
+
+ function makeWidget(cm, options) {
+ var widget = getOption(cm, options, "widget");
+ if (typeof widget == "string") {
+ var text = document.createTextNode(widget);
+ widget = document.createElement("span");
+ widget.appendChild(text);
+ widget.className = "CodeMirror-foldmarker";
+ }
+ return widget;
+ }
+
+ // Clumsy backwards-compatible interface
+ CodeMirror.newFoldFunction = function(rangeFinder, widget) {
+ return function(cm, pos) { doFold(cm, pos, {rangeFinder: rangeFinder, widget: widget}); };
+ };
+
+ // New-style interface
+ CodeMirror.defineExtension("foldCode", function(pos, options, force) {
+ doFold(this, pos, options, force);
+ });
+
+ CodeMirror.defineExtension("isFolded", function(pos) {
+ var marks = this.findMarksAt(pos);
+ for (var i = 0; i < marks.length; ++i)
+ if (marks[i].__isFold) return true;
+ });
+
+ CodeMirror.commands.toggleFold = function(cm) {
+ cm.foldCode(cm.getCursor());
+ };
+ CodeMirror.commands.fold = function(cm) {
+ cm.foldCode(cm.getCursor(), null, "fold");
+ };
+ CodeMirror.commands.unfold = function(cm) {
+ cm.foldCode(cm.getCursor(), null, "unfold");
+ };
+ CodeMirror.commands.foldAll = function(cm) {
+ cm.operation(function() {
+ for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)
+ cm.foldCode(CodeMirror.Pos(i, 0), null, "fold");
+ });
+ };
+ CodeMirror.commands.unfoldAll = function(cm) {
+ cm.operation(function() {
+ for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)
+ cm.foldCode(CodeMirror.Pos(i, 0), null, "unfold");
+ });
+ };
+
+ CodeMirror.registerHelper("fold", "combine", function() {
+ var funcs = Array.prototype.slice.call(arguments, 0);
+ return function(cm, start) {
+ for (var i = 0; i < funcs.length; ++i) {
+ var found = funcs[i](cm, start);
+ if (found) return found;
+ }
+ };
+ });
+
+ CodeMirror.registerHelper("fold", "auto", function(cm, start) {
+ var helpers = cm.getHelpers(start, "fold");
+ for (var i = 0; i < helpers.length; i++) {
+ var cur = helpers[i](cm, start);
+ if (cur) return cur;
+ }
+ });
+
+ var defaultOptions = {
+ rangeFinder: CodeMirror.fold.auto,
+ widget: "\u2194",
+ minFoldSize: 0,
+ scanUp: false
+ };
+
+ CodeMirror.defineOption("foldOptions", null);
+
+ function getOption(cm, options, name) {
+ if (options && options[name] !== undefined)
+ return options[name];
+ var editorOptions = cm.options.foldOptions;
+ if (editorOptions && editorOptions[name] !== undefined)
+ return editorOptions[name];
+ return defaultOptions[name];
+ }
+});
http://git-wip-us.apache.org/repos/asf/jena/blob/470ee4d7/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/addon/fold/foldgutter.js
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/addon/fold/foldgutter.js b/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/addon/fold/foldgutter.js
new file mode 100644
index 0000000..bd31ec4
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/addon/fold/foldgutter.js
@@ -0,0 +1,134 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"), require("./foldcode"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror", "./foldcode"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+ "use strict";
+
+ CodeMirror.defineOption("foldGutter", false, function(cm, val, old) {
+ if (old && old != CodeMirror.Init) {
+ cm.clearGutter(cm.state.foldGutter.options.gutter);
+ cm.state.foldGutter = null;
+ cm.off("gutterClick", onGutterClick);
+ cm.off("change", onChange);
+ cm.off("viewportChange", onViewportChange);
+ cm.off("fold", onFold);
+ cm.off("unfold", onFold);
+ cm.off("swapDoc", updateInViewport);
+ }
+ if (val) {
+ cm.state.foldGutter = new State(parseOptions(val));
+ updateInViewport(cm);
+ cm.on("gutterClick", onGutterClick);
+ cm.on("change", onChange);
+ cm.on("viewportChange", onViewportChange);
+ cm.on("fold", onFold);
+ cm.on("unfold", onFold);
+ cm.on("swapDoc", updateInViewport);
+ }
+ });
+
+ var Pos = CodeMirror.Pos;
+
+ function State(options) {
+ this.options = options;
+ this.from = this.to = 0;
+ }
+
+ function parseOptions(opts) {
+ if (opts === true) opts = {};
+ if (opts.gutter == null) opts.gutter = "CodeMirror-foldgutter";
+ if (opts.indicatorOpen == null) opts.indicatorOpen = "CodeMirror-foldgutter-open";
+ if (opts.indicatorFolded == null) opts.indicatorFolded = "CodeMirror-foldgutter-folded";
+ return opts;
+ }
+
+ function isFolded(cm, line) {
+ var marks = cm.findMarksAt(Pos(line));
+ for (var i = 0; i < marks.length; ++i)
+ if (marks[i].__isFold && marks[i].find().from.line == line) return true;
+ }
+
+ function marker(spec) {
+ if (typeof spec == "string") {
+ var elt = document.createElement("div");
+ elt.className = spec + " CodeMirror-guttermarker-subtle";
+ return elt;
+ } else {
+ return spec.cloneNode(true);
+ }
+ }
+
+ function updateFoldInfo(cm, from, to) {
+ var opts = cm.state.foldGutter.options, cur = from;
+ cm.eachLine(from, to, function(line) {
+ var mark = null;
+ if (isFolded(cm, cur)) {
+ mark = marker(opts.indicatorFolded);
+ } else {
+ var pos = Pos(cur, 0), func = opts.rangeFinder || CodeMirror.fold.auto;
+ var range = func && func(cm, pos);
+ if (range && range.from.line + 1 < range.to.line)
+ mark = marker(opts.indicatorOpen);
+ }
+ cm.setGutterMarker(line, opts.gutter, mark);
+ ++cur;
+ });
+ }
+
+ function updateInViewport(cm) {
+ var vp = cm.getViewport(), state = cm.state.foldGutter;
+ if (!state) return;
+ cm.operation(function() {
+ updateFoldInfo(cm, vp.from, vp.to);
+ });
+ state.from = vp.from; state.to = vp.to;
+ }
+
+ function onGutterClick(cm, line, gutter) {
+ var opts = cm.state.foldGutter.options;
+ if (gutter != opts.gutter) return;
+ cm.foldCode(Pos(line, 0), opts.rangeFinder);
+ }
+
+ function onChange(cm) {
+ var state = cm.state.foldGutter, opts = cm.state.foldGutter.options;
+ state.from = state.to = 0;
+ clearTimeout(state.changeUpdate);
+ state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600);
+ }
+
+ function onViewportChange(cm) {
+ var state = cm.state.foldGutter, opts = cm.state.foldGutter.options;
+ clearTimeout(state.changeUpdate);
+ state.changeUpdate = setTimeout(function() {
+ var vp = cm.getViewport();
+ if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) {
+ updateInViewport(cm);
+ } else {
+ cm.operation(function() {
+ if (vp.from < state.from) {
+ updateFoldInfo(cm, vp.from, state.from);
+ state.from = vp.from;
+ }
+ if (vp.to > state.to) {
+ updateFoldInfo(cm, state.to, vp.to);
+ state.to = vp.to;
+ }
+ });
+ }
+ }, opts.updateViewportTimeSpan || 400);
+ }
+
+ function onFold(cm, from) {
+ var state = cm.state.foldGutter, line = from.line;
+ if (line >= state.from && line < state.to)
+ updateFoldInfo(cm, line, line + 1);
+ }
+});
http://git-wip-us.apache.org/repos/asf/jena/blob/470ee4d7/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/addon/fold/xml-fold.js
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/addon/fold/xml-fold.js b/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/addon/fold/xml-fold.js
new file mode 100644
index 0000000..a45da58
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/addon/fold/xml-fold.js
@@ -0,0 +1,181 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(function(mod) {
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
+ mod(require("../../lib/codemirror"));
+ else if (typeof define == "function" && define.amd) // AMD
+ define(["../../lib/codemirror"], mod);
+ else // Plain browser env
+ mod(CodeMirror);
+})(function(CodeMirror) {
+ "use strict";
+
+ var Pos = CodeMirror.Pos;
+ function cmp(a, b) { return a.line - b.line || a.ch - b.ch; }
+
+ var nameStartChar = "A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
+ var nameChar = nameStartChar + "\-\:\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
+ var xmlTagStart = new RegExp("<(/?)([" + nameStartChar + "][" + nameChar + "]*)", "g");
+
+ function Iter(cm, line, ch, range) {
+ this.line = line; this.ch = ch;
+ this.cm = cm; this.text = cm.getLine(line);
+ this.min = range ? range.from : cm.firstLine();
+ this.max = range ? range.to - 1 : cm.lastLine();
+ }
+
+ function tagAt(iter, ch) {
+ var type = iter.cm.getTokenTypeAt(Pos(iter.line, ch));
+ return type && /\btag\b/.test(type);
+ }
+
+ function nextLine(iter) {
+ if (iter.line >= iter.max) return;
+ iter.ch = 0;
+ iter.text = iter.cm.getLine(++iter.line);
+ return true;
+ }
+ function prevLine(iter) {
+ if (iter.line <= iter.min) return;
+ iter.text = iter.cm.getLine(--iter.line);
+ iter.ch = iter.text.length;
+ return true;
+ }
+
+ function toTagEnd(iter) {
+ for (;;) {
+ var gt = iter.text.indexOf(">", iter.ch);
+ if (gt == -1) { if (nextLine(iter)) continue; else return; }
+ if (!tagAt(iter, gt + 1)) { iter.ch = gt + 1; continue; }
+ var lastSlash = iter.text.lastIndexOf("/", gt);
+ var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt));
+ iter.ch = gt + 1;
+ return selfClose ? "selfClose" : "regular";
+ }
+ }
+ function toTagStart(iter) {
+ for (;;) {
+ var lt = iter.ch ? iter.text.lastIndexOf("<", iter.ch - 1) : -1;
+ if (lt == -1) { if (prevLine(iter)) continue; else return; }
+ if (!tagAt(iter, lt + 1)) { iter.ch = lt; continue; }
+ xmlTagStart.lastIndex = lt;
+ iter.ch = lt;
+ var match = xmlTagStart.exec(iter.text);
+ if (match && match.index == lt) return match;
+ }
+ }
+
+ function toNextTag(iter) {
+ for (;;) {
+ xmlTagStart.lastIndex = iter.ch;
+ var found = xmlTagStart.exec(iter.text);
+ if (!found) { if (nextLine(iter)) continue; else return; }
+ if (!tagAt(iter, found.index + 1)) { iter.ch = found.index + 1; continue; }
+ iter.ch = found.index + found[0].length;
+ return found;
+ }
+ }
+ function toPrevTag(iter) {
+ for (;;) {
+ var gt = iter.ch ? iter.text.lastIndexOf(">", iter.ch - 1) : -1;
+ if (gt == -1) { if (prevLine(iter)) continue; else return; }
+ if (!tagAt(iter, gt + 1)) { iter.ch = gt; continue; }
+ var lastSlash = iter.text.lastIndexOf("/", gt);
+ var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt));
+ iter.ch = gt + 1;
+ return selfClose ? "selfClose" : "regular";
+ }
+ }
+
+ function findMatchingClose(iter, tag) {
+ var stack = [];
+ for (;;) {
+ var next = toNextTag(iter), end, startLine = iter.line, startCh = iter.ch - (next ? next[0].length : 0);
+ if (!next || !(end = toTagEnd(iter))) return;
+ if (end == "selfClose") continue;
+ if (next[1]) { // closing tag
+ for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == next[2]) {
+ stack.length = i;
+ break;
+ }
+ if (i < 0 && (!tag || tag == next[2])) return {
+ tag: next[2],
+ from: Pos(startLine, startCh),
+ to: Pos(iter.line, iter.ch)
+ };
+ } else { // opening tag
+ stack.push(next[2]);
+ }
+ }
+ }
+ function findMatchingOpen(iter, tag) {
+ var stack = [];
+ for (;;) {
+ var prev = toPrevTag(iter);
+ if (!prev) return;
+ if (prev == "selfClose") { toTagStart(iter); continue; }
+ var endLine = iter.line, endCh = iter.ch;
+ var start = toTagStart(iter);
+ if (!start) return;
+ if (start[1]) { // closing tag
+ stack.push(start[2]);
+ } else { // opening tag
+ for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == start[2]) {
+ stack.length = i;
+ break;
+ }
+ if (i < 0 && (!tag || tag == start[2])) return {
+ tag: start[2],
+ from: Pos(iter.line, iter.ch),
+ to: Pos(endLine, endCh)
+ };
+ }
+ }
+ }
+
+ CodeMirror.registerHelper("fold", "xml", function(cm, start) {
+ var iter = new Iter(cm, start.line, 0);
+ for (;;) {
+ var openTag = toNextTag(iter), end;
+ if (!openTag || iter.line != start.line || !(end = toTagEnd(iter))) return;
+ if (!openTag[1] && end != "selfClose") {
+ var start = Pos(iter.line, iter.ch);
+ var close = findMatchingClose(iter, openTag[2]);
+ return close && {from: start, to: close.from};
+ }
+ }
+ });
+ CodeMirror.findMatchingTag = function(cm, pos, range) {
+ var iter = new Iter(cm, pos.line, pos.ch, range);
+ if (iter.text.indexOf(">") == -1 && iter.text.indexOf("<") == -1) return;
+ var end = toTagEnd(iter), to = end && Pos(iter.line, iter.ch);
+ var start = end && toTagStart(iter);
+ if (!end || end == "selfClose" || !start || cmp(iter, pos) > 0) return;
+ var here = {from: Pos(iter.line, iter.ch), to: to, tag: start[2]};
+
+ if (start[1]) { // closing tag
+ return {open: findMatchingOpen(iter, start[2]), close: here, at: "close"};
+ } else { // opening tag
+ iter = new Iter(cm, to.line, to.ch, range);
+ return {open: here, close: findMatchingClose(iter, start[2]), at: "open"};
+ }
+ };
+
+ CodeMirror.findEnclosingTag = function(cm, pos, range) {
+ var iter = new Iter(cm, pos.line, pos.ch, range);
+ for (;;) {
+ var open = findMatchingOpen(iter);
+ if (!open) break;
+ var forward = new Iter(cm, pos.line, pos.ch, range);
+ var close = findMatchingClose(forward, open.tag);
+ if (close) return {open: open, close: close};
+ }
+ };
+
+ // Used by addon/edit/closetag.js
+ CodeMirror.scanForClosingTag = function(cm, pos, name, end) {
+ var iter = new Iter(cm, pos.line, pos.ch, end ? {from: 0, to: end} : null);
+ return findMatchingClose(iter, name);
+ };
+});
http://git-wip-us.apache.org/repos/asf/jena/blob/470ee4d7/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/backbone-min.js
----------------------------------------------------------------------
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/backbone-min.js b/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/backbone-min.js
new file mode 100644
index 0000000..3b2593d
--- /dev/null
+++ b/jena-fuseki2/jena-fuseki-core/src/main/webapp/js/lib/backbone-min.js
@@ -0,0 +1,2 @@
+(function(){var t=this;var e=t.Backbone;var i=[];var r=i.push;var s=i.slice;var n=i.splice;var a;if(typeof exports!=="undefined"){a=exports}else{a=t.Backbone={}}a.VERSION="1.1.0";var h=t._;if(!h&&typeof require!=="undefined")h=require("underscore");a.$=t.jQuery||t.Zepto||t.ender||t.$;a.noConflict=function(){t.Backbone=e;return this};a.emulateHTTP=false;a.emulateJSON=false;var o=a.Events={on:function(t,e,i){if(!l(this,"on",t,[e,i])||!e)return this;this._events||(this._events={});var r=this._events[t]||(this._events[t]=[]);r.push({callback:e,context:i,ctx:i||this});return this},once:function(t,e,i){if(!l(this,"once",t,[e,i])||!e)return this;var r=this;var s=h.once(function(){r.off(t,s);e.apply(this,arguments)});s._callback=e;return this.on(t,s,i)},off:function(t,e,i){var r,s,n,a,o,u,c,f;if(!this._events||!l(this,"off",t,[e,i]))return this;if(!t&&!e&&!i){this._events={};return this}a=t?[t]:h.keys(this._events);for(o=0,u=a.length;o<u;o++){t=a[o];if(n=this._events[t]){this._events[t]=r=[
];if(e||i){for(c=0,f=n.length;c<f;c++){s=n[c];if(e&&e!==s.callback&&e!==s.callback._callback||i&&i!==s.context){r.push(s)}}}if(!r.length)delete this._events[t]}}return this},trigger:function(t){if(!this._events)return this;var e=s.call(arguments,1);if(!l(this,"trigger",t,e))return this;var i=this._events[t];var r=this._events.all;if(i)c(i,e);if(r)c(r,arguments);return this},stopListening:function(t,e,i){var r=this._listeningTo;if(!r)return this;var s=!e&&!i;if(!i&&typeof e==="object")i=this;if(t)(r={})[t._listenId]=t;for(var n in r){t=r[n];t.off(e,i,this);if(s||h.isEmpty(t._events))delete this._listeningTo[n]}return this}};var u=/\s+/;var l=function(t,e,i,r){if(!i)return true;if(typeof i==="object"){for(var s in i){t[e].apply(t,[s,i[s]].concat(r))}return false}if(u.test(i)){var n=i.split(u);for(var a=0,h=n.length;a<h;a++){t[e].apply(t,[n[a]].concat(r))}return false}return true};var c=function(t,e){var i,r=-1,s=t.length,n=e[0],a=e[1],h=e[2];switch(e.length){case 0:while(++r<s)(i=t[r]
).callback.call(i.ctx);return;case 1:while(++r<s)(i=t[r]).callback.call(i.ctx,n);return;case 2:while(++r<s)(i=t[r]).callback.call(i.ctx,n,a);return;case 3:while(++r<s)(i=t[r]).callback.call(i.ctx,n,a,h);return;default:while(++r<s)(i=t[r]).callback.apply(i.ctx,e)}};var f={listenTo:"on",listenToOnce:"once"};h.each(f,function(t,e){o[e]=function(e,i,r){var s=this._listeningTo||(this._listeningTo={});var n=e._listenId||(e._listenId=h.uniqueId("l"));s[n]=e;if(!r&&typeof i==="object")r=this;e[t](i,r,this);return this}});o.bind=o.on;o.unbind=o.off;h.extend(a,o);var d=a.Model=function(t,e){var i=t||{};e||(e={});this.cid=h.uniqueId("c");this.attributes={};if(e.collection)this.collection=e.collection;if(e.parse)i=this.parse(i,e)||{};i=h.defaults({},i,h.result(this,"defaults"));this.set(i,e);this.changed={};this.initialize.apply(this,arguments)};h.extend(d.prototype,o,{changed:null,validationError:null,idAttribute:"id",initialize:function(){},toJSON:function(t){return h.clone(this.attributes)},
sync:function(){return a.sync.apply(this,arguments)},get:function(t){return this.attributes[t]},escape:function(t){return h.escape(this.get(t))},has:function(t){return this.get(t)!=null},set:function(t,e,i){var r,s,n,a,o,u,l,c;if(t==null)return this;if(typeof t==="object"){s=t;i=e}else{(s={})[t]=e}i||(i={});if(!this._validate(s,i))return false;n=i.unset;o=i.silent;a=[];u=this._changing;this._changing=true;if(!u){this._previousAttributes=h.clone(this.attributes);this.changed={}}c=this.attributes,l=this._previousAttributes;if(this.idAttribute in s)this.id=s[this.idAttribute];for(r in s){e=s[r];if(!h.isEqual(c[r],e))a.push(r);if(!h.isEqual(l[r],e)){this.changed[r]=e}else{delete this.changed[r]}n?delete c[r]:c[r]=e}if(!o){if(a.length)this._pending=true;for(var f=0,d=a.length;f<d;f++){this.trigger("change:"+a[f],this,c[a[f]],i)}}if(u)return this;if(!o){while(this._pending){this._pending=false;this.trigger("change",this,i)}}this._pending=false;this._changing=false;return this},unset:funct
ion(t,e){return this.set(t,void 0,h.extend({},e,{unset:true}))},clear:function(t){var e={};for(var i in this.attributes)e[i]=void 0;return this.set(e,h.extend({},t,{unset:true}))},hasChanged:function(t){if(t==null)return!h.isEmpty(this.changed);return h.has(this.changed,t)},changedAttributes:function(t){if(!t)return this.hasChanged()?h.clone(this.changed):false;var e,i=false;var r=this._changing?this._previousAttributes:this.attributes;for(var s in t){if(h.isEqual(r[s],e=t[s]))continue;(i||(i={}))[s]=e}return i},previous:function(t){if(t==null||!this._previousAttributes)return null;return this._previousAttributes[t]},previousAttributes:function(){return h.clone(this._previousAttributes)},fetch:function(t){t=t?h.clone(t):{};if(t.parse===void 0)t.parse=true;var e=this;var i=t.success;t.success=function(r){if(!e.set(e.parse(r,t),t))return false;if(i)i(e,r,t);e.trigger("sync",e,r,t)};M(this,t);return this.sync("read",this,t)},save:function(t,e,i){var r,s,n,a=this.attributes;if(t==null||
typeof t==="object"){r=t;i=e}else{(r={})[t]=e}i=h.extend({validate:true},i);if(r&&!i.wait){if(!this.set(r,i))return false}else{if(!this._validate(r,i))return false}if(r&&i.wait){this.attributes=h.extend({},a,r)}if(i.parse===void 0)i.parse=true;var o=this;var u=i.success;i.success=function(t){o.attributes=a;var e=o.parse(t,i);if(i.wait)e=h.extend(r||{},e);if(h.isObject(e)&&!o.set(e,i)){return false}if(u)u(o,t,i);o.trigger("sync",o,t,i)};M(this,i);s=this.isNew()?"create":i.patch?"patch":"update";if(s==="patch")i.attrs=r;n=this.sync(s,this,i);if(r&&i.wait)this.attributes=a;return n},destroy:function(t){t=t?h.clone(t):{};var e=this;var i=t.success;var r=function(){e.trigger("destroy",e,e.collection,t)};t.success=function(s){if(t.wait||e.isNew())r();if(i)i(e,s,t);if(!e.isNew())e.trigger("sync",e,s,t)};if(this.isNew()){t.success();return false}M(this,t);var s=this.sync("delete",this,t);if(!t.wait)r();return s},url:function(){var t=h.result(this,"urlRoot")||h.result(this.collection,"url")|
|U();if(this.isNew())return t;return t+(t.charAt(t.length-1)==="/"?"":"/")+encodeURIComponent(this.id)},parse:function(t,e){return t},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return this.id==null},isValid:function(t){return this._validate({},h.extend(t||{},{validate:true}))},_validate:function(t,e){if(!e.validate||!this.validate)return true;t=h.extend({},this.attributes,t);var i=this.validationError=this.validate(t,e)||null;if(!i)return true;this.trigger("invalid",this,i,h.extend(e,{validationError:i}));return false}});var p=["keys","values","pairs","invert","pick","omit"];h.each(p,function(t){d.prototype[t]=function(){var e=s.call(arguments);e.unshift(this.attributes);return h[t].apply(h,e)}});var v=a.Collection=function(t,e){e||(e={});if(e.model)this.model=e.model;if(e.comparator!==void 0)this.comparator=e.comparator;this._reset();this.initialize.apply(this,arguments);if(t)this.reset(t,h.extend({silent:true},e))};var g={add:true,remove:true,m
erge:true};var m={add:true,remove:false};h.extend(v.prototype,o,{model:d,initialize:function(){},toJSON:function(t){return this.map(function(e){return e.toJSON(t)})},sync:function(){return a.sync.apply(this,arguments)},add:function(t,e){return this.set(t,h.extend({merge:false},e,m))},remove:function(t,e){var i=!h.isArray(t);t=i?[t]:h.clone(t);e||(e={});var r,s,n,a;for(r=0,s=t.length;r<s;r++){a=t[r]=this.get(t[r]);if(!a)continue;delete this._byId[a.id];delete this._byId[a.cid];n=this.indexOf(a);this.models.splice(n,1);this.length--;if(!e.silent){e.index=n;a.trigger("remove",a,this,e)}this._removeReference(a)}return i?t[0]:t},set:function(t,e){e=h.defaults({},e,g);if(e.parse)t=this.parse(t,e);var i=!h.isArray(t);t=i?t?[t]:[]:h.clone(t);var r,s,n,a,o,u,l;var c=e.at;var f=this.model;var p=this.comparator&&c==null&&e.sort!==false;var v=h.isString(this.comparator)?this.comparator:null;var m=[],y=[],_={};var w=e.add,b=e.merge,x=e.remove;var E=!p&&w&&x?[]:false;for(r=0,s=t.length;r<s;r++){o
=t[r];if(o instanceof d){n=a=o}else{n=o[f.prototype.idAttribute]}if(u=this.get(n)){if(x)_[u.cid]=true;if(b){o=o===a?a.attributes:o;if(e.parse)o=u.parse(o,e);u.set(o,e);if(p&&!l&&u.hasChanged(v))l=true}t[r]=u}else if(w){a=t[r]=this._prepareModel(o,e);if(!a)continue;m.push(a);a.on("all",this._onModelEvent,this);this._byId[a.cid]=a;if(a.id!=null)this._byId[a.id]=a}if(E)E.push(u||a)}if(x){for(r=0,s=this.length;r<s;++r){if(!_[(a=this.models[r]).cid])y.push(a)}if(y.length)this.remove(y,e)}if(m.length||E&&E.length){if(p)l=true;this.length+=m.length;if(c!=null){for(r=0,s=m.length;r<s;r++){this.models.splice(c+r,0,m[r])}}else{if(E)this.models.length=0;var T=E||m;for(r=0,s=T.length;r<s;r++){this.models.push(T[r])}}}if(l)this.sort({silent:true});if(!e.silent){for(r=0,s=m.length;r<s;r++){(a=m[r]).trigger("add",a,this,e)}if(l||E&&E.length)this.trigger("sort",this,e)}return i?t[0]:t},reset:function(t,e){e||(e={});for(var i=0,r=this.models.length;i<r;i++){this._removeReference(this.models[i])}e.pr
eviousModels=this.models;this._reset();t=this.add(t,h.extend({silent:true},e));if(!e.silent)this.trigger("reset",this,e);return t},push:function(t,e){return this.add(t,h.extend({at:this.length},e))},pop:function(t){var e=this.at(this.length-1);this.remove(e,t);return e},unshift:function(t,e){return this.add(t,h.extend({at:0},e))},shift:function(t){var e=this.at(0);this.remove(e,t);return e},slice:function(){return s.apply(this.models,arguments)},get:function(t){if(t==null)return void 0;return this._byId[t.id]||this._byId[t.cid]||this._byId[t]},at:function(t){return this.models[t]},where:function(t,e){if(h.isEmpty(t))return e?void 0:[];return this[e?"find":"filter"](function(e){for(var i in t){if(t[i]!==e.get(i))return false}return true})},findWhere:function(t){return this.where(t,true)},sort:function(t){if(!this.comparator)throw new Error("Cannot sort a set without a comparator");t||(t={});if(h.isString(this.comparator)||this.comparator.length===1){this.models=this.sortBy(this.compa
rator,this)}else{this.models.sort(h.bind(this.comparator,this))}if(!t.silent)this.trigger("sort",this,t);return this},pluck:function(t){return h.invoke(this.models,"get",t)},fetch:function(t){t=t?h.clone(t):{};if(t.parse===void 0)t.parse=true;var e=t.success;var i=this;t.success=function(r){var s=t.reset?"reset":"set";i[s](r,t);if(e)e(i,r,t);i.trigger("sync",i,r,t)};M(this,t);return this.sync("read",this,t)},create:function(t,e){e=e?h.clone(e):{};if(!(t=this._prepareModel(t,e)))return false;if(!e.wait)this.add(t,e);var i=this;var r=e.success;e.success=function(t,e,s){if(s.wait)i.add(t,s);if(r)r(t,e,s)};t.save(null,e);return t},parse:function(t,e){return t},clone:function(){return new this.constructor(this.models)},_reset:function(){this.length=0;this.models=[];this._byId={}},_prepareModel:function(t,e){if(t instanceof d){if(!t.collection)t.collection=this;return t}e=e?h.clone(e):{};e.collection=this;var i=new this.model(t,e);if(!i.validationError)return i;this.trigger("invalid",this
,i.validationError,e);return false},_removeReference:function(t){if(this===t.collection)delete t.collection;t.off("all",this._onModelEvent,this)},_onModelEvent:function(t,e,i,r){if((t==="add"||t==="remove")&&i!==this)return;if(t==="destroy")this.remove(e,r);if(e&&t==="change:"+e.idAttribute){delete this._byId[e.previous(e.idAttribute)];if(e.id!=null)this._byId[e.id]=e}this.trigger.apply(this,arguments)}});var y=["forEach","each","map","collect","reduce","foldl","inject","reduceRight","foldr","find","detect","filter","select","reject","every","all","some","any","include","contains","invoke","max","min","toArray","size","first","head","take","initial","rest","tail","drop","last","without","difference","indexOf","shuffle","lastIndexOf","isEmpty","chain"];h.each(y,function(t){v.prototype[t]=function(){var e=s.call(arguments);e.unshift(this.models);return h[t].apply(h,e)}});var _=["groupBy","countBy","sortBy"];h.each(_,function(t){v.prototype[t]=function(e,i){var r=h.isFunction(e)?e:func
tion(t){return t.get(e)};return h[t](this.models,r,i)}});var w=a.View=function(t){this.cid=h.uniqueId("view");t||(t={});h.extend(this,h.pick(t,x));this._ensureElement();this.initialize.apply(this,arguments);this.delegateEvents()};var b=/^(\S+)\s*(.*)$/;var x=["model","collection","el","id","attributes","className","tagName","events"];h.extend(w.prototype,o,{tagName:"div",$:function(t){return this.$el.find(t)},initialize:function(){},render:function(){return this},remove:function(){this.$el.remove();this.stopListening();return this},setElement:function(t,e){if(this.$el)this.undelegateEvents();this.$el=t instanceof a.$?t:a.$(t);this.el=this.$el[0];if(e!==false)this.delegateEvents();return this},delegateEvents:function(t){if(!(t||(t=h.result(this,"events"))))return this;this.undelegateEvents();for(var e in t){var i=t[e];if(!h.isFunction(i))i=this[t[e]];if(!i)continue;var r=e.match(b);var s=r[1],n=r[2];i=h.bind(i,this);s+=".delegateEvents"+this.cid;if(n===""){this.$el.on(s,i)}else{this.
$el.on(s,n,i)}}return this},undelegateEvents:function(){this.$el.off(".delegateEvents"+this.cid);return this},_ensureElement:function(){if(!this.el){var t=h.extend({},h.result(this,"attributes"));if(this.id)t.id=h.result(this,"id");if(this.className)t["class"]=h.result(this,"className");var e=a.$("<"+h.result(this,"tagName")+">").attr(t);this.setElement(e,false)}else{this.setElement(h.result(this,"el"),false)}}});a.sync=function(t,e,i){var r=T[t];h.defaults(i||(i={}),{emulateHTTP:a.emulateHTTP,emulateJSON:a.emulateJSON});var s={type:r,dataType:"json"};if(!i.url){s.url=h.result(e,"url")||U()}if(i.data==null&&e&&(t==="create"||t==="update"||t==="patch")){s.contentType="application/json";s.data=JSON.stringify(i.attrs||e.toJSON(i))}if(i.emulateJSON){s.contentType="application/x-www-form-urlencoded";s.data=s.data?{model:s.data}:{}}if(i.emulateHTTP&&(r==="PUT"||r==="DELETE"||r==="PATCH")){s.type="POST";if(i.emulateJSON)s.data._method=r;var n=i.beforeSend;i.beforeSend=function(t){t.setRequ
estHeader("X-HTTP-Method-Override",r);if(n)return n.apply(this,arguments)}}if(s.type!=="GET"&&!i.emulateJSON){s.processData=false}if(s.type==="PATCH"&&E){s.xhr=function(){return new ActiveXObject("Microsoft.XMLHTTP")}}var o=i.xhr=a.ajax(h.extend(s,i));e.trigger("request",e,o,i);return o};var E=typeof window!=="undefined"&&!!window.ActiveXObject&&!(window.XMLHttpRequest&&(new XMLHttpRequest).dispatchEvent);var T={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};a.ajax=function(){return a.$.ajax.apply(a.$,arguments)};var k=a.Router=function(t){t||(t={});if(t.routes)this.routes=t.routes;this._bindRoutes();this.initialize.apply(this,arguments)};var S=/\((.*?)\)/g;var $=/(\(\?)?:\w+/g;var H=/\*\w+/g;var A=/[\-{}\[\]+?.,\\\^$|#\s]/g;h.extend(k.prototype,o,{initialize:function(){},route:function(t,e,i){if(!h.isRegExp(t))t=this._routeToRegExp(t);if(h.isFunction(e)){i=e;e=""}if(!i)i=this[e];var r=this;a.history.route(t,function(s){var n=r._extractParameters(t,s);i&&i.ap
ply(r,n);r.trigger.apply(r,["route:"+e].concat(n));r.trigger("route",e,n);a.history.trigger("route",r,e,n)});return this},navigate:function(t,e){a.history.navigate(t,e);return this},_bindRoutes:function(){if(!this.routes)return;this.routes=h.result(this,"routes");var t,e=h.keys(this.routes);while((t=e.pop())!=null){this.route(t,this.routes[t])}},_routeToRegExp:function(t){t=t.replace(A,"\\$&").replace(S,"(?:$1)?").replace($,function(t,e){return e?t:"([^/]+)"}).replace(H,"(.*?)");return new RegExp("^"+t+"$")},_extractParameters:function(t,e){var i=t.exec(e).slice(1);return h.map(i,function(t){return t?decodeURIComponent(t):null})}});var I=a.History=function(){this.handlers=[];h.bindAll(this,"checkUrl");if(typeof window!=="undefined"){this.location=window.location;this.history=window.history}};var N=/^[#\/]|\s+$/g;var O=/^\/+|\/+$/g;var P=/msie [\w.]+/;var C=/\/$/;var j=/[?#].*$/;I.started=false;h.extend(I.prototype,o,{interval:50,getHash:function(t){var e=(t||this).location.href.matc
h(/#(.*)$/);return e?e[1]:""},getFragment:function(t,e){if(t==null){if(this._hasPushState||!this._wantsHashChange||e){t=this.location.pathname;var i=this.root.replace(C,"");if(!t.indexOf(i))t=t.slice(i.length)}else{t=this.getHash()}}return t.replace(N,"")},start:function(t){if(I.started)throw new Error("Backbone.history has already been started");I.started=true;this.options=h.extend({root:"/"},this.options,t);this.root=this.options.root;this._wantsHashChange=this.options.hashChange!==false;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.options.pushState&&this.history&&this.history.pushState);var e=this.getFragment();var i=document.documentMode;var r=P.exec(navigator.userAgent.toLowerCase())&&(!i||i<=7);this.root=("/"+this.root+"/").replace(O,"/");if(r&&this._wantsHashChange){this.iframe=a.$('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo("body")[0].contentWindow;this.navigate(e)}if(this._hasPushState){a.$(window).on("popstate",this.checkUrl)}
else if(this._wantsHashChange&&"onhashchange"in window&&!r){a.$(window).on("hashchange",this.checkUrl)}else if(this._wantsHashChange){this._checkUrlInterval=setInterval(this.checkUrl,this.interval)}this.fragment=e;var s=this.location;var n=s.pathname.replace(/[^\/]$/,"$&/")===this.root;if(this._wantsHashChange&&this._wantsPushState){if(!this._hasPushState&&!n){this.fragment=this.getFragment(null,true);this.location.replace(this.root+this.location.search+"#"+this.fragment);return true}else if(this._hasPushState&&n&&s.hash){this.fragment=this.getHash().replace(N,"");this.history.replaceState({},document.title,this.root+this.fragment+s.search)}}if(!this.options.silent)return this.loadUrl()},stop:function(){a.$(window).off("popstate",this.checkUrl).off("hashchange",this.checkUrl);clearInterval(this._checkUrlInterval);I.started=false},route:function(t,e){this.handlers.unshift({route:t,callback:e})},checkUrl:function(t){var e=this.getFragment();if(e===this.fragment&&this.iframe){e=this.ge
tFragment(this.getHash(this.iframe))}if(e===this.fragment)return false;if(this.iframe)this.navigate(e);this.loadUrl()},loadUrl:function(t){t=this.fragment=this.getFragment(t);return h.any(this.handlers,function(e){if(e.route.test(t)){e.callback(t);return true}})},navigate:function(t,e){if(!I.started)return false;if(!e||e===true)e={trigger:!!e};var i=this.root+(t=this.getFragment(t||""));t=t.replace(j,"");if(this.fragment===t)return;this.fragment=t;if(t===""&&i!=="/")i=i.slice(0,-1);if(this._hasPushState){this.history[e.replace?"replaceState":"pushState"]({},document.title,i)}else if(this._wantsHashChange){this._updateHash(this.location,t,e.replace);if(this.iframe&&t!==this.getFragment(this.getHash(this.iframe))){if(!e.replace)this.iframe.document.open().close();this._updateHash(this.iframe.location,t,e.replace)}}else{return this.location.assign(i)}if(e.trigger)return this.loadUrl(t)},_updateHash:function(t,e,i){if(i){var r=t.href.replace(/(javascript:|#).*$/,"");t.replace(r+"#"+e)}e
lse{t.hash="#"+e}}});a.history=new I;var R=function(t,e){var i=this;var r;if(t&&h.has(t,"constructor")){r=t.constructor}else{r=function(){return i.apply(this,arguments)}}h.extend(r,i,e);var s=function(){this.constructor=r};s.prototype=i.prototype;r.prototype=new s;if(t)h.extend(r.prototype,t);r.__super__=i.prototype;return r};d.extend=v.extend=k.extend=w.extend=I.extend=R;var U=function(){throw new Error('A "url" property or function must be specified')};var M=function(t,e){var i=e.error;e.error=function(r){if(i)i(t,r,e);t.trigger("error",t,r,e)}}}).call(this);
+//# sourceMappingURL=backbone-min.map
\ No newline at end of file