You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tika.apache.org by ma...@apache.org on 2016/02/20 08:37:57 UTC

svn commit: r1731338 [8/38] - in /tika/site: publish/ publish/0.10/ publish/0.5/ publish/0.6/ publish/0.7/ publish/0.8/ publish/0.9/ publish/1.0/ publish/1.1/ publish/1.10/ publish/1.11/ publish/1.11/miredot/ publish/1.11/miredot/css/ publish/1.11/mire...

Added: tika/site/publish/1.11/miredot/js/controllers.js
URL: http://svn.apache.org/viewvc/tika/site/publish/1.11/miredot/js/controllers.js?rev=1731338&view=auto
==============================================================================
--- tika/site/publish/1.11/miredot/js/controllers.js (added)
+++ tika/site/publish/1.11/miredot/js/controllers.js Sat Feb 20 07:37:52 2016
@@ -0,0 +1,386 @@
+'use strict';
+
+/* Controllers */
+
+
+/**
+ * The main viewmodel for the doc. Loads a variable named restApiSource.
+ * @param $scope
+ * @constructor
+ */
+function DocRoot($scope, $location, $localStorage, $filter, $http) {
+
+    $scope.restBase = 'http://www.miredot.com/miredot/rest/';
+    $scope.visitWebsiteForProVersion = 'Visit our <a href="http://www.miredot.com/price/?licencerequest=pro" target="_blank">website</a> to get the full version (free for open source).';
+
+    $scope.$storage = $localStorage.$default({
+        //baseUrl: com.qmino.miredot.restApiSource.baseUrl || "http://example.com",
+        globalCollapsedState: false
+    });
+    $scope.$storage.baseUrl = com.qmino.miredot.restApiSource.baseUrl || "http://example.com";
+    $scope.editingBaseUrl = false;
+    $scope.projectTitle = com.qmino.miredot.restApiSource.projectTitle;
+    $scope.miredotVersion = com.qmino.miredot.restApiSource.miredotVersion;
+    $scope.validLicence = com.qmino.miredot.restApiSource.validLicence;
+    $scope.licenceType = com.qmino.miredot.restApiSource.licenceType;
+    $scope.licenceErrorMessage = com.qmino.miredot.restApiSource.licenceErrorMessage;
+    $scope.licenceHash = com.qmino.miredot.restApiSource.licenceHash;
+    $scope.allowUsageTracking = com.qmino.miredot.restApiSource.allowUsageTracking;
+    $scope.dateOfGeneration = com.qmino.miredot.restApiSource.dateOfGeneration;
+    $scope.projectWarnings = com.qmino.miredot.projectWarnings;
+    $scope.interfaces = com.qmino.miredot.restApiSource.interfaces;
+    $scope.tos = com.qmino.miredot.restApiSource.tos;
+    $scope.processErrors = com.qmino.miredot.processErrors;
+    $scope.jsonDocConfig = {
+        enabled: com.qmino.miredot.restApiSource.jsonDocEnabled,
+        hidden: com.qmino.miredot.restApiSource.jsonDocHidden
+    };
+
+    $scope.searchByExample = "";
+    $scope.searchQuery = {url : "", http: ""};
+    $scope.location = $location;
+    $scope.navigationView = 'hierarchical';
+
+    ensureLinksHaveTargetInApiIntro();
+
+    setGlobalCollapsedState($localStorage.globalCollapsedState);
+    $scope.hierarchyOpen = true;
+
+    // Set the view, based on the current location hash.
+    setView($location.hash());
+    // Watch the location hash and update the view when it changes.
+    $scope.$watch('location.hash()', function(newValue, oldValue) {
+        if (oldValue != newValue) {
+            setView(newValue);
+        }
+    });
+
+    $http.jsonp(
+        $scope.restBase +
+        'version' +
+        '?hash=' + $scope.licenceHash + '&version=' + $scope.miredotVersion + '&licencetype=' + ($scope.licenceType || 'FREE') +
+        '&callback=JSON_CALLBACK')
+        .success(function(data) {
+            if (data.upToDate) {
+                $scope.versionCheckResult = "";
+            } else {
+                $scope.versionCheckResult = " | New version available: " + data.version;
+            }
+        });
+
+    $scope.formatTypeValue = function(typeValue) {
+        switch(typeValue.type) {
+            case 'collection':
+                return '[ ' + $scope.formatTypeValue(typeValue.typeValue) + ' ]';
+
+            case 'enum':
+                return 'enum';
+
+            default:
+                return typeValue.typeValue;
+        }
+    };
+
+    $scope.formatDefaultValue = function(typeValue, defaultValue) {
+        switch(typeValue.type) {
+            case 'enum':
+                var enumValues = enumArrayToString(typeValue.values);
+                enumValues = enumValues.replace(defaultValue, '<span class="default" title="Default value">' + defaultValue + '</span>');
+                return enumValues;
+            default:
+                if (defaultValue != undefined) {
+                    return '<span class="default" title="Default value">' + defaultValue + '</span>'
+                }
+                return "";
+        }
+    };
+
+    /**
+     * Sets $scope.view, based on the given hash.
+     * Currently sets the view to 'interfaces' when it's not 'warnings'.
+     * eg. #1465486435 (interface hash) will cause the view to be 'interfaces'
+     *
+     * @param hash A string from which the current view will be determined
+     */
+    function setView(hash) {
+        if (hash === 'warnings') {
+            $scope.view = 'warnings';
+        } else {
+            $scope.view = 'interfaces';
+        }
+    }
+
+    /**
+     * Ensures that all links in the API intro have a target.
+     */
+    function ensureLinksHaveTargetInApiIntro() {
+        $("#intro a").attr('target', function(i, current) {
+            return current || '_self';
+        });
+    }
+
+    /**
+     * Function to clear the selection of service tags
+     */
+    function clearServiceTagSelection() {
+        _.each($scope.serviceTags, function(serviceTag) { serviceTag.selected = false; } );
+    }
+
+    // Build a map interfaceHash->interfaceObject
+    var interfacesByHash = {};
+    _.each($scope.interfaces, function(iface) {
+        interfacesByHash[iface.hash] = iface;
+    });
+
+    /**
+     * Build a list of tag objects
+     * {
+     *   name: string, tag name
+     *   selected: boolean, selected for filtering?
+     * }
+     */
+    $scope.serviceTags = (function() {
+        var tagNames = [];
+        _.each($scope.interfaces, function(currentInterface) {
+            _.each(currentInterface.tags, function(tagName) {
+                tagNames.push(tagName);
+            });
+        });
+        tagNames = _.uniq(tagNames);
+        return _.map(tagNames, function(tagName) { return {name : tagName, selected: false }; } );
+    }());
+
+    /**
+     * Function to look up the state of a service tag by name
+     * @param tagName The name of the service tag
+     */
+    $scope.isServiceTagSelected = function(tagName) {
+        var tag = _.find($scope.serviceTags, function(serviceTag) { return serviceTag.name === tagName; } );
+        return tag.selected;
+    };
+
+    // Build a map warningCategory->[warning]
+    $scope.projectWarningsByType = (function() {
+        var result = {};
+        _.each($scope.projectWarnings, function(projectWarning) {
+            result[projectWarning.category] = result[projectWarning.category] || [];
+            result[projectWarning.category].push(projectWarning);
+        });
+        return result;
+    }());
+
+    function appendUrl(rootParts, leafPart, url, method, hash, rootResource) {
+
+        var currentResource = null;
+        var parentResource = rootResource;
+        _.each(rootParts, function(rootPart) {
+
+            if (rootPart != "") {
+                currentResource = _.find(parentResource.resources, function(resource) {return resource.name === rootPart});
+
+                if (!currentResource) {
+                    currentResource = {
+                        name: rootPart,
+                        resources: [],
+                        leafResources: []
+                    };
+                    parentResource.resources.push(currentResource);
+                }
+                parentResource = currentResource;
+            } else {
+                currentResource = parentResource;
+            }
+        });
+
+        var existingLeaf = _.find(currentResource.leafResources, function(leaf) {
+            return leaf.url === url;
+        });
+
+        if (existingLeaf) {
+            existingLeaf.methods.push({method: method, hash: hash});
+        } else {
+            currentResource.leafResources.push({
+                name: leafPart,
+                url: url,
+                methods: [{method: method, hash: hash}]
+            });
+        }
+    }
+
+    /**
+     * Constructs a tree structure of the available resources. Stops on the first path parameter (starts with '{')
+     * {
+     *    '/rest' :{
+     *       resource: '/rest',
+     *       subresources: {
+     *          '/myresource': {
+     *             resource: '/myresource',
+     *             subresources: [ .. ]
+     *          },
+     *          {
+     *             ..
+     *          }
+     *       }
+     *    }
+     * }
+     */
+     function splitPaths(interfaces) {
+        //add the root resource
+        var resources = [
+            {
+                name: "",
+                resources: [],
+                leafResources: []
+            }
+        ];
+
+        _.each(interfaces, function(element, index, list) {
+            if (element.url.indexOf('/') !== 0) {
+                element.url = '/' + element.url;
+            }
+
+            var baseUrl, varUrl;
+            var varSplitIndex = element.url.indexOf('{');
+            if (varSplitIndex > -1) {
+                baseUrl = element.url.substring(0, varSplitIndex);
+                varUrl = element.url.substring(varSplitIndex, element.url.length);
+            } else {
+                baseUrl = element.url;
+                varUrl = undefined;
+            }
+
+            if (baseUrl === '/') {
+                baseUrl = '';
+            }
+
+            appendUrl(baseUrl.split('/'), varUrl, element.url, element.http, element.hash, resources[0]);
+        });
+
+        //remove the root resource if not used
+        if (resources[0].leafResources.length === 0) {
+            resources = resources[0].resources;
+        }
+
+        //sort resources on highest level
+        resources.sort(function(r1, r2) { return r1.name.localeCompare(r2.name) } );
+
+        return resources;
+    }
+
+    $scope.resourceTree = splitPaths(com.qmino.miredot.restApiSource.interfaces);
+
+    $scope.isComplexObject = function(type) {
+        return angular.isObject(type);
+    };
+
+    /**
+     * Gives the interface (from $scope.interfaces) given the interface's hash ($scope.interfaces[x].hash).
+     *
+     * @param {string} interfaceHash The hash value of the interface
+     * @return {object} An object contained in $scope.interfaces or undefined if not found.
+     */
+    $scope.getInterfaceByHash = function(interfaceHash) {
+        return interfacesByHash[interfaceHash];
+    };
+
+    $scope.interfaceHttpOrderFunction = function(iface) {
+        return _.indexOf($scope.httpMethods, iface.http);
+    };
+
+    $scope.methodHttpOrderFunction = function(method) {
+        return _.indexOf($scope.httpMethods, method.method);
+    };
+
+    $scope.httpMethods = ['GET','HEAD','PUT','POST','DELETE'];
+
+    $scope.toggleSearchQueryHttp = function(http) {
+        if ($scope.searchQuery.http === http) {
+            $scope.searchQuery.http = "";
+        } else {
+            $scope.searchQuery.http = http;
+        }
+    };
+
+    $scope.setGlobalCollapsedState = setGlobalCollapsedState;
+
+    function setGlobalCollapsedState(collapsed) {
+        $localStorage.globalCollapsedState = collapsed;
+        _.each($scope.interfaces, function(currentInterface) {
+            currentInterface.collapsed = collapsed;
+        })
+    }
+
+    $scope.getFirstLeaf = function(resource) {
+        var orderBy = $filter('orderBy');
+        if (resource.leafResources.length > 0) {
+            var orderedLeafResources = orderBy(resource.leafResources, 'url');
+            var firstLeafResource = orderedLeafResources[0];
+            var orderedMethods = orderBy(firstLeafResource.methods, $scope.methodHttpOrderFunction);
+            return orderedMethods[0];
+        } else {
+            return $scope.getFirstLeaf(orderBy(resource.resources, 'name')[0]);
+        }
+    };
+
+    /*
+    $scope.collapseTree = function() {
+
+        collapseResources($scope.resourceTree);
+    };
+
+    function collapseResources(resources) {
+        _.each(resources, function(resource) {
+            resource.hierarchyOpen = false;
+            collapseResources(resource.resources);
+        })
+    }
+
+    $scope.collapseTree();
+    */
+}
+
+/**
+ * Parses an escaped url query string into key-value pairs.
+ * @source AngularJS
+ * @returns Object.<(string|boolean)>
+ */
+function parseKeyValue(/**string*/keyValue) {
+    var obj = {}, key_value, key;
+    angular.forEach((keyValue || "").split('&'), function(keyValue) {
+        if (keyValue) {
+            key_value = keyValue.split('=');
+            key = decodeURIComponent(key_value[0]);
+            obj[key] = angular.isDefined(key_value[1]) ? decodeURIComponent(key_value[1]) : true;
+        }
+    });
+    return obj;
+}
+
+/**
+ * Assumes as input an array of strings (eg ['a', 'b']) and generates a string representation '"a" | "b"'
+ * @param enumArray the array of strings
+ * @returns {string} the stringrepresentation of the given array
+ */
+function enumArrayToString(enumArray) {
+    var output = '';
+    for (var i=0;i<enumArray.length; i++) {
+        if (i != 0) {
+            output += ' | ';
+        }
+        output += enumArray[i];
+    }
+    return output;
+}
+
+String.prototype.stripTrailingSlash = function() {
+    if (this.substr(-1) === '/') {
+        return this.substr(0, this.length - 1);
+    }
+    return this;
+};
+String.prototype.ensureStartsWithSlash = function() {
+    if (this.substr(0, 1) !== '/') {
+        return '/' + this;
+    }
+    return this;
+};
\ No newline at end of file

Added: tika/site/publish/1.11/miredot/js/directives.js
URL: http://svn.apache.org/viewvc/tika/site/publish/1.11/miredot/js/directives.js?rev=1731338&view=auto
==============================================================================
--- tika/site/publish/1.11/miredot/js/directives.js (added)
+++ tika/site/publish/1.11/miredot/js/directives.js Sat Feb 20 07:37:52 2016
@@ -0,0 +1,320 @@
+'use strict';
+
+/* Directives */
+
+angular.module('miredot.directives', []);
+
+angular.module('miredot.directives')
+    /**
+    *  Renders a json-to
+    */
+    .directive('jsonTo', function ($compile) {
+
+        var _idCount = 0;
+        function getNewId() {
+            return _idCount++;
+        }
+
+        function getHighlightHtml(to) {
+            var html = '';
+            var id = to.__md_id || to.__sub_id;
+            var addHoverClass = 'onmouseover="$(\'#' + id + '\').addClass(\'highlightJsonRecursive\');"';
+            var removeHoverClass = 'onmouseout="$(\'#' + id + '\').removeClass(\'highlightJsonRecursive\');"';
+            html += '<a href="#' + id + '_a" ' + addHoverClass + ' ' + removeHoverClass + ' class="recursionLink" target="_self">';
+            html += '<i class="icon-retweet"></i>';
+            html += '</a>';
+            return html;
+        }
+
+        return {
+            restrict: 'E',
+            transclude: false,
+            scope: {
+                to:'=',
+                jsonDocConfig:'='
+            },
+            link: function (scope, element, attrs) {
+
+                /**
+                 * Recursively renders the given TO as json.
+                 * @param {Object | string} to The current object to render.
+                 * @param {string} comment The comment of this field.
+                 * @param {Array} history      All TOs that have already been rendered in the path leading here.
+                 * @return {String}
+                 */
+                var build = function(to, comment, history) {
+                    history = history || [];
+                    var newHistory;
+
+                    var html = '';
+
+                    switch (to.type) {
+                        case 'simple':
+                            html += '<span class="parameterType">';
+                            html += to.typeValue;
+                            html += '</span>';
+                            html += buildComment(comment);
+                            break;
+
+                        case 'enum':
+                            html += '<span class="parameterType">';
+                            html += enumArrayToString(to.values);
+                            html += '</span>';
+                            html += buildComment(comment);
+                            break;
+
+                        case 'collection':
+                            html += '<span>[</span>';
+                            html += buildComment(comment);
+                            html += '<ul class="toContainer"><li class="parameterItem">';
+                            html += build(to.typeValue, to.comment, history);
+                            html += '</li></ul>';
+                            html += '<span>]</span>';
+                            break;
+
+                        case 'map':
+                            html += '<span>{</span>';
+                            html += buildComment(comment);
+                            html += '<ul class="toContainer"><li class="parameterItem">';
+                            html += '<span class="parameterType">string</span> =>';
+                            html += build(to.typeValue, to.comment, history);
+                            html += '</li></ul>';
+                            html += '<span>}</span>';
+                            break;
+
+                        default: //(abstract or complex)
+                            //did wee see this type before?
+                            if (_.indexOf(history, to.name) >= 0) {
+                                //use it's id to highlight it
+                                html += getHighlightHtml(to);
+                                html += buildComment(comment);
+                            } else {
+                                newHistory = history.slice(0); // clone the history
+                                newHistory.push(to.name);
+
+                                //set a unique id for this type
+                                to.__md_id = 'md_to_' + getNewId();
+
+                                html += buildComment(comment);
+
+                                //start TO div (with id to be able to highlight)
+                                html += '<a id="' + to.__md_id + '_a" class="anchor"></a>';
+                                html += '<div id="' + to.__md_id + '">';
+                                html += '<span>{</span>';
+                                html += '<ul class="toContainer">';
+
+                                switch(to.type) {
+                                    case 'abstract':
+                                        html += buildAbstractToProperties(to, newHistory);
+                                    break;
+
+                                    case 'complex':
+                                        html += buildComplexToProperties(to, newHistory);
+                                    break;
+                                }
+
+                                //end TO div
+                                html += '</ul>';
+                                html += '<span>}</span>';
+                                html += '</div>';
+                            }
+                            break;
+                    }
+                    return html;
+                };
+
+                function buildComment(comment) {
+                    var result = '';
+                    if (scope.jsonDocConfig.enabled && comment) {
+                        result += '<span class="propertyComment" ng-show="!jsonDocConfig.hidden">';
+                        result += comment;
+                        result += '</span>';
+                    }
+                    return result;
+                }
+
+                /**
+                 * Lists properties of complex to.
+                 * @param {Object | string} to The current object to render.
+                 * @param {Array} history      All TOs that have already been rendered in the path leading here.
+                 * @param {Array} listedProperties  All properties that have been shown and should not be shown again
+                 */
+                 function buildComplexToProperties(to, history, listedProperties) {
+                    listedProperties = listedProperties || [];
+
+                    var html = '';
+
+                    _.each(to.content, function(field) {
+                        if (_.indexOf(listedProperties, field.name) < 0) {
+                            html += '<li class="parameterItem"><span class="parameterName">' + field.name + ':</span>';
+                            html += build(field.typeValue, field.comment, history);
+                            html += "</li>";
+
+                            listedProperties.push(field.name);
+                        }
+                    });
+                    return html;
+                }
+
+                /**
+                 * Lists properties of abstract to.
+                 * @param {Object | string} to The current object to render.
+                 * @param {Array} history      All TOs that have already been rendered in the path leading here.
+                 * @param {Array} listedProperties  All properties that have been shown and should not be shown again
+                 */
+                function buildAbstractToProperties(to, history, listedProperties) {
+                    listedProperties = listedProperties || [];
+                    if (to.property) { //property name used in JsonTypeInfo should not be repeated in the list of properties
+                        listedProperties.push(to.property);
+                    }
+
+                    var html = '';
+
+                    //get a unique name for the angular model for the subType switcher
+                    var subTypeModel = 'subTypeModel' + getNewId();
+
+                    //list properties of this class
+                    html += buildComplexToProperties(to, history, listedProperties);
+
+                    //show subType switcher
+                    html += '<li class="parameterItem">';
+                    if (to.property) { //property name used in JsonTypeInfo
+                        html += '<span class="parameterName">' + to.property + ':</span>';
+                    }
+                    html += '<span class="parameterType"><div class="btn-group">';
+
+                    var first = true;
+                    _.each(to.subTypes, function(subType) {
+                        //set a unique id for this subType
+                        subType.to.__sub_id = 'md_to_' + getNewId();
+                        if (first) {
+                            scope[subTypeModel] = subType.to.__sub_id; //set the default model value to the first subType id
+                            first = false;
+                        }
+                        //show the button with the name of the subType (based on JsonTypeInfo)
+                        //clicking this button changes the value of the current subTypeModel property to the id of the subType
+                        html += '<button type="button" class="btn" ng-model="' + subTypeModel + '" ' +
+                            'btn-radio="\'' + subType.to.__sub_id + '\'">' + subType.name + '</button>';
+                    });
+
+                    html += '</div></span>';
+                    html += buildComment(to.comment);
+                    html += '</li>';
+
+
+                    //show subTypes, like complex type, but inline fields & only shown when subTypeModel is set to it's id
+                    _.each(to.subTypes, function(subType) {
+                        var newHistory = history.slice(0); // clone the history
+                        var newListedProperties = listedProperties.slice(0);  // clone the already listed properties
+
+                        html += '<a id="' + subType.to.__sub_id + '_a" class="anchor"></a>';
+                        //only show this subType's fields when subTypeModel is set to it's id
+                        html += '<div ng-show="' + subTypeModel + ' == \'' + subType.to.__sub_id + '\'" id="' + subType.to.__sub_id + '">';
+
+                        switch (subType.to.type) {
+                            case 'complex':
+                                newHistory.push(subType.to.name);
+                                html += buildComplexToProperties(subType.to, newHistory, newListedProperties);
+                                break;
+                            case 'abstract':
+                                html += buildAbstractToProperties(subType.to, newHistory, newListedProperties);
+                                break;
+                        }
+                        html += '</div>';
+                    });
+                    return html;
+                }
+
+
+                var togglePropertyCommentsHtml = '';
+
+                if (scope.jsonDocConfig.enabled) {
+                    togglePropertyCommentsHtml += '<span class="togglePropertyComments" ' +
+                    'ng-click="jsonDocConfig.hidden = !jsonDocConfig.hidden">' +
+                    '<span ng-show="jsonDocConfig.hidden">Show</span>' +
+                    '<span ng-show="!jsonDocConfig.hidden">Hide</span>' +
+                    ' descriptions</span>';
+                }
+
+                var newElement = angular.element(togglePropertyCommentsHtml + build(scope.to));
+                $compile(newElement)(scope);
+                element.replaceWith(newElement);
+            }
+        };
+    })
+
+    .directive('widthonblur', function () {
+        return function(scope, element, attrs) {
+            element.css("width", attrs.widthonblur);
+
+            element.bind("blur", function() {
+                element.css("width", attrs.widthonblur);
+            });
+        }
+    })
+    .directive('widthonfocus', function () {
+        return function(scope, element, attrs) {
+            element.bind("focus", function() {
+                element.css("width", attrs.widthonfocus);
+            })
+        }
+    })
+    //ngFocus will be included in later angular versions
+    .directive('onFocus', ['$parse', function($parse) {
+        return function(scope, element, attr) {
+            var fn = $parse(attr['onFocus']);
+            element.bind('focus', function(event) {
+                scope.$apply(function() {
+                    fn(scope, {$event:event});
+                });
+            });
+        }
+}   ])
+    //ngBlur will be included in later angular versions
+    .directive('onBlur', ['$parse', function($parse) {
+        return function(scope, element, attr) {
+            var fn = $parse(attr['onBlur']);
+            element.bind('blur', function(event) {
+                scope.$apply(function() {
+                    fn(scope, {$event:event});
+                });
+            });
+        }
+    }])
+    //focus when some condition becomes true
+    .directive('focusWhen', function($parse, $timeout) {
+        return function(scope, element, attr) {
+            scope.$watch(attr['focusWhen'],
+                function(newValue, oldValue) {
+                    if (!oldValue && !!newValue) {
+                        $timeout(function() {
+                            element.focus();
+
+                            //move cursor te end if input field (not required in chrome)
+                            if (element.val()) {
+                                var tmpStr = element.val();
+                                element.val('');
+                                element.val(tmpStr);
+                            }
+                        });
+                    }
+                }, true);
+        };
+    })
+    //evaluate expression when user presses enter
+    .directive('onEnter', function() {
+        return function(scope, element, attrs) {
+            element.bind("keydown keypress", function(event) {
+                if(event.which === 13) {
+                    scope.$apply(function(){
+                        scope.$eval(attrs.onEnter);
+                    });
+
+                    event.preventDefault();
+                }
+            });
+        };
+    });
+
+
+

Added: tika/site/publish/1.11/miredot/js/filters.js
URL: http://svn.apache.org/viewvc/tika/site/publish/1.11/miredot/js/filters.js?rev=1731338&view=auto
==============================================================================
--- tika/site/publish/1.11/miredot/js/filters.js (added)
+++ tika/site/publish/1.11/miredot/js/filters.js Sat Feb 20 07:37:52 2016
@@ -0,0 +1,218 @@
+'use strict';
+
+/* Filters */
+
+angular.module('miredot.filters', ['ngSanitize', 'ui.filters']).
+    filter('formatUrlParams', function(){
+        return function(value) {
+            if (!value) {
+                return value;
+            }
+            return value.toString().replace(new RegExp("{(.*?)}", 'gi'), '<span class="paramName">$1</span>');
+        };
+    }).
+    filter('capitaliseFirstLetter', function(){
+        return function (string) {
+            return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
+        };
+    }).
+    filter('arraySort', function() {
+        return function(input) {
+            return input.sort();
+        }
+    }).
+    filter('searchByExampleFilter', function() {
+        /**
+         * Removes the domain (and protocol) from an uri. Requires / after domain part.
+         * @param uri
+         */
+        function removeDomain(uri) {
+            return uri.replace(/^.*\/\/[^\/]+/, '');
+        }
+
+        /**
+         * Builds a regexp for the given interface
+         * @param iface the interface to get the regex for
+         * @return a case insensitive regex for the current interface
+         */
+        function getRegExp(iface) {
+            var url = iface.url.stripTrailingSlash();
+
+            // Escape regexp special characters.
+            // url = url.replace(/[-\/\\^$*+?.()|[\]]/g, "\\$&");
+            url = '^' + url + '$';
+            var regex = '';
+
+            //matches everything within {} (start with '{', than anything but '}', end with '}')
+            var re = /{([^\}]+)}/g, paramMatch, lastMatchedIndex = 0;
+
+            while ((paramMatch = re.exec(url)) !== null) {
+                // Find each {param} in `url` and replace it with a capturing group.
+                // Append all other sections of url unchanged.
+
+                regex += url.slice(lastMatchedIndex, paramMatch.index);
+
+                // The path param is the part between "{}" (the first parenthesized substring match)
+                var pathParam = paramMatch[1];
+
+                // Special case if path contains params with regex, e.g. {id : \d+}
+                if (pathParam.indexOf(":") > 0) {
+                    //the regex is the part after the ":"
+                    var paramRegex = jQuery.trim(pathParam.split(":")[1]);
+                    //just use this as regex
+                    regex += '(' + paramRegex + ')';
+                } else {
+                    regex += '([^\\/]*)'; //anything except "/"
+                }
+                lastMatchedIndex = re.lastIndex;
+            }
+            // Append trailing path part.
+            regex += url.substr(lastMatchedIndex);
+
+            // Case insensitive regex
+            return new RegExp(regex, "i");
+        }
+
+        /**
+         * Filters out all interfaces that don't match the given search string.
+         *
+         * The baseUrl is dropped from the search string in searchString
+         * If the search string contains a query param, all query params need to be filled in to match.
+         *
+         * e.g. search string: http://www.example.com/feature/5?limit=10
+         * will match interface: /feature/{id} with query params limit
+         * will not match interface: /feature/{id} with no query params
+         * will not match interface: /feature/{id} with query params limit, start
+         * will not match interface: /feature/ with query params limit
+         *
+         * @param searchString The search string
+         * @return function that returns true if the given interface matches the search string, false otherwise
+         */
+        function searchByExampleFilter(searchString) {
+            return function(currentInterface, baseUrl) {
+                if (searchString.length === 0) {
+                    return true;
+                }
+
+                var split = searchString.split("?");
+                var locationPart = split[0];
+                var queryPart = split[1];
+
+                if (angular.isDefined(queryPart)) {
+                    var queryParams = parseKeyValue(queryPart);
+                    var valid = true;
+                    angular.forEach(currentInterface.inputs.QUERY, function(queryParam) {
+                        valid = valid && (valid = angular.isDefined(queryParams[queryParam.name.toLowerCase()]));
+                    });
+                    if (!valid) return false;
+                }
+
+                var search = locationPart.replace(baseUrl, "").stripTrailingSlash().ensureStartsWithSlash();
+
+                //interface will not change, so create the regex only once
+                currentInterface.regexp = currentInterface.regexp || getRegExp(currentInterface);
+
+                return currentInterface.regexp.test(search);
+            }
+        }
+
+        //expects a list of interfaces, returns a list of interfaces (default for filter)
+//        return function(interfaces, searchString) {
+//            return _.filter(interfaces, searchByExampleFilter(searchString));
+//        }
+
+        //expects one interface, returns true or false
+        return function(iface, searchString, baseUrl) {
+            return searchByExampleFilter(searchString)(iface, baseUrl);
+        }
+    }).
+    filter('filterBySearchQuery', function() {
+        function recursiveMatch(searchQuery) {
+            return function(resource) {
+                if (searchQuery.url.length === 0) {
+                    return true;
+                }
+                if (resource.name.toLowerCase().indexOf(searchQuery.url.toLowerCase()) > -1) {
+                    return true;
+                }
+                for (var i = 0; i<resource.leafResources.length; i++) {
+                    if (resource.leafResources[i].url.toLowerCase().indexOf(searchQuery.url.toLowerCase()) > -1) {
+                        return true;
+                    }
+                }
+                for (var j = 0; j<resource.resources.length; j++) {
+                    if (recursiveMatch(searchQuery)(resource.resources[j])) {
+                        return true;
+                    }
+                }
+                return false;
+            }
+        }
+
+        //expects a list of resources, returns a list of resources (default for filter)
+//        return function(resources, searchQuery) {
+//            return _.filter(resources, recursiveMatch(searchQuery));
+//        }
+
+        //expects one resource, returns true or false
+        return function(resource, searchQuery) {
+            return recursiveMatch(searchQuery)(resource);
+        }
+
+    }).
+    filter('serviceTagFilter', function() {
+        /**
+         * Filters out all interfaces that don't have all the currently selected service tags
+         *
+         * @param currentInterface The interface to check the service tags for
+         */
+        function matchesServiceTags(serviceTags) {
+            return function(currentInterface) {
+                return _.every(serviceTags, function(serviceTag) {
+                    if (serviceTag.selected) {
+                        return _.contains(currentInterface.tags, serviceTag.name);
+                    }
+                    return true;
+                });
+            }
+        }
+
+        //expects a list of interfaces, returns a list of interfaces (default for filter)
+//        return function(interfaces, serviceTags) {
+//            return _.filter(interfaces, matchesServiceTags(serviceTags));
+//        };
+
+        //expects one interface, returns true or false
+        return function(currentInterface, serviceTags) {
+            return matchesServiceTags(serviceTags)(currentInterface);
+        }
+    }).
+    filter('searchQueryFilter', function() {
+        /**
+         * Filters out all interfaces that don't match the current search query
+         *
+         * @param currentInterface The interface to check the search query for
+         */
+        function matchesSearchQuery(searchQuery) {
+            return function(currentInterface) {
+                if(searchQuery.http && currentInterface.http.indexOf(searchQuery.http) < 0) {
+                    return false;
+                }
+                if(searchQuery.url && currentInterface.url.toLowerCase().indexOf(searchQuery.url.toLowerCase()) < 0) {
+                    return false;
+                }
+                
+                return true;
+            }
+        }
+
+        //expects a list of interfaces, returns a list of interfaces (default for filter)
+//        return function(interfaces, serviceTags) {
+//            return _.filter(interfaces, matchesServiceTags(serviceTags));
+//        };
+
+        //expects one interface, returns true or false
+        return function(currentInterface, searchQuery) {
+            return matchesSearchQuery(searchQuery)(currentInterface);
+        }
+    });
\ No newline at end of file

Added: tika/site/publish/1.11/miredot/js/ngStorage.js
URL: http://svn.apache.org/viewvc/tika/site/publish/1.11/miredot/js/ngStorage.js?rev=1731338&view=auto
==============================================================================
--- tika/site/publish/1.11/miredot/js/ngStorage.js (added)
+++ tika/site/publish/1.11/miredot/js/ngStorage.js Sat Feb 20 07:37:52 2016
@@ -0,0 +1,113 @@
+'use strict';
+
+(function() {
+
+    /**
+     * From: https://github.com/gsklee/ngStorage
+     * @ngdoc overview
+     * @name ngStorage
+     */
+
+    angular.module('ngStorage', []).
+
+    /**
+     * @ngdoc object
+     * @name ngStorage.$localStorage
+     * @requires $rootScope
+     * @requires $browser
+     * @requires $window
+     */
+
+    factory('$localStorage', _storageFactory('localStorage')).
+
+    /**
+     * @ngdoc object
+     * @name ngStorage.$sessionStorage
+     * @requires $rootScope
+     * @requires $browser
+     * @requires $window
+     */
+
+    factory('$sessionStorage', _storageFactory('sessionStorage'));
+
+    function _storageFactory(storageType) {
+        return [
+            '$rootScope',
+            '$browser',
+            '$window',
+
+            function(
+                $rootScope,
+                $browser,
+                $window
+            ){
+                var webStorage = $window[storageType],
+                    $storage = {
+                        $default: function(items) {
+                            for (var k in items) {
+                                angular.isDefined($storage[k]) || ($storage[k] = items[k]);
+                            }
+
+                            return $storage;
+                        },
+                        $reset: function(items) {
+                            for (var k in $storage) {
+                                '$' === k[0] || delete $storage[k];
+                            }
+
+                            return $storage.$default(items);
+                        }
+                    },
+                    _last$storage;
+
+                //degrade gracefully in Internet Explorer when loading page from filesystem
+                webStorage = webStorage || { setItem: function() {}, getItem: function() {}, removeItem:function() {} };
+
+                // (#8) `i < webStorage.length` is needed for IE9
+                for (var i = 0, k; i < webStorage.length && (k = webStorage.key(i)); i++) {
+                    'ngStorage-' === k.slice(0, 10) && ($storage[k.slice(10)] = angular.fromJson(webStorage.getItem(k)));
+                }
+
+                _last$storage = angular.copy($storage);
+
+                $browser.addPollFn(function() {
+                    if (!angular.equals($storage, _last$storage)) {
+                        angular.forEach($storage, function(v, k) {
+                            if (angular.isDefined(v) && '$' !== k[0]) {
+
+                                // Remove $$hashKey and other things that cannot be stringified
+                                $storage[k] = angular.fromJson(angular.toJson(v));
+
+                                webStorage.setItem('ngStorage-' + k, angular.toJson(v));
+                            }
+
+                            delete _last$storage[k];
+                        });
+
+                        for (var k in _last$storage) {
+                            webStorage.removeItem('ngStorage-' + k);
+                        }
+
+                        _last$storage = angular.copy($storage);
+
+                        $rootScope.$apply();
+                    }
+                });
+
+                // (#6) Use `$window.addEventListener` instead of `angular.element` to avoid the jQuery-specific `event.originalEvent`
+                'localStorage' === storageType && $window.addEventListener && $window.addEventListener('storage', function(event) {
+                    if ('ngStorage-' === event.key.slice(0, 10)) {
+                        event.newValue ? $storage[event.key.slice(10)] = angular.fromJson(event.newValue) : delete $storage[event.key.slice(10)];
+
+                        _last$storage = angular.copy($storage);
+
+                        $rootScope.$apply();
+                    }
+                });
+
+                return $storage;
+            }
+        ];
+    }
+
+})();

Added: tika/site/publish/1.11/miredot/js/watch-fighters.js
URL: http://svn.apache.org/viewvc/tika/site/publish/1.11/miredot/js/watch-fighters.js?rev=1731338&view=auto
==============================================================================
--- tika/site/publish/1.11/miredot/js/watch-fighters.js (added)
+++ tika/site/publish/1.11/miredot/js/watch-fighters.js Sat Feb 20 07:37:52 2016
@@ -0,0 +1,108 @@
+'use strict';
+
+//based on https://github.com/abourget/abourget-angular
+angular.module('watchFighers', [])
+
+  .directive('setIf', [function () {
+    return {
+      transclude: 'element',
+      priority: 1000,
+      terminal: true,
+      restrict: 'A',
+      compile: function (element, attr, linker) {
+        return function (scope, iterStartElement, attr) {
+          iterStartElement[0].doNotMove = true;
+          var expression = attr.setIf;
+          var value = scope.$eval(expression);
+          if (value) {
+            linker(scope, function (clone) {
+              iterStartElement.after(clone);
+            });
+          }
+        };
+      }
+    };
+  }])
+
+
+  .directive('setHtml', function() {
+    return {
+      restrict: "A",
+      priority: 100,
+      link: function($scope, $el, $attr) {
+        $($el).html($scope.$eval($attr.setHtml) || '');
+      }
+    };
+  })
+
+  .directive('setText', function() {
+    return {
+      restrict: "A",
+      priority: 100,
+      link: function($scope, $el, $attr) {
+        $($el).text($scope.$eval($attr.setText) || '');
+      }
+    };
+  })
+
+  .directive('setClass', function() {
+    return {
+      restrict: "A",
+      priority: 100,
+      link: function($scope, $el, $attr) {
+
+          function setClass(attributeValue, $scope, $el) {
+              if (attributeValue.indexOf(":") > 0) { //classname : condition
+                  var classNameCondition = attributeValue.split(":", 2);
+                  var className = jQuery.trim(classNameCondition[0]);
+                  var condition = $scope.$eval(jQuery.trim(classNameCondition[1]));
+                  if (condition) {
+                      $($el).addClass(className);
+                  }
+              } else { //just classname
+                  $($el).addClass($scope.$eval(attributeValue) || '');
+              }
+          }
+
+          if ($attr.setClass.indexOf(",") > 0) { //multiple classes
+              _.each($attr.setClass.split(','), function(attributeValue) {
+                  setClass(jQuery.trim(attributeValue), $scope, $el);
+              });
+          } else {
+              setClass($attr.setClass, $scope, $el);
+          }
+      }
+    };
+  })
+
+  .directive('setTitle', function() {
+    return {
+      restrict: "A",
+      priority: 100,
+      link: function($scope, $el, $attr) {
+        $($el).attr('title', $scope.$eval($attr.setTitle) || '');
+      }
+    };
+  })
+
+  .directive('setHref', function() {
+    return {
+      restrict: "A",
+      priority: 100,
+      link: function($scope, $el, $attr) {
+        $($el).attr('href', $scope.$eval($attr.setHref) || '');
+      }
+    };
+  })
+
+  .directive('setId', function() {
+    return {
+      restrict: "A",
+      priority: 100,
+      link: function($scope, $el, $attr) {
+        $($el).attr('id', $scope.$eval($attr.setId) || '');
+      }
+    };
+  })
+
+  ;
\ No newline at end of file

Added: tika/site/publish/1.11/miredot/lib/angular-ui/angular-ui-ieshiv.js
URL: http://svn.apache.org/viewvc/tika/site/publish/1.11/miredot/lib/angular-ui/angular-ui-ieshiv.js?rev=1731338&view=auto
==============================================================================
--- tika/site/publish/1.11/miredot/lib/angular-ui/angular-ui-ieshiv.js (added)
+++ tika/site/publish/1.11/miredot/lib/angular-ui/angular-ui-ieshiv.js Sat Feb 20 07:37:52 2016
@@ -0,0 +1,59 @@
+/**
+ * AngularUI - The companion suite for AngularJS
+ * @version v0.4.0 - 2013-02-15
+ * @link http://angular-ui.github.com
+ * @license MIT License, http://www.opensource.org/licenses/MIT
+ */
+
+// READ: http://docs-next.angularjs.org/guide/ie
+// element tags are statically defined in order to accommodate lazy-loading whereby directives are also unknown
+
+// The ieshiv takes care of our ui.directives and AngularJS's ng-view, ng-include, ng-pluralize, ng-switch.
+// However, IF you have custom directives that can be used as html tags (yours or someone else's) then
+// add list of directives into <code>window.myCustomTags</code>
+
+// <!--[if lte IE 8]>
+//    <script>
+//    window.myCustomTags = [ 'yourCustomDirective', 'somebodyElsesDirective' ]; // optional
+//    </script>
+//    <script src="build/angular-ui-ieshiv.js"></script>
+// <![endif]-->
+
+(function (exports) {
+
+  var debug = window.ieShivDebug || false,
+      tags = [ "ngInclude", "ngPluralize", "ngView", "ngSwitch", "uiCurrency", "uiCodemirror", "uiDate", "uiEvent",
+                "uiKeypress", "uiKeyup", "uiKeydown", "uiMask", "uiMapInfoWindow", "uiMapMarker", "uiMapPolyline",
+                "uiMapPolygon", "uiMapRectangle", "uiMapCircle", "uiMapGroundOverlay", "uiModal", "uiReset",
+                "uiScrollfix", "uiSelect2", "uiShow", "uiHide", "uiToggle", "uiSortable", "uiTinymce"
+                ];
+
+  window.myCustomTags =  window.myCustomTags || []; // externally defined by developer using angular-ui directives
+  tags.push.apply(tags, window.myCustomTags);
+
+  var toCustomElements = function (str) {
+    var result = [];
+    var dashed = str.replace(/([A-Z])/g, function ($1) {
+      return " " + $1.toLowerCase();
+    });
+    var tokens = dashed.split(' ');
+    var ns = tokens[0];
+    var dirname = tokens.slice(1).join('-');
+
+    // this is finite list and it seemed senseless to create a custom method
+    result.push(ns + ":" + dirname);
+    result.push(ns + "-" + dirname);
+    result.push("x-" + ns + "-" + dirname);
+    result.push("data-" + ns + "-" + dirname);
+    return result;
+  };
+
+  for (var i = 0, tlen = tags.length; i < tlen; i++) {
+    var customElements = toCustomElements(tags[i]);
+    for (var j = 0, clen = customElements.length; j < clen; j++) {
+      var customElement = customElements[j];
+      document.createElement(customElement);
+    }
+  }
+
+})(window);
\ No newline at end of file

Added: tika/site/publish/1.11/miredot/lib/angular-ui/angular-ui-ieshiv.min.js
URL: http://svn.apache.org/viewvc/tika/site/publish/1.11/miredot/lib/angular-ui/angular-ui-ieshiv.min.js?rev=1731338&view=auto
==============================================================================
--- tika/site/publish/1.11/miredot/lib/angular-ui/angular-ui-ieshiv.min.js (added)
+++ tika/site/publish/1.11/miredot/lib/angular-ui/angular-ui-ieshiv.min.js Sat Feb 20 07:37:52 2016
@@ -0,0 +1,7 @@
+/**
+ * AngularUI - The companion suite for AngularJS
+ * @version v0.4.0 - 2013-02-15
+ * @link http://angular-ui.github.com
+ * @license MIT License, http://www.opensource.org/licenses/MIT
+ */
+(function(e){var t=window.ieShivDebug||!1,n=["ngInclude","ngPluralize","ngView","ngSwitch","uiCurrency","uiCodemirror","uiDate","uiEvent","uiKeypress","uiKeyup","uiKeydown","uiMask","uiMapInfoWindow","uiMapMarker","uiMapPolyline","uiMapPolygon","uiMapRectangle","uiMapCircle","uiMapGroundOverlay","uiModal","uiReset","uiScrollfix","uiSelect2","uiShow","uiHide","uiToggle","uiSortable","uiTinymce"];window.myCustomTags=window.myCustomTags||[],n.push.apply(n,window.myCustomTags);var r=function(e){var t=[],n=e.replace(/([A-Z])/g,function(e){return" "+e.toLowerCase()}),r=n.split(" "),i=r[0],s=r.slice(1).join("-");return t.push(i+":"+s),t.push(i+"-"+s),t.push("x-"+i+"-"+s),t.push("data-"+i+"-"+s),t};for(var i=0,s=n.length;i<s;i++){var o=r(n[i]);for(var u=0,a=o.length;u<a;u++){var f=o[u];document.createElement(f)}}})(window);
\ No newline at end of file

Added: tika/site/publish/1.11/miredot/lib/angular-ui/angular-ui.css
URL: http://svn.apache.org/viewvc/tika/site/publish/1.11/miredot/lib/angular-ui/angular-ui.css?rev=1731338&view=auto
==============================================================================
--- tika/site/publish/1.11/miredot/lib/angular-ui/angular-ui.css (added)
+++ tika/site/publish/1.11/miredot/lib/angular-ui/angular-ui.css Sat Feb 20 07:37:52 2016
@@ -0,0 +1,50 @@
+/**
+ * import components to builds angular-ui.css
+ */
+
+/* ui-reset */
+
+.ui-resetwrap {
+  position: relative;
+  display: inline-block;
+}
+
+.ui-reset {
+  position: absolute;
+  top: 0;
+  right: 0;
+  z-index: 2;
+  display: none;
+  height: 100%;
+  cursor: pointer;
+}
+
+.ui-resetwrap:hover .ui-reset {
+  display: block;
+}
+
+/* ui-currency */
+
+.ui-currency-pos {
+  color: green;
+}
+
+.ui-currency-neg {
+  color: red;
+}
+
+.ui-currency-zero {
+  color: blue;
+}
+
+.ui-currency-pos.ui-bignum,
+.ui-currency-neg.ui-smallnum {
+  font-size: 110%;
+}
+
+/* highlight */
+
+.ui-match {
+  background: yellow;
+}
+