`, and ``.\n@font-family-monospace: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n@font-family-base: @font-family-sans-serif;\n\n@font-size-base: 14px;\n@font-size-large: ceil((@font-size-base * 1.25)); // ~18px\n@font-size-small: ceil((@font-size-base * 0.85)); // ~12px\n\n@font-size-h1: floor((@font-size-base * 2.6)); // ~36px\n@font-size-h2: floor((@font-size-base * 2.15)); // ~30px\n@font-size-h3: ceil((@font-size-base * 1.7)); // ~24px\n@font-size-h4: ceil((@font-size-base * 1.25)); // ~18px\n@font-size-h5: @font-size-base;\n@font-size-h6: ceil((@font-size-base * 0.85)); // ~12px\n\n//** Unit-less `line-height` for use in components like buttons.\n@line-height-base: 1.428571429; // 20/14\n//** Computed \"line-height\" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.\n@line-height-computed: floor((@font-size-base * @line-height-base)); // ~20px\n\n//** By default, this inherits from the ``.\n@headings-font-family: inherit;\n@headings-font-weight: 500;\n@headings-line-height: 1.1;\n@headings-color: inherit;\n\n\n//-- Iconography\n//\n//## Specify custom locations of the include Glyphicons icon font. Useful for those including Bootstrap via Bower.\n\n@icon-font-path: \"../fonts/\";\n@icon-font-name: \"glyphicons-halflings-regular\";\n@icon-font-svg-id: \"glyphicons_halflingsregular\";\n\n//== Components\n//\n//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).\n\n@padding-base-vertical: 6px;\n@padding-base-horizontal: 12px;\n\n@padding-large-vertical: 10px;\n@padding-large-horizontal: 16px;\n\n@padding-small-vertical: 5px;\n@padding-small-horizontal: 10px;\n\n@padding-xs-vertical: 1px;\n@padding-xs-horizontal: 5px;\n\n@line-height-large: 1.33;\n@line-height-small: 1.5;\n\n@border-radius-base: 4px;\n@border-radius-large: 6px;\n@border-radius-small: 3px;\n\n//** Global color for active items (e.g., navs or dropdowns).\n@component-active-color: #fff;\n//** Global background color for active items (e.g., navs or dropdowns).\n@component-active-bg: @brand-primary;\n\n//** Width of the `border` for generating carets that indicator dropdowns.\n@caret-width-base: 4px;\n//** Carets increase slightly in size for larger components.\n@caret-width-large: 5px;\n\n\n//== Tables\n//\n//## Customizes the `.table` component with basic values, each used across all table variations.\n\n//** Padding for ``s and ` | `s.\n@table-cell-padding: 8px;\n//** Padding for cells in `.table-condensed`.\n@table-condensed-cell-padding: 5px;\n\n//** Default background color used for all tables.\n@table-bg: transparent;\n//** Background color used for `.table-striped`.\n@table-bg-accent: #f9f9f9;\n//** Background color used for `.table-hover`.\n@table-bg-hover: #f5f5f5;\n@table-bg-active: @table-bg-hover;\n\n//** Border color for table and cell borders.\n@table-border-color: #ddd;\n\n\n//== Buttons\n//\n//## For each of Bootstrap's buttons, define text, background and border color.\n\n@btn-font-weight: normal;\n\n@btn-default-color: #333;\n@btn-default-bg: #fff;\n@btn-default-border: #ccc;\n\n@btn-primary-color: #fff;\n@btn-primary-bg: @brand-primary;\n@btn-primary-border: darken(@btn-primary-bg, 5%);\n\n@btn-success-color: #fff;\n@btn-success-bg: @brand-success;\n@btn-success-border: darken(@btn-success-bg, 5%);\n\n@btn-info-color: #fff;\n@btn-info-bg: @brand-info;\n@btn-info-border: darken(@btn-info-bg, 5%);\n\n@btn-warning-color: #fff;\n@btn-warning-bg: @brand-warning;\n@btn-warning-border: darken(@btn-warning-bg, 5%);\n\n@btn-danger-color: #fff;\n@btn-danger-bg: @brand-danger;\n@btn-danger-border: darken(@btn-danger-bg, 5%);\n\n@btn-link-disabled-color: @gray-light;\n\n\n//== Forms\n//\n//##\n\n//** `` background color\n@input-bg: #fff;\n//** `` background color\n@input-bg-disabled: @gray-lighter;\n\n//** Text color for ``s\n@input-color: @gray;\n//** `` border color\n@input-border: #ccc;\n//** `` border radius\n@input-border-radius: @border-radius-base;\n//** Border color for inputs on focus\n@input-border-focus: #66afe9;\n\n//** Placeholder text color\n@input-color-placeholder: @gray-light;\n\n//** Default `.form-control` height\n@input-height-base: (@line-height-computed + (@padding-base-vertical * 2) + 2);\n//** Large `.form-control` height\n@input-height-large: (ceil(@font-size-large * @line-height-large) + (@padding-large-vertical * 2) + 2);\n//** Small `.form-control` height\n@input-height-small: (floor(@font-size-small * @line-height-small) + (@padding-small-vertical * 2) + 2);\n\n@legend-color: @gray-dark;\n@legend-border-color: #e5e5e5;\n\n//** Background color for textual input addons\n@input-group-addon-bg: @gray-lighter;\n//** Border color for textual input addons\n@input-group-addon-border-color: @input-border;\n\n\n//== Dropdowns\n//\n//## Dropdown menu container and contents.\n\n//** Background for the dropdown menu.\n@dropdown-bg: #fff;\n//** Dropdown menu `border-color`.\n@dropdown-border: rgba(0,0,0,.15);\n//** Dropdown menu `border-color` **for IE8**.\n@dropdown-fallback-border: #ccc;\n//** Divider color for between dropdown items.\n@dropdown-divider-bg: #e5e5e5;\n\n//** Dropdown link text color.\n@dropdown-link-color: @gray-dark;\n//** Hover color for dropdown links.\n@dropdown-link-hover-color: darken(@gray-dark, 5%);\n//** Hover background for dropdown links.\n@dropdown-link-hover-bg: #f5f5f5;\n\n//** Active dropdown menu item text color.\n@dropdown-link-active-color: @component-active-color;\n//** Active dropdown menu item background color.\n@dropdown-link-active-bg: @component-active-bg;\n\n//** Disabled dropdown menu item background color.\n@dropdown-link-disabled-color: @gray-light;\n\n//** Text color for headers within dropdown menus.\n@dropdown-header-color: @gray-light;\n\n// Note: Deprecated @dropdown-caret-color as of v3.1.0\n@dropdown-caret-color: #000;\n\n\n//-- Z-index master list\n//\n// Warning: Avoid customizing these values. They're used for a bird's eye view\n// of components dependent on the z-axis and are designed to all work together.\n//\n// Note: These variables are not generated into the Customizer.\n\n@zindex-navbar: 1000;\n@zindex-dropdown: 1000;\n@zindex-popover: 1010;\n@zindex-tooltip: 1030;\n@zindex-navbar-fixed: 1030;\n@zindex-modal-background: 1040;\n@zindex-modal: 1050;\n\n\n//== Media queries breakpoints\n//\n//## Define the breakpoints at which your layout will change, adapting to different screen sizes.\n\n// Extra small screen / phone\n// Note: Deprecated @screen-xs and @screen-phone as of v3.0.1\n@screen-xs: 480px;\n@screen-xs-min: @screen-xs;\n@screen-phone: @screen-xs-min;\n\n// Small screen / tablet\n// Note: Deprecated @screen-sm and @screen-tablet as of v3.0.1\n@screen-sm: 768px;\n@screen-sm-min: @screen-sm;\n@screen-tablet: @screen-sm-min;\n\n// Medium screen / desktop\n// Note: Deprecated @screen-md and @screen-desktop as of v3.0.1\n@screen-md: 992px;\n@screen-md-min: @screen-md;\n@screen-desktop: @screen-md-min;\n\n// Large screen / wide desktop\n// Note: Deprecated @screen-lg and @screen-lg-desktop as of v3.0.1\n@screen-lg: 1200px;\n@screen-lg-min: @screen-lg;\n@screen-lg-desktop: @screen-lg-min;\n\n// So media queries don't overlap when required, provide a maximum\n@screen-xs-max: (@screen-sm-min - 1);\n@screen-sm-max: (@screen-md-min - 1);\n@screen-md-max: (@screen-lg-min - 1);\n\n\n//== Grid system\n//\n//## Define your custom responsive grid.\n\n//** Number of columns in the grid.\n@grid-columns: 12;\n//** Padding between columns. Gets divided in half for the left and right.\n@grid-gutter-width: 30px;\n// Navbar collapse\n//** Point at which the navbar becomes uncollapsed.\n@grid-float-breakpoint: @screen-sm-min;\n//** Point at which the navbar begins collapsing.\n@grid-float-breakpoint-max: (@grid-float-breakpoint - 1);\n\n\n//== Container sizes\n//\n//## Define the maximum width of `.container` for different screen sizes.\n\n// Small screen / tablet\n@container-tablet: ((720px + @grid-gutter-width));\n//** For `@screen-sm-min` and up.\n@container-sm: @container-tablet;\n\n// Medium screen / desktop\n@container-desktop: ((940px + @grid-gutter-width));\n//** For `@screen-md-min` and up.\n@container-md: @container-desktop;\n\n// Large screen / wide desktop\n@container-large-desktop: ((1140px + @grid-gutter-width));\n//** For `@screen-lg-min` and up.\n@container-lg: @container-large-desktop;\n\n\n//== Navbar\n//\n//##\n\n// Basics of a navbar\n@navbar-height: 50px;\n@navbar-margin-bottom: @line-height-computed;\n@navbar-border-radius: @border-radius-base;\n@navbar-padding-horizontal: floor((@grid-gutter-width / 2));\n@navbar-padding-vertical: ((@navbar-height - @line-height-computed) / 2);\n@navbar-collapse-max-height: 340px;\n\n@navbar-default-color: #777;\n@navbar-default-bg: #f8f8f8;\n@navbar-default-border: darken(@navbar-default-bg, 6.5%);\n\n// Navbar links\n@navbar-default-link-color: #777;\n@navbar-default-link-hover-color: #333;\n@navbar-default-link-hover-bg: transparent;\n@navbar-default-link-active-color: #555;\n@navbar-default-link-active-bg: darken(@navbar-default-bg, 6.5%);\n@navbar-default-link-disabled-color: #ccc;\n@navbar-default-link-disabled-bg: transparent;\n\n// Navbar brand label\n@navbar-default-brand-color: @navbar-default-link-color;\n@navbar-default-brand-hover-color: darken(@navbar-default-brand-color, 10%);\n@navbar-default-brand-hover-bg: transparent;\n\n// Navbar toggle\n@navbar-default-toggle-hover-bg: #ddd;\n@navbar-default-toggle-icon-bar-bg: #888;\n@navbar-default-toggle-border-color: #ddd;\n\n\n// Inverted navbar\n// Reset inverted navbar basics\n@navbar-inverse-color: @gray-light;\n@navbar-inverse-bg: #222;\n@navbar-inverse-border: darken(@navbar-inverse-bg, 10%);\n\n// Inverted navbar links\n@navbar-inverse-link-color: @gray-light;\n@navbar-inverse-link-hover-color: #fff;\n@navbar-inverse-link-hover-bg: transparent;\n@navbar-inverse-link-active-color: @navbar-inverse-link-hover-color;\n@navbar-inverse-link-active-bg: darken(@navbar-inverse-bg, 10%);\n@navbar-inverse-link-disabled-color: #444;\n@navbar-inverse-link-disabled-bg: transparent;\n\n// Inverted navbar brand label\n@navbar-inverse-brand-color: @navbar-inverse-link-color;\n@navbar-inverse-brand-hover-color: #fff;\n@navbar-inverse-brand-hover-bg: transparent;\n\n// Inverted navbar toggle\n@navbar-inverse-toggle-hover-bg: #333;\n@navbar-inverse-toggle-icon-bar-bg: #fff;\n@navbar-inverse-toggle-border-color: #333;\n\n\n//== Navs\n//\n//##\n\n//=== Shared nav styles\n@nav-link-padding: 10px 15px;\n@nav-link-hover-bg: @gray-lighter;\n\n@nav-disabled-link-color: @gray-light;\n@nav-disabled-link-hover-color: @gray-light;\n\n@nav-open-link-hover-color: #fff;\n\n//== Tabs\n@nav-tabs-border-color: #ddd;\n\n@nav-tabs-link-hover-border-color: @gray-lighter;\n\n@nav-tabs-active-link-hover-bg: @body-bg;\n@nav-tabs-active-link-hover-color: @gray;\n@nav-tabs-active-link-hover-border-color: #ddd;\n\n@nav-tabs-justified-link-border-color: #ddd;\n@nav-tabs-justified-active-link-border-color: @body-bg;\n\n//== Pills\n@nav-pills-border-radius: @border-radius-base;\n@nav-pills-active-link-hover-bg: @component-active-bg;\n@nav-pills-active-link-hover-color: @component-active-color;\n\n\n//== Pagination\n//\n//##\n\n@pagination-color: @link-color;\n@pagination-bg: #fff;\n@pagination-border: #ddd;\n\n@pagination-hover-color: @link-hover-color;\n@pagination-hover-bg: @gray-lighter;\n@pagination-hover-border: #ddd;\n\n@pagination-active-color: #fff;\n@pagination-active-bg: @brand-primary;\n@pagination-active-border: @brand-primary;\n\n@pagination-disabled-color: @gray-light;\n@pagination-disabled-bg: #fff;\n@pagination-disabled-border: #ddd;\n\n\n//== Pager\n//\n//##\n\n@pager-bg: @pagination-bg;\n@pager-border: @pagination-border;\n@pager-border-radius: 15px;\n\n@pager-hover-bg: @pagination-hover-bg;\n\n@pager-active-bg: @pagination-active-bg;\n@pager-active-color: @pagination-active-color;\n\n@pager-disabled-color: @pagination-disabled-color;\n\n\n//== Jumbotron\n//\n//##\n\n@jumbotron-padding: 30px;\n@jumbotron-color: inherit;\n@jumbotron-bg: @gray-lighter;\n@jumbotron-heading-color: inherit;\n@jumbotron-font-size: ceil((@font-size-base * 1.5));\n\n\n//== Form states and alerts\n//\n//## Define colors for form feedback states and, by default, alerts.\n\n@state-success-text: #3c763d;\n@state-success-bg: #dff0d8;\n@state-success-border: darken(spin(@state-success-bg, -10), 5%);\n\n@state-info-text: #31708f;\n@state-info-bg: #d9edf7;\n@state-info-border: darken(spin(@state-info-bg, -10), 7%);\n\n@state-warning-text: #8a6d3b;\n@state-warning-bg: #fcf8e3;\n@state-warning-border: darken(spin(@state-warning-bg, -10), 5%);\n\n@state-danger-text: #a94442;\n@state-danger-bg: #f2dede;\n@state-danger-border: darken(spin(@state-danger-bg, -10), 5%);\n\n\n//== Tooltips\n//\n//##\n\n//** Tooltip max width\n@tooltip-max-width: 200px;\n//** Tooltip text color\n@tooltip-color: #fff;\n//** Tooltip background color\n@tooltip-bg: #000;\n@tooltip-opacity: .9;\n\n//** Tooltip arrow width\n@tooltip-arrow-width: 5px;\n//** Tooltip arrow color\n@tooltip-arrow-color: @tooltip-bg;\n\n\n//== Popovers\n//\n//##\n\n//** Popover body background color\n@popover-bg: #fff;\n//** Popover maximum width\n@popover-max-width: 276px;\n//** Popover border color\n@popover-border-color: rgba(0,0,0,.2);\n//** Popover fallback border color\n@popover-fallback-border-color: #ccc;\n\n//** Popover title background color\n@popover-title-bg: darken(@popover-bg, 3%);\n\n//** Popover arrow width\n@popover-arrow-width: 10px;\n//** Popover arrow color\n@popover-arrow-color: #fff;\n\n//** Popover outer arrow width\n@popover-arrow-outer-width: (@popover-arrow-width + 1);\n//** Popover outer arrow color\n@popover-arrow-outer-color: fadein(@popover-border-color, 5%);\n//** Popover outer arrow fallback color\n@popover-arrow-outer-fallback-color: darken(@popover-fallback-border-color, 20%);\n\n\n//== Labels\n//\n//##\n\n//** Default label background color\n@label-default-bg: @gray-light;\n//** Primary label background color\n@label-primary-bg: @brand-primary;\n//** Success label background color\n@label-success-bg: @brand-success;\n//** Info label background color\n@label-info-bg: @brand-info;\n//** Warning label background color\n@label-warning-bg: @brand-warning;\n//** Danger label background color\n@label-danger-bg: @brand-danger;\n\n//** Default label text color\n@label-color: #fff;\n//** Default text color of a linked label\n@label-link-hover-color: #fff;\n\n\n//== Modals\n//\n//##\n\n//** Padding applied to the modal body\n@modal-inner-padding: 20px;\n\n//** Padding applied to the modal title\n@modal-title-padding: 15px;\n//** Modal title line-height\n@modal-title-line-height: @line-height-base;\n\n//** Background color of modal content area\n@modal-content-bg: #fff;\n//** Modal content border color\n@modal-content-border-color: rgba(0,0,0,.2);\n//** Modal content border color **for IE8**\n@modal-content-fallback-border-color: #999;\n\n//** Modal backdrop background color\n@modal-backdrop-bg: #000;\n//** Modal backdrop opacity\n@modal-backdrop-opacity: .5;\n//** Modal header border color\n@modal-header-border-color: #e5e5e5;\n//** Modal footer border color\n@modal-footer-border-color: @modal-header-border-color;\n\n@modal-lg: 900px;\n@modal-md: 600px;\n@modal-sm: 300px;\n\n\n//== Alerts\n//\n//## Define alert colors, border radius, and padding.\n\n@alert-padding: 15px;\n@alert-border-radius: @border-radius-base;\n@alert-link-font-weight: bold;\n\n@alert-success-bg: @state-success-bg;\n@alert-success-text: @state-success-text;\n@alert-success-border: @state-success-border;\n\n@alert-info-bg: @state-info-bg;\n@alert-info-text: @state-info-text;\n@alert-info-border: @state-info-border;\n\n@alert-warning-bg: @state-warning-bg;\n@alert-warning-text: @state-warning-text;\n@alert-warning-border: @state-warning-border;\n\n@alert-danger-bg: @state-danger-bg;\n@alert-danger-text: @state-danger-text;\n@alert-danger-border: @state-danger-border;\n\n\n//== Progress bars\n//\n//##\n\n//** Background color of the whole progress component\n@progress-bg: #f5f5f5;\n//** Progress bar text color\n@progress-bar-color: #fff;\n\n//** Default progress bar color\n@progress-bar-bg: @brand-primary;\n//** Success progress bar color\n@progress-bar-success-bg: @brand-success;\n//** Warning progress bar color\n@progress-bar-warning-bg: @brand-warning;\n//** Danger progress bar color\n@progress-bar-danger-bg: @brand-danger;\n//** Info progress bar color\n@progress-bar-info-bg: @brand-info;\n\n\n//== List group\n//\n//##\n\n//** Background color on `.list-group-item`\n@list-group-bg: #fff;\n//** `.list-group-item` border color\n@list-group-border: #ddd;\n//** List group border radius\n@list-group-border-radius: @border-radius-base;\n\n//** Background color of single list elements on hover\n@list-group-hover-bg: #f5f5f5;\n//** Text color of active list elements\n@list-group-active-color: @component-active-color;\n//** Background color of active list elements\n@list-group-active-bg: @component-active-bg;\n//** Border color of active list elements\n@list-group-active-border: @list-group-active-bg;\n@list-group-active-text-color: lighten(@list-group-active-bg, 40%);\n\n@list-group-link-color: #555;\n@list-group-link-heading-color: #333;\n\n\n//== Panels\n//\n//##\n\n@panel-bg: #fff;\n@panel-body-padding: 15px;\n@panel-border-radius: @border-radius-base;\n\n//** Border color for elements within panels\n@panel-inner-border: #ddd;\n@panel-footer-bg: #f5f5f5;\n\n@panel-default-text: @gray-dark;\n@panel-default-border: #ddd;\n@panel-default-heading-bg: #f5f5f5;\n\n@panel-primary-text: #fff;\n@panel-primary-border: @brand-primary;\n@panel-primary-heading-bg: @brand-primary;\n\n@panel-success-text: @state-success-text;\n@panel-success-border: @state-success-border;\n@panel-success-heading-bg: @state-success-bg;\n\n@panel-info-text: @state-info-text;\n@panel-info-border: @state-info-border;\n@panel-info-heading-bg: @state-info-bg;\n\n@panel-warning-text: @state-warning-text;\n@panel-warning-border: @state-warning-border;\n@panel-warning-heading-bg: @state-warning-bg;\n\n@panel-danger-text: @state-danger-text;\n@panel-danger-border: @state-danger-border;\n@panel-danger-heading-bg: @state-danger-bg;\n\n\n//== Thumbnails\n//\n//##\n\n//** Padding around the thumbnail image\n@thumbnail-padding: 4px;\n//** Thumbnail background color\n@thumbnail-bg: @body-bg;\n//** Thumbnail border color\n@thumbnail-border: #ddd;\n//** Thumbnail border radius\n@thumbnail-border-radius: @border-radius-base;\n\n//** Custom text color for thumbnail captions\n@thumbnail-caption-color: @text-color;\n//** Padding around the thumbnail caption\n@thumbnail-caption-padding: 9px;\n\n\n//== Wells\n//\n//##\n\n@well-bg: #f5f5f5;\n@well-border: darken(@well-bg, 7%);\n\n\n//== Badges\n//\n//##\n\n@badge-color: #fff;\n//** Linked badge text color on hover\n@badge-link-hover-color: #fff;\n@badge-bg: @gray-light;\n\n//** Badge text color in active nav link\n@badge-active-color: @link-color;\n//** Badge background color in active nav link\n@badge-active-bg: #fff;\n\n@badge-font-weight: bold;\n@badge-line-height: 1;\n@badge-border-radius: 10px;\n\n\n//== Breadcrumbs\n//\n//##\n\n@breadcrumb-padding-vertical: 8px;\n@breadcrumb-padding-horizontal: 15px;\n//** Breadcrumb background color\n@breadcrumb-bg: #f5f5f5;\n//** Breadcrumb text color\n@breadcrumb-color: #ccc;\n//** Text color of current page in the breadcrumb\n@breadcrumb-active-color: @gray-light;\n//** Textual separator for between breadcrumb elements\n@breadcrumb-separator: \"/\";\n\n\n//== Carousel\n//\n//##\n\n@carousel-text-shadow: 0 1px 2px rgba(0,0,0,.6);\n\n@carousel-control-color: #fff;\n@carousel-control-width: 15%;\n@carousel-control-opacity: .5;\n@carousel-control-font-size: 20px;\n\n@carousel-indicator-active-bg: #fff;\n@carousel-indicator-border-color: #fff;\n\n@carousel-caption-color: #fff;\n\n\n//== Close\n//\n//##\n\n@close-font-weight: bold;\n@close-color: #000;\n@close-text-shadow: 0 1px 0 #fff;\n\n\n//== Code\n//\n//##\n\n@code-color: #c7254e;\n@code-bg: #f9f2f4;\n\n@kbd-color: #fff;\n@kbd-bg: #333;\n\n@pre-bg: #f5f5f5;\n@pre-color: @gray-dark;\n@pre-border-color: #ccc;\n@pre-scrollable-max-height: 340px;\n\n\n//== Type\n//\n//##\n\n//** Text muted color\n@text-muted: @gray-light;\n//** Abbreviations and acronyms border color\n@abbr-border-color: @gray-light;\n//** Headings small color\n@headings-small-color: @gray-light;\n//** Blockquote small color\n@blockquote-small-color: @gray-light;\n//** Blockquote font size\n@blockquote-font-size: (@font-size-base * 1.25);\n//** Blockquote border color\n@blockquote-border-color: @gray-lighter;\n//** Page header border color\n@page-header-border-color: @gray-lighter;\n\n\n//== Miscellaneous\n//\n//##\n\n//** Horizontal line color.\n@hr-border: @gray-lighter;\n\n//** Horizontal offset for forms and lists.\n@component-offset-horizontal: 180px;\n","//\n// Thumbnails\n// --------------------------------------------------\n\n\n// Mixin and adjust the regular image class\n.thumbnail {\n display: block;\n padding: @thumbnail-padding;\n margin-bottom: @line-height-computed;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(all .2s ease-in-out);\n\n > img,\n a > img {\n &:extend(.img-responsive);\n margin-left: auto;\n margin-right: auto;\n }\n\n // Add a hover state for linked versions only\n a&:hover,\n a&:focus,\n a&.active {\n border-color: @link-color;\n }\n\n // Image captions\n .caption {\n padding: @thumbnail-caption-padding;\n color: @thumbnail-caption-color;\n }\n}\n","//\n// Carousel\n// --------------------------------------------------\n\n\n// Wrapper for the slide container and indicators\n.carousel {\n position: relative;\n}\n\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n\n > .item {\n display: none;\n position: relative;\n .transition(.6s ease-in-out left);\n\n // Account for jankitude on images\n > img,\n > a > img {\n &:extend(.img-responsive);\n line-height: 1;\n }\n }\n\n > .active,\n > .next,\n > .prev { display: block; }\n\n > .active {\n left: 0;\n }\n\n > .next,\n > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n }\n\n > .next {\n left: 100%;\n }\n > .prev {\n left: -100%;\n }\n > .next.left,\n > .prev.right {\n left: 0;\n }\n\n > .active.left {\n left: -100%;\n }\n > .active.right {\n left: 100%;\n }\n\n}\n\n// Left/right controls for nav\n// ---------------------------\n\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: @carousel-control-width;\n .opacity(@carousel-control-opacity);\n font-size: @carousel-control-font-size;\n color: @carousel-control-color;\n text-align: center;\n text-shadow: @carousel-text-shadow;\n // We can't have this transition here because WebKit cancels the carousel\n // animation if you trip this while in the middle of another animation.\n\n // Set gradients for backgrounds\n &.left {\n #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001));\n }\n &.right {\n left: auto;\n right: 0;\n #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5));\n }\n\n // Hover/focus state\n &:hover,\n &:focus {\n outline: none;\n color: @carousel-control-color;\n text-decoration: none;\n .opacity(.9);\n }\n\n // Toggles\n .icon-prev,\n .icon-next,\n .glyphicon-chevron-left,\n .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n z-index: 5;\n display: inline-block;\n }\n .icon-prev,\n .glyphicon-chevron-left {\n left: 50%;\n }\n .icon-next,\n .glyphicon-chevron-right {\n right: 50%;\n }\n .icon-prev,\n .icon-next {\n width: 20px;\n height: 20px;\n margin-top: -10px;\n margin-left: -10px;\n font-family: serif;\n }\n\n .icon-prev {\n &:before {\n content: '\\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)\n }\n }\n .icon-next {\n &:before {\n content: '\\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)\n }\n }\n}\n\n// Optional indicator pips\n//\n// Add an unordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n\n li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid @carousel-indicator-border-color;\n border-radius: 10px;\n cursor: pointer;\n\n // IE8-9 hack for event handling\n //\n // Internet Explorer 8-9 does not support clicks on elements without a set\n // `background-color`. We cannot use `filter` since that's not viewed as a\n // background color by the browser. Thus, a hack is needed.\n //\n // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we\n // set alpha transparency for the best results possible.\n background-color: #000 \\9; // IE8\n background-color: rgba(0,0,0,0); // IE9\n }\n .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: @carousel-indicator-active-bg;\n }\n}\n\n// Optional captions\n// -----------------------------\n// Hidden by default for smaller viewports\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: @carousel-caption-color;\n text-align: center;\n text-shadow: @carousel-text-shadow;\n & .btn {\n text-shadow: none; // No shadow for button elements in carousel-caption\n }\n}\n\n\n// Scale up controls for tablets and up\n@media screen and (min-width: @screen-sm-min) {\n\n // Scale up the controls a smidge\n .carousel-control {\n .glyphicon-chevron-left,\n .glyphicon-chevron-right,\n .icon-prev,\n .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -15px;\n margin-left: -15px;\n font-size: 30px;\n }\n }\n\n // Show and left align the captions\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n\n // Move up the indicators\n .carousel-indicators {\n bottom: 20px;\n }\n}\n","//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n font-family: @headings-font-family;\n font-weight: @headings-font-weight;\n line-height: @headings-line-height;\n color: @headings-color;\n\n small,\n .small {\n font-weight: normal;\n line-height: 1;\n color: @headings-small-color;\n }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n margin-top: @line-height-computed;\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 65%;\n }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n margin-top: (@line-height-computed / 2);\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 75%;\n }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n margin-bottom: @line-height-computed;\n font-size: floor((@font-size-base * 1.15));\n font-weight: 200;\n line-height: 1.4;\n\n @media (min-width: @screen-sm-min) {\n font-size: (@font-size-base * 1.5);\n }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: 14px base font * 85% = about 12px\nsmall,\n.small { font-size: 85%; }\n\n// Undo browser default styling\ncite { font-style: normal; }\n\n// Alignment\n.text-left { text-align: left; }\n.text-right { text-align: right; }\n.text-center { text-align: center; }\n.text-justify { text-align: justify; }\n\n// Contextual colors\n.text-muted {\n color: @text-muted;\n}\n.text-primary {\n .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n // Given the contrast here, this is the only class to have its color inverted\n // automatically.\n color: #fff;\n .bg-variant(@brand-primary);\n}\n.bg-success {\n .bg-variant(@state-success-bg);\n}\n.bg-info {\n .bg-variant(@state-info-bg);\n}\n.bg-warning {\n .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n padding-bottom: ((@line-height-computed / 2) - 1);\n margin: (@line-height-computed * 2) 0 @line-height-computed;\n border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// --------------------------------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n margin-top: 0;\n margin-bottom: (@line-height-computed / 2);\n ul,\n ol {\n margin-bottom: 0;\n }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n .list-unstyled();\n margin-left: -5px;\n\n > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n }\n}\n\n// Description Lists\ndl {\n margin-top: 0; // Remove browser default\n margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n line-height: @line-height-base;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n@media (min-width: @grid-float-breakpoint) {\n .dl-horizontal {\n dt {\n float: left;\n width: (@component-offset-horizontal - 20);\n clear: left;\n text-align: right;\n .text-overflow();\n }\n dd {\n margin-left: @component-offset-horizontal;\n &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n }\n }\n}\n\n// MISC\n// ----\n\n// Abbreviations and acronyms\nabbr[title],\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted @abbr-border-color;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\n\n// Blockquotes\nblockquote {\n padding: (@line-height-computed / 2) @line-height-computed;\n margin: 0 0 @line-height-computed;\n font-size: @blockquote-font-size;\n border-left: 5px solid @blockquote-border-color;\n\n p,\n ul,\n ol {\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n // Note: Deprecated small and .small as of v3.1.0\n // Context: https://github.com/twbs/bootstrap/issues/11660\n footer,\n small,\n .small {\n display: block;\n font-size: 80%; // back to default font-size\n line-height: @line-height-base;\n color: @blockquote-small-color;\n\n &:before {\n content: '\\2014 \\00A0'; // em dash, nbsp\n }\n }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid @blockquote-border-color;\n border-left: 0;\n text-align: right;\n\n // Account for citation\n footer,\n small,\n .small {\n &:before { content: ''; }\n &:after {\n content: '\\00A0 \\2014'; // nbsp, em dash\n }\n }\n}\n\n// Quotes\nblockquote:before,\nblockquote:after {\n content: \"\";\n}\n\n// Addresses\naddress {\n margin-bottom: @line-height-computed;\n font-style: normal;\n line-height: @line-height-base;\n}\n","//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: @code-color;\n background-color: @code-bg;\n white-space: nowrap;\n border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: @kbd-color;\n background-color: @kbd-bg;\n border-radius: @border-radius-small;\n box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);\n}\n\n// Blocks of code\npre {\n display: block;\n padding: ((@line-height-computed - 1) / 2);\n margin: 0 0 (@line-height-computed / 2);\n font-size: (@font-size-base - 1); // 14px to 13px\n line-height: @line-height-base;\n word-break: break-all;\n word-wrap: break-word;\n color: @pre-color;\n background-color: @pre-bg;\n border: 1px solid @pre-border-color;\n border-radius: @border-radius-base;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: @pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n .container-fixed();\n\n @media (min-width: @screen-sm-min) {\n width: @container-sm;\n }\n @media (min-width: @screen-md-min) {\n width: @container-md;\n }\n @media (min-width: @screen-lg-min) {\n width: @container-lg;\n }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n .make-row();\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n .make-grid(lg);\n}\n","//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n max-width: 100%;\n background-color: @table-bg;\n}\nth {\n text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n width: 100%;\n margin-bottom: @line-height-computed;\n // Cells\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-cell-padding;\n line-height: @line-height-base;\n vertical-align: top;\n border-top: 1px solid @table-border-color;\n }\n }\n }\n // Bottom align for column headings\n > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid @table-border-color;\n }\n // Remove top border from thead by default\n > caption + thead,\n > colgroup + thead,\n > thead:first-child {\n > tr:first-child {\n > th,\n > td {\n border-top: 0;\n }\n }\n }\n // Account for multiple tbody instances\n > tbody + tbody {\n border-top: 2px solid @table-border-color;\n }\n\n // Nesting\n .table {\n background-color: @body-bg;\n }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-condensed-cell-padding;\n }\n }\n }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n border: 1px solid @table-border-color;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n border: 1px solid @table-border-color;\n }\n }\n }\n > thead > tr {\n > th,\n > td {\n border-bottom-width: 2px;\n }\n }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n > tbody > tr:nth-child(odd) {\n > td,\n > th {\n background-color: @table-bg-accent;\n }\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n > tbody > tr:hover {\n > td,\n > th {\n background-color: @table-bg-hover;\n }\n }\n}\n\n\n// Table cell sizing\n//\n// Reset default table behavior\n\ntable col[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9/10 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-column;\n}\ntable {\n td,\n th {\n &[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9/10 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-cell;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n@media (max-width: @screen-xs-max) {\n .table-responsive {\n width: 100%;\n margin-bottom: (@line-height-computed * 0.75);\n overflow-y: hidden;\n overflow-x: scroll;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid @table-border-color;\n -webkit-overflow-scrolling: touch;\n\n // Tighten up spacing\n > .table {\n margin-bottom: 0;\n\n // Ensure the content doesn't wrap\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n white-space: nowrap;\n }\n }\n }\n }\n\n // Special overrides for the bordered tables\n > .table-bordered {\n border: 0;\n\n // Nuke the appropriate borders so that the parent can handle them\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n\n // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n // chances are there will be only one `tr` in a `thead` and that would\n // remove the border altogether.\n > tbody,\n > tfoot {\n > tr:last-child {\n > th,\n > td {\n border-bottom: 0;\n }\n }\n }\n\n }\n }\n}\n","//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n // Chrome and Firefox set a `min-width: -webkit-min-content;` on fieldsets,\n // so we reset that to ensure it behaves more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359.\n min-width: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: @line-height-computed;\n font-size: (@font-size-base * 1.5);\n line-height: inherit;\n color: @legend-color;\n border: 0;\n border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: 5px;\n font-weight: bold;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9; /* IE8-9 */\n line-height: normal;\n}\n\n// Set the height of file controls to match text inputs\ninput[type=\"file\"] {\n display: block;\n}\n\n// Make range inputs behave like textual form controls\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n height: auto;\n}\n\n// Focus for file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n .tab-focus();\n}\n\n// Adjust output element\noutput {\n display: block;\n padding-top: (@padding-base-vertical + 1);\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n display: block;\n width: 100%;\n height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n background-color: @input-bg;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid @input-border;\n border-radius: @input-border-radius;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n // Customize the `:focus` state to imitate native WebKit styles.\n .form-control-focus();\n\n // Placeholder\n .placeholder();\n\n // Disabled and read-only inputs\n //\n // HTML5 says that controls under a fieldset > legend:first-child won't be\n // disabled if the fieldset is disabled. Due to implementation difficulty, we\n // don't honor that edge case; we style them as disabled anyway.\n &[disabled],\n &[readonly],\n fieldset[disabled] & {\n cursor: not-allowed;\n background-color: @input-bg-disabled;\n opacity: 1; // iOS fix for unreadable disabled content\n }\n\n // Reset height for `textarea`s\n textarea& {\n height: auto;\n }\n}\n\n\n// Search inputs in iOS\n//\n// This overrides the extra rounded corners on search inputs in iOS so that our\n// `.form-control` class can properly style them. Note that this cannot simply\n// be added to `.form-control` as it's not specific enough. For details, see\n// https://github.com/twbs/bootstrap/issues/11586.\n\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n\n\n// Special styles for iOS date input\n//\n// In Mobile Safari, date inputs require a pixel line-height that matches the\n// given height of the input.\n\ninput[type=\"date\"] {\n line-height: @input-height-base;\n}\n\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n margin-bottom: 15px;\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.radio,\n.checkbox {\n display: block;\n min-height: @line-height-computed; // clear the floating input if there is no label text\n margin-top: 10px;\n margin-bottom: 10px;\n padding-left: 20px;\n label {\n display: inline;\n font-weight: normal;\n cursor: pointer;\n }\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n float: left;\n margin-left: -20px;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing\n}\n\n// Radios and checkboxes on same line\n.radio-inline,\n.checkbox-inline {\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px; // space out consecutive inline controls\n}\n\n// Apply same disabled cursor tweak as for inputs\n//\n// Note: Neither radios nor checkboxes can be readonly.\ninput[type=\"radio\"],\ninput[type=\"checkbox\"],\n.radio,\n.radio-inline,\n.checkbox,\n.checkbox-inline {\n &[disabled],\n fieldset[disabled] & {\n cursor: not-allowed;\n }\n}\n\n\n// Form control sizing\n//\n// Build on `.form-control` with modifier classes to decrease or increase the\n// height and font-size of form controls.\n\n.input-sm {\n .input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n\n.input-lg {\n .input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n\n\n// Form control feedback states\n//\n// Apply contextual and semantic states to individual form controls.\n\n.has-feedback {\n // Enable absolute positioning\n position: relative;\n\n // Ensure icons don't overlap text\n .form-control {\n padding-right: (@input-height-base * 1.25);\n }\n\n // Feedback icon (requires .glyphicon classes)\n .form-control-feedback {\n position: absolute;\n top: (@line-height-computed + 5); // Height of the `label` and its margin\n right: 0;\n display: block;\n width: @input-height-base;\n height: @input-height-base;\n line-height: @input-height-base;\n text-align: center;\n }\n}\n\n// Feedback states\n.has-success {\n .form-control-validation(@state-success-text; @state-success-text; @state-success-bg);\n}\n.has-warning {\n .form-control-validation(@state-warning-text; @state-warning-text; @state-warning-bg);\n}\n.has-error {\n .form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg);\n}\n\n\n// Static form control text\n//\n// Apply class to a `p` element to make any string of text align with labels in\n// a horizontal form layout.\n\n.form-control-static {\n margin-bottom: 0; // Remove default margin from `p`\n}\n\n\n// Help text\n//\n// Apply to any element you wish to create light text for placement immediately\n// below a form control. Use for general help, formatting, or instructional text.\n\n.help-block {\n display: block; // account for any element using help-block\n margin-top: 5px;\n margin-bottom: 10px;\n color: lighten(@text-color, 25%); // lighten the text some for contrast\n}\n\n\n\n// Inline forms\n//\n// Make forms appear inline(-block) by adding the `.form-inline` class. Inline\n// forms begin stacked on extra small (mobile) devices and then go inline when\n// viewports reach <768px.\n//\n// Requires wrapping inputs and labels with `.form-group` for proper display of\n// default HTML form controls and our custom form controls (e.g., input groups).\n//\n// Heads up! This is mixin-ed into `.navbar-form` in navbars.less.\n\n.form-inline {\n\n // Kick in the inline\n @media (min-width: @screen-sm-min) {\n // Inline-block all the things for \"inline\"\n .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n\n // In navbar-form, allow folks to *not* use `.form-group`\n .form-control {\n display: inline-block;\n width: auto; // Prevent labels from stacking above inputs in `.form-group`\n vertical-align: middle;\n }\n // Input groups need that 100% width though\n .input-group > .form-control {\n width: 100%;\n }\n\n .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n\n // Remove default margin on radios/checkboxes that were used for stacking, and\n // then undo the floating of radios and checkboxes to match (which also avoids\n // a bug in WebKit: https://github.com/twbs/bootstrap/issues/1969).\n .radio,\n .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 0;\n vertical-align: middle;\n }\n .radio input[type=\"radio\"],\n .checkbox input[type=\"checkbox\"] {\n float: none;\n margin-left: 0;\n }\n\n // Validation states\n //\n // Reposition the icon because it's now within a grid column and columns have\n // `position: relative;` on them. Also accounts for the grid gutter padding.\n .has-feedback .form-control-feedback {\n top: 0;\n }\n }\n}\n\n\n// Horizontal forms\n//\n// Horizontal forms are built on grid classes and allow you to create forms with\n// labels on the left and inputs on the right.\n\n.form-horizontal {\n\n // Consistent vertical alignment of labels, radios, and checkboxes\n .control-label,\n .radio,\n .checkbox,\n .radio-inline,\n .checkbox-inline {\n margin-top: 0;\n margin-bottom: 0;\n padding-top: (@padding-base-vertical + 1); // Default padding plus a border\n }\n // Account for padding we're adding to ensure the alignment and of help text\n // and other content below items\n .radio,\n .checkbox {\n min-height: (@line-height-computed + (@padding-base-vertical + 1));\n }\n\n // Make form groups behave like rows\n .form-group {\n .make-row();\n }\n\n .form-control-static {\n padding-top: (@padding-base-vertical + 1);\n }\n\n // Only right align form labels here when the columns stop stacking\n @media (min-width: @screen-sm-min) {\n .control-label {\n text-align: right;\n }\n }\n\n // Validation states\n //\n // Reposition the icon because it's now within a grid column and columns have\n // `position: relative;` on them. Also accounts for the grid gutter padding.\n .has-feedback .form-control-feedback {\n top: 0;\n right: (@grid-gutter-width / 2);\n }\n}\n","//\n// Buttons\n// --------------------------------------------------\n\n\n// Base styles\n// --------------------------------------------------\n\n.btn {\n display: inline-block;\n margin-bottom: 0; // For input.btn\n font-weight: @btn-font-weight;\n text-align: center;\n vertical-align: middle;\n cursor: pointer;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n white-space: nowrap;\n .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @border-radius-base);\n .user-select(none);\n\n &,\n &:active,\n &.active {\n &:focus {\n .tab-focus();\n }\n }\n\n &:hover,\n &:focus {\n color: @btn-default-color;\n text-decoration: none;\n }\n\n &:active,\n &.active {\n outline: 0;\n background-image: none;\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n cursor: not-allowed;\n pointer-events: none; // Future-proof disabling of clicks\n .opacity(.65);\n .box-shadow(none);\n }\n}\n\n\n// Alternate buttons\n// --------------------------------------------------\n\n.btn-default {\n .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);\n}\n.btn-primary {\n .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);\n}\n// Success appears as green\n.btn-success {\n .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);\n}\n// Info appears as blue-green\n.btn-info {\n .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);\n}\n// Warning appears as orange\n.btn-warning {\n .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);\n}\n// Danger and error appear as red\n.btn-danger {\n .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);\n}\n\n\n// Link buttons\n// -------------------------\n\n// Make a button look and behave like a link\n.btn-link {\n color: @link-color;\n font-weight: normal;\n cursor: pointer;\n border-radius: 0;\n\n &,\n &:active,\n &[disabled],\n fieldset[disabled] & {\n background-color: transparent;\n .box-shadow(none);\n }\n &,\n &:hover,\n &:focus,\n &:active {\n border-color: transparent;\n }\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: underline;\n background-color: transparent;\n }\n &[disabled],\n fieldset[disabled] & {\n &:hover,\n &:focus {\n color: @btn-link-disabled-color;\n text-decoration: none;\n }\n }\n}\n\n\n// Button Sizes\n// --------------------------------------------------\n\n.btn-lg {\n // line-height: ensure even-numbered height of button next to large input\n .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n.btn-sm {\n // line-height: ensure proper height of button next to small input\n .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n.btn-xs {\n .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n\n\n// Block button\n// --------------------------------------------------\n\n.btn-block {\n display: block;\n width: 100%;\n padding-left: 0;\n padding-right: 0;\n}\n\n// Vertically space out multiple block buttons\n.btn-block + .btn-block {\n margin-top: 5px;\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n &.btn-block {\n width: 100%;\n }\n}\n","//\n// Button groups\n// --------------------------------------------------\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle; // match .btn alignment given font-size hack above\n > .btn {\n position: relative;\n float: left;\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active,\n &.active {\n z-index: 2;\n }\n &:focus {\n // Remove focus outline when dropdown JS adds it after closing the menu\n outline: none;\n }\n }\n}\n\n// Prevent double borders when buttons are next to each other\n.btn-group {\n .btn + .btn,\n .btn + .btn-group,\n .btn-group + .btn,\n .btn-group + .btn-group {\n margin-left: -1px;\n }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n margin-left: -5px; // Offset the first child's margin\n &:extend(.clearfix all);\n\n .btn-group,\n .input-group {\n float: left;\n }\n > .btn,\n > .btn-group,\n > .input-group {\n margin-left: 5px;\n }\n}\n\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n\n// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match\n.btn-group > .btn:first-child {\n margin-left: 0;\n &:not(:last-child):not(.dropdown-toggle) {\n .border-right-radius(0);\n }\n}\n// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n .border-left-radius(0);\n}\n\n// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-right-radius(0);\n }\n}\n.btn-group > .btn-group:last-child > .btn:first-child {\n .border-left-radius(0);\n}\n\n// On active and open, don't show outline\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-xs > .btn { &:extend(.btn-xs); }\n.btn-group-sm > .btn { &:extend(.btn-sm); }\n.btn-group-lg > .btn { &:extend(.btn-lg); }\n\n\n// Split button dropdowns\n// ----------------------\n\n// Give the line between buttons some depth\n.btn-group > .btn + .dropdown-toggle {\n padding-left: 8px;\n padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-left: 12px;\n padding-right: 12px;\n}\n\n// The clickable button for toggling the menu\n// Remove the gradient and set the same inset shadow as the :active state\n.btn-group.open .dropdown-toggle {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n\n // Show no shadow for `.btn-link` since it has no other button styles.\n &.btn-link {\n .box-shadow(none);\n }\n}\n\n\n// Reposition the caret\n.btn .caret {\n margin-left: 0;\n}\n// Carets in other button sizes\n.btn-lg .caret {\n border-width: @caret-width-large @caret-width-large 0;\n border-bottom-width: 0;\n}\n// Upside down carets for .dropup\n.dropup .btn-lg .caret {\n border-width: 0 @caret-width-large @caret-width-large;\n}\n\n\n// Vertical button groups\n// ----------------------\n\n.btn-group-vertical {\n > .btn,\n > .btn-group,\n > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n }\n\n // Clear floats so dropdown menus can be properly placed\n > .btn-group {\n &:extend(.clearfix all);\n > .btn {\n float: none;\n }\n }\n\n > .btn + .btn,\n > .btn + .btn-group,\n > .btn-group + .btn,\n > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n }\n}\n\n.btn-group-vertical > .btn {\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n &:first-child:not(:last-child) {\n border-top-right-radius: @border-radius-base;\n .border-bottom-radius(0);\n }\n &:last-child:not(:first-child) {\n border-bottom-left-radius: @border-radius-base;\n .border-top-radius(0);\n }\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) {\n > .btn:last-child,\n > .dropdown-toggle {\n .border-bottom-radius(0);\n }\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n .border-top-radius(0);\n}\n\n\n\n// Justified button groups\n// ----------------------\n\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n > .btn,\n > .btn-group {\n float: none;\n display: table-cell;\n width: 1%;\n }\n > .btn-group .btn {\n width: 100%;\n }\n}\n\n\n// Checkbox and radio options\n[data-toggle=\"buttons\"] > .btn > input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn > input[type=\"checkbox\"] {\n display: none;\n}\n","//\n// Component animations\n// --------------------------------------------------\n\n// Heads up!\n//\n// We don't use the `.opacity()` mixin here since it causes a bug with text\n// fields in IE7-8. Source: https://github.com/twitter/bootstrap/pull/3552.\n\n.fade {\n opacity: 0;\n .transition(opacity .15s linear);\n &.in {\n opacity: 1;\n }\n}\n\n.collapse {\n display: none;\n &.in {\n display: block;\n }\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n .transition(height .35s ease);\n}\n","//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n// Star\n\n// Import the fonts\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: ~\"url('@{icon-font-path}@{icon-font-name}.eot')\";\n src: ~\"url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype')\",\n ~\"url('@{icon-font-path}@{icon-font-name}.woff') format('woff')\",\n ~\"url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype')\",\n ~\"url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg')\";\n}\n\n// Catchall baseclass\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk { &:before { content: \"\\2a\"; } }\n.glyphicon-plus { &:before { content: \"\\2b\"; } }\n.glyphicon-euro { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil { &:before { content: \"\\270f\"; } }\n.glyphicon-glass { &:before { content: \"\\e001\"; } }\n.glyphicon-music { &:before { content: \"\\e002\"; } }\n.glyphicon-search { &:before { content: \"\\e003\"; } }\n.glyphicon-heart { &:before { content: \"\\e005\"; } }\n.glyphicon-star { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty { &:before { content: \"\\e007\"; } }\n.glyphicon-user { &:before { content: \"\\e008\"; } }\n.glyphicon-film { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large { &:before { content: \"\\e010\"; } }\n.glyphicon-th { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list { &:before { content: \"\\e012\"; } }\n.glyphicon-ok { &:before { content: \"\\e013\"; } }\n.glyphicon-remove { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out { &:before { content: \"\\e016\"; } }\n.glyphicon-off { &:before { content: \"\\e017\"; } }\n.glyphicon-signal { &:before { content: \"\\e018\"; } }\n.glyphicon-cog { &:before { content: \"\\e019\"; } }\n.glyphicon-trash { &:before { content: \"\\e020\"; } }\n.glyphicon-home { &:before { content: \"\\e021\"; } }\n.glyphicon-file { &:before { content: \"\\e022\"; } }\n.glyphicon-time { &:before { content: \"\\e023\"; } }\n.glyphicon-road { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt { &:before { content: \"\\e025\"; } }\n.glyphicon-download { &:before { content: \"\\e026\"; } }\n.glyphicon-upload { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt { &:before { content: \"\\e032\"; } }\n.glyphicon-lock { &:before { content: \"\\e033\"; } }\n.glyphicon-flag { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode { &:before { content: \"\\e040\"; } }\n.glyphicon-tag { &:before { content: \"\\e041\"; } }\n.glyphicon-tags { &:before { content: \"\\e042\"; } }\n.glyphicon-book { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark { &:before { content: \"\\e044\"; } }\n.glyphicon-print { &:before { content: \"\\e045\"; } }\n.glyphicon-camera { &:before { content: \"\\e046\"; } }\n.glyphicon-font { &:before { content: \"\\e047\"; } }\n.glyphicon-bold { &:before { content: \"\\e048\"; } }\n.glyphicon-italic { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify { &:before { content: \"\\e055\"; } }\n.glyphicon-list { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video { &:before { content: \"\\e059\"; } }\n.glyphicon-picture { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust { &:before { content: \"\\e063\"; } }\n.glyphicon-tint { &:before { content: \"\\e064\"; } }\n.glyphicon-edit { &:before { content: \"\\e065\"; } }\n.glyphicon-share { &:before { content: \"\\e066\"; } }\n.glyphicon-check { &:before { content: \"\\e067\"; } }\n.glyphicon-move { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward { &:before { content: \"\\e070\"; } }\n.glyphicon-backward { &:before { content: \"\\e071\"; } }\n.glyphicon-play { &:before { content: \"\\e072\"; } }\n.glyphicon-pause { &:before { content: \"\\e073\"; } }\n.glyphicon-stop { &:before { content: \"\\e074\"; } }\n.glyphicon-forward { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward { &:before { content: \"\\e077\"; } }\n.glyphicon-eject { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign { &:before { content: \"\\e101\"; } }\n.glyphicon-gift { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf { &:before { content: \"\\e103\"; } }\n.glyphicon-fire { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign { &:before { content: \"\\e107\"; } }\n.glyphicon-plane { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar { &:before { content: \"\\e109\"; } }\n.glyphicon-random { &:before { content: \"\\e110\"; } }\n.glyphicon-comment { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn { &:before { content: \"\\e122\"; } }\n.glyphicon-bell { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down { &:before { content: \"\\e134\"; } }\n.glyphicon-globe { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks { &:before { content: \"\\e137\"; } }\n.glyphicon-filter { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty { &:before { content: \"\\e143\"; } }\n.glyphicon-link { &:before { content: \"\\e144\"; } }\n.glyphicon-phone { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin { &:before { content: \"\\e146\"; } }\n.glyphicon-usd { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp { &:before { content: \"\\e149\"; } }\n.glyphicon-sort { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked { &:before { content: \"\\e157\"; } }\n.glyphicon-expand { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in { &:before { content: \"\\e161\"; } }\n.glyphicon-flash { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window { &:before { content: \"\\e164\"; } }\n.glyphicon-record { &:before { content: \"\\e165\"; } }\n.glyphicon-save { &:before { content: \"\\e166\"; } }\n.glyphicon-open { &:before { content: \"\\e167\"; } }\n.glyphicon-saved { &:before { content: \"\\e168\"; } }\n.glyphicon-import { &:before { content: \"\\e169\"; } }\n.glyphicon-export { &:before { content: \"\\e170\"; } }\n.glyphicon-send { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery { &:before { content: \"\\e179\"; } }\n.glyphicon-header { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt { &:before { content: \"\\e183\"; } }\n.glyphicon-tower { &:before { content: \"\\e184\"; } }\n.glyphicon-stats { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1 { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1 { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1 { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous { &:before { content: \"\\e200\"; } }\n","//\n// Dropdown menus\n// --------------------------------------------------\n\n\n// Dropdown arrow/caret\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: @caret-width-base solid;\n border-right: @caret-width-base solid transparent;\n border-left: @caret-width-base solid transparent;\n}\n\n// The dropdown wrapper (div)\n.dropdown {\n position: relative;\n}\n\n// Prevent the focus on the dropdown toggle when closing dropdowns\n.dropdown-toggle:focus {\n outline: 0;\n}\n\n// The dropdown menu (ul)\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: @zindex-dropdown;\n display: none; // none by default, but block on \"open\" of the menu\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0; // override default ul\n list-style: none;\n font-size: @font-size-base;\n background-color: @dropdown-bg;\n border: 1px solid @dropdown-fallback-border; // IE8 fallback\n border: 1px solid @dropdown-border;\n border-radius: @border-radius-base;\n .box-shadow(0 6px 12px rgba(0,0,0,.175));\n background-clip: padding-box;\n\n // Aligns the dropdown menu to right\n //\n // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`\n &.pull-right {\n right: 0;\n left: auto;\n }\n\n // Dividers (basically an hr) within the dropdown\n .divider {\n .nav-divider(@dropdown-divider-bg);\n }\n\n // Links within the dropdown menu\n > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: @line-height-base;\n color: @dropdown-link-color;\n white-space: nowrap; // prevent links from randomly breaking onto new lines\n }\n}\n\n// Hover/Focus state\n.dropdown-menu > li > a {\n &:hover,\n &:focus {\n text-decoration: none;\n color: @dropdown-link-hover-color;\n background-color: @dropdown-link-hover-bg;\n }\n}\n\n// Active state\n.dropdown-menu > .active > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-active-color;\n text-decoration: none;\n outline: 0;\n background-color: @dropdown-link-active-bg;\n }\n}\n\n// Disabled state\n//\n// Gray out text and ensure the hover/focus state remains gray\n\n.dropdown-menu > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @dropdown-link-disabled-color;\n }\n}\n// Nuke hover/focus effects\n.dropdown-menu > .disabled > a {\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: transparent;\n background-image: none; // Remove CSS gradient\n .reset-filter();\n cursor: not-allowed;\n }\n}\n\n// Open state for the dropdown\n.open {\n // Show the menu\n > .dropdown-menu {\n display: block;\n }\n\n // Remove the outline when :focus is triggered\n > a {\n outline: 0;\n }\n}\n\n// Menu positioning\n//\n// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown\n// menu with the parent.\n.dropdown-menu-right {\n left: auto; // Reset the default from `.dropdown-menu`\n right: 0;\n}\n// With v3, we enabled auto-flipping if you have a dropdown within a right\n// aligned nav component. To enable the undoing of that, we provide an override\n// to restore the default dropdown menu alignment.\n//\n// This is only for left-aligning a dropdown menu within a `.navbar-right` or\n// `.pull-right` nav component.\n.dropdown-menu-left {\n left: 0;\n right: auto;\n}\n\n// Dropdown section headers\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: @font-size-small;\n line-height: @line-height-base;\n color: @dropdown-header-color;\n}\n\n// Backdrop to catch body clicks on mobile, etc.\n.dropdown-backdrop {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n top: 0;\n z-index: (@zindex-dropdown - 10);\n}\n\n// Right aligned dropdowns\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n//\n// Just add .dropup after the standard .dropdown class and you're set, bro.\n// TODO: abstract this so that the navbar fixed styles are not placed here?\n\n.dropup,\n.navbar-fixed-bottom .dropdown {\n // Reverse the caret\n .caret {\n border-top: 0;\n border-bottom: @caret-width-base solid;\n content: \"\";\n }\n // Different positioning for bottom up menu\n .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 1px;\n }\n}\n\n\n// Component alignment\n//\n// Reiterate per navbar.less and the modified component alignment there.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-right {\n .dropdown-menu {\n .dropdown-menu-right();\n }\n // Necessary for overrides of the default right aligned menu.\n // Will remove come v4 in all likelihood.\n .dropdown-menu-left {\n .dropdown-menu-left();\n }\n }\n}\n\n","//\n// Input groups\n// --------------------------------------------------\n\n// Base styles\n// -------------------------\n.input-group {\n position: relative; // For dropdowns\n display: table;\n border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table\n\n // Undo padding and float of grid classes\n &[class*=\"col-\"] {\n float: none;\n padding-left: 0;\n padding-right: 0;\n }\n\n .form-control {\n // Ensure that the input is always above the *appended* addon button for\n // proper border colors.\n position: relative;\n z-index: 2;\n\n // IE9 fubars the placeholder attribute in text inputs and the arrows on\n // select elements in input groups. To fix it, we float the input. Details:\n // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855\n float: left;\n\n width: 100%;\n margin-bottom: 0;\n }\n}\n\n// Sizing options\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn { .input-lg(); }\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn { .input-sm(); }\n\n\n// Display as table-cell\n// -------------------------\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n\n &:not(:first-child):not(:last-child) {\n border-radius: 0;\n }\n}\n// Addon and addon wrapper for buttons\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle; // Match the inputs\n}\n\n// Text input groups\n// -------------------------\n.input-group-addon {\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n font-weight: normal;\n line-height: 1;\n color: @input-color;\n text-align: center;\n background-color: @input-group-addon-bg;\n border: 1px solid @input-group-addon-border-color;\n border-radius: @border-radius-base;\n\n // Sizing\n &.input-sm {\n padding: @padding-small-vertical @padding-small-horizontal;\n font-size: @font-size-small;\n border-radius: @border-radius-small;\n }\n &.input-lg {\n padding: @padding-large-vertical @padding-large-horizontal;\n font-size: @font-size-large;\n border-radius: @border-radius-large;\n }\n\n // Nuke default margins from checkboxes and radios to vertically center within.\n input[type=\"radio\"],\n input[type=\"checkbox\"] {\n margin-top: 0;\n }\n}\n\n// Reset rounded corners\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n .border-right-radius(0);\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n .border-left-radius(0);\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n\n// Button input groups\n// -------------------------\n.input-group-btn {\n position: relative;\n // Jankily prevent input button groups from wrapping with `white-space` and\n // `font-size` in combination with `inline-block` on buttons.\n font-size: 0;\n white-space: nowrap;\n\n // Negative margin for spacing, position for bringing hovered/focused/actived\n // element above the siblings.\n > .btn {\n position: relative;\n + .btn {\n margin-left: -1px;\n }\n // Bring the \"active\" button to the front\n &:hover,\n &:focus,\n &:active {\n z-index: 2;\n }\n }\n\n // Negative margin to only have a 1px border between the two\n &:first-child {\n > .btn,\n > .btn-group {\n margin-right: -1px;\n }\n }\n &:last-child {\n > .btn,\n > .btn-group {\n margin-left: -1px;\n }\n }\n}\n","//\n// Navs\n// --------------------------------------------------\n\n\n// Base class\n// --------------------------------------------------\n\n.nav {\n margin-bottom: 0;\n padding-left: 0; // Override default ul/ol\n list-style: none;\n &:extend(.clearfix all);\n\n > li {\n position: relative;\n display: block;\n\n > a {\n position: relative;\n display: block;\n padding: @nav-link-padding;\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: @nav-link-hover-bg;\n }\n }\n\n // Disabled state sets text to gray and nukes hover/tab effects\n &.disabled > a {\n color: @nav-disabled-link-color;\n\n &:hover,\n &:focus {\n color: @nav-disabled-link-hover-color;\n text-decoration: none;\n background-color: transparent;\n cursor: not-allowed;\n }\n }\n }\n\n // Open dropdowns\n .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @nav-link-hover-bg;\n border-color: @link-color;\n }\n }\n\n // Nav dividers (deprecated with v3.0.1)\n //\n // This should have been removed in v3 with the dropping of `.nav-list`, but\n // we missed it. We don't currently support this anywhere, but in the interest\n // of maintaining backward compatibility in case you use it, it's deprecated.\n .nav-divider {\n .nav-divider();\n }\n\n // Prevent IE8 from misplacing imgs\n //\n // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989\n > li > a > img {\n max-width: none;\n }\n}\n\n\n// Tabs\n// -------------------------\n\n// Give the tabs something to sit on\n.nav-tabs {\n border-bottom: 1px solid @nav-tabs-border-color;\n > li {\n float: left;\n // Make the list-items overlay the bottom border\n margin-bottom: -1px;\n\n // Actual tabs (as links)\n > a {\n margin-right: 2px;\n line-height: @line-height-base;\n border: 1px solid transparent;\n border-radius: @border-radius-base @border-radius-base 0 0;\n &:hover {\n border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color;\n }\n }\n\n // Active state, and its :hover to override normal :hover\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-tabs-active-link-hover-color;\n background-color: @nav-tabs-active-link-hover-bg;\n border: 1px solid @nav-tabs-active-link-hover-border-color;\n border-bottom-color: transparent;\n cursor: default;\n }\n }\n }\n // pulling this in mainly for less shorthand\n &.nav-justified {\n .nav-justified();\n .nav-tabs-justified();\n }\n}\n\n\n// Pills\n// -------------------------\n.nav-pills {\n > li {\n float: left;\n\n // Links rendered as pills\n > a {\n border-radius: @nav-pills-border-radius;\n }\n + li {\n margin-left: 2px;\n }\n\n // Active state\n &.active > a {\n &,\n &:hover,\n &:focus {\n color: @nav-pills-active-link-hover-color;\n background-color: @nav-pills-active-link-hover-bg;\n }\n }\n }\n}\n\n\n// Stacked pills\n.nav-stacked {\n > li {\n float: none;\n + li {\n margin-top: 2px;\n margin-left: 0; // no need for this gap between nav items\n }\n }\n}\n\n\n// Nav variations\n// --------------------------------------------------\n\n// Justified nav links\n// -------------------------\n\n.nav-justified {\n width: 100%;\n\n > li {\n float: none;\n > a {\n text-align: center;\n margin-bottom: 5px;\n }\n }\n\n > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n }\n\n @media (min-width: @screen-sm-min) {\n > li {\n display: table-cell;\n width: 1%;\n > a {\n margin-bottom: 0;\n }\n }\n }\n}\n\n// Move borders to anchors instead of bottom of list\n//\n// Mixin for adding on top the shared `.nav-justified` styles for our tabs\n.nav-tabs-justified {\n border-bottom: 0;\n\n > li > a {\n // Override margin from .nav-tabs\n margin-right: 0;\n border-radius: @border-radius-base;\n }\n\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border: 1px solid @nav-tabs-justified-link-border-color;\n }\n\n @media (min-width: @screen-sm-min) {\n > li > a {\n border-bottom: 1px solid @nav-tabs-justified-link-border-color;\n border-radius: @border-radius-base @border-radius-base 0 0;\n }\n > .active > a,\n > .active > a:hover,\n > .active > a:focus {\n border-bottom-color: @nav-tabs-justified-active-link-border-color;\n }\n }\n}\n\n\n// Tabbable tabs\n// -------------------------\n\n// Hide tabbable panes to start, show them when `.active`\n.tab-content {\n > .tab-pane {\n display: none;\n }\n > .active {\n display: block;\n }\n}\n\n\n// Dropdowns\n// -------------------------\n\n// Specific dropdowns\n.nav-tabs .dropdown-menu {\n // make dropdown border overlap tab border\n margin-top: -1px;\n // Remove the top rounded corners here since there is a hard edge above the menu\n .border-top-radius(0);\n}\n","//\n// Navbars\n// --------------------------------------------------\n\n\n// Wrapper and base class\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n position: relative;\n min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)\n margin-bottom: @navbar-margin-bottom;\n border: 1px solid transparent;\n\n // Prevent floats from breaking the navbar\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: @navbar-border-radius;\n }\n}\n\n\n// Navbar heading\n//\n// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy\n// styling of responsive aspects.\n\n.navbar-header {\n &:extend(.clearfix all);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n }\n}\n\n\n// Navbar collapse (body)\n//\n// Group your navbar content into this for easy collapsing and expanding across\n// various device sizes. By default, this content is collapsed when <768px, but\n// will expand past that for a horizontal display.\n//\n// To start (on mobile devices) the navbar links, forms, and buttons are stacked\n// vertically and include a `max-height` to overflow in case you have too much\n// content for the user's viewport.\n\n.navbar-collapse {\n max-height: @navbar-collapse-max-height;\n overflow-x: visible;\n padding-right: @navbar-padding-horizontal;\n padding-left: @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255,255,255,.1);\n &:extend(.clearfix all);\n -webkit-overflow-scrolling: touch;\n\n &.in {\n overflow-y: auto;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border-top: 0;\n box-shadow: none;\n\n &.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0; // Override default setting\n overflow: visible !important;\n }\n\n &.in {\n overflow-y: visible;\n }\n\n // Undo the collapse side padding for navbars with containers to ensure\n // alignment of right-aligned contents.\n .navbar-fixed-top &,\n .navbar-static-top &,\n .navbar-fixed-bottom & {\n padding-left: 0;\n padding-right: 0;\n }\n }\n}\n\n\n// Both navbar header and collapse\n//\n// When a container is present, change the behavior of the header and collapse.\n\n.container,\n.container-fluid {\n > .navbar-header,\n > .navbar-collapse {\n margin-right: -@navbar-padding-horizontal;\n margin-left: -@navbar-padding-horizontal;\n\n @media (min-width: @grid-float-breakpoint) {\n margin-right: 0;\n margin-left: 0;\n }\n }\n}\n\n\n//\n// Navbar alignment options\n//\n// Display the navbar across the entirety of the page or fixed it to the top or\n// bottom of the page.\n\n// Static top (unfixed, but 100% wide) navbar\n.navbar-static-top {\n z-index: @zindex-navbar;\n border-width: 0 0 1px;\n\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n\n// Fix the top/bottom navbars when screen real estate supports it\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: @zindex-navbar-fixed;\n\n // Undo the rounded corners\n @media (min-width: @grid-float-breakpoint) {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0; // override .navbar defaults\n border-width: 1px 0 0;\n}\n\n\n// Brand/project name\n\n.navbar-brand {\n float: left;\n padding: @navbar-padding-vertical @navbar-padding-horizontal;\n font-size: @font-size-large;\n line-height: @line-height-computed;\n height: @navbar-height;\n\n &:hover,\n &:focus {\n text-decoration: none;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n .navbar > .container &,\n .navbar > .container-fluid & {\n margin-left: -@navbar-padding-horizontal;\n }\n }\n}\n\n\n// Navbar toggle\n//\n// Custom button for toggling the `.navbar-collapse`, powered by the collapse\n// JavaScript plugin.\n\n.navbar-toggle {\n position: relative;\n float: right;\n margin-right: @navbar-padding-horizontal;\n padding: 9px 10px;\n .navbar-vertical-align(34px);\n background-color: transparent;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid transparent;\n border-radius: @border-radius-base;\n\n // We remove the `outline` here, but later compensate by attaching `:hover`\n // styles to `:focus`.\n &:focus {\n outline: none;\n }\n\n // Bars\n .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n }\n .icon-bar + .icon-bar {\n margin-top: 4px;\n }\n\n @media (min-width: @grid-float-breakpoint) {\n display: none;\n }\n}\n\n\n// Navbar nav links\n//\n// Builds on top of the `.nav` components with its own modifier class to make\n// the nav the full height of the horizontal nav (above 768px).\n\n.navbar-nav {\n margin: (@navbar-padding-vertical / 2) -@navbar-padding-horizontal;\n\n > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: @line-height-computed;\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n > li > a,\n .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n > li > a {\n line-height: @line-height-computed;\n &:hover,\n &:focus {\n background-image: none;\n }\n }\n }\n }\n\n // Uncollapse the nav\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin: 0;\n\n > li {\n float: left;\n > a {\n padding-top: @navbar-padding-vertical;\n padding-bottom: @navbar-padding-vertical;\n }\n }\n\n &.navbar-right:last-child {\n margin-right: -@navbar-padding-horizontal;\n }\n }\n}\n\n\n// Component alignment\n//\n// Repurpose the pull utilities as their own navbar utilities to avoid specificity\n// issues with parents and chaining. Only do this when the navbar is uncollapsed\n// though so that navbar contents properly stack and align in mobile.\n\n@media (min-width: @grid-float-breakpoint) {\n .navbar-left { .pull-left(); }\n .navbar-right { .pull-right(); }\n}\n\n\n// Navbar form\n//\n// Extension of the `.form-inline` with some extra flavor for optimum display in\n// our navbars.\n\n.navbar-form {\n margin-left: -@navbar-padding-horizontal;\n margin-right: -@navbar-padding-horizontal;\n padding: 10px @navbar-padding-horizontal;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n\n // Mixin behavior for optimum display\n .form-inline();\n\n .form-group {\n @media (max-width: @grid-float-breakpoint-max) {\n margin-bottom: 5px;\n }\n }\n\n // Vertically center in expanded, horizontal navbar\n .navbar-vertical-align(@input-height-base);\n\n // Undo 100% width for pull classes\n @media (min-width: @grid-float-breakpoint) {\n width: auto;\n border: 0;\n margin-left: 0;\n margin-right: 0;\n padding-top: 0;\n padding-bottom: 0;\n .box-shadow(none);\n\n // Outdent the form if last child to line up with content down the page\n &.navbar-right:last-child {\n margin-right: -@navbar-padding-horizontal;\n }\n }\n}\n\n\n// Dropdown menus\n\n// Menu position and menu carets\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n .border-top-radius(0);\n}\n// Menu position and menu caret support for dropups via extra dropup class\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n .border-bottom-radius(0);\n}\n\n\n// Buttons in navbars\n//\n// Vertically center a button within a navbar (when *not* in a form).\n\n.navbar-btn {\n .navbar-vertical-align(@input-height-base);\n\n &.btn-sm {\n .navbar-vertical-align(@input-height-small);\n }\n &.btn-xs {\n .navbar-vertical-align(22);\n }\n}\n\n\n// Text in navbars\n//\n// Add a class to make any element properly align itself vertically within the navbars.\n\n.navbar-text {\n .navbar-vertical-align(@line-height-computed);\n\n @media (min-width: @grid-float-breakpoint) {\n float: left;\n margin-left: @navbar-padding-horizontal;\n margin-right: @navbar-padding-horizontal;\n\n // Outdent the form if last child to line up with content down the page\n &.navbar-right:last-child {\n margin-right: 0;\n }\n }\n}\n\n// Alternate navbars\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n background-color: @navbar-default-bg;\n border-color: @navbar-default-border;\n\n .navbar-brand {\n color: @navbar-default-brand-color;\n &:hover,\n &:focus {\n color: @navbar-default-brand-hover-color;\n background-color: @navbar-default-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-default-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-default-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n\n .navbar-toggle {\n border-color: @navbar-default-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-default-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-default-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: @navbar-default-border;\n }\n\n // Dropdown menu items\n .navbar-nav {\n // Remove background color from open dropdown\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-default-link-active-bg;\n color: @navbar-default-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display when collapsed\n .open .dropdown-menu {\n > li > a {\n color: @navbar-default-link-color;\n &:hover,\n &:focus {\n color: @navbar-default-link-hover-color;\n background-color: @navbar-default-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-active-color;\n background-color: @navbar-default-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-default-link-disabled-color;\n background-color: @navbar-default-link-disabled-bg;\n }\n }\n }\n }\n }\n\n\n // Links in navbars\n //\n // Add a class to ensure links outside the navbar nav are colored correctly.\n\n .navbar-link {\n color: @navbar-default-link-color;\n &:hover {\n color: @navbar-default-link-hover-color;\n }\n }\n\n}\n\n// Inverse navbar\n\n.navbar-inverse {\n background-color: @navbar-inverse-bg;\n border-color: @navbar-inverse-border;\n\n .navbar-brand {\n color: @navbar-inverse-brand-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-brand-hover-color;\n background-color: @navbar-inverse-brand-hover-bg;\n }\n }\n\n .navbar-text {\n color: @navbar-inverse-color;\n }\n\n .navbar-nav {\n > li > a {\n color: @navbar-inverse-link-color;\n\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n\n // Darken the responsive nav toggle\n .navbar-toggle {\n border-color: @navbar-inverse-toggle-border-color;\n &:hover,\n &:focus {\n background-color: @navbar-inverse-toggle-hover-bg;\n }\n .icon-bar {\n background-color: @navbar-inverse-toggle-icon-bar-bg;\n }\n }\n\n .navbar-collapse,\n .navbar-form {\n border-color: darken(@navbar-inverse-bg, 7%);\n }\n\n // Dropdowns\n .navbar-nav {\n > .open > a {\n &,\n &:hover,\n &:focus {\n background-color: @navbar-inverse-link-active-bg;\n color: @navbar-inverse-link-active-color;\n }\n }\n\n @media (max-width: @grid-float-breakpoint-max) {\n // Dropdowns get custom display\n .open .dropdown-menu {\n > .dropdown-header {\n border-color: @navbar-inverse-border;\n }\n .divider {\n background-color: @navbar-inverse-border;\n }\n > li > a {\n color: @navbar-inverse-link-color;\n &:hover,\n &:focus {\n color: @navbar-inverse-link-hover-color;\n background-color: @navbar-inverse-link-hover-bg;\n }\n }\n > .active > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-active-color;\n background-color: @navbar-inverse-link-active-bg;\n }\n }\n > .disabled > a {\n &,\n &:hover,\n &:focus {\n color: @navbar-inverse-link-disabled-color;\n background-color: @navbar-inverse-link-disabled-bg;\n }\n }\n }\n }\n }\n\n .navbar-link {\n color: @navbar-inverse-link-color;\n &:hover {\n color: @navbar-inverse-link-hover-color;\n }\n }\n\n}\n","//\n// Utility classes\n// --------------------------------------------------\n\n\n// Floats\n// -------------------------\n\n.clearfix {\n .clearfix();\n}\n.center-block {\n .center-block();\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n\n\n// Toggling content\n// -------------------------\n\n// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n .text-hide();\n}\n\n\n// Hide from screenreaders and browsers\n//\n// Credit: HTML5 Boilerplate\n\n.hidden {\n display: none !important;\n visibility: hidden !important;\n}\n\n\n// For Affix plugin\n// -------------------------\n\n.affix {\n position: fixed;\n}\n","//\n// Breadcrumbs\n// --------------------------------------------------\n\n\n.breadcrumb {\n padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal;\n margin-bottom: @line-height-computed;\n list-style: none;\n background-color: @breadcrumb-bg;\n border-radius: @border-radius-base;\n\n > li {\n display: inline-block;\n\n + li:before {\n content: \"@{breadcrumb-separator}\\00a0\"; // Unicode space added since inline-block means non-collapsing white-space\n padding: 0 5px;\n color: @breadcrumb-color;\n }\n }\n\n > .active {\n color: @breadcrumb-active-color;\n }\n}\n","//\n// Pagination (multiple pages)\n// --------------------------------------------------\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: @line-height-computed 0;\n border-radius: @border-radius-base;\n\n > li {\n display: inline; // Remove list-style and block-level defaults\n > a,\n > span {\n position: relative;\n float: left; // Collapse white-space\n padding: @padding-base-vertical @padding-base-horizontal;\n line-height: @line-height-base;\n text-decoration: none;\n color: @pagination-color;\n background-color: @pagination-bg;\n border: 1px solid @pagination-border;\n margin-left: -1px;\n }\n &:first-child {\n > a,\n > span {\n margin-left: 0;\n .border-left-radius(@border-radius-base);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius-base);\n }\n }\n }\n\n > li > a,\n > li > span {\n &:hover,\n &:focus {\n color: @pagination-hover-color;\n background-color: @pagination-hover-bg;\n border-color: @pagination-hover-border;\n }\n }\n\n > .active > a,\n > .active > span {\n &,\n &:hover,\n &:focus {\n z-index: 2;\n color: @pagination-active-color;\n background-color: @pagination-active-bg;\n border-color: @pagination-active-border;\n cursor: default;\n }\n }\n\n > .disabled {\n > span,\n > span:hover,\n > span:focus,\n > a,\n > a:hover,\n > a:focus {\n color: @pagination-disabled-color;\n background-color: @pagination-disabled-bg;\n border-color: @pagination-disabled-border;\n cursor: not-allowed;\n }\n }\n}\n\n// Sizing\n// --------------------------------------------------\n\n// Large\n.pagination-lg {\n .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @border-radius-large);\n}\n\n// Small\n.pagination-sm {\n .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @border-radius-small);\n}\n","//\n// Pager pagination\n// --------------------------------------------------\n\n\n.pager {\n padding-left: 0;\n margin: @line-height-computed 0;\n list-style: none;\n text-align: center;\n &:extend(.clearfix all);\n li {\n display: inline;\n > a,\n > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: @pager-bg;\n border: 1px solid @pager-border;\n border-radius: @pager-border-radius;\n }\n\n > a:hover,\n > a:focus {\n text-decoration: none;\n background-color: @pager-hover-bg;\n }\n }\n\n .next {\n > a,\n > span {\n float: right;\n }\n }\n\n .previous {\n > a,\n > span {\n float: left;\n }\n }\n\n .disabled {\n > a,\n > a:hover,\n > a:focus,\n > span {\n color: @pager-disabled-color;\n background-color: @pager-bg;\n cursor: not-allowed;\n }\n }\n\n}\n","//\n// Labels\n// --------------------------------------------------\n\n.label {\n display: inline;\n padding: .2em .6em .3em;\n font-size: 75%;\n font-weight: bold;\n line-height: 1;\n color: @label-color;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: .25em;\n\n // Add hover effects, but only for links\n &[href] {\n &:hover,\n &:focus {\n color: @label-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n }\n\n // Empty labels collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for labels in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n}\n\n// Colors\n// Contextual variations (linked labels get darker on :hover)\n\n.label-default {\n .label-variant(@label-default-bg);\n}\n\n.label-primary {\n .label-variant(@label-primary-bg);\n}\n\n.label-success {\n .label-variant(@label-success-bg);\n}\n\n.label-info {\n .label-variant(@label-info-bg);\n}\n\n.label-warning {\n .label-variant(@label-warning-bg);\n}\n\n.label-danger {\n .label-variant(@label-danger-bg);\n}\n","//\n// Badges\n// --------------------------------------------------\n\n\n// Base classes\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: @font-size-small;\n font-weight: @badge-font-weight;\n color: @badge-color;\n line-height: @badge-line-height;\n vertical-align: baseline;\n white-space: nowrap;\n text-align: center;\n background-color: @badge-bg;\n border-radius: @badge-border-radius;\n\n // Empty badges collapse automatically (not available in IE8)\n &:empty {\n display: none;\n }\n\n // Quick fix for badges in buttons\n .btn & {\n position: relative;\n top: -1px;\n }\n .btn-xs & {\n top: 0;\n padding: 1px 5px;\n }\n}\n\n// Hover state, but only for links\na.badge {\n &:hover,\n &:focus {\n color: @badge-link-hover-color;\n text-decoration: none;\n cursor: pointer;\n }\n}\n\n// Account for counters in navs\na.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n color: @badge-active-color;\n background-color: @badge-active-bg;\n}\n.nav-pills > li > a > .badge {\n margin-left: 3px;\n}\n","//\n// Jumbotron\n// --------------------------------------------------\n\n\n.jumbotron {\n padding: @jumbotron-padding;\n margin-bottom: @jumbotron-padding;\n color: @jumbotron-color;\n background-color: @jumbotron-bg;\n\n h1,\n .h1 {\n color: @jumbotron-heading-color;\n }\n p {\n margin-bottom: (@jumbotron-padding / 2);\n font-size: @jumbotron-font-size;\n font-weight: 200;\n }\n\n .container & {\n border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container\n }\n\n .container {\n max-width: 100%;\n }\n\n @media screen and (min-width: @screen-sm-min) {\n padding-top: (@jumbotron-padding * 1.6);\n padding-bottom: (@jumbotron-padding * 1.6);\n\n .container & {\n padding-left: (@jumbotron-padding * 2);\n padding-right: (@jumbotron-padding * 2);\n }\n\n h1,\n .h1 {\n font-size: (@font-size-base * 4.5);\n }\n }\n}\n","//\n// Alerts\n// --------------------------------------------------\n\n\n// Base styles\n// -------------------------\n\n.alert {\n padding: @alert-padding;\n margin-bottom: @line-height-computed;\n border: 1px solid transparent;\n border-radius: @alert-border-radius;\n\n // Headings for larger alerts\n h4 {\n margin-top: 0;\n // Specified for the h4 to prevent conflicts of changing @headings-color\n color: inherit;\n }\n // Provide class for links that match alerts\n .alert-link {\n font-weight: @alert-link-font-weight;\n }\n\n // Improve alignment and spacing of inner content\n > p,\n > ul {\n margin-bottom: 0;\n }\n > p + p {\n margin-top: 5px;\n }\n}\n\n// Dismissable alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissable {\n padding-right: (@alert-padding + 20);\n\n // Adjust close link position\n .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n }\n}\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n.alert-success {\n .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);\n}\n.alert-info {\n .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);\n}\n.alert-warning {\n .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);\n}\n.alert-danger {\n .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);\n}\n","//\n// Progress bars\n// --------------------------------------------------\n\n\n// Bar animations\n// -------------------------\n\n// WebKit\n@-webkit-keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n// Spec and IE10+\n@keyframes progress-bar-stripes {\n from { background-position: 40px 0; }\n to { background-position: 0 0; }\n}\n\n\n\n// Bar itself\n// -------------------------\n\n// Outer container\n.progress {\n overflow: hidden;\n height: @line-height-computed;\n margin-bottom: @line-height-computed;\n background-color: @progress-bg;\n border-radius: @border-radius-base;\n .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));\n}\n\n// Bar of progress\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: @font-size-small;\n line-height: @line-height-computed;\n color: @progress-bar-color;\n text-align: center;\n background-color: @progress-bar-bg;\n .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));\n .transition(width .6s ease);\n}\n\n// Striped bars\n.progress-striped .progress-bar {\n #gradient > .striped();\n background-size: 40px 40px;\n}\n\n// Call animation for the active one\n.progress.active .progress-bar {\n .animation(progress-bar-stripes 2s linear infinite);\n}\n\n\n\n// Variations\n// -------------------------\n\n.progress-bar-success {\n .progress-bar-variant(@progress-bar-success-bg);\n}\n\n.progress-bar-info {\n .progress-bar-variant(@progress-bar-info-bg);\n}\n\n.progress-bar-warning {\n .progress-bar-variant(@progress-bar-warning-bg);\n}\n\n.progress-bar-danger {\n .progress-bar-variant(@progress-bar-danger-bg);\n}\n","// Media objects\n// Source: http://stubbornella.org/content/?p=497\n// --------------------------------------------------\n\n\n// Common styles\n// -------------------------\n\n// Clear the floats\n.media,\n.media-body {\n overflow: hidden;\n zoom: 1;\n}\n\n// Proper spacing between instances of .media\n.media,\n.media .media {\n margin-top: 15px;\n}\n.media:first-child {\n margin-top: 0;\n}\n\n// For images and videos, set to block\n.media-object {\n display: block;\n}\n\n// Reset margins on headings for tighter default spacing\n.media-heading {\n margin: 0 0 5px;\n}\n\n\n// Media image alignment\n// -------------------------\n\n.media {\n > .pull-left {\n margin-right: 10px;\n }\n > .pull-right {\n margin-left: 10px;\n }\n}\n\n\n// Media list variation\n// -------------------------\n\n// Undo default ul/ol styles\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n","//\n// List groups\n// --------------------------------------------------\n\n\n// Base class\n//\n// Easily usable on , , or .\n\n.list-group {\n // No need to set list-style: none; since .list-group-item is block level\n margin-bottom: 20px;\n padding-left: 0; // reset padding because ul and ol\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n // Place the border on the list items and negative margin up for better styling\n margin-bottom: -1px;\n background-color: @list-group-bg;\n border: 1px solid @list-group-border;\n\n // Round the first and last items\n &:first-child {\n .border-top-radius(@list-group-border-radius);\n }\n &:last-child {\n margin-bottom: 0;\n .border-bottom-radius(@list-group-border-radius);\n }\n\n // Align badges within list items\n > .badge {\n float: right;\n }\n > .badge + .badge {\n margin-right: 5px;\n }\n}\n\n\n// Linked list items\n//\n// Use anchor elements instead of `li`s or `div`s to create linked list items.\n// Includes an extra `.active` modifier class for showing selected items.\n\na.list-group-item {\n color: @list-group-link-color;\n\n .list-group-item-heading {\n color: @list-group-link-heading-color;\n }\n\n // Hover state\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: @list-group-hover-bg;\n }\n\n // Active class on item itself, not parent\n &.active,\n &.active:hover,\n &.active:focus {\n z-index: 2; // Place active items above their siblings for proper border styling\n color: @list-group-active-color;\n background-color: @list-group-active-bg;\n border-color: @list-group-active-border;\n\n // Force color to inherit for custom content\n .list-group-item-heading {\n color: inherit;\n }\n .list-group-item-text {\n color: @list-group-active-text-color;\n }\n }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n.list-group-item-variant(success; @state-success-bg; @state-success-text);\n.list-group-item-variant(info; @state-info-bg; @state-info-text);\n.list-group-item-variant(warning; @state-warning-bg; @state-warning-text);\n.list-group-item-variant(danger; @state-danger-bg; @state-danger-text);\n\n\n// Custom content options\n//\n// Extra classes for creating well-formatted content within `.list-group-item`s.\n\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n","//\n// Panels\n// --------------------------------------------------\n\n\n// Base class\n.panel {\n margin-bottom: @line-height-computed;\n background-color: @panel-bg;\n border: 1px solid transparent;\n border-radius: @panel-border-radius;\n .box-shadow(0 1px 1px rgba(0,0,0,.05));\n}\n\n// Panel contents\n.panel-body {\n padding: @panel-body-padding;\n &:extend(.clearfix all);\n}\n\n// Optional heading\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n .border-top-radius((@panel-border-radius - 1));\n\n > .dropdown .dropdown-toggle {\n color: inherit;\n }\n}\n\n// Within heading, strip any `h*` tag of its default margins for spacing.\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: ceil((@font-size-base * 1.125));\n color: inherit;\n\n > a {\n color: inherit;\n }\n}\n\n// Optional footer (stays gray in every modifier class)\n.panel-footer {\n padding: 10px 15px;\n background-color: @panel-footer-bg;\n border-top: 1px solid @panel-inner-border;\n .border-bottom-radius((@panel-border-radius - 1));\n}\n\n\n// List groups in panels\n//\n// By default, space out list group content from panel headings to account for\n// any kind of custom content between the two.\n\n.panel {\n > .list-group {\n margin-bottom: 0;\n\n .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n }\n\n // Add border top radius for first one\n &:first-child {\n .list-group-item:first-child {\n border-top: 0;\n .border-top-radius((@panel-border-radius - 1));\n }\n }\n // Add border bottom radius for last one\n &:last-child {\n .list-group-item:last-child {\n border-bottom: 0;\n .border-bottom-radius((@panel-border-radius - 1));\n }\n }\n }\n}\n// Collapse space between when there's no additional content.\n.panel-heading + .list-group {\n .list-group-item:first-child {\n border-top-width: 0;\n }\n}\n\n\n// Tables in panels\n//\n// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and\n// watch it go full width.\n\n.panel {\n > .table,\n > .table-responsive > .table {\n margin-bottom: 0;\n }\n // Add border top radius for first one\n > .table:first-child,\n > .table-responsive:first-child > .table:first-child {\n .border-top-radius((@panel-border-radius - 1));\n\n > thead:first-child,\n > tbody:first-child {\n > tr:first-child {\n td:first-child,\n th:first-child {\n border-top-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-top-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n // Add border bottom radius for last one\n > .table:last-child,\n > .table-responsive:last-child > .table:last-child {\n .border-bottom-radius((@panel-border-radius - 1));\n\n > tbody:last-child,\n > tfoot:last-child {\n > tr:last-child {\n td:first-child,\n th:first-child {\n border-bottom-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-bottom-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n > .panel-body + .table,\n > .panel-body + .table-responsive {\n border-top: 1px solid @table-border-color;\n }\n > .table > tbody:first-child > tr:first-child th,\n > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n }\n > .table-bordered,\n > .table-responsive > .table-bordered {\n border: 0;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n > thead,\n > tbody {\n > tr:first-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n > tbody,\n > tfoot {\n > tr:last-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n }\n > .table-responsive {\n border: 0;\n margin-bottom: 0;\n }\n}\n\n\n// Collapsable panels (aka, accordion)\n//\n// Wrap a series of panels in `.panel-group` to turn them into an accordion with\n// the help of our collapse JavaScript plugin.\n\n.panel-group {\n margin-bottom: @line-height-computed;\n\n // Tighten up margin so it's only between panels\n .panel {\n margin-bottom: 0;\n border-radius: @panel-border-radius;\n overflow: hidden; // crop contents when collapsed\n + .panel {\n margin-top: 5px;\n }\n }\n\n .panel-heading {\n border-bottom: 0;\n + .panel-collapse .panel-body {\n border-top: 1px solid @panel-inner-border;\n }\n }\n .panel-footer {\n border-top: 0;\n + .panel-collapse .panel-body {\n border-bottom: 1px solid @panel-inner-border;\n }\n }\n}\n\n\n// Contextual variations\n.panel-default {\n .panel-variant(@panel-default-border; @panel-default-text; @panel-default-heading-bg; @panel-default-border);\n}\n.panel-primary {\n .panel-variant(@panel-primary-border; @panel-primary-text; @panel-primary-heading-bg; @panel-primary-border);\n}\n.panel-success {\n .panel-variant(@panel-success-border; @panel-success-text; @panel-success-heading-bg; @panel-success-border);\n}\n.panel-info {\n .panel-variant(@panel-info-border; @panel-info-text; @panel-info-heading-bg; @panel-info-border);\n}\n.panel-warning {\n .panel-variant(@panel-warning-border; @panel-warning-text; @panel-warning-heading-bg; @panel-warning-border);\n}\n.panel-danger {\n .panel-variant(@panel-danger-border; @panel-danger-text; @panel-danger-heading-bg; @panel-danger-border);\n}\n","//\n// Wells\n// --------------------------------------------------\n\n\n// Base class\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: @well-bg;\n border: 1px solid @well-border;\n border-radius: @border-radius-base;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));\n blockquote {\n border-color: #ddd;\n border-color: rgba(0,0,0,.15);\n }\n}\n\n// Sizes\n.well-lg {\n padding: 24px;\n border-radius: @border-radius-large;\n}\n.well-sm {\n padding: 9px;\n border-radius: @border-radius-small;\n}\n","//\n// Close icons\n// --------------------------------------------------\n\n\n.close {\n float: right;\n font-size: (@font-size-base * 1.5);\n font-weight: @close-font-weight;\n line-height: 1;\n color: @close-color;\n text-shadow: @close-text-shadow;\n .opacity(.2);\n\n &:hover,\n &:focus {\n color: @close-color;\n text-decoration: none;\n cursor: pointer;\n .opacity(.5);\n }\n\n // Additional properties for button version\n // iOS requires the button element instead of an anchor tag.\n // If you want the anchor version, it requires `href=\"#\"`.\n button& {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n }\n}\n","//\n// Modals\n// --------------------------------------------------\n\n// .modal-open - body class for killing the scroll\n// .modal - container to scroll within\n// .modal-dialog - positioning shell for the actual modal\n// .modal-content - actual modal w/ bg and corners and shit\n\n// Kill the scroll on the body\n.modal-open {\n overflow: hidden;\n}\n\n// Container that the modal scrolls within\n.modal {\n display: none;\n overflow: auto;\n overflow-y: scroll;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: @zindex-modal;\n -webkit-overflow-scrolling: touch;\n\n // Prevent Chrome on Windows from adding a focus outline. For details, see\n // https://github.com/twbs/bootstrap/pull/10951.\n outline: 0;\n\n // When fading in the modal, animate it to slide down\n &.fade .modal-dialog {\n .translate(0, -25%);\n .transition-transform(~\"0.3s ease-out\");\n }\n &.in .modal-dialog { .translate(0, 0)}\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n\n// Actual modal\n.modal-content {\n position: relative;\n background-color: @modal-content-bg;\n border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)\n border: 1px solid @modal-content-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 3px 9px rgba(0,0,0,.5));\n background-clip: padding-box;\n // Remove focus outline from opened modal\n outline: none;\n}\n\n// Modal background\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: @zindex-modal-background;\n background-color: @modal-backdrop-bg;\n // Fade for backdrop\n &.fade { .opacity(0); }\n &.in { .opacity(@modal-backdrop-opacity); }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n padding: @modal-title-padding;\n border-bottom: 1px solid @modal-header-border-color;\n min-height: (@modal-title-padding + @modal-title-line-height);\n}\n// Close icon\n.modal-header .close {\n margin-top: -2px;\n}\n\n// Title text within header\n.modal-title {\n margin: 0;\n line-height: @modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n position: relative;\n padding: @modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n margin-top: 15px;\n padding: (@modal-inner-padding - 1) @modal-inner-padding @modal-inner-padding;\n text-align: right; // right align buttons\n border-top: 1px solid @modal-footer-border-color;\n &:extend(.clearfix all); // clear it in case folks use .pull-* classes on buttons\n\n // Properly space out buttons\n .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0; // account for input[type=\"submit\"] which gets the bottom margin like all other inputs\n }\n // but override that for button groups\n .btn-group .btn + .btn {\n margin-left: -1px;\n }\n // and override it for block buttons as well\n .btn-block + .btn-block {\n margin-left: 0;\n }\n}\n\n// Scale up the modal\n@media (min-width: @screen-sm-min) {\n // Automatically set modal's width for larger viewports\n .modal-dialog {\n width: @modal-md;\n margin: 30px auto;\n }\n .modal-content {\n .box-shadow(0 5px 15px rgba(0,0,0,.5));\n }\n\n // Modal sizes\n .modal-sm { width: @modal-sm; }\n}\n\n@media (min-width: @screen-md-min) {\n .modal-lg { width: @modal-lg; }\n}\n","//\n// Tooltips\n// --------------------------------------------------\n\n\n// Base class\n.tooltip {\n position: absolute;\n z-index: @zindex-tooltip;\n display: block;\n visibility: visible;\n font-size: @font-size-small;\n line-height: 1.4;\n .opacity(0);\n\n &.in { .opacity(@tooltip-opacity); }\n &.top { margin-top: -3px; padding: @tooltip-arrow-width 0; }\n &.right { margin-left: 3px; padding: 0 @tooltip-arrow-width; }\n &.bottom { margin-top: 3px; padding: @tooltip-arrow-width 0; }\n &.left { margin-left: -3px; padding: 0 @tooltip-arrow-width; }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n max-width: @tooltip-max-width;\n padding: 3px 8px;\n color: @tooltip-color;\n text-align: center;\n text-decoration: none;\n background-color: @tooltip-bg;\n border-radius: @border-radius-base;\n}\n\n// Arrows\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.tooltip {\n &.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-left .tooltip-arrow {\n bottom: 0;\n left: @tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-right .tooltip-arrow {\n bottom: 0;\n right: @tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;\n border-right-color: @tooltip-arrow-color;\n }\n &.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-left-color: @tooltip-arrow-color;\n }\n &.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-left .tooltip-arrow {\n top: 0;\n left: @tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-right .tooltip-arrow {\n top: 0;\n right: @tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n}\n","//\n// Popovers\n// --------------------------------------------------\n\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: @zindex-popover;\n display: none;\n max-width: @popover-max-width;\n padding: 1px;\n text-align: left; // Reset given new insertion method\n background-color: @popover-bg;\n background-clip: padding-box;\n border: 1px solid @popover-fallback-border-color;\n border: 1px solid @popover-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 5px 10px rgba(0,0,0,.2));\n\n // Overrides for proper insertion\n white-space: normal;\n\n // Offset the popover to account for the popover arrow\n &.top { margin-top: -@popover-arrow-width; }\n &.right { margin-left: @popover-arrow-width; }\n &.bottom { margin-top: @popover-arrow-width; }\n &.left { margin-left: -@popover-arrow-width; }\n}\n\n.popover-title {\n margin: 0; // reset heading margin\n padding: 8px 14px;\n font-size: @font-size-base;\n font-weight: normal;\n line-height: 18px;\n background-color: @popover-title-bg;\n border-bottom: 1px solid darken(@popover-title-bg, 5%);\n border-radius: 5px 5px 0 0;\n}\n\n.popover-content {\n padding: 9px 14px;\n}\n\n// Arrows\n//\n// .arrow is outer, .arrow:after is inner\n\n.popover > .arrow {\n &,\n &:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n }\n}\n.popover > .arrow {\n border-width: @popover-arrow-outer-width;\n}\n.popover > .arrow:after {\n border-width: @popover-arrow-width;\n content: \"\";\n}\n\n.popover {\n &.top > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-top-color: @popover-arrow-outer-color;\n bottom: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n bottom: 1px;\n margin-left: -@popover-arrow-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-color;\n }\n }\n &.right > .arrow {\n top: 50%;\n left: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-right-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n left: 1px;\n bottom: -@popover-arrow-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-color;\n }\n }\n &.bottom > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-bottom-color: @popover-arrow-outer-color;\n top: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n top: 1px;\n margin-left: -@popover-arrow-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-color;\n }\n }\n\n &.left > .arrow {\n top: 50%;\n right: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-right-width: 0;\n border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-left-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: @popover-arrow-color;\n bottom: -@popover-arrow-width;\n }\n }\n\n}\n","//\n// Responsive: Utility classes\n// --------------------------------------------------\n\n\n// IE10 in Windows (Phone) 8\n//\n// Support for responsive views via media queries is kind of borked in IE10, for\n// Surface/desktop in split view and for Windows Phone 8. This particular fix\n// must be accompanied by a snippet of JavaScript to sniff the user agent and\n// apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at\n// our Getting Started page for more information on this bug.\n//\n// For more information, see the following:\n//\n// Issue: https://github.com/twbs/bootstrap/issues/10497\n// Docs: http://getbootstrap.com/getting-started/#browsers\n// Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/\n\n@-ms-viewport {\n width: device-width;\n}\n\n\n// Visibility utilities\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n .responsive-invisibility();\n}\n\n.visible-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-visibility();\n }\n}\n.visible-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-visibility();\n }\n}\n.visible-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-visibility();\n }\n}\n.visible-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-visibility();\n }\n}\n\n.hidden-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-invisibility();\n }\n}\n.hidden-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-invisibility();\n }\n}\n.hidden-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-invisibility();\n }\n}\n.hidden-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-invisibility();\n }\n}\n\n\n// Print utilities\n//\n// Media queries are placed on the inside to be mixin-friendly.\n\n.visible-print {\n .responsive-invisibility();\n\n @media print {\n .responsive-visibility();\n }\n}\n\n.hidden-print {\n @media print {\n .responsive-invisibility();\n }\n}\n"]}
\ No newline at end of file
diff --git a/triplestores/fuseki/webapp/css/bootstrap.min.css b/triplestores/fuseki/webapp/css/bootstrap.min.css
deleted file mode 100644
index 679272d258..0000000000
--- a/triplestores/fuseki/webapp/css/bootstrap.min.css
+++ /dev/null
@@ -1,7 +0,0 @@
-/*!
- * Bootstrap v3.1.1 (http://getbootstrap.com)
- * Copyright 2011-2014 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- */
-
-/*! normalize.css v3.0.0 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:0 0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@media print{*{text-shadow:none!important;color:#000!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.table td,.table th{background-color:#fff!important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:before,:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:62.5%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:400;line-height:1;color:#999}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:200;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}cite{font-style:normal}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-muted{color:#999}.text-primary{color:#428bca}a.text-primary:hover{color:#3071a9}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#428bca}a.bg-primary:hover{background-color:#3071a9}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#999}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0;text-align:right}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}blockquote:before,blockquote:after{content:""}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;white-space:nowrap;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;word-break:break-all;word-wrap:break-word;color:#333;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:0}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:0}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:0}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:0}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:0}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:0}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:0}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:0}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{max-width:100%;background-color:transparent}th{text-align:left}.table{width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th{background-color:#f5f5f5}table col[class*=col-]{position:static;float:none;display:table-column}table td[class*=col-],table th[class*=col-]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}@media (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;overflow-x:scroll;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd;-webkit-overflow-scrolling:touch}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=radio],input[type=checkbox]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}input[type=date]{line-height:34px}.form-group{margin-bottom:15px}.radio,.checkbox{display:block;min-height:20px;margin-top:10px;margin-bottom:10px;padding-left:20px}.radio label,.checkbox label{display:inline;font-weight:400;cursor:pointer}.radio input[type=radio],.radio-inline input[type=radio],.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox]{float:left;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:400;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type=radio][disabled],input[type=checkbox][disabled],.radio[disabled],.radio-inline[disabled],.checkbox[disabled],.checkbox-inline[disabled],fieldset[disabled] input[type=radio],fieldset[disabled] input[type=checkbox],fieldset[disabled] .radio,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.has-feedback .form-control-feedback{position:absolute;top:25px;right:0;display:block;width:34px;height:34px;line-height:34px;text-align:center}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.has-error .form-control-feedback{color:#a94442}.form-control-static{margin-bottom:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;padding-left:0;vertical-align:middle}.form-inline .radio input[type=radio],.form-inline .checkbox input[type=checkbox]{float:none;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .control-label,.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}.form-horizontal .form-control-static{padding-top:7px}@media (min-width:768px){.form-horizontal .control-label{text-align:right}}.form-horizontal .has-feedback .form-control-feedback{top:0;right:15px}.btn{display:inline-block;margin-bottom:0;font-weight:400;text-align:center;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus{color:#333;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;pointer-events:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{color:#333;background-color:#ebebeb;border-color:#adadad}.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{color:#fff;background-color:#3276b1;border-color:#285e8e}.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd}.btn-primary .badge{color:#428bca;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{color:#fff;background-color:#47a447;border-color:#398439}.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{color:#fff;background-color:#ed9c28;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{color:#fff;background-color:#d2322d;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#428bca;font-weight:400;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#999;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%;padding-left:0;padding-right:0}.btn-block+.btn-block{margin-top:5px}input[type=submit].btn-block,input[type=reset].btn-block,input[type=button].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;transition:height .35s ease}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:14px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#262626;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;outline:0;background-color:#428bca}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#999}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-bottom-left-radius:4px;border-top-right-radius:0;border-top-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%}.btn-group-justified>.btn-group .btn{width:100%}[data-toggle=buttons]>.btn>input[type=radio],[data-toggle=buttons]>.btn>input[type=checkbox]{display:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-left:0;padding-right:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=radio],.input-group-addon input[type=checkbox]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{margin-bottom:0;padding-left:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#999}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#999;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#428bca}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#428bca}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{max-height:340px;overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right:0}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;padding:15px;font-size:18px;line-height:20px;height:50px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;margin-right:15px;padding:9px 10px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}.navbar-nav.navbar-right:last-child{margin-right:-15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.navbar-form{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);margin-top:8px;margin-bottom:8px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;padding-left:0;vertical-align:middle}.navbar-form .radio input[type=radio],.navbar-form .checkbox input[type=checkbox]{float:none;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media (min-width:768px){.navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}.navbar-form.navbar-right:last-child{margin-right:-15px}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-left:15px;margin-right:15px}.navbar-text.navbar-right:last-child{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:#e7e7e7;color:#555}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#999}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .navbar-nav>li>a{color:#999}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:#080808;color:#fff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#999}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover{color:#fff}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{content:"/\00a0";padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;line-height:1.42857143;text-decoration:none;color:#428bca;background-color:#fff;border:1px solid #ddd;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#2a6496;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca;cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#999;background-color:#fff;border-color:#ddd;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{padding-left:0;margin:20px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;background-color:#fff;cursor:not-allowed}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.label[href]:hover,.label[href]:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#999}.label-default[href]:hover,.label-default[href]:focus{background-color:gray}.label-primary{background-color:#428bca}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;color:#fff;line-height:1;vertical-align:baseline;white-space:nowrap;text-align:center;background-color:#999;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#428bca;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.container .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-left:60px;padding-right:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-left:auto;margin-right:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#428bca}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable{padding-right:35px}.alert-dismissable .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{background-color:#f2dede;border-color:#ebccd1;color:#a94442}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#428bca;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:40px 40px}.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media,.media-body{overflow:hidden;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{padding-left:0;list-style:none}.list-group{margin-bottom:20px;padding-left:0}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{text-decoration:none;background-color:#f5f5f5}a.list-group-item.active,a.list-group-item.active:hover,a.list-group-item.active:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}a.list-group-item.active .list-group-item-heading,a.list-group-item.active:hover .list-group-item-heading,a.list-group-item.active:focus .list-group-item-heading{color:inherit}a.list-group-item.active .list-group-item-text,a.list-group-item.active:hover .list-group-item-text,a.list-group-item.active:focus .list-group-item-text{color:#e1edf7}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,a.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,a.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,a.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,a.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-right-radius:3px;border-top-left-radius:3px}.panel>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-right-radius:3px;border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{border:0;margin-bottom:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px;overflow:hidden}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse .panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse .panel-body{border-top-color:#ddd}.panel-default>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#428bca}.panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.panel-primary>.panel-heading+.panel-collapse .panel-body{border-top-color:#428bca}.panel-primary>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#428bca}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse .panel-body{border-top-color:#d6e9c6}.panel-success>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse .panel-body{border-top-color:#bce8f1}.panel-info>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse .panel-body{border-top-color:#faebcc}.panel-warning>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse .panel-body{border-top-color:#ebccd1}.panel-danger>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ebccd1}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:auto;overflow-y:scroll;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0)}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5);background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5;min-height:16.42857143px}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:20px}.modal-footer{margin-top:15px;padding:19px 20px 20px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1030;display:block;visibility:visible;font-size:12px;line-height:1.4;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;right:5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);white-space:normal}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{margin:0;padding:8px 14px;font-size:14px;font-weight:400;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{border-width:10px;content:""}.popover.top>.arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0,0,0,.25);bottom:-11px}.popover.top>.arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#fff}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0,0,0,.25)}.popover.right>.arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#fff}.popover.bottom>.arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25);top:-11px}.popover.bottom>.arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#fff;bottom:-10px}.carousel{position:relative}.carousel-inner{position:relative;overflow:hidden;width:100%}.carousel-inner>.item{display:none;position:relative;-webkit-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;left:0;bottom:0;width:15%;opacity:.5;filter:alpha(opacity=50);font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-control.left{background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,.5) 0),color-stop(rgba(0,0,0,.0001) 100%));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)}.carousel-control.right{left:auto;right:0;background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,.0001) 0),color-stop(rgba(0,0,0,.5) 100%));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.carousel-control:hover,.carousel-control:focus{outline:0;color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;margin-left:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;margin-left:-30%;padding-left:0;list-style:none;text-align:center}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;border:1px solid #fff;border-radius:10px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0)}.carousel-indicators .active{margin:0;width:12px;height:12px;background-color:#fff}.carousel-caption{position:absolute;left:15%;right:15%;bottom:20px;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;margin-left:-15px;font-size:30px}.carousel-caption{left:20%;right:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-footer:before,.modal-footer:after{content:" ";display:table}.clearfix:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-footer:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}}@media print{.hidden-print{display:none!important}}
\ No newline at end of file
diff --git a/triplestores/fuseki/webapp/css/codemirror.css b/triplestores/fuseki/webapp/css/codemirror.css
deleted file mode 100644
index c0897771aa..0000000000
--- a/triplestores/fuseki/webapp/css/codemirror.css
+++ /dev/null
@@ -1,301 +0,0 @@
-/* BASICS */
-
-.CodeMirror {
- /* Set height, width, borders, and global font properties here */
- font-family: monospace;
- height: 300px;
-}
-.CodeMirror-scroll {
- /* Set scrolling behaviour here */
- overflow: auto;
-}
-
-/* PADDING */
-
-.CodeMirror-lines {
- padding: 4px 0; /* Vertical padding around content */
-}
-.CodeMirror pre {
- padding: 0 4px; /* Horizontal padding of content */
-}
-
-.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
- background-color: white; /* The little square between H and V scrollbars */
-}
-
-/* GUTTER */
-
-.CodeMirror-gutters {
- border-right: 1px solid #ddd;
- background-color: #f7f7f7;
- white-space: nowrap;
-}
-.CodeMirror-linenumbers {}
-.CodeMirror-linenumber {
- padding: 0 3px 0 5px;
- min-width: 20px;
- text-align: right;
- color: #999;
- -moz-box-sizing: content-box;
- box-sizing: content-box;
-}
-
-.CodeMirror-guttermarker { color: black; }
-.CodeMirror-guttermarker-subtle { color: #999; }
-
-/* CURSOR */
-
-.CodeMirror div.CodeMirror-cursor {
- border-left: 1px solid black;
-}
-/* Shown when moving in bi-directional text */
-.CodeMirror div.CodeMirror-secondarycursor {
- border-left: 1px solid silver;
-}
-.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor {
- width: auto;
- border: 0;
- background: #7e7;
-}
-.cm-animate-fat-cursor {
- width: auto;
- border: 0;
- -webkit-animation: blink 1.06s steps(1) infinite;
- -moz-animation: blink 1.06s steps(1) infinite;
- animation: blink 1.06s steps(1) infinite;
-}
-@-moz-keyframes blink {
- 0% { background: #7e7; }
- 50% { background: none; }
- 100% { background: #7e7; }
-}
-@-webkit-keyframes blink {
- 0% { background: #7e7; }
- 50% { background: none; }
- 100% { background: #7e7; }
-}
-@keyframes blink {
- 0% { background: #7e7; }
- 50% { background: none; }
- 100% { background: #7e7; }
-}
-
-/* Can style cursor different in overwrite (non-insert) mode */
-div.CodeMirror-overwrite div.CodeMirror-cursor {}
-
-.cm-tab { display: inline-block; }
-
-.CodeMirror-ruler {
- border-left: 1px solid #ccc;
- position: absolute;
-}
-
-/* DEFAULT THEME */
-
-.cm-s-default .cm-keyword {color: #708;}
-.cm-s-default .cm-atom {color: #219;}
-.cm-s-default .cm-number {color: #164;}
-.cm-s-default .cm-def {color: #00f;}
-.cm-s-default .cm-variable,
-.cm-s-default .cm-punctuation,
-.cm-s-default .cm-property,
-.cm-s-default .cm-operator {}
-.cm-s-default .cm-variable-2 {color: #05a;}
-.cm-s-default .cm-variable-3 {color: #085;}
-.cm-s-default .cm-comment {color: #a50;}
-.cm-s-default .cm-string {color: #a11;}
-.cm-s-default .cm-string-2 {color: #f50;}
-.cm-s-default .cm-meta {color: #555;}
-.cm-s-default .cm-qualifier {color: #555;}
-.cm-s-default .cm-builtin {color: #30a;}
-.cm-s-default .cm-bracket {color: #997;}
-.cm-s-default .cm-tag {color: #170;}
-.cm-s-default .cm-attribute {color: #00c;}
-.cm-s-default .cm-header {color: blue;}
-.cm-s-default .cm-quote {color: #090;}
-.cm-s-default .cm-hr {color: #999;}
-.cm-s-default .cm-link {color: #00c;}
-
-.cm-negative {color: #d44;}
-.cm-positive {color: #292;}
-.cm-header, .cm-strong {font-weight: bold;}
-.cm-em {font-style: italic;}
-.cm-link {text-decoration: underline;}
-
-.cm-s-default .cm-error {color: #f00;}
-.cm-invalidchar {color: #f00;}
-
-/* Default styles for common addons */
-
-div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
-div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
-.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
-.CodeMirror-activeline-background {background: #e8f2ff;}
-
-/* STOP */
-
-/* The rest of this file contains styles related to the mechanics of
- the editor. You probably shouldn't touch them. */
-
-.CodeMirror {
- line-height: 1;
- position: relative;
- overflow: hidden;
- background: white;
- color: black;
-}
-
-.CodeMirror-scroll {
- /* 30px is the magic margin used to hide the element's real scrollbars */
- /* See overflow: hidden in .CodeMirror */
- margin-bottom: -30px; margin-right: -30px;
- padding-bottom: 30px;
- height: 100%;
- outline: none; /* Prevent dragging from highlighting the element */
- position: relative;
- -moz-box-sizing: content-box;
- box-sizing: content-box;
-}
-.CodeMirror-sizer {
- position: relative;
- border-right: 30px solid transparent;
- -moz-box-sizing: content-box;
- box-sizing: content-box;
-}
-
-/* The fake, visible scrollbars. Used to force redraw during scrolling
- before actuall scrolling happens, thus preventing shaking and
- flickering artifacts. */
-.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
- position: absolute;
- z-index: 6;
- display: none;
-}
-.CodeMirror-vscrollbar {
- right: 0; top: 0;
- overflow-x: hidden;
- overflow-y: scroll;
-}
-.CodeMirror-hscrollbar {
- bottom: 0; left: 0;
- overflow-y: hidden;
- overflow-x: scroll;
-}
-.CodeMirror-scrollbar-filler {
- right: 0; bottom: 0;
-}
-.CodeMirror-gutter-filler {
- left: 0; bottom: 0;
-}
-
-.CodeMirror-gutters {
- position: absolute; left: 0; top: 0;
- padding-bottom: 30px;
- z-index: 3;
-}
-.CodeMirror-gutter {
- white-space: normal;
- height: 100%;
- -moz-box-sizing: content-box;
- box-sizing: content-box;
- padding-bottom: 30px;
- margin-bottom: -32px;
- display: inline-block;
- /* Hack to make IE7 behave */
- *zoom:1;
- *display:inline;
-}
-.CodeMirror-gutter-elt {
- position: absolute;
- cursor: default;
- z-index: 4;
-}
-
-.CodeMirror-lines {
- cursor: text;
-}
-.CodeMirror pre {
- /* Reset some styles that the rest of the page might have set */
- -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
- border-width: 0;
- background: transparent;
- font-family: inherit;
- font-size: inherit;
- margin: 0;
- white-space: pre;
- word-wrap: normal;
- line-height: inherit;
- color: inherit;
- z-index: 2;
- position: relative;
- overflow: visible;
-}
-.CodeMirror-wrap pre {
- word-wrap: break-word;
- white-space: pre-wrap;
- word-break: normal;
-}
-
-.CodeMirror-linebackground {
- position: absolute;
- left: 0; right: 0; top: 0; bottom: 0;
- z-index: 0;
-}
-
-.CodeMirror-linewidget {
- position: relative;
- z-index: 2;
- overflow: auto;
-}
-
-.CodeMirror-widget {}
-
-.CodeMirror-wrap .CodeMirror-scroll {
- overflow-x: hidden;
-}
-
-.CodeMirror-measure {
- position: absolute;
- width: 100%;
- height: 0;
- overflow: hidden;
- visibility: hidden;
-}
-.CodeMirror-measure pre { position: static; }
-
-.CodeMirror div.CodeMirror-cursor {
- position: absolute;
- border-right: none;
- width: 0;
-}
-
-div.CodeMirror-cursors {
- visibility: hidden;
- position: relative;
- z-index: 1;
-}
-.CodeMirror-focused div.CodeMirror-cursors {
- visibility: visible;
-}
-
-.CodeMirror-selected { background: #d9d9d9; }
-.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
-.CodeMirror-crosshair { cursor: crosshair; }
-
-.cm-searching {
- background: #ffa;
- background: rgba(255, 255, 0, .4);
-}
-
-/* IE7 hack to prevent it from returning funny offsetTops on the spans */
-.CodeMirror span { *vertical-align: text-bottom; }
-
-/* Used to force a border model for a node */
-.cm-force-border { padding-right: .1px; }
-
-@media print {
- /* Hide the cursor when printing */
- .CodeMirror div.CodeMirror-cursors {
- visibility: hidden;
- }
-}
diff --git a/triplestores/fuseki/webapp/css/codemirror.min.css b/triplestores/fuseki/webapp/css/codemirror.min.css
deleted file mode 100644
index d2366ca776..0000000000
--- a/triplestores/fuseki/webapp/css/codemirror.min.css
+++ /dev/null
@@ -1 +0,0 @@
-.CodeMirror{font-family:monospace;height:300px}.CodeMirror-scroll{overflow:auto}.CodeMirror-lines{padding:4px 0}.CodeMirror pre{padding:0 4px}.CodeMirror-gutter-filler,.CodeMirror-scrollbar-filler{background-color:#fff}.CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-guttermarker{color:#000}.CodeMirror-guttermarker-subtle{color:#999}.CodeMirror div.CodeMirror-cursor{border-left:1px solid #000}.CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.CodeMirror.cm-fat-cursor div.CodeMirror-cursor{width:auto;border:0;background:#7e7}.CodeMirror.cm-fat-cursor div.CodeMirror-cursors{z-index:1}.cm-animate-fat-cursor{width:auto;border:0;-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite}@-moz-keyframes blink{0%{background:#7e7}50%{background:0 0}100%{background:#7e7}}@-webkit-keyframes blink{0%{background:#7e7}50%{background:0 0}100%{background:#7e7}}@keyframes blink{0%{background:#7e7}50%{background:0 0}100%{background:#7e7}}.cm-tab{display:inline-block;text-decoration:inherit}.CodeMirror-ruler{border-left:1px solid #ccc;position:absolute}.cm-s-default .cm-keyword{color:#708}.cm-s-default .cm-atom{color:#219}.cm-s-default .cm-number{color:#164}.cm-s-default .cm-def{color:#00f}.cm-s-default .cm-variable-2{color:#05a}.cm-s-default .cm-variable-3{color:#085}.cm-s-default .cm-comment{color:#a50}.cm-s-default .cm-string{color:#a11}.cm-s-default .cm-string-2{color:#f50}.cm-s-default .cm-meta,.cm-s-default .cm-qualifier{color:#555}.cm-s-default .cm-builtin{color:#30a}.cm-s-default .cm-bracket{color:#997}.cm-s-default .cm-tag{color:#170}.cm-s-default .cm-attribute{color:#00c}.cm-s-default .cm-header{color:#00f}.cm-s-default .cm-quote{color:#090}.cm-s-default .cm-hr{color:#999}.cm-s-default .cm-link{color:#00c}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:700}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-strikethrough{text-decoration:line-through}.cm-invalidchar,.cm-s-default .cm-error{color:red}div.CodeMirror span.CodeMirror-matchingbracket{color:#0f0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#f22}.CodeMirror-matchingtag{background:rgba(255,150,0,.3)}.CodeMirror-activeline-background{background:#e8f2ff}.CodeMirror{line-height:1;position:relative;overflow:hidden;background:#fff;color:#000}.CodeMirror-scroll{margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:0;position:relative;-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-sizer{position:relative;border-right:30px solid transparent;-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-gutter-filler,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-vscrollbar{position:absolute;z-index:6;display:none}.CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.CodeMirror-scrollbar-filler{right:0;bottom:0}.CodeMirror-gutter-filler{left:0;bottom:0}.CodeMirror-gutters{position:absolute;left:0;top:0;padding-bottom:30px;z-index:3}.CodeMirror-gutter{white-space:normal;height:100%;-moz-box-sizing:content-box;box-sizing:content-box;padding-bottom:30px;margin-bottom:-32px;display:inline-block}.CodeMirror-gutter-wrapper{position:absolute;z-index:4;height:100%}.CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.CodeMirror-lines{cursor:text;min-height:1px}.CodeMirror pre{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;border-width:0;background:0 0;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible}.CodeMirror-wrap pre{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.CodeMirror-linewidget{position:relative;z-index:2;overflow:auto}.CodeMirror-wrap .CodeMirror-scroll{overflow-x:hidden}.CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.CodeMirror-measure pre{position:static}.CodeMirror div.CodeMirror-cursor{position:absolute;border-right:none;width:0}div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:3}.CodeMirror-focused div.CodeMirror-cursors{visibility:visible}.CodeMirror-selected{background:#d9d9d9}.CodeMirror-focused .CodeMirror-selected{background:#d7d4f0}.CodeMirror-crosshair{cursor:crosshair}.cm-searching{background:#ffa;background:rgba(255,255,0,.4)}.cm-force-border{padding-right:.1px}@media print{.CodeMirror div.CodeMirror-cursors{visibility:hidden}}.cm-tab-wrap-hack:after{content:''}span.CodeMirror-selectedtext{background:0 0}
\ No newline at end of file
diff --git a/triplestores/fuseki/webapp/css/font-awesome.min.css b/triplestores/fuseki/webapp/css/font-awesome.min.css
deleted file mode 100644
index 3d920fc87c..0000000000
--- a/triplestores/fuseki/webapp/css/font-awesome.min.css
+++ /dev/null
@@ -1,4 +0,0 @@
-/*!
- * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome
- * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
- */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.1.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.1.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.1.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1)}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-square:before,.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}
\ No newline at end of file
diff --git a/triplestores/fuseki/webapp/css/fui.css b/triplestores/fuseki/webapp/css/fui.css
deleted file mode 100644
index b2445e3446..0000000000
--- a/triplestores/fuseki/webapp/css/fui.css
+++ /dev/null
@@ -1,191 +0,0 @@
-h1 {
- margin-top: 0;
- font-size: 18pt;
-}
-
-h1 + p {
- margin-bottom: 20px;
-}
-
-h2 {
- margin-top: 0;
- font-size: 16pt;
-}
-
-h2 + p {
- margin-bottom: 18px;
-}
-
-h3 {
- font-size: 13pt;
-}
-
-a#server-status-light {
- display: inline-block;
- margin: 0;
- padding-left: 8px;
- padding-top: 2px;
-}
-#server-status-light span {
- width: 24px;
- height: 24px;
- border-radius: 12px;
- display: inline-block;
- margin-bottom: -8px;
-}
-#server-status-light span.server-up {
- background-color: #38a800;
- border:1px solid #4b9b23;
-
- background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #59e811), color-stop(1, #38a800));
- background:-moz-linear-gradient(top, #59e811 5%, #38a800 100%);
- background:-webkit-linear-gradient(top, #59e811 5%, #38a800 100%);
- background:-o-linear-gradient(top, #59e811 5%, #38a800 100%);
- background:-ms-linear-gradient(top, #59e811 5%, #38a800 100%);
- background:linear-gradient(to bottom, #59e811 5%, #38a800 100%);
- filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#59e811', endColorstr='#38a800',GradientType=0);
-}
-
-#server-status-light span.server-down {
- background-color: #d21e1e;
- border:1px solid #a02323;
-
- background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #ed2424), color-stop(1, #d21e1e));
- background:-moz-linear-gradient(top, #ed2424 5%, #d21e1e 100%);
- background:-webkit-linear-gradient(top, #ed2424 5%, #d21e1e 100%);
- background:-o-linear-gradient(top, #ed2424 5%, #d21e1e 100%);
- background:-ms-linear-gradient(top, #ed2424 5%, #d21e1e 100%);
- background:linear-gradient(to bottom, #ed2424 5%, #d21e1e 100%);
- filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbb450', endColorstr='#f89306',GradientType=0);
-}
-
-a.navbar-brand {
- padding-top: 0;
- padding-bottom: 0;
- font-size: 15px;
- line-height: 1.0;
-}
-
-a.navbar-brand div {
- display: inline-block;
-}
-
-a.navbar-brand img {
- margin-top: -25px;
-}
-
-.navbar-right {
- color: #777;
- line-height: 1.0;
-}
-
-.navbar-item {
- padding-top: 15px;
- padding-right: 4px;
-}
-
-.navbar-nav > li > a > i {
- color: #428bca;
-}
-
-.options-list {
- margin-bottom: 5px;
-}
-
-.validation-warning {
- display:none;
-}
-.has-error .validation-warning, .has-warning .validation-warning {
- display:block;
-}
-
-.current-dataset {
- margin-right: 20px;
-}
-
-.current-datasets {
- margin-top: 20px;
- margin-bottom: 20px;
-}
-
-.status-indicator {
- padding-top: 10px;
-}
-
-.select-picker-label {
- height: 30px;
- vertical-align: middle;
- display: inline-block;
-}
-
-.content-frame {
- background-color: #eee;
- border: 1px solid #aaa;
- border-radius: 5px;
- padding: 5px;
-}
-
-.tab-pane > div {
- background-color: white;
- border-radius: 3px;
-}
-
-#sparqlEndpoint {
- min-width: 300px;
-}
-
-#fileuploadForm .progress {
- margin-top: 0;
- margin-bottom: 5px;
-}
-
-.tab-pane .with-dataset {
- padding: 5px;
-}
-
-.file-description {
- margin-top: 10px;
-}
-
-.graph-label label {
- text-align: right;
- padding-top: 5px;
-}
-
-.dl-horizontal dt {
- width: 240px;
-}
-
-.dl-horizontal dd {
- margin-left: 260px
-}
-
-dt span.heading, dd span.heading {
- font-weight: bold;
- background-color: #eee;
- padding: 3px 8px;
-}
-
-dt span.heading {
- padding-right: 2px;
-}
-dd span.heading {
- padding-left: 2px;
-}
-dt.font-weight-normal {
- font-weight: normal;
-}
-dd .numeric {
- display: inline-block;
- min-width: 4em;
- text-align: right;
-}
-
-.bordered-box {
- border: 1px solid #ccc;
- border-radius: 5px;
-}
-
-.pull-right > button {
- margin: 10px 2px 0 0;
-}
diff --git a/triplestores/fuseki/webapp/css/jquery.dataTables.css b/triplestores/fuseki/webapp/css/jquery.dataTables.css
deleted file mode 100644
index 86845c8e82..0000000000
--- a/triplestores/fuseki/webapp/css/jquery.dataTables.css
+++ /dev/null
@@ -1,220 +0,0 @@
-
-/*
- * Table
- */
-table.dataTable {
- margin: 0 auto;
- clear: both;
- width: 100%;
-}
-
-table.dataTable thead th {
- padding: 3px 18px 3px 10px;
- border-bottom: 1px solid black;
- font-weight: bold;
- cursor: pointer;
- *cursor: hand;
-}
-
-table.dataTable tfoot th {
- padding: 3px 18px 3px 10px;
- border-top: 1px solid black;
- font-weight: bold;
-}
-
-table.dataTable td {
- padding: 3px 10px;
-}
-
-table.dataTable td.center,
-table.dataTable td.dataTables_empty {
- text-align: center;
-}
-
-table.dataTable tr.odd { background-color: #E2E4FF; }
-table.dataTable tr.even { background-color: white; }
-
-table.dataTable tr.odd td.sorting_1 { background-color: #D3D6FF; }
-table.dataTable tr.odd td.sorting_2 { background-color: #DADCFF; }
-table.dataTable tr.odd td.sorting_3 { background-color: #E0E2FF; }
-table.dataTable tr.even td.sorting_1 { background-color: #EAEBFF; }
-table.dataTable tr.even td.sorting_2 { background-color: #F2F3FF; }
-table.dataTable tr.even td.sorting_3 { background-color: #F9F9FF; }
-
-
-/*
- * Table wrapper
- */
-.dataTables_wrapper {
- position: relative;
- clear: both;
- *zoom: 1;
-}
-
-
-/*
- * Page length menu
- */
-.dataTables_length {
- float: left;
-}
-
-
-/*
- * Filter
- */
-.dataTables_filter {
- float: right;
- text-align: right;
-}
-
-
-/*
- * Table information
- */
-.dataTables_info {
- clear: both;
- float: left;
-}
-
-
-/*
- * Pagination
- */
-.dataTables_paginate {
- float: right;
- text-align: right;
-}
-
-/* Two button pagination - previous / next */
-.paginate_disabled_previous,
-.paginate_enabled_previous,
-.paginate_disabled_next,
-.paginate_enabled_next {
- height: 19px;
- float: left;
- cursor: pointer;
- *cursor: hand;
- color: #111 !important;
-}
-.paginate_disabled_previous:hover,
-.paginate_enabled_previous:hover,
-.paginate_disabled_next:hover,
-.paginate_enabled_next:hover {
- text-decoration: none !important;
-}
-.paginate_disabled_previous:active,
-.paginate_enabled_previous:active,
-.paginate_disabled_next:active,
-.paginate_enabled_next:active {
- outline: none;
-}
-
-.paginate_disabled_previous,
-.paginate_disabled_next {
- color: #666 !important;
-}
-.paginate_disabled_previous,
-.paginate_enabled_previous {
- padding-left: 23px;
-}
-.paginate_disabled_next,
-.paginate_enabled_next {
- padding-right: 23px;
- margin-left: 10px;
-}
-
-.paginate_enabled_previous { background: url('../images/back_enabled.png') no-repeat top left; }
-.paginate_enabled_previous:hover { background: url('../images/back_enabled_hover.png') no-repeat top left; }
-.paginate_disabled_previous { background: url('../images/back_disabled.png') no-repeat top left; }
-
-.paginate_enabled_next { background: url('../images/forward_enabled.png') no-repeat top right; }
-.paginate_enabled_next:hover { background: url('../images/forward_enabled_hover.png') no-repeat top right; }
-.paginate_disabled_next { background: url('../images/forward_disabled.png') no-repeat top right; }
-
-/* Full number pagination */
-.paging_full_numbers {
- height: 22px;
- line-height: 22px;
-}
-.paging_full_numbers a:active {
- outline: none
-}
-.paging_full_numbers a:hover {
- text-decoration: none;
-}
-
-.paging_full_numbers a.paginate_button,
-.paging_full_numbers a.paginate_active {
- border: 1px solid #aaa;
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
- border-radius: 5px;
- padding: 2px 5px;
- margin: 0 3px;
- cursor: pointer;
- *cursor: hand;
- color: #333 !important;
-}
-
-.paging_full_numbers a.paginate_button {
- background-color: #ddd;
-}
-
-.paging_full_numbers a.paginate_button:hover {
- background-color: #ccc;
- text-decoration: none !important;
-}
-
-.paging_full_numbers a.paginate_active {
- background-color: #99B3FF;
-}
-
-
-/*
- * Processing indicator
- */
-.dataTables_processing {
- position: absolute;
- top: 50%;
- left: 50%;
- width: 250px;
- height: 30px;
- margin-left: -125px;
- margin-top: -15px;
- padding: 14px 0 2px 0;
- border: 1px solid #ddd;
- text-align: center;
- color: #999;
- font-size: 14px;
- background-color: white;
-}
-
-
-/*
- * Sorting
- */
-.sorting { background: url('../images/sort_both.png') no-repeat center right; }
-.sorting_asc { background: url('../images/sort_asc.png') no-repeat center right; }
-.sorting_desc { background: url('../images/sort_desc.png') no-repeat center right; }
-
-.sorting_asc_disabled { background: url('../images/sort_asc_disabled.png') no-repeat center right; }
-.sorting_desc_disabled { background: url('../images/sort_desc_disabled.png') no-repeat center right; }
-
-table.dataTable thead th:active,
-table.dataTable thead td:active {
- outline: none;
-}
-
-
-/*
- * Scrolling
- */
-.dataTables_scroll {
- clear: both;
-}
-
-.dataTables_scrollBody {
- *margin-top: -1px;
- -webkit-overflow-scrolling: touch;
-}
diff --git a/triplestores/fuseki/webapp/css/jquery.fileupload-noscript.css b/triplestores/fuseki/webapp/css/jquery.fileupload-noscript.css
deleted file mode 100644
index 64d728fc31..0000000000
--- a/triplestores/fuseki/webapp/css/jquery.fileupload-noscript.css
+++ /dev/null
@@ -1,22 +0,0 @@
-@charset "UTF-8";
-/*
- * jQuery File Upload Plugin NoScript CSS 1.2.0
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2013, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * http://www.opensource.org/licenses/MIT
- */
-
-.fileinput-button input {
- position: static;
- opacity: 1;
- filter: none;
- font-size: inherit;
- direction: inherit;
-}
-.fileinput-button span {
- display: none;
-}
diff --git a/triplestores/fuseki/webapp/css/jquery.fileupload-ui-noscript.css b/triplestores/fuseki/webapp/css/jquery.fileupload-ui-noscript.css
deleted file mode 100644
index 87f110cdbd..0000000000
--- a/triplestores/fuseki/webapp/css/jquery.fileupload-ui-noscript.css
+++ /dev/null
@@ -1,17 +0,0 @@
-@charset "UTF-8";
-/*
- * jQuery File Upload UI Plugin NoScript CSS 8.8.5
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2012, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * http://www.opensource.org/licenses/MIT
- */
-
-.fileinput-button i,
-.fileupload-buttonbar .delete,
-.fileupload-buttonbar .toggle {
- display: none;
-}
diff --git a/triplestores/fuseki/webapp/css/jquery.fileupload-ui.css b/triplestores/fuseki/webapp/css/jquery.fileupload-ui.css
deleted file mode 100644
index 76fb376de0..0000000000
--- a/triplestores/fuseki/webapp/css/jquery.fileupload-ui.css
+++ /dev/null
@@ -1,57 +0,0 @@
-@charset "UTF-8";
-/*
- * jQuery File Upload UI Plugin CSS 9.0.0
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2010, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * http://www.opensource.org/licenses/MIT
- */
-
-.fileupload-buttonbar .btn,
-.fileupload-buttonbar .toggle {
- margin-bottom: 5px;
-}
-.progress-animated .progress-bar,
-.progress-animated .bar {
- background: url("../img/progressbar.gif") !important;
- filter: none;
-}
-.fileupload-process {
- float: right;
- display: none;
-}
-.fileupload-processing .fileupload-process,
-.files .processing .preview {
- display: block;
- width: 32px;
- height: 32px;
- background: url("../img/loading.gif") center no-repeat;
- background-size: contain;
-}
-.files audio,
-.files video {
- max-width: 300px;
-}
-
-@media (max-width: 767px) {
- .fileupload-buttonbar .toggle,
- .files .toggle,
- .files .btn span {
- display: none;
- }
- .files .name {
- width: 80px;
- word-wrap: break-word;
- }
- .files audio,
- .files video {
- max-width: 80px;
- }
- .files img,
- .files canvas {
- max-width: 100%;
- }
-}
diff --git a/triplestores/fuseki/webapp/css/jquery.fileupload.css b/triplestores/fuseki/webapp/css/jquery.fileupload.css
deleted file mode 100644
index fb6044d34f..0000000000
--- a/triplestores/fuseki/webapp/css/jquery.fileupload.css
+++ /dev/null
@@ -1,36 +0,0 @@
-@charset "UTF-8";
-/*
- * jQuery File Upload Plugin CSS 1.3.0
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2013, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * http://www.opensource.org/licenses/MIT
- */
-
-.fileinput-button {
- position: relative;
- overflow: hidden;
-}
-.fileinput-button input {
- position: absolute;
- top: 0;
- right: 0;
- margin: 0;
- opacity: 0;
- -ms-filter: 'alpha(opacity=0)';
- font-size: 200px;
- direction: ltr;
- cursor: pointer;
-}
-
-/* Fixes for IE < 8 */
-@media screen\9 {
- .fileinput-button input {
- filter: alpha(opacity=0);
- font-size: 100%;
- height: 100%;
- }
-}
diff --git a/triplestores/fuseki/webapp/css/pivot.min.css b/triplestores/fuseki/webapp/css/pivot.min.css
deleted file mode 100644
index b489e1e90c..0000000000
--- a/triplestores/fuseki/webapp/css/pivot.min.css
+++ /dev/null
@@ -1 +0,0 @@
-table.pvtTable{font-family:arial;font-size:8pt;text-align:left;border-collapse:collapse}table.pvtTable tr th{background-color:#e6EEEE;border:1px solid #CDCDCD;font-size:8pt;padding:5px}table.pvtTable .pvtColLabel{text-align:center}table.pvtTable .pvtTotalLabel{text-align:right}table.pvtTable tr td{color:#3D3D3D;padding:5px;background-color:#FFF;border:1px solid #CDCDCD;vertical-align:top;text-align:right}.pvtGrandTotal,.pvtTotal{font-weight:700}.pvtVals{text-align:center}.pvtAggregator{margin-bottom:5px}.pvtAxisContainer,.pvtVals{border:1px solid gray;background:#EEE;padding:5px;min-width:20px;min-height:20px}.pvtAxisContainer li{padding:8px 6px;list-style-type:none;cursor:move}.pvtAxisContainer li.pvtPlaceholder{-webkit-border-radius:5px;padding:3px 15px;-moz-border-radius:5px;border-radius:5px;border:1px dashed #aaa}.pvtAxisContainer li span.pvtAttr{background:#F3F3F3;border:1px solid #DEDEDE;padding:2px 5px;white-space:nowrap;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.pvtTriangle{cursor:pointer;color:grey}.pvtHorizList li{display:inline}.pvtVertList{vertical-align:top}.pvtFilteredAttribute{font-style:italic}.pvtFilterBox{z-index:100;width:280px;border:1px solid gray;background-color:#fff;position:absolute;padding:20px;text-align:center}.pvtFilterBox h4{margin:0}.pvtCheckContainer{text-align:left;overflow:scroll;width:100%;max-height:200px}.pvtCheckContainer p{margin:5px}
\ No newline at end of file
diff --git a/triplestores/fuseki/webapp/css/qonsole.css b/triplestores/fuseki/webapp/css/qonsole.css
deleted file mode 100644
index 99180cbfa3..0000000000
--- a/triplestores/fuseki/webapp/css/qonsole.css
+++ /dev/null
@@ -1,172 +0,0 @@
-/* Copyright (c) 2012-2013 Epimorphics Ltd. Released under Apache License 2.0 http://www.apache.org/licenses/ */
-
-.qonsole h2, .query-chrome label {
- font-size: 10px;
- color: #666666;
- margin: 0;
- text-transform: uppercase;
- display: block;
- font-weight: normal;
-}
-
-.qonsole .well {
- padding: 5px;
-}
-
-.qonsole h2+ul {
- display: inline-block;
-}
-
-.navbar h1.brand, .navbar h2.brand {
- line-height: 12px;
-}
-
-.navbar h1.brand {
- font-weight: bold;
- font-size: 16pt;
- display: inline-block;
-}
-
-h2.brand {
- display: inline-block;
- font-size: 14pt;
-}
-
-.query-chrome {
- margin-top: 1em;
-}
-
-.timeTaken {
- font-style: italic;
- text-transform: none;
- color: #666;
- margin-bottom: 5px;
-}
-
-pre.results-plain {
- overflow: auto;
- word-wrap: normal;
- white-space: pre;
-}
-
-.well ul {
- margin-bottom: 0;
-}
-
-.well ul li {
- margin-bottom: 2px;
- margin-top: 2px;
-}
-
-a.run-query {
- margin-left: 10px;
-}
-
-footer {
- font-size: smaller;
- color: #99999f;
- border: 1px solid #ddd;
- border-radius: 5px;
- padding: 5px;
-}
-
-footer p {
- margin: 0;
-}
-
-/* Custom buttons */
-
-.btn-custom1, .btn-custom2.active {
- background-color: hsl(201, 91%, 39%) !important;
- background-repeat: repeat-x;
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#087ebd", endColorstr="#087ebd");
- background-image: -khtml-gradient(linear, left top, left bottom, from(#087ebd), to(#087ebd));
- background-image: -moz-linear-gradient(top, #087ebd, #087ebd);
- background-image: -ms-linear-gradient(top, #087ebd, #087ebd);
- background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #087ebd), color-stop(100%, #087ebd));
- background-image: -webkit-linear-gradient(top, #087ebd, #087ebd);
- background-image: -o-linear-gradient(top, #087ebd, #087ebd);
- background-image: linear-gradient(#087ebd, #087ebd);
- border-color: #087ebd #087ebd hsl(201, 91%, 39%);
- color: #fff !important;
- text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.00);
- -webkit-font-smoothing: antialiased;
-}
-
-.btn-custom1:hover, .btn-custom2.active:hover {
- background-color: hsl(201, 91%, 43%) !important;
- background-repeat: repeat-x;
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#098bd1", endColorstr="#098bd1");
- background-image: -khtml-gradient(linear, left top, left bottom, from(#098bd1), to(#098bd1));
- background-image: -moz-linear-gradient(top, #098bd1, #098bd1);
- background-image: -ms-linear-gradient(top, #098bd1, #098bd1);
- background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #098bd1), color-stop(100%, #098bd1));
- background-image: -webkit-linear-gradient(top, #098bd1, #098bd1);
- background-image: -o-linear-gradient(top, #098bd1, #098bd1);
- background-image: linear-gradient(#098bd1, #098bd1);
- border-color: #098bd1 #098bd1 hsl(201, 91%, 43%);
- color: #fff !important;
- text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.00);
- -webkit-font-smoothing: antialiased;
-}
-
-
-.btn-custom2 {
- background-color: hsl(193, 32%, 75%) !important;
- background-repeat: repeat-x;
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#aacad3", endColorstr="#aacad3");
- background-image: -khtml-gradient(linear, left top, left bottom, from(#aacad3), to(#aacad3));
- background-image: -moz-linear-gradient(top, #aacad3, #aacad3);
- background-image: -ms-linear-gradient(top, #aacad3, #aacad3);
- background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #aacad3), color-stop(100%, #aacad3));
- background-image: -webkit-linear-gradient(top, #aacad3, #aacad3);
- background-image: -o-linear-gradient(top, #aacad3, #aacad3);
- background-image: linear-gradient(#aacad3, #aacad3);
- border-color: #aacad3 #aacad3 hsl(193, 32%, 75%);
- color: #333 !important;
- text-shadow: 0 1px 1px rgba(255, 255, 255, 0.00);
- -webkit-font-smoothing: antialiased;
-}
-
-.btn-custom2:hover {
- background-color: hsl(193, 31%, 70%) !important;
- background-repeat: repeat-x;
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#9abfca", endColorstr="#9abfca");
- background-image: -khtml-gradient(linear, left top, left bottom, from(#9abfca), to(#9abfca));
- background-image: -moz-linear-gradient(top, #9abfca, #9abfca);
- background-image: -ms-linear-gradient(top, #9abfca, #9abfca);
- background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #9abfca), color-stop(100%, #9abfca));
- background-image: -webkit-linear-gradient(top, #9abfca, #9abfca);
- background-image: -o-linear-gradient(top, #9abfca, #9abfca);
- background-image: linear-gradient(#9abfca, #9abfca);
- border-color: #9abfca #9abfca hsl(193, 31%, 70%);
- color: #333 !important;
- text-shadow: 0 1px 1px rgba(255, 255, 255, 0.00);
- -webkit-font-smoothing: antialiased;
-}
-
-.auto-overflow {
- overflow: auto;
-}
-
-.CodeMirror-foldmarker {
- color: blue;
- text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px;
- font-family: arial;
- line-height: .3;
- cursor: pointer;
-}
-.CodeMirror-foldgutter {
- width: .7em;
-}
-.CodeMirror-foldgutter-open,
-.CodeMirror-foldgutter-folded {
- color: #555;
- cursor: pointer;
-}
-.CodeMirror-foldgutter-open:after {
- content: "\25BE";
-}
-.CodeMirror-foldgutter-folded:after {
- content: "\25B8";
-}
diff --git a/triplestores/fuseki/webapp/css/yasqe.min.css b/triplestores/fuseki/webapp/css/yasqe.min.css
deleted file mode 100644
index abebf2ca21..0000000000
--- a/triplestores/fuseki/webapp/css/yasqe.min.css
+++ /dev/null
@@ -1 +0,0 @@
-.yasqe{position:relative}.yasqe .CodeMirror{font-family:monospace;height:300px;color:#000}.yasqe .CodeMirror-lines{padding:4px 0}.yasqe .CodeMirror pre{padding:0 4px}.yasqe .CodeMirror-gutter-filler,.yasqe .CodeMirror-scrollbar-filler{background-color:#fff}.yasqe .CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.yasqe .CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;white-space:nowrap}.yasqe .CodeMirror-guttermarker{color:#000}.yasqe .CodeMirror-guttermarker-subtle{color:#999}.yasqe .CodeMirror-cursor{border-left:1px solid #000;border-right:none;width:0}.yasqe .CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.yasqe .cm-fat-cursor .CodeMirror-cursor{width:auto;border:0;background:#7e7}.yasqe .cm-fat-cursor div.CodeMirror-cursors{z-index:1}.yasqe .cm-animate-fat-cursor{width:auto;border:0;-webkit-animation:a 1.06s steps(1) infinite;animation:a 1.06s steps(1) infinite;background-color:#7e7}@-webkit-keyframes a{50%{background-color:transparent}}@keyframes a{50%{background-color:transparent}}.yasqe .cm-tab{display:inline-block;text-decoration:inherit}.yasqe .CodeMirror-ruler{border-left:1px solid #ccc;position:absolute}.yasqe .cm-s-default .cm-header{color:blue}.yasqe .cm-s-default .cm-quote{color:#090}.yasqe .cm-negative{color:#d44}.yasqe .cm-positive{color:#292}.yasqe .cm-header,.yasqe .cm-strong{font-weight:700}.yasqe .cm-em{font-style:italic}.yasqe .cm-link{text-decoration:underline}.yasqe .cm-strikethrough{text-decoration:line-through}.yasqe .cm-s-default .cm-keyword{color:#708}.yasqe .cm-s-default .cm-atom{color:#219}.yasqe .cm-s-default .cm-number{color:#164}.yasqe .cm-s-default .cm-def{color:#00f}.yasqe .cm-s-default .cm-variable-2{color:#05a}.yasqe .cm-s-default .cm-variable-3{color:#085}.yasqe .cm-s-default .cm-comment{color:#a50}.yasqe .cm-s-default .cm-string{color:#a11}.yasqe .cm-s-default .cm-string-2{color:#f50}.yasqe .cm-s-default .cm-meta,.yasqe .cm-s-default .cm-qualifier{color:#555}.yasqe .cm-s-default .cm-builtin{color:#30a}.yasqe .cm-s-default .cm-bracket{color:#997}.yasqe .cm-s-default .cm-tag{color:#170}.yasqe .cm-s-default .cm-attribute{color:#00c}.yasqe .cm-s-default .cm-hr{color:#999}.yasqe .cm-s-default .cm-link{color:#00c}.yasqe .cm-invalidchar,.yasqe .cm-s-default .cm-error{color:red}.yasqe .CodeMirror-composing{border-bottom:2px solid}.yasqe div.CodeMirror span.CodeMirror-matchingbracket{color:#0f0}.yasqe div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#f22}.yasqe .CodeMirror-matchingtag{background:rgba(255,150,0,.3)}.yasqe .CodeMirror-activeline-background{background:#e8f2ff}.yasqe .CodeMirror{position:relative;overflow:hidden;background:#fff}.yasqe .CodeMirror-scroll{overflow:scroll!important;margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:none;position:relative}.yasqe .CodeMirror-sizer{position:relative;border-right:30px solid transparent}.yasqe .CodeMirror-gutter-filler,.yasqe .CodeMirror-hscrollbar,.yasqe .CodeMirror-scrollbar-filler,.yasqe .CodeMirror-vscrollbar{position:absolute;z-index:6;display:none}.yasqe .CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.yasqe .CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.yasqe .CodeMirror-scrollbar-filler{right:0;bottom:0}.yasqe .CodeMirror-gutter-filler{left:0;bottom:0}.yasqe .CodeMirror-gutters{position:absolute;left:0;top:0;z-index:3}.yasqe .CodeMirror-gutter{white-space:normal;height:100%;display:inline-block;margin-bottom:-30px;*zoom:1;*display:inline}.yasqe .CodeMirror-gutter-wrapper{position:absolute;z-index:4;background:none!important;border:none!important}.yasqe .CodeMirror-gutter-background{position:absolute;top:0;bottom:0;z-index:4}.yasqe .CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.yasqe .CodeMirror-gutter-wrapper{-webkit-user-select:none;-ms-user-select:none;user-select:none}.yasqe .CodeMirror-lines{cursor:text;min-height:1px}.yasqe .CodeMirror pre{border-radius:0;border-width:0;background:transparent;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible;-webkit-tap-highlight-color:transparent}.yasqe .CodeMirror-wrap pre{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.yasqe .CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.yasqe .CodeMirror-linewidget{position:relative;z-index:2;overflow:auto}.yasqe .CodeMirror-code{outline:none}.yasqe .CodeMirror-gutter,.yasqe .CodeMirror-gutters,.yasqe .CodeMirror-linenumber,.yasqe .CodeMirror-scroll,.yasqe .CodeMirror-sizer{box-sizing:content-box}.yasqe .CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.yasqe .CodeMirror-cursor{position:absolute}.yasqe .CodeMirror-measure pre{position:static}.yasqe div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:3}.yasqe .CodeMirror-focused div.CodeMirror-cursors,.yasqe div.CodeMirror-dragcursors{visibility:visible}.yasqe .CodeMirror-selected{background:#d9d9d9}.yasqe .CodeMirror-focused .CodeMirror-selected{background:#d7d4f0}.yasqe .CodeMirror-crosshair{cursor:crosshair}.yasqe .CodeMirror-line::selection,.yasqe .CodeMirror-line>span::selection,.yasqe .CodeMirror-line>span>span::selection{background:#d7d4f0}.yasqe .CodeMirror-line::-moz-selection,.yasqe .CodeMirror-line>span::-moz-selection,.yasqe .CodeMirror-line>span>span::-moz-selection{background:#d7d4f0}.yasqe .cm-searching{background:#ffa;background:rgba(255,255,0,.4)}.yasqe .CodeMirror span{*vertical-align:text-bottom}.yasqe .cm-force-border{padding-right:.1px}@media print{.yasqe .CodeMirror div.CodeMirror-cursors{visibility:hidden}}.yasqe .cm-tab-wrap-hack:after{content:''}.yasqe span.CodeMirror-selectedtext{background:none}.yasqe .CodeMirror-fullscreen{position:fixed;top:0;left:0;right:0;bottom:0;height:auto;z-index:7}.yasqe .CodeMirror-foldmarker{color:blue;text-shadow:#b9f 1px 1px 2px,#b9f -1px -1px 2px,#b9f 1px -1px 2px,#b9f -1px 1px 2px;font-family:arial;line-height:.3;cursor:pointer}.yasqe .CodeMirror-foldgutter{width:.7em}.yasqe .CodeMirror-foldgutter-folded,.yasqe .CodeMirror-foldgutter-open{cursor:pointer}.yasqe .CodeMirror-foldgutter-open:after{content:"\25BE"}.yasqe .CodeMirror-foldgutter-folded:after{content:"\25B8"}@-webkit-keyframes b{to{-webkit-transform:rotate(1turn)}}.yasqe .yasqe_btn{color:#333;border:1px solid transparent;background-color:#fff;border-color:#ccc;border-width:1px;display:inline-block;text-align:center;vertical-align:middle;cursor:pointer;white-space:nowrap;padding:6px 12px;border-radius:4px;-webkit-user-select:none;-ms-user-select:none;user-select:none;-webkit-appearance:button;overflow:visible;box-sizing:border-box}.yasqe .yasqe_btn.btn_icon{padding:4px 8px}.yasqe .yasqe_btn.disabled,.yasqe .yasqe_btn[disabled]{cursor:default;opacity:.5;filter:alpha(opacity=50);box-shadow:none}.yasqe .yasqe_btn:hover{outline:0;background-color:#ebebeb;border-color:#adadad}.yasqe .yasqe_btn.selected,.yasqe .yasqe_btn:focus{color:#fff;outline:0;background-color:#337ab7;border-color:#337ab7}.yasqe .yasqe_btn.btn_icon:focus{color:#333;border:1px solid transparent;background-color:#fff;border-color:#ccc}.yasqe .yasqe_btn.yasqe_btn-sm{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.yasqe .backdrop{background-color:#000;opacity:.5;position:absolute;top:0;left:0;right:0;bottom:0;z-index:5;display:none}.yasqe .svgImg{display:inline-block}.yasqe .CodeMirror{line-height:1.5em;border:1px solid #d1d1d1}.yasqe pre{font-size:13px}.yasqe span.cm-error{border-bottom:2px dotted red}.yasqe .gutterErrorBar{width:4px}.yasqe .yasqe_buttons{position:absolute;top:5px;right:5px;z-index:5}.yasqe .yasqe_buttons .yasqe_share{cursor:pointer;height:20px;width:20px;margin-top:3px}.yasqe .yasqe_buttons div{vertical-align:top;margin-left:5px}.yasqe .yasqe_buttons div.yasqe_sharePopup{position:absolute;padding:4px;margin-left:0;border:1px solid #e3e3e3;border-radius:4px;box-shadow:inset 0 1px 1px rgba(0,0,0,.05);width:600px;height:auto;display:-webkit-box;display:flex}.yasqe .yasqe_buttons div.yasqe_sharePopup .inputWrapper{-webkit-box-flex:100;flex-grow:100}.yasqe .yasqe_buttons div.yasqe_sharePopup input{float:left;width:100%;border:0;-ms-box-sizing:border-box;-khtml-box-sizing:border-box;box-sizing:border-box}.yasqe .yasqe_buttons div.yasqe_sharePopup button{float:right;margin-left:5px}.yasqe .yasqe_buttons div.yasqe_sharePopup textarea{width:100%}.yasqe .yasqe_buttons .yasqe_queryButton{display:inline-block;cursor:pointer;width:40px;height:40px;margin-left:10px}.yasqe .yasqe_buttons .yasqe_queryButton div{margin-left:0}.yasqe .yasqe_buttons .yasqe_queryButton .svgImg{display:block}.yasqe .yasqe_buttons .yasqe_queryButton .loader{width:36px;height:36px;border-radius:50%;box-sizing:border-box;border:4px solid rgba(0,0,0,.2);border-top-color:#000;-webkit-animation:b 1s infinite linear;animation:b 1s infinite linear}.yasqe span.shortlinkErr{font-size:small;color:red;font-weight:700;float:left}.yasqe .completionNotification{color:#999;background-color:#f7f7f7;position:absolute;padding:0 5px;right:0;bottom:0;font-size:90%}.yasqe .CodeMirror-fullscreen .fullscreenToggleBtns .yasqe_smallscreenBtn{display:inline-block}.yasqe .CodeMirror-fullscreen .fullscreenToggleBtns .yasqe_fullscreenBtn{display:none}.yasqe .fullscreenToggleBtns{display:inline-block;margin-top:3px}.yasqe .fullscreenToggleBtns div{cursor:pointer;width:20px;height:20px}.yasqe .fullscreenToggleBtns .yasqe_smallscreenBtn{display:none}.yasqe .parseErrorIcon{width:15px;height:15px}.yasqe .yasqe_tooltip{display:inline;background:#333;background:rgba(0,0,0,.8);border-radius:5px;bottom:26px;color:#fff;left:20%;padding:5px 15px;position:absolute;width:220px;white-space:-moz-pre-wrap!important;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;white-space:normal}.yasqe .notificationLoader{width:18px;height:18px;vertical-align:middle}.yasqe .CodeMirror-foldmarker{color:#6e2500;text-shadow:#ff935e 1px 1px 2px,#ff935e -1px -1px 2px,#ff935e 1px -1px 2px,#ff935e -1px 1px 2px;font-size:19px}.yasqe .matchingVar{background-color:#dbdeed;border-radius:6px;-webkit-transition:background .5s linear;transition:background .5s linear}.CodeMirror-hints{position:absolute;z-index:8;overflow:hidden;list-style:none;margin:0;padding:2px;box-shadow:2px 3px 5px rgba(0,0,0,.2);border-radius:3px;border:1px solid silver;background:#fff;font-size:90%;font-family:monospace;max-height:20em;overflow-y:auto}.CodeMirror-hint{margin:0;padding:0 4px;border-radius:2px;max-width:19em;overflow:hidden;white-space:pre;color:#000;cursor:pointer}li.CodeMirror-hint-active{background:#08f;color:#fff}.CodeMirror-hint{max-width:30em}
\ No newline at end of file
diff --git a/triplestores/fuseki/webapp/css/yasr.min.css b/triplestores/fuseki/webapp/css/yasr.min.css
deleted file mode 100644
index 04fe1011a8..0000000000
--- a/triplestores/fuseki/webapp/css/yasr.min.css
+++ /dev/null
@@ -1 +0,0 @@
-.yasr{padding-top:5px;background-color:#fff;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.428571429;color:#333}.yasr table.dataTable{width:100%;margin:0 auto;clear:both;border-collapse:separate;border-spacing:0}.yasr table.dataTable thead th,.yasr table.dataTable tfoot th{font-weight:700}.yasr table.dataTable thead th,.yasr table.dataTable thead td{padding:10px 18px;border-bottom:1px solid #111}.yasr table.dataTable thead th:active,.yasr table.dataTable thead td:active{outline:0}.yasr table.dataTable tfoot th,.yasr table.dataTable tfoot td{padding:10px 18px 6px 18px;border-top:1px solid #111}.yasr table.dataTable thead .sorting,.yasr table.dataTable thead .sorting_asc,.yasr table.dataTable thead .sorting_desc{cursor:pointer;}.yasr table.dataTable thead .sorting,.yasr table.dataTable thead .sorting_asc,.yasr table.dataTable thead .sorting_desc,.yasr table.dataTable thead .sorting_asc_disabled,.yasr table.dataTable thead .sorting_desc_disabled{background-repeat:no-repeat;background-position:center right}.yasr table.dataTable thead .sorting{background-image:url(../images/sort_both.png)}.yasr table.dataTable thead .sorting_asc{background-image:url(../images/sort_asc.png)}.yasr table.dataTable thead .sorting_desc{background-image:url(../images/sort_desc.png)}.yasr table.dataTable thead .sorting_asc_disabled{background-image:url(../images/sort_asc_disabled.png)}.yasr table.dataTable thead .sorting_desc_disabled{background-image:url(../images/sort_desc_disabled.png)}.yasr table.dataTable tbody tr{background-color:#fff}.yasr table.dataTable tbody tr.selected{background-color:#B0BED9}.yasr table.dataTable tbody th,.yasr table.dataTable tbody td{padding:8px 10px}.yasr table.dataTable.row-border tbody th,.yasr table.dataTable.row-border tbody td,.yasr table.dataTable.display tbody th,.yasr table.dataTable.display tbody td{border-top:1px solid #ddd}.yasr table.dataTable.row-border tbody tr:first-child th,.yasr table.dataTable.row-border tbody tr:first-child td,.yasr table.dataTable.display tbody tr:first-child th,.yasr table.dataTable.display tbody tr:first-child td{border-top:none}.yasr table.dataTable.cell-border tbody th,.yasr table.dataTable.cell-border tbody td{border-top:1px solid #ddd;border-right:1px solid #ddd}.yasr table.dataTable.cell-border tbody tr th:first-child,.yasr table.dataTable.cell-border tbody tr td:first-child{border-left:1px solid #ddd}.yasr table.dataTable.cell-border tbody tr:first-child th,.yasr table.dataTable.cell-border tbody tr:first-child td{border-top:none}.yasr table.dataTable.stripe tbody tr.odd,.yasr table.dataTable.display tbody tr.odd{background-color:#f9f9f9}.yasr table.dataTable.stripe tbody tr.odd.selected,.yasr table.dataTable.display tbody tr.odd.selected{background-color:#abb9d3}.yasr table.dataTable.hover tbody tr:hover,.yasr table.dataTable.display tbody tr:hover{background-color:#f5f5f5}.yasr table.dataTable.hover tbody tr:hover.selected,.yasr table.dataTable.display tbody tr:hover.selected{background-color:#a9b7d1}.yasr table.dataTable.order-column tbody tr>.sorting_1,.yasr table.dataTable.order-column tbody tr>.sorting_2,.yasr table.dataTable.order-column tbody tr>.sorting_3,.yasr table.dataTable.display tbody tr>.sorting_1,.yasr table.dataTable.display tbody tr>.sorting_2,.yasr table.dataTable.display tbody tr>.sorting_3{background-color:#f9f9f9}.yasr table.dataTable.order-column tbody tr.selected>.sorting_1,.yasr table.dataTable.order-column tbody tr.selected>.sorting_2,.yasr table.dataTable.order-column tbody tr.selected>.sorting_3,.yasr table.dataTable.display tbody tr.selected>.sorting_1,.yasr table.dataTable.display tbody tr.selected>.sorting_2,.yasr table.dataTable.display tbody tr.selected>.sorting_3{background-color:#acbad4}.yasr table.dataTable.display tbody tr.odd>.sorting_1,.yasr table.dataTable.order-column.stripe tbody tr.odd>.sorting_1{background-color:#f1f1f1}.yasr table.dataTable.display tbody tr.odd>.sorting_2,.yasr table.dataTable.order-column.stripe tbody tr.odd>.sorting_2{background-color:#f3f3f3}.yasr table.dataTable.display tbody tr.odd>.sorting_3,.yasr table.dataTable.order-column.stripe tbody tr.odd>.sorting_3{background-color:#f5f5f5}.yasr table.dataTable.display tbody tr.odd.selected>.sorting_1,.yasr table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_1{background-color:#a6b3cd}.yasr table.dataTable.display tbody tr.odd.selected>.sorting_2,.yasr table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_2{background-color:#a7b5ce}.yasr table.dataTable.display tbody tr.odd.selected>.sorting_3,.yasr table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_3{background-color:#a9b6d0}.yasr table.dataTable.display tbody tr.even>.sorting_1,.yasr table.dataTable.order-column.stripe tbody tr.even>.sorting_1{background-color:#f9f9f9}.yasr table.dataTable.display tbody tr.even>.sorting_2,.yasr table.dataTable.order-column.stripe tbody tr.even>.sorting_2{background-color:#fbfbfb}.yasr table.dataTable.display tbody tr.even>.sorting_3,.yasr table.dataTable.order-column.stripe tbody tr.even>.sorting_3{background-color:#fdfdfd}.yasr table.dataTable.display tbody tr.even.selected>.sorting_1,.yasr table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_1{background-color:#acbad4}.yasr table.dataTable.display tbody tr.even.selected>.sorting_2,.yasr table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_2{background-color:#adbbd6}.yasr table.dataTable.display tbody tr.even.selected>.sorting_3,.yasr table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_3{background-color:#afbdd8}.yasr table.dataTable.display tbody tr:hover>.sorting_1,.yasr table.dataTable.order-column.hover tbody tr:hover>.sorting_1{background-color:#eaeaea}.yasr table.dataTable.display tbody tr:hover>.sorting_2,.yasr table.dataTable.order-column.hover tbody tr:hover>.sorting_2{background-color:#ebebeb}.yasr table.dataTable.display tbody tr:hover>.sorting_3,.yasr table.dataTable.order-column.hover tbody tr:hover>.sorting_3{background-color:#eee}.yasr table.dataTable.display tbody tr:hover.selected>.sorting_1,.yasr table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_1{background-color:#a1aec7}.yasr table.dataTable.display tbody tr:hover.selected>.sorting_2,.yasr table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_2{background-color:#a2afc8}.yasr table.dataTable.display tbody tr:hover.selected>.sorting_3,.yasr table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_3{background-color:#a4b2cb}.yasr table.dataTable.no-footer{border-bottom:1px solid #111}.yasr table.dataTable.nowrap th,.yasr table.dataTable.nowrap td{white-space:nowrap}.yasr table.dataTable.compact thead th,.yasr table.dataTable.compact thead td{padding:4px 17px 4px 4px}.yasr table.dataTable.compact tfoot th,.yasr table.dataTable.compact tfoot td{padding:4px}.yasr table.dataTable.compact tbody th,.yasr table.dataTable.compact tbody td{padding:4px}.yasr table.dataTable th.dt-left,.yasr table.dataTable td.dt-left{text-align:left}.yasr table.dataTable th.dt-center,.yasr table.dataTable td.dt-center,.yasr table.dataTable td.dataTables_empty{text-align:center}.yasr table.dataTable th.dt-right,.yasr table.dataTable td.dt-right{text-align:right}.yasr table.dataTable th.dt-justify,.yasr table.dataTable td.dt-justify{text-align:justify}.yasr table.dataTable th.dt-nowrap,.yasr table.dataTable td.dt-nowrap{white-space:nowrap}.yasr table.dataTable thead th.dt-head-left,.yasr table.dataTable thead td.dt-head-left,.yasr table.dataTable tfoot th.dt-head-left,.yasr table.dataTable tfoot td.dt-head-left{text-align:left}.yasr table.dataTable thead th.dt-head-center,.yasr table.dataTable thead td.dt-head-center,.yasr table.dataTable tfoot th.dt-head-center,.yasr table.dataTable tfoot td.dt-head-center{text-align:center}.yasr table.dataTable thead th.dt-head-right,.yasr table.dataTable thead td.dt-head-right,.yasr table.dataTable tfoot th.dt-head-right,.yasr table.dataTable tfoot td.dt-head-right{text-align:right}.yasr table.dataTable thead th.dt-head-justify,.yasr table.dataTable thead td.dt-head-justify,.yasr table.dataTable tfoot th.dt-head-justify,.yasr table.dataTable tfoot td.dt-head-justify{text-align:justify}.yasr table.dataTable thead th.dt-head-nowrap,.yasr table.dataTable thead td.dt-head-nowrap,.yasr table.dataTable tfoot th.dt-head-nowrap,.yasr table.dataTable tfoot td.dt-head-nowrap{white-space:nowrap}.yasr table.dataTable tbody th.dt-body-left,.yasr table.dataTable tbody td.dt-body-left{text-align:left}.yasr table.dataTable tbody th.dt-body-center,.yasr table.dataTable tbody td.dt-body-center{text-align:center}.yasr table.dataTable tbody th.dt-body-right,.yasr table.dataTable tbody td.dt-body-right{text-align:right}.yasr table.dataTable tbody th.dt-body-justify,.yasr table.dataTable tbody td.dt-body-justify{text-align:justify}.yasr table.dataTable tbody th.dt-body-nowrap,.yasr table.dataTable tbody td.dt-body-nowrap{white-space:nowrap}.yasr table.dataTable,.yasr table.dataTable th,.yasr table.dataTable td{box-sizing:content-box}.yasr .dataTables_wrapper{position:relative;clear:both;;zoom:1}.yasr .dataTables_wrapper .dataTables_length{float:left}.yasr .dataTables_wrapper .dataTables_filter{float:right;text-align:right}.yasr .dataTables_wrapper .dataTables_filter input{margin-left:.5em}.yasr .dataTables_wrapper .dataTables_info{clear:both;float:left;padding-top:.755em}.yasr .dataTables_wrapper .dataTables_paginate{float:right;text-align:right;padding-top:.25em}.yasr .dataTables_wrapper .dataTables_paginate .paginate_button{box-sizing:border-box;display:inline-block;min-width:1.5em;padding:.5em 1em;margin-left:2px;text-align:center;text-decoration:none!important;cursor:pointer;;color:#333!important;border:1px solid transparent}.yasr .dataTables_wrapper .dataTables_paginate .paginate_button.current,.yasr .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover{color:#333!important;border:1px solid #cacaca;background-color:#fff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#fff),color-stop(100%,#dcdcdc));background:-webkit-linear-gradient(top,#fff 0,#dcdcdc 100%);background:linear-gradient(to bottom,#fff 0,#dcdcdc 100%)}.yasr .dataTables_wrapper .dataTables_paginate .paginate_button.disabled,.yasr .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover,.yasr .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active{cursor:default;color:#666!important;border:1px solid transparent;background:0 0;box-shadow:none}.yasr .dataTables_wrapper .dataTables_paginate .paginate_button:hover{color:#fff!important;border:1px solid #111;background-color:#585858;background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#585858),color-stop(100%,#111));background:-webkit-linear-gradient(top,#585858 0,#111 100%);background:linear-gradient(to bottom,#585858 0,#111 100%)}.yasr .dataTables_wrapper .dataTables_paginate .paginate_button:active{outline:0;background-color:#2b2b2b;background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#2b2b2b),color-stop(100%,#0c0c0c));background:-webkit-linear-gradient(top,#2b2b2b 0,#0c0c0c 100%);background:linear-gradient(to bottom,#2b2b2b 0,#0c0c0c 100%);box-shadow:inset 0 0 3px #111}.yasr .dataTables_wrapper .dataTables_paginate .ellipsis{padding:0 1em}.yasr .dataTables_wrapper .dataTables_processing{position:absolute;top:50%;left:50%;width:100%;height:40px;margin-left:-50%;margin-top:-25px;padding-top:20px;text-align:center;font-size:1.2em;background-color:#fff;background:-webkit-gradient(linear,left top,right top,color-stop(0%,rgba(255,255,255,0)),color-stop(25%,rgba(255,255,255,.9)),color-stop(75%,rgba(255,255,255,.9)),color-stop(100%,rgba(255,255,255,0)));background:-webkit-linear-gradient(left,rgba(255,255,255,0) 0,rgba(255,255,255,.9) 25%,rgba(255,255,255,.9) 75%,rgba(255,255,255,0) 100%);background:linear-gradient(to right,rgba(255,255,255,0) 0,rgba(255,255,255,.9) 25%,rgba(255,255,255,.9) 75%,rgba(255,255,255,0) 100%)}.yasr .dataTables_wrapper .dataTables_length,.yasr .dataTables_wrapper .dataTables_filter,.yasr .dataTables_wrapper .dataTables_info,.yasr .dataTables_wrapper .dataTables_processing,.yasr .dataTables_wrapper .dataTables_paginate{color:#333}.yasr .dataTables_wrapper .dataTables_scroll{clear:both}.yasr .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody{;-webkit-overflow-scrolling:touch}.yasr .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th>div.dataTables_sizing,.yasr .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td>div.dataTables_sizing{height:0;overflow:hidden;margin:0!important;padding:0!important}.yasr .dataTables_wrapper.no-footer .dataTables_scrollBody{border-bottom:1px solid #111}.yasr .dataTables_wrapper.no-footer div.dataTables_scrollHead table,.yasr .dataTables_wrapper.no-footer div.dataTables_scrollBody table{border-bottom:none}.yasr .dataTables_wrapper:after{visibility:hidden;display:block;content:"";clear:both;height:0}@media screen and (max-width:767px){.yasr .dataTables_wrapper .dataTables_info,.yasr .dataTables_wrapper .dataTables_paginate{float:none;text-align:center}.yasr .dataTables_wrapper .dataTables_paginate{margin-top:.5em}}@media screen and (max-width:640px){.yasr .dataTables_wrapper .dataTables_length,.yasr .dataTables_wrapper .dataTables_filter{float:none;text-align:center}.yasr .dataTables_wrapper .dataTables_filter{margin-top:.5em}}.yasr .pvtUi{color:#333}.yasr table.pvtTable{font-size:8pt;text-align:left;border-collapse:collapse}.yasr table.pvtTable tr th,.yasr table.pvtTable tr th{background-color:#e6EEEE;border:1px solid #CDCDCD;font-size:8pt;padding:5px}.yasr table.pvtTable .pvtColLabel{text-align:center}.yasr table.pvtTable .pvtTotalLabel{text-align:right}.yasr table.pvtTable tr td{color:#3D3D3D;padding:5px;background-color:#FFF;border:1px solid #CDCDCD;vertical-align:top;text-align:right}.yasr .pvtTotal,.yasr .pvtGrandTotal{font-weight:700}.yasr .pvtVals{text-align:center}.yasr .pvtAggregator{margin-bottom:5px}.yasr .pvtAxisContainer,.yasr .pvtVals{border:1px solid gray;background:#EEE;padding:5px;min-width:20px;min-height:20px}.yasr .pvtAxisContainer li{padding:8px 6px;list-style-type:none;cursor:move}.yasr .pvtAxisContainer li.pvtPlaceholder{-webkit-border-radius:5px;padding:3px 15px;border-radius:5px;border:1px dashed #aaa}.yasr .pvtAxisContainer li span.pvtAttr{background:#F3F3F3;border:1px solid #DEDEDE;padding:2px 5px;white-space:nowrap;border-radius:5px}.yasr .pvtTriangle{cursor:pointer;color:grey}.yasr .pvtHorizList li{display:inline}.yasr .pvtVertList{vertical-align:top}.yasr .pvtFilteredAttribute{font-style:italic}.yasr .pvtFilterBox{z-index:100;width:280px;border:1px solid gray;background-color:#fff;position:absolute;padding:20px;text-align:center}.yasr .pvtFilterBox h4{margin:0}.yasr .pvtFilterBox p{margin:1em auto}.yasr .pvtFilterBox label{font-weight:400}.yasr .pvtFilterBox input[type=checkbox]{margin-right:5px}.yasr .pvtCheckContainer{text-align:left;overflow:scroll;width:100%;max-height:200px}.yasr .pvtCheckContainer p{margin:5px}.yasr .pvtRendererArea{padding:5px}.yasr .CodeMirror{font-family:monospace;height:300px}.yasr .CodeMirror-lines{padding:4px 0}.yasr .CodeMirror pre{padding:0 4px}.yasr .CodeMirror-scrollbar-filler,.yasr .CodeMirror-gutter-filler{background-color:#fff}.yasr .CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.yasr .CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;box-sizing:content-box}.yasr .CodeMirror-guttermarker{color:#000}.yasr .CodeMirror-guttermarker-subtle{color:#999}.yasr .CodeMirror div.CodeMirror-cursor{border-left:1px solid #000}.yasr .CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.yasr .CodeMirror.cm-fat-cursor div.CodeMirror-cursor{width:auto;border:0;background:#7e7}.yasr .CodeMirror.cm-fat-cursor div.CodeMirror-cursors{z-index:1}.yasr .cm-animate-fat-cursor{width:auto;border:0;-webkit-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite}@-webkit-keyframes blink{0%{background:#7e7}50%{background:0 0}100%{background:#7e7}}@keyframes blink{0%{background:#7e7}50%{background:0 0}100%{background:#7e7}}.yasr .cm-tab{display:inline-block;text-decoration:inherit}.yasr .CodeMirror-ruler{border-left:1px solid #ccc;position:absolute}.yasr .cm-s-default .cm-keyword{color:#708}.yasr .cm-s-default .cm-atom{color:#219}.yasr .cm-s-default .cm-number{color:#164}.yasr .cm-s-default .cm-def{color:#00f}.yasr .cm-s-default .cm-variable-2{color:#05a}.yasr .cm-s-default .cm-variable-3{color:#085}.yasr .cm-s-default .cm-comment{color:#a50}.yasr .cm-s-default .cm-string{color:#a11}.yasr .cm-s-default .cm-string-2{color:#f50}.yasr .cm-s-default .cm-meta{color:#555}.yasr .cm-s-default .cm-qualifier{color:#555}.yasr .cm-s-default .cm-builtin{color:#30a}.yasr .cm-s-default .cm-bracket{color:#997}.yasr .cm-s-default .cm-tag{color:#170}.yasr .cm-s-default .cm-attribute{color:#00c}.yasr .cm-s-default .cm-header{color:#00f}.yasr .cm-s-default .cm-quote{color:#090}.yasr .cm-s-default .cm-hr{color:#999}.yasr .cm-s-default .cm-link{color:#00c}.yasr .cm-negative{color:#d44}.yasr .cm-positive{color:#292}.yasr .cm-header,.yasr .cm-strong{font-weight:700}.yasr .cm-em{font-style:italic}.yasr .cm-link{text-decoration:underline}.yasr .cm-strikethrough{text-decoration:line-through}.yasr .cm-s-default .cm-error{color:red}.yasr .cm-invalidchar{color:red}.yasr div.CodeMirror span.CodeMirror-matchingbracket{color:#0f0}.yasr div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#f22}.yasr .CodeMirror-matchingtag{background:rgba(255,150,0,.3)}.yasr .CodeMirror-activeline-background{background:#e8f2ff}.yasr .CodeMirror{line-height:1;position:relative;overflow:hidden;background:#fff;color:#000}.yasr .CodeMirror-scroll{overflow:scroll!important;margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:0;position:relative;box-sizing:content-box}.yasr .CodeMirror-sizer{position:relative;border-right:30px solid transparent;box-sizing:content-box}.yasr .CodeMirror-vscrollbar,.yasr .CodeMirror-hscrollbar,.yasr .CodeMirror-scrollbar-filler,.yasr .CodeMirror-gutter-filler{position:absolute;z-index:6;display:none}.yasr .CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.yasr .CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.yasr .CodeMirror-scrollbar-filler{right:0;bottom:0}.yasr .CodeMirror-gutter-filler{left:0;bottom:0}.yasr .CodeMirror-gutters{position:absolute;left:0;top:0;z-index:3}.yasr .CodeMirror-gutter{white-space:normal;height:100%;box-sizing:content-box;display:inline-block;margin-bottom:-30px;;}.yasr .CodeMirror-gutter-wrapper{position:absolute;z-index:4;height:100%}.yasr .CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.yasr .CodeMirror-lines{cursor:text;min-height:1px}.yasr .CodeMirror pre{border-radius:0;border-width:0;background:0 0;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible}.yasr .CodeMirror-wrap pre{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.yasr .CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.yasr .CodeMirror-linewidget{position:relative;z-index:2;overflow:auto}.yasr .CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.yasr .CodeMirror-measure pre{position:static}.yasr .CodeMirror div.CodeMirror-cursor{position:absolute;border-right:none;width:0}.yasr div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:3}.yasr .CodeMirror-focused div.CodeMirror-cursors{visibility:visible}.yasr .CodeMirror-selected{background:#d9d9d9}.yasr .CodeMirror-focused .CodeMirror-selected{background:#d7d4f0}.yasr .CodeMirror-crosshair{cursor:crosshair}.yasr .cm-searching{background:#ffa;background:rgba(255,255,0,.4)}.yasr .cm-force-border{padding-right:.1px}@media print{.yasr .CodeMirror div.CodeMirror-cursors{visibility:hidden}}.yasr .cm-tab-wrap-hack:after{content:''}.yasr span.CodeMirror-selectedtext{background:0 0}.yasr .CodeMirror-foldmarker{color:#00f;text-shadow:#b9f 1px 1px 2px,#b9f -1px -1px 2px,#b9f 1px -1px 2px,#b9f -1px 1px 2px;font-family:arial;line-height:.3;cursor:pointer}.yasr .CodeMirror-foldgutter{width:.7em}.yasr .CodeMirror-foldgutter-open,.yasr .CodeMirror-foldgutter-folded{cursor:pointer}.yasr .CodeMirror-foldgutter-open:after{content:"\25BE"}.yasr .CodeMirror-foldgutter-folded:after{content:"\25B8"}.yasr .svgImg{display:inline-block;bottom:-2px}.yasr button.btn_smallscreen{display:none}.yasr button.btn_smallscreen div,.yasr button.btn_fullscreen div{width:15px;height:15px}.yasr.yasr_fullscreen{z-index:10;position:fixed;overflow:auto;top:0;bottom:0;left:0;right:0}.yasr.yasr_fullscreen .btn_smallscreen{display:inline-block}.yasr.yasr_fullscreen .btn_fullscreen{display:none}.yasr a{color:#428bca;text-decoration:none}.yasr a:hover,.yasr a:active{outline:0;color:#2a6496;text-decoration:underline}.yasr th{text-align:left}.yasr .yasr_header *{z-index:5;position:relative}.yasr .yasr_header>*{margin-left:6px}.yasr .yasr_btn{color:#333;border:1px solid transparent;background-color:#fff;border-color:#ccc;border-width:1px;display:inline-block;text-align:center;vertical-align:middle;cursor:pointer;white-space:nowrap;padding:6px 12px;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-appearance:button;overflow:visible;box-sizing:border-box}.yasr .yasr_btn.btn_icon{padding:4px 8px}.yasr .yasr_btn[disabled],.yasr .yasr_btn.disabled{cursor:default;opacity:.5;filter:alpha(opacity=50);box-shadow:none}.yasr .yasr_btn:hover{outline:0;background-color:#ebebeb;border-color:#adadad}.yasr .yasr_btn:focus,.yasr .yasr_btn.selected{color:#fff;outline:0;background-color:#337ab7;border-color:#337ab7}.yasr .yasr_btn.btn_icon:focus{color:#333;border:1px solid transparent;background-color:#fff;border-color:#ccc}.yasr .yasr_downloadIcon.yasr_btn.btn_icon{padding-top:6px;padding-bottom:6px}.yasr .yasr_downloadIcon.yasr_btn.btn_icon div{height:14px;width:15px}.yasr .yasr_embedBtn.yasr_btn{font-family:Consolas,monospace;padding-left:4px;padding-right:4px}.yasr .yasr_embedPopup{position:absolute;padding:6px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;box-shadow:inset 0 1px 1px rgba(0,0,0,.05);width:700px;height:300px;font-family:Consolas,monospace}.yasr .yasr_embedPopup textarea{width:100%;height:100%;border:0}.yasr .yasr_btnGroup{display:inline-block;vertical-align:middle}.yasr .yasr_btnGroup>button:first-child:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.yasr .yasr_btnGroup>button:last-child:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.yasr .yasr_btnGroup>button:not(:first-child):not(:last-child){border-radius:0}.yasr .yasr_btnGroup button+button{margin-left:-1px}.yasr .toggableWarning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc;padding:15px 35px 15px 15px;border:1px solid transparent;border-radius:4px}.yasr .toggableWarning .toggleWarning{float:right;font-size:21px;cursor:pointer;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;position:relative;top:-2px;right:-21px;color:inherit}.yasr .toggableWarning .toggleWarning:hover{color:#000;cursor:pointer;filter:alpha(opacity=50);opacity:.5}.yasr .booleanResult{width:70px;margin:0 auto;vertical-align:middle}.yasr .booleanResult svg{margin-bottom:-10px;margin-right:7px}.yasr .errorResult{padding:10px}.yasr .errorResult .errorHeader{overflow:hidden}.yasr .errorResult .errorHeader .yasr_tryQuery{float:right;padding-top:3px;padding-bottom:3px}.yasr .errorResult .errorHeader span.exception{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em;background-color:#d9534f}.yasr .errorResult pre{display:block;padding:10px;margin:10px 0 10px;font-size:13px;line-height:1.42857;word-break:break-all;word-wrap:break-word;color:#333;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}.yasr .errorResult .corsMessage{color:#a94442;background-color:#f2dede;margin-top:10px;padding:5px;border:1px solid #ebccd1;border-radius:4px}.yasr .yasr_results .CodeMirror{border:1px solid #d1d1d1;margin-top:5px;height:100%}.yasr .dataTables_wrapper{margin-top:10px}.yasr .dataTables_wrapper .dataTables_length{float:right;margin-left:10px}.yasr .dataTables_wrapper .dataTables_length label,.yasr .dataTables_wrapper .dataTables_length select{vertical-align:middle}.yasr table.dataTable thead th{background:none!important;border-right:1px dotted gray;padding:7px 0}.yasr table.dataTable thead th:first-child,.yasr table.dataTable thead th:last-child{border-right:0}.yasr table.dataTable thead th span{margin-left:5px}.yasr table.dataTable td div{-ms-word-break:break-all;word-break:break-all;word-break:break-word;-webkit-hyphens:auto;-moz-hyphens:auto;-ms-hyphens:auto;hyphens:auto;padding:0 5px}.yasr .sortIcons{float:right;width:8px;height:13px;margin-right:10px}.yasr .dtTopHeader .dataTables_info{padding-top:0;margin:0 10px}.yasr .pivotTable{margin-top:5px}.yasr .pivotTable>table{background-color:#fff}.yasr .pivotTable td.pvtAxisContainer,.yasr .pivotTable td.pvtVals{border:1px solid #ddd;background-color:transparent}.yasr .pivotTable li span.pvtAttr{background-color:#337ab7;color:#fff;padding:4px 7px}.yasr .pivotTable li span.pvtAttr svg{fill:#fff}.yasr .pivotTable li span.pvtAttr div{margin-left:6px;vertical-align:middle}.yasr .pivotTable .pvtCols{vertical-align:top}.yasr .pivotTable table.pvtTable tr th{background-color:#f2f2f2}.yasr .pivotTable table.pvtTable tr th.pvtAxisLabel{background-color:#337ab7;color:#fff}.yasr .pivotTable .containerHeader{margin-left:8px;margin-bottom:8px;font-style:italic;font-size:110%;color:#999;text-align:left}.yasr .pivotTable .pvtAttr .svgImg{width:14px;height:14px}.yasr .pivotTable .node{border:solid 1px #fff;font:10px sans-serif;line-height:12px;overflow:hidden;position:absolute;text-indent:2px}.yasr .openPivotGchart{float:right;position:relative;display:none;top:-38px;margin-bottom:-38px}.yasr .openGchartBtn{float:right;position:relative;top:-35px;margin-bottom:-35px}.yasr .gchartWrapper{width:100%;height:600px;margin-top:2px}.modal-dialog.google-visualization-charteditor-dialog{z-index:11;width:auto;margin:inherit}.modal-dialog.google-visualization-charteditor-dialog .charts-flat-menu-button{box-sizing:content-box}
\ No newline at end of file
diff --git a/triplestores/fuseki/webapp/dataset.html b/triplestores/fuseki/webapp/dataset.html
deleted file mode 100644
index 229bcfca19..0000000000
--- a/triplestores/fuseki/webapp/dataset.html
+++ /dev/null
@@ -1,247 +0,0 @@
-
-
-
- Apache Jena Fuseki - inspect dataset
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Please select a dataset.
-
-
-
- SPARQL query
- To try out some SPARQL queries against the selected dataset, enter your
- query here.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Please select a dataset.
-
-
-
-
- Please select a dataset.
-
-
-
-
- Please select a dataset.
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/triplestores/fuseki/webapp/documentation.html b/triplestores/fuseki/webapp/documentation.html
deleted file mode 100644
index d12f1e74f1..0000000000
--- a/triplestores/fuseki/webapp/documentation.html
+++ /dev/null
@@ -1,83 +0,0 @@
-
-
-
- Apache Jena Fuseki - documentation
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/triplestores/fuseki/webapp/fonts/FontAwesome.otf b/triplestores/fuseki/webapp/fonts/FontAwesome.otf
deleted file mode 100644
index 3461e3fce6..0000000000
Binary files a/triplestores/fuseki/webapp/fonts/FontAwesome.otf and /dev/null differ
diff --git a/triplestores/fuseki/webapp/fonts/fontawesome-webfont.eot b/triplestores/fuseki/webapp/fonts/fontawesome-webfont.eot
deleted file mode 100755
index 6cfd566095..0000000000
Binary files a/triplestores/fuseki/webapp/fonts/fontawesome-webfont.eot and /dev/null differ
diff --git a/triplestores/fuseki/webapp/fonts/fontawesome-webfont.svg b/triplestores/fuseki/webapp/fonts/fontawesome-webfont.svg
deleted file mode 100755
index a9f8469503..0000000000
--- a/triplestores/fuseki/webapp/fonts/fontawesome-webfont.svg
+++ /dev/null
@@ -1,504 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/triplestores/fuseki/webapp/fonts/fontawesome-webfont.ttf b/triplestores/fuseki/webapp/fonts/fontawesome-webfont.ttf
deleted file mode 100755
index 5cd6cff6d6..0000000000
Binary files a/triplestores/fuseki/webapp/fonts/fontawesome-webfont.ttf and /dev/null differ
diff --git a/triplestores/fuseki/webapp/fonts/fontawesome-webfont.woff b/triplestores/fuseki/webapp/fonts/fontawesome-webfont.woff
deleted file mode 100755
index 9eaecb3799..0000000000
Binary files a/triplestores/fuseki/webapp/fonts/fontawesome-webfont.woff and /dev/null differ
diff --git a/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.eot b/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.eot
deleted file mode 100644
index 4a4ca865d6..0000000000
Binary files a/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.eot and /dev/null differ
diff --git a/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.svg b/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.svg
deleted file mode 100644
index e3e2dc739d..0000000000
--- a/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.svg
+++ /dev/null
@@ -1,229 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.ttf b/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.ttf
deleted file mode 100644
index 67fa00bf83..0000000000
Binary files a/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.ttf and /dev/null differ
diff --git a/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.woff b/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.woff
deleted file mode 100644
index 8c54182aa5..0000000000
Binary files a/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.woff and /dev/null differ
diff --git a/triplestores/fuseki/webapp/images/back_disabled.png b/triplestores/fuseki/webapp/images/back_disabled.png
deleted file mode 100644
index 881de7976f..0000000000
Binary files a/triplestores/fuseki/webapp/images/back_disabled.png and /dev/null differ
diff --git a/triplestores/fuseki/webapp/images/back_enabled.png b/triplestores/fuseki/webapp/images/back_enabled.png
deleted file mode 100644
index c608682b04..0000000000
Binary files a/triplestores/fuseki/webapp/images/back_enabled.png and /dev/null differ
diff --git a/triplestores/fuseki/webapp/images/back_enabled_hover.png b/triplestores/fuseki/webapp/images/back_enabled_hover.png
deleted file mode 100644
index d300f1064b..0000000000
Binary files a/triplestores/fuseki/webapp/images/back_enabled_hover.png and /dev/null differ
diff --git a/triplestores/fuseki/webapp/images/favicon.ico b/triplestores/fuseki/webapp/images/favicon.ico
deleted file mode 100644
index f5d685e085..0000000000
Binary files a/triplestores/fuseki/webapp/images/favicon.ico and /dev/null differ
diff --git a/triplestores/fuseki/webapp/images/forward_disabled.png b/triplestores/fuseki/webapp/images/forward_disabled.png
deleted file mode 100644
index 6a6ded7de8..0000000000
Binary files a/triplestores/fuseki/webapp/images/forward_disabled.png and /dev/null differ
diff --git a/triplestores/fuseki/webapp/images/forward_enabled.png b/triplestores/fuseki/webapp/images/forward_enabled.png
deleted file mode 100644
index a4e6b5384b..0000000000
Binary files a/triplestores/fuseki/webapp/images/forward_enabled.png and /dev/null differ
diff --git a/triplestores/fuseki/webapp/images/forward_enabled_hover.png b/triplestores/fuseki/webapp/images/forward_enabled_hover.png
deleted file mode 100644
index fc46c5ebf0..0000000000
Binary files a/triplestores/fuseki/webapp/images/forward_enabled_hover.png and /dev/null differ
diff --git a/triplestores/fuseki/webapp/images/jena-logo-notext-small.png b/triplestores/fuseki/webapp/images/jena-logo-notext-small.png
deleted file mode 100644
index 2990c2d14e..0000000000
Binary files a/triplestores/fuseki/webapp/images/jena-logo-notext-small.png and /dev/null differ
diff --git a/triplestores/fuseki/webapp/images/sort_asc.png b/triplestores/fuseki/webapp/images/sort_asc.png
deleted file mode 100644
index a88d7975fe..0000000000
Binary files a/triplestores/fuseki/webapp/images/sort_asc.png and /dev/null differ
diff --git a/triplestores/fuseki/webapp/images/sort_asc_disabled.png b/triplestores/fuseki/webapp/images/sort_asc_disabled.png
deleted file mode 100644
index 4e144cf0b1..0000000000
Binary files a/triplestores/fuseki/webapp/images/sort_asc_disabled.png and /dev/null differ
diff --git a/triplestores/fuseki/webapp/images/sort_both.png b/triplestores/fuseki/webapp/images/sort_both.png
deleted file mode 100644
index 18670406bc..0000000000
Binary files a/triplestores/fuseki/webapp/images/sort_both.png and /dev/null differ
diff --git a/triplestores/fuseki/webapp/images/sort_desc.png b/triplestores/fuseki/webapp/images/sort_desc.png
deleted file mode 100644
index def071ed5a..0000000000
Binary files a/triplestores/fuseki/webapp/images/sort_desc.png and /dev/null differ
diff --git a/triplestores/fuseki/webapp/images/sort_desc_disabled.png b/triplestores/fuseki/webapp/images/sort_desc_disabled.png
deleted file mode 100644
index 7824973cc6..0000000000
Binary files a/triplestores/fuseki/webapp/images/sort_desc_disabled.png and /dev/null differ
diff --git a/triplestores/fuseki/webapp/images/wait30.gif b/triplestores/fuseki/webapp/images/wait30.gif
deleted file mode 100644
index 9337ee2162..0000000000
Binary files a/triplestores/fuseki/webapp/images/wait30.gif and /dev/null differ
diff --git a/triplestores/fuseki/webapp/index.html b/triplestores/fuseki/webapp/index.html
deleted file mode 100644
index d9aa2cb93a..0000000000
--- a/triplestores/fuseki/webapp/index.html
+++ /dev/null
@@ -1,101 +0,0 @@
-
-
-
- Apache Jena Fuseki
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Apache Jena Fuseki
-
-
-
-
-
-
-
-
-
- Datasets on this server
-
-
-
-
-
-
-
- Use the following pages to perform actions or tasks on this server:
-
- - Dataset
- - Run queries and modify datasets hosted by this server.
- - Manage datasets
- - Administer the datasets on this server, including adding datasets,
- uploading data and performing backups.
- - Help
- - Summary of commands and links to online documentation.
-
-
-
-
-
-
-
diff --git a/triplestores/fuseki/webapp/js/app/controllers/.svnkeep b/triplestores/fuseki/webapp/js/app/controllers/.svnkeep
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/triplestores/fuseki/webapp/js/app/controllers/dataset-controller.js b/triplestores/fuseki/webapp/js/app/controllers/dataset-controller.js
deleted file mode 100644
index 4080c8467c..0000000000
--- a/triplestores/fuseki/webapp/js/app/controllers/dataset-controller.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/** Controller for the dataset.html page */
-
-define(
- function( require ) {
-
- var Marionette = require( "marionette" ),
- Backbone = require( "backbone" ),
- _ = require( "underscore" ),
- fui = require( "app/fui" ),
- DatasetSelectorView = require( "app/views/dataset-selector" ),
- TabbedViewManagerView = require( "app/views/tabbed-view-manager" ),
- FileUploadView = require( "app/views/file-upload" ),
- DatasetInfoView = require( "app/views/dataset-info" ),
- DatasetEditView = require( "app/views/dataset-edit" ),
- QueryController = require( "app/controllers/query-controller" ),
- UploadController = require( "app/controllers/upload-controller" );
-
- var DatasetController = function() {
- this.initEvents();
- };
-
- // add the behaviours defined on the controller
- _.extend( DatasetController.prototype, {
-
- initEvents: function() {
- _.bindAll( this, "onServerModelReady", "onDatasetChanged" );
-
- if (fui.models.fusekiServer && fui.models.fusekiServer.get( "ready" )) {
- this.onServerModelReady();
- }
- else {
- fui.vent.on( "models.fuseki-server.ready", this.onServerModelReady );
- }
-
- fui.vent.on( "dataset.changed", this.onDatasetChanged );
- },
-
- /**
- * When the fuseki server is ready, we can list the initial datasets, and
- * start the tab manager to manage the tabbed content.
- **/
- onServerModelReady: function() {
- fui.views.datasetSelectorView = new DatasetSelectorView( {model: fui.models.fusekiServer} )
- fui.views.datasetSelectorView.render();
-
- fui.views.tabbedViewManagerView = new TabbedViewManagerView();
- fui.views.tabbedViewManagerView.render();
-
- fui.controllers.queryController = new QueryController();
- fui.controllers.uploadController = new UploadController();
-
- },
-
- /** Dataset has changed */
- onDatasetChanged: function( dsName ) {
- var dataset = fui.models.fusekiServer.dataset( dsName );
- fui.views.datasetInfoView = new DatasetInfoView( {model: dataset} );
- fui.views.datasetInfoView.render();
-
- fui.views.datasetEditView = new DatasetEditView( {model: dataset} );
- fui.views.datasetEditView.render();
- }
-
- } );
-
- return DatasetController;
-
- }
-);
\ No newline at end of file
diff --git a/triplestores/fuseki/webapp/js/app/controllers/index-controller.js b/triplestores/fuseki/webapp/js/app/controllers/index-controller.js
deleted file mode 100644
index 8dba423b77..0000000000
--- a/triplestores/fuseki/webapp/js/app/controllers/index-controller.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/** Controller for the main index.html page */
-define(
- function( require ) {
- var Marionette = require( "marionette" ),
- Backbone = require( "backbone" ),
- _ = require( "underscore" ),
- fui = require( "app/fui" ),
- sprintf = require( "sprintf" ),
- DatasetSelectionListView = require( "app/views/dataset-selection-list" );
-
- var IndexController = function() {
- this.initEvents();
- };
-
- // add the behaviours defined on the controller
- _.extend( IndexController.prototype, {
-
- initEvents: function() {
- _.bindAll( this, "onServerModelReady" );
- fui.vent.on( "models.fuseki-server.ready", this.onServerModelReady );
- },
-
- onServerModelReady: function() {
- new DatasetSelectionListView( {model: fui.models.fusekiServer} ).render();
- this.displayVersion();
- },
-
- /** Display the fuseki software version */
- displayVersion: function() {
- var sd = fui.models.fusekiServer.get( "serverDescription" );
- var version = sd.version;
- var uptime = sd.uptime;
- var s = uptime % 60;
- var m = Math.floor( (uptime / 60) % 60 );
- var h = Math.floor( (uptime / (60 * 60)) % 24 );
- var d = Math.floor( (uptime / (60 * 60 * 24)) );
-
- var status = sprintf( "Version %s. Uptime: %s %s %dm %02ds",
- version,
- (d > 0 ? d + "d" : ""),
- (h > 0 ? h + "h" : ""),
- m, s );
- $('.host-details').html( status );
- }
-
- } );
-
- return IndexController;
- }
-);
diff --git a/triplestores/fuseki/webapp/js/app/controllers/manage-controller.js b/triplestores/fuseki/webapp/js/app/controllers/manage-controller.js
deleted file mode 100644
index e789844590..0000000000
--- a/triplestores/fuseki/webapp/js/app/controllers/manage-controller.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/** Controller for the admin/data-management.html page */
-define(
- function( require ) {
- var Marionette = require( "marionette" ),
- Backbone = require( "backbone" ),
- _ = require( "underscore" ),
- fui = require( "app/fui" ),
- TabbedViewManagerView = require( "app/views/tabbed-view-manager" ),
- DatasetSimpleCreateView = require( "app/views/dataset-simple-create" ),
- DatasetManagementView = require( "app/views/dataset-management" );
-
- var ManageController = function() {
- this.initEvents();
- };
-
- _.extend( ManageController.prototype, {
-
- initEvents: function() {
- _.bindAll( this, "onServerModelReady" );
- fui.vent.on( "models.fuseki-server.ready", this.onServerModelReady );
- },
-
- /** When the fuseki server is ready, we can list the initial datasets */
- onServerModelReady: function( event ) {
- fui.views.datasetManagement = new DatasetManagementView( {model: fui.models.fusekiServer} );
- fui.views.datasetManagement.render();
-
- fui.views.tabbedViewManagerView = new TabbedViewManagerView();
- fui.views.tabbedViewManagerView.render();
-
- fui.views.datasetSimpleCreate = new DatasetSimpleCreateView();
- fui.views.datasetSimpleCreate.render();
- }
-
- } );
-
- return ManageController;
- }
-);
diff --git a/triplestores/fuseki/webapp/js/app/controllers/query-controller.js b/triplestores/fuseki/webapp/js/app/controllers/query-controller.js
deleted file mode 100644
index d2fd11b195..0000000000
--- a/triplestores/fuseki/webapp/js/app/controllers/query-controller.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Controller for the embedded Qonsole component.
- *
- * Note: unlike some Qonsole installations, the endpoint URL selector dropdown
- * has been removed in favour of the dataset selector control higher up the page.
- **/
-
-define(
- function( require ) {
- var Marionette = require( "marionette" ),
- Backbone = require( "backbone" ),
- _ = require( "underscore" ),
- fui = require( "app/fui" ),
- qonsole = require( "qonsole" ),
- pageUtils = require( "app/util/page-utils" );
-
- var QueryController = function() {
- this.initEvents();
- };
-
- // add the behaviours defined on the controller
- _.extend( QueryController.prototype, {
-
- initEvents: function() {
- _.bindAll( this, "onServerModelReady", "onDatasetChanged" );
-
- if (fui.models.fusekiServer && fui.models.fusekiServer.get( "ready" )) {
- this.onServerModelReady();
- }
- else {
- fui.vent.on( "models.fuseki-server.ready", this.onServerModelReady );
- }
-
- fui.vent.on( "dataset.changed", this.onDatasetChanged );
- },
-
- /** Initialise the qonsole component */
- initQonsole: function( datasetsConfig ) {
- var qonfig = require( "app/qonsole-config" );
- qonsole.init( qonfig );
-
- var dsName = fui.models.fusekiServer.selectedDatasetName();
- if (dsName) {
- this.setEndpointURL( dsName );
- }
- },
-
- /** When the fuseki server is ready, we can init the qonsole */
- onServerModelReady: function( event ) {
- var fusekiServer = fui.models.fusekiServer;
- var endpoints = {};
- var datasets = fusekiServer.datasets();
-
- this.initQonsole( {} );
- },
-
- /** When notified that the selected dataset name has changed, update the endpoint URL */
- onDatasetChanged: function( dsName ) {
- this.setEndpointURL( dsName );
- },
-
- /** Set the endpoint URL based on the selected dataset name */
- setEndpointURL: function( dsName ) {
- var dataset = fui.models.fusekiServer.dataset( dsName );
- qonsole.setCurrentEndpoint( dataset.queryURL() );
- }
-
- } );
-
- return QueryController;
- }
-);
diff --git a/triplestores/fuseki/webapp/js/app/controllers/upload-controller.js b/triplestores/fuseki/webapp/js/app/controllers/upload-controller.js
deleted file mode 100644
index ace254726a..0000000000
--- a/triplestores/fuseki/webapp/js/app/controllers/upload-controller.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/** Controller for the file uploader component */
-
-define(
- function( require ) {
- var Marionette = require( "marionette" ),
- Backbone = require( "backbone" ),
- _ = require( "underscore" ),
- sprintf = require("sprintf"),
- pageUtils = require( "app/util/page-utils" ),
- fui = require( "app/fui" ),
- FileUploadView = require( "app/views/file-upload" );
-
- var UploadController = function() {
- this.initialize();
- };
-
- _.extend( UploadController.prototype, {
-
- /** Initialize the controler */
- initialize: function() {
- if (fui.models.fusekiServer && fui.models.fusekiServer.get( "ready" )) {
- this.onServerModelReady();
- }
- else {
- _.bindAll( this, "onServerModelReady" );
- fui.vent.on( "models.fuseki-server.ready", this.onServerModelReady );
- }
-
- },
-
- /** When the fuseki server is ready, we can set up the initial view */
- onServerModelReady: function( event ) {
- var fusekiServer = fui.models.fusekiServer;
-
- fui.views.fileUploadView = new FileUploadView();
- fui.views.fileUploadView.render();
- },
- } );
-
- return UploadController;
- }
-);
diff --git a/triplestores/fuseki/webapp/js/app/controllers/validation-controller.js b/triplestores/fuseki/webapp/js/app/controllers/validation-controller.js
deleted file mode 100644
index 43ed8ceaa3..0000000000
--- a/triplestores/fuseki/webapp/js/app/controllers/validation-controller.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/** Controller for the main index.html page */
-define(
- function( require ) {
- var Marionette = require( "marionette" ),
- Backbone = require( "backbone" ),
- _ = require( "underscore" ),
- fui = require( "app/fui" ),
- ValidationOptions = require( "app/views/validation-options" ),
- ValidationService = require( "app/services/validation-service" );
-
- var ValidationController = function() {
- this.initServices();
- this.initEvents();
- };
-
- // add the behaviours defined on the controller
- _.extend( ValidationController.prototype, {
- initEvents: function() {
- fui.vent.on( "models.validation-options.ready", this.onValidationOptionsModelReady );
- $(".validation").on( "click", "a.perform-validation", function( event ) {
- fui.services.validation.performValidation( fui.views.validationOptions.model );
- } );
- },
-
- onValidationOptionsModelReady: function( e ) {
- fui.views.validationOptions = new ValidationOptions( {model: fui.models.validationOptions} );
- },
-
- initServices: function() {
- fui.services.validation = new ValidationService( "#query-edit-cm", "#validation-output-cm" );
- fui.services.validation.init();
- }
-
- } );
-
- return ValidationController;
- }
-);
diff --git a/triplestores/fuseki/webapp/js/app/fui.js b/triplestores/fuseki/webapp/js/app/fui.js
deleted file mode 100644
index e8bc41df5a..0000000000
--- a/triplestores/fuseki/webapp/js/app/fui.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * Top-level application code module for Fuseki UI
- */
-
-define( ['require', 'backbone', 'marionette'],
- function( require, Backbone, Marionette ) {
- // define the application object, and add it to the global namespace
- var fui = new Marionette.Application();
-
- // define some Marionette modules, because they have a lifecycle component
- // see https://github.com/marionettejs/backbone.marionette/wiki/AMD-Modules-vs-Marionette%27s-Modules
- fui.module( "models" );
- fui.module( "views" );
- fui.module( "layouts" );
- fui.module( "controllers" );
- fui.module( "services" );
-
- // define top-level regions where our layouts will go
- fui.addRegions({
- });
-
- fui.on('initialize:before', function( options ) {
- });
-
- fui.on('initialize:after', function( options ) {
- // Backbone.history.start();
- this.initialized = true;
- });
-
-
- return fui;
- }
-);
diff --git a/triplestores/fuseki/webapp/js/app/layouts/.svnkeep b/triplestores/fuseki/webapp/js/app/layouts/.svnkeep
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/triplestores/fuseki/webapp/js/app/main.dataset.js b/triplestores/fuseki/webapp/js/app/main.dataset.js
deleted file mode 100644
index 50ba27bb08..0000000000
--- a/triplestores/fuseki/webapp/js/app/main.dataset.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/** RequireJS dependency configuration for dataset.html page */
-
-define( ['require', '../common-config'],
- function( require ) {
- require(
- ['underscore', 'jquery', 'backbone', 'marionette', 'app/fui', 'app/controllers/dataset-controller',
- 'sprintf',
- 'bootstrap-select.min',
- 'app/controllers/query-controller',
- 'app/controllers/upload-controller',
- 'app/models/fuseki-server',
- 'app/models/dataset',
- 'app/views/dataset-selector',
- 'app/views/tabbed-view-manager',
- 'app/services/ping-service',
- 'jquery.xdomainrequest',
- 'jquery.form',
- 'jquery.fileupload'
- ],
- function( _, $, Backbone, Marionette, fui, DatasetController ) {
- var options = { };
-
- // initialise the backbone application
- fui.controllers.datasetController = new DatasetController();
- fui.start( options );
-
- // additional services
- require( 'app/services/ping-service' ).start();
- });
- }
-);
diff --git a/triplestores/fuseki/webapp/js/app/main.index.js b/triplestores/fuseki/webapp/js/app/main.index.js
deleted file mode 100644
index 56c8903d8a..0000000000
--- a/triplestores/fuseki/webapp/js/app/main.index.js
+++ /dev/null
@@ -1,24 +0,0 @@
-
-define( ['require', '../common-config'],
- function( require ) {
- require(
- ['underscore', 'jquery', 'backbone', 'marionette',
- 'app/fui', 'app/controllers/index-controller',
- 'sprintf', 'bootstrap',
- 'app/models/fuseki-server',
- 'app/models/dataset',
- 'app/views/dataset-selection-list',
- 'app/services/ping-service'
- ],
- function( _, $, Backbone, Marionette, fui, IndexController ) {
- var options = { };
-
- // initialise the backbone application
- fui.controllers.indexController = new IndexController();
- fui.start( options );
-
- // additional services
- require( 'app/services/ping-service' ).start();
- });
- }
-);
\ No newline at end of file
diff --git a/triplestores/fuseki/webapp/js/app/main.manage.js b/triplestores/fuseki/webapp/js/app/main.manage.js
deleted file mode 100644
index 312972c71e..0000000000
--- a/triplestores/fuseki/webapp/js/app/main.manage.js
+++ /dev/null
@@ -1,27 +0,0 @@
-
-define( ['require', '../common-config'],
- function( require ) {
- require(
- ['underscore', 'jquery', 'backbone', 'marionette',
- 'app/fui', 'app/controllers/manage-controller',
- 'sprintf', 'bootstrap',
- 'app/models/fuseki-server',
- 'app/models/dataset',
- 'app/models/task',
- 'app/views/dataset-management',
- 'app/services/ping-service',
- 'jquery.xdomainrequest'
- ],
- function( _, $, Backbone, Marionette, fui, ManageController ) {
-
- var options = { } ;
-
- // initialise the backbone application
- fui.controllers.manageController = new ManageController();
- fui.start( options );
-
- // additional services
- require( 'app/services/ping-service' ).start();
- });
- }
-);
diff --git a/triplestores/fuseki/webapp/js/app/main.validation.js b/triplestores/fuseki/webapp/js/app/main.validation.js
deleted file mode 100644
index 0e30fad4c2..0000000000
--- a/triplestores/fuseki/webapp/js/app/main.validation.js
+++ /dev/null
@@ -1,24 +0,0 @@
-
-define( ['require', '../common-config'],
- function( require ) {
- require(
- ['underscore', 'jquery', 'backbone', 'marionette',
- 'app/fui', 'app/controllers/validation-controller',
- 'sprintf', 'bootstrap',
- 'app/models/validation-options',
- 'app/services/ping-service',
- 'app/services/validation-service',
- 'jquery.xdomainrequest'
- ],
- function( _, $, Backbone, Marionette, fui, ValidationController ) {
- var options = { } ;
-
- // initialise the backbone application
- fui.controllers.validationController = new ValidationController();
- fui.start( options );
-
- // additional services
-// require( 'services/ping-service' ).start(); TODO restore
- });
- }
-);
\ No newline at end of file
diff --git a/triplestores/fuseki/webapp/js/app/models/dataset-stats.js b/triplestores/fuseki/webapp/js/app/models/dataset-stats.js
deleted file mode 100644
index 35527c7d0e..0000000000
--- a/triplestores/fuseki/webapp/js/app/models/dataset-stats.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * Backbone model denoting statistics on a dataset
- */
-define(
- function( require ) {
- "use strict";
-
- var Marionette = require( "marionette" ),
- Backbone = require( "backbone" ),
- _ = require( "underscore" ),
- fui = require( "app/fui" ),
- sprintf = require( "sprintf" );
-
- /**
- * This model represents the statistics available on a one or more datasets
- */
- var DatasetStats = Backbone.Model.extend( {
- initialize: function( dataset, stats ) {
- this.set( {dataset: dataset, stats: stats} );
- },
-
- /** Return the number of datasets we have statistics for */
- size: function() {
- return _.keys( datasets() ).length;
- },
-
- toJSON: function() {
- return this.asTable();
- },
-
- /** Return a table of the statistics we have, one row per dataset */
- asTable: function() {
- var ds = this.datasets();
- var endpoints = this.collectEndpoints( ds );
- var rows = [];
-
- _.each( ds, function( d, dsName ) {
- var row = [dsName, d.Requests, d.RequestsGood, d.RequestsBad];
- var es = d.endpoints;
-
- _.each( endpoints, function( e ) {
- if (es[e.key]) {
- var servStats = es[e.key];
-
- if (servStats.Requests === 0) {
- row.push( "0" );
- }
- else {
- row.push( sprintf( "%d (%d bad)", servStats.Requests, servStats.RequestsBad ))
- }
- }
- else {
- row.push( "–" );
- }
- } );
-
- rows.push( row );
- } );
-
- return {headings: this.columnHeadings( endpoints ), rows: rows};
- },
-
- stats: function() {
- return this.get( "stats" );
- },
-
- datasets: function() {
- return this.stats().datasets;
- },
-
- /** Reload the numbers from the server */
- refresh: function() {
- var self = this;
-
- this.get( "dataset" )
- .statistics()
- .done( function( data ) {
- self.set( "stats", data );
- } );
- },
-
- // internal methods
-
- collectEndpoints: function( ds ) {
- var endpoints = [];
- _.each( ds, function( d ) {
- var ep = _.each( d.endpoints, function( v, k ) {
- endpoints.push( {key: k, label: v.description} );
- } );
- } );
-
- return _.uniq( endpoints ).sort();
- },
-
- columnHeadings: function( services ) {
- return ["Name", "Overall", "Overall good", "Overall bad"].concat( _.pluck( services, 'label' ) );
- }
- } );
-
- return DatasetStats;
- }
-);
\ No newline at end of file
diff --git a/triplestores/fuseki/webapp/js/app/models/dataset.js b/triplestores/fuseki/webapp/js/app/models/dataset.js
deleted file mode 100644
index 9c911c2621..0000000000
--- a/triplestores/fuseki/webapp/js/app/models/dataset.js
+++ /dev/null
@@ -1,254 +0,0 @@
-/**
- * Backbone model denoting the remote Fuseki server.
- */
-define(
- function( require ) {
- "use strict";
-
- var Marionette = require( "marionette" ),
- Backbone = require( "backbone" ),
- _ = require( "underscore" ),
- fui = require( "app/fui" ),
- sprintf = require( "sprintf" ),
- Task = require( "app/models/task" );
-
- /**
- * This model represents the core representation of the remote Fuseki
- * server. Individual datasets have their own model.
- */
- var Dataset = Backbone.Model.extend( {
- initialize: function( datasetDescription, baseURL, mgmtURL ) {
- this.set( datasetDescription );
- this.set( {
- baseURL: baseURL,
- mgmtURL: mgmtURL,
- counts: {},
- countPerformed: false,
- counting: false,
- statistics: false
- } );
- },
-
- baseURL: function() {
- return this.get( "baseURL" );
- },
-
- mgmtURL: function() {
- return this.get( "mgmtURL" );
- },
-
- mgmtActionURL: function() {
- return this.get( "mgmtURL" ) + this.name();
- },
-
- statisticsURL: function() {
- return sprintf( "%s/$/stats%s", this.baseURL(), this.name() );
- },
-
- name: function() {
- return this.get( "ds.name" );
- },
-
- services: function() {
- return this.get( "ds.services" );
- },
-
- countPerformed: function() {
- return this.get( "countPerformed" );
- },
-
- counts: function() {
- return this.get( "counts" );
- },
-
- serviceTypes: function() {
- return _.map( this.services(), function( s ) {return s["srv.type"];} );
- },
-
- /** Return a descriptive data-structure listing all this datasets services */
- servicesDescription: function() {
- var description = [];
- var self = this;
-
- _.each( this.services(), function( s ) {
- _.each( s["srv.endpoints"], function( e ) {
- description.push( {label: s["srv.description"],
- url: self.datasetEndpointURL( e )
- } );
- } );
- } );
-
- description.sort( function( d0, d1 ) {
- return (d0.label < d1.label) ? -1 : (d0.label > d1.label ? 1 : 0);
- } );
-
- return description;
- },
-
- /** Return the first service that has the given type */
- serviceOfType: function( serviceType ) {
- return _.find( this.services(), function( s ) {
- return s["srv.type"] === serviceType;
- } );
- },
-
- /** Return the first endpoint of the first service that has the given type */
- endpointOfType: function( serviceType ) {
- var service = this.serviceOfType( serviceType );
- return service && _.first( service["srv.endpoints"] );
- },
-
- /* Return URL for a service of a given type or null, if no such service */
- endpointURL: function( serviceType ) {
- var endpoint = this.endpointOfType( serviceType );
- return endpoint ? this.datasetEndpointURL( endpoint ) : null;
- },
-
- /** Return the URL for the given endpoint */
- datasetEndpointURL: function( endpoint ) {
- return sprintf( "%s%s/%s", this.baseURL(), this.name(), endpoint );
- },
-
- /** Return the sparql query URL for this dataset, if it has one, or null */
- queryURL: function() {
- return this.endpointURL( "Query" ) ;
- },
-
- /** Return the sparql query URL for this dataset, if it has one, or null */
- quadsURL: function() {
- return this.endpointURL( "Quads" ) ;
- },
-
- /** Return the sparql update URL for this dataset, if it has one, or null */
- updateURL: function() {
- return this.endpointURL( "Update" ) ;
- },
-
- /** Return the GSP write URL for this dataset, if it has one, or null */
- graphStoreProtocolURL: function() {
- if ( this.endpointURL( "GSP" ) )
- // Old name
- return this.endpointURL( "GSP" ) ;
- return this.endpointURL( "GSP_RW" ) ;
- },
-
- /** Return the GSP read URL for this dataset, if it has one, or null */
- graphStoreProtocolReadURL: function() {
- return this.endpointURL( "GSP_R" ) ;
- },
-
- /** Return the upload URL for this dataset, if it has one, or null */
- uploadURL: function( graphName ) {
- if (this.graphStoreProtocolURL() !== null) {
- return sprintf( "%s%s", this.graphStoreProtocolURL(), (graphName === "default" ? "" : ("?graph=" + graphName) ));
- }
- else {
- return null;
- }
- },
-
- /** Perform the action to delete the dataset. Returns the Ajax deferred object */
- deleteDataset: function() {
- return $.ajax( {
- url: this.mgmtActionURL(),
- type: 'DELETE'
- } );
- },
-
- /** Perform the action of taking a backup of this dataset */
- backupDataset: function() {
- var backupURL = sprintf( "%s/$/backup%s", this.baseURL(), this.name() );
- var ds = this;
-
- return $.ajax( {
- url: backupURL,
- type: 'POST'
- } )
- .done( function( taskDescription ) {
- new Task( ds, "backup", taskDescription );
- } );
- },
-
- /**
- * Request the statistics for this dataset, and return the promise object for the callback.
- * @param keep If truthy, and we have existing statistics, re-use the existing stats
- * */
- statistics: function( keep ) {
- var self = this;
- var currentStats = this.get( "statistics" );
-
- if (currentStats && keep) {
- return $.Deferred().resolveWith( null, currentStats );
- }
- else {
- return $.getJSON( this.statisticsURL() )
- .then( function( data ) {
- self.set( "statistics", data );
- return data;
- } );
- }
- },
-
- /** Perform a count query to determine the size of the dataset. Changes the size property when done,
- * but also returns the JQuery promise object used to monitor the query response */
- count: function() {
- var self = this;
- var query1 = sprintf( "select (count(*) as ?count) {?s ?p ?o}" );
- var query2 = sprintf( "select ?g (count(*) as ?count) {graph ?g {?s ?p ?o}} group by ?g" );
-
- self.set( "counting", true );
-
- var updateCount = function( model, result, graph ) {
- var n = parseInt( result.count.value );
- var counts = _.extend( {}, model.get( "counts" ) );
- counts[graph] = n;
- model.set( "counts", counts );
- };
-
- $.getJSON( sprintf( "%s?query=%s", self.queryURL(), query1 ) )
- .done( function( data ) {
- updateCount( self, data.results.bindings[0], "default graph" );
-
- $.getJSON( sprintf( "%s?query=%s", self.queryURL(), query2 ) )
- .done( function( data ) {
- _.each( data.results.bindings, function( binding ) {
- if (binding.g) {
- updateCount( self, binding, binding.g.value );
- }
- } );
- } );
-
- self.set( {countPerformed: true, counting: false} );
- } );
- },
-
- /**
- * Fetch the content of the given graph as Turtle. Return the jQuery promise
- * object for the Ajax call.
- */
- fetchGraph: function( graphName ) {
- return $.ajax( this.graphStoreProtocolReadURL(),
- {method: "get",
- headers: {Accept : "text/turtle; charset=utf-8"},
- dataType: "html",
- data: {graph: graphName}
- } );
- },
-
- /**
- * Put the given Turtle content back to the server using the given graph name
- */
- putGraph: function( turtle, graphName ) {
- return $.ajax( sprintf( "%s?graph=%s", this.graphStoreProtocolURL(), graphName ),
- {method: "put",
- dataType: "json",
- data: turtle,
- contentType: "text/turtle; charset=uft-8"
- } );
- }
-
- } );
-
- return Dataset;
- }
-);
diff --git a/triplestores/fuseki/webapp/js/app/models/fuseki-server.js b/triplestores/fuseki/webapp/js/app/models/fuseki-server.js
deleted file mode 100644
index 9c09574248..0000000000
--- a/triplestores/fuseki/webapp/js/app/models/fuseki-server.js
+++ /dev/null
@@ -1,184 +0,0 @@
-/**
- * Backbone model denoting the remote Fuseki server.
- */
-
-define(
- function( require ) {
- "use strict";
-
- var Marionette = require( "marionette" ),
- Backbone = require( "backbone" ),
- _ = require( "underscore" ),
- fui = require( "app/fui" ),
- sprintf = require( "sprintf" ),
- Dataset = require( "app/models/dataset" ),
- PageUtils = require( "app/util/page-utils" );
-
- var DATASETS_MANAGEMENT_PATH = "/$/datasets";
-
- /**
- * This model represents the core representation of the remote Fuseki
- * server. Individual datasets have their own model.
- */
- var FusekiServer = Backbone.Model.extend( {
- /** This initializer occurs when the module starts, not when the constructor is invoked */
- init: function( options ) {
- this._baseURL = this.currentRootPath();
- this._managementURL = null;
- this.set( "selectedDatasetName", PageUtils.queryParam( "ds" ) )
- },
-
- baseURL: function() {
- return this._baseURL;
- },
-
- /** Return the URL from which we extract the details of the current server */
- serverDetailsURL: function() {
- return sprintf( "%s/$/server", this.baseURL() );
- },
-
- /** Return the URL for issuing commands to the management API, or null if no API defined */
- managementURL: function() {
- return this._managementURL;
- },
-
- /** Return the URL for getting the stats for all datasets */
- statsURL: function() {
- return sprintf( "%s/$/stats", this.managementURL() );
- },
-
- /** Return the list of datasets that this server knows about. Each dataset will be a Dataset model object */
- datasets: function() {
- return this.get( "datasets" );
- },
-
- /** Return the dataset with the given name */
- dataset: function( dsName ) {
- return _.find( this.datasets(), function( ds ) {return dsName === ds.name();} )
- },
-
- /** Return the name of the currently selected dataset, if known */
- selectedDatasetName: function() {
- return this.get( "selectedDatasetName" );
- },
-
- /** Return the dataset that is currently selected, or null */
- selectedDataset: function() {
- var dsName = this.selectedDatasetName();
- return dsName && this.dataset( dsName );
- },
-
- /** Load and cache the remote server description. Trigger change event when done */
- loadServerDescription: function() {
- var self = this;
- return this.getJSON( this.serverDetailsURL() )
- .done( function( data ) {
- self.saveServerDescription( data );
- } )
- .then( function() {
- fui.vent.trigger( "models.fuseki-server.ready" );
- });
- },
-
- /** Store the server description in this model */
- saveServerDescription: function( serverDesc ) {
- // wrap each dataset JSON description as a dataset model
- var bURL = this.baseURL();
- var mgmtURL = bURL;
-
- if (serverDesc.admin) {
- // This is too simple. window.location.port may be empty and matches protocol.
- //mgmtURL = bURL.replace( ":" + window.location.port, ":" + serverDesc.admin.port );
- //console.log("managementURL -- s/"+window.location.port+"/"+serverDesc.admin.port+"/") ;
- var path = window.location.pathname.replace( /\/[^/]*$/, "" ) ;
- mgmtURL = sprintf( "%s//%s:%s%s", window.location.protocol, window.location.hostname, serverDesc.admin, path );
- }
- this._managementURL = mgmtURL ;
-
- var datasets = _.map( serverDesc.datasets, function( d ) {
- return new Dataset( d, bURL, mgmtURL + DATASETS_MANAGEMENT_PATH );
- } );
-
- datasets.sort( function( ds0, ds1 ) {
- if (ds0.name() > ds1.name()) {
- return 1;
- }
- else if (ds0.name() < ds1.name()) {
- return -1;
- }
- else
- return 0;
- } );
-
- this.set( {
- serverDescription: serverDesc,
- datasets: datasets,
- ready: true
- } );
- },
-
- /**
- * Get the given relative path from the server, and return a promise object which will
- * complete with the JSON object denoted by the path.
- */
- getJSON: function( path, data ) {
- return $.getJSON( path, data );
- },
-
- /** Update or create a dataset by posting to its endpoint */
- updateOrCreateDataset: function( datasetId, data ) {
- var url = sprintf( "%s/$/datasets%s", this.managementURL(),
- datasetId ? ("/" + datasetId) : ""
- );
-
- return $.ajax( url,
- { data: data,
- method: "post"
- }
- );
- },
-
- /** Extract the server root path from the current window href */
- currentRootPath: function() {
- var path = window.location.pathname.replace( /\/[^/]*$/, "" );
-
- /*
- console.log("window.location="+window.location) ;
- console.log("window.location.href="+window.location.href) ;
- console.log("window.location.protocol="+window.location.protocol) ;
- console.log("window.location.host="+window.location.host) ;
- console.log("window.location.hostname="+window.location.hostname) ;
- console.log("window.location.port="+window.location.port) ;
- console.log("window.location.pathname="+window.location.pathname) ;
- console.log("window.location.origin="+window.location.origin) ;
- console.log("window.location.hash="+window.location.hash) ;
- console.log("window.location.search="+window.location.search) ;
- console.log("path='"+path+"'") ;
- */
-
- var path2 ;
- var port = window.location.port ;
- //console.log("port='"+port+"'") ;
- if ( !port || 0 === port.length ) {
- // No explicit port.
- path2 = sprintf( "%s//%s%s", window.location.protocol, window.location.hostname, path ) ;
- } else {
- path2 = sprintf( "%s//%s:%s%s", window.location.protocol, window.location.hostname, window.location.port, path );
- }
- //console.log("path2='"+path2+"'") ;
- return path2 ;
- }
- } );
-
- // when the models module starts, automatically load the server description
- fui.models.addInitializer( function( options ) {
- var fusekiServer = new FusekiServer();
- fui.models.fusekiServer = fusekiServer;
-
- fusekiServer.init( options );
- fusekiServer.loadServerDescription();
- } );
-
- return FusekiServer;
- }
-);
diff --git a/triplestores/fuseki/webapp/js/app/models/task.js b/triplestores/fuseki/webapp/js/app/models/task.js
deleted file mode 100644
index 10c05637de..0000000000
--- a/triplestores/fuseki/webapp/js/app/models/task.js
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * A long-running task, which periodically pings the server for its task status
- */
-
-define(
- function( require ) {
- "use strict";
-
- var Marionette = require( "marionette" ),
- Backbone = require( "backbone" ),
- _ = require( "underscore" ),
- fui = require( "app/fui" ),
- sprintf = require( "sprintf" );
-
- /* Constants */
-
- var MS = 1000;
- var MAX_DELAY = 10 * MS;
-
- /**
- * This model represents a long running task process
- */
- var Task = function( ds, operationType, taskDescription ) {
- this.taskDescription = taskDescription;
- this.ds = ds;
- this.operationType = operationType;
- this.delay = 500;
-
- _.bindAll( this, "checkTaskStatus", "onCurrentTaskStatusFail", "onCurrentTaskStatus" );
-
- this.checkTaskStatus();
- };
-
- _.extend( Task.prototype, {
- /** Return the unique ID (on this server) of the task */
- taskId: function() {
- return this.taskDescription.taskId;
- },
-
- /** Return the URL for the task's API */
- taskURL: function() {
- return sprintf( "%s/$/tasks/%s", this.ds.baseURL(), this.taskId() );
- },
-
- /** Test the current status of the task */
- checkTaskStatus: function() {
- $.getJSON( this.taskURL() )
- .done( this.onCurrentTaskStatus )
- .fail( this.onCurrentTaskStatusFail )
- },
-
- /** Successful result from checking the task */
- onCurrentTaskStatus: function( taskDescription ) {
- this.taskDescription = taskDescription;
-
- var status = {
- task: this,
- dsId: this.ds.name(),
- finished: this.taskFinished()
- };
-
- fui.vent.trigger( "task.status", status );
-
- this.queueTaskStatusCheck();
- },
-
- /** Failed to check the task */
- onCurrentTaskStatusFail: function( jqxhr, msg, err ) {
- var status = {
- task: this,
- dsId: this.ds.name(),
- errorMessage: err || msg
- };
-
- fui.vent.trigger( "task.failed", status );
- },
-
- /** Re-queue the status check if the task is not yet complete */
- queueTaskStatusCheck: function() {
- if (!this.taskFinished()) {
- _.delay( this.checkTaskStatus, this.statusDelay() );
- }
- },
-
- /** Return the completion time if the task has been fid, otherwise null */
- taskFinished: function() {
- return this.taskDescription.finished;
- },
-
- /** Return the delay in ms until the next status check is due. */
- statusDelay: function() {
- var t = this.delay;
-
- if (t < MAX_DELAY) {
- this.delay = t * 2;
- }
-
- return t;
- }
- } );
-
- return Task;
- }
-);
-
diff --git a/triplestores/fuseki/webapp/js/app/models/validation-options.js b/triplestores/fuseki/webapp/js/app/models/validation-options.js
deleted file mode 100644
index b114cf9404..0000000000
--- a/triplestores/fuseki/webapp/js/app/models/validation-options.js
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * Backbone model denoting the remote Fuseki server.
- */
-define(
- function( require ) {
- "use strict";
-
- var Marionette = require( "marionette" ),
- Backbone = require( "backbone" ),
- _ = require( "underscore" ),
- fui = require( "app/fui" ),
- sprintf = require( "sprintf" );
-
- /**
- * This model represents the users current choice of options to the
- * validation service.
- */
- var ValidationOptions = Backbone.Model.extend( {
- initialize: function() {
- this.set( {validateAs: "sparql"} );
- this.set( {outputFormat: "algebra"} );
- },
-
- validateAs: function() {
- return this.get( "validateAs" );
- },
-
- validateAsQuery: function() {
- return this.validateAs() === "sparql" || this.validateAs() === "arq";
- },
-
- setValidateAs: function( va ) {
- this.set( "validateAs", va );
- console.log( JSON.stringify( this.toJSON() ));
- console.log( "----" );
- },
-
- outputFormat: function() {
- return this.get( "outputFormat" );
- },
-
- setOutputFormat: function( of ) {
- this.set( "outputFormat", of );
- },
-
- validationURL: function() {
- switch (this.get( "validateAs" )) {
- case "sparql": return "/validate/query";
- case "arq": return "/validate/query";
- case "Turtle": return "/validate/data";
- case "TriG": return "/validate/data";
- case "N-Triples": return "/validate/data";
- case "N-Quads": return "/validate/data";
- }
- },
-
- payloadParam: function() {
- return this.validateAsQuery() ? "query" : "data";
- },
-
- toJSON: function() {
- var json = {
- languageSyntax: this.validateAs(),
- lineNumbers: true
- };
-
- if (this.validateAsQuery()) {
- json.outputFormat = this.outputFormat();
- }
-
- return json;
- }
-
- } );
-
- // when the models module starts, create the model
- fui.models.addInitializer( function( options ) {
- fui.models.validationOptions = new ValidationOptions();
- fui.vent.trigger( "models.validation-options.ready" );
- } );
-
-
- return ValidationOptions;
- }
-);
\ No newline at end of file
diff --git a/triplestores/fuseki/webapp/js/app/qonsole-config.js b/triplestores/fuseki/webapp/js/app/qonsole-config.js
deleted file mode 100644
index 0c48273e8e..0000000000
--- a/triplestores/fuseki/webapp/js/app/qonsole-config.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/** Standalone configuration for qonsole on index page */
-
-define( [], function() {
- return {
- prefixes: {
- "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
- "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
- "owl": "http://www.w3.org/2002/07/owl#",
- "xsd": "http://www.w3.org/2001/XMLSchema#"
- },
- queries: [
- { "name": "Selection of triples",
- "query": "SELECT ?subject ?predicate ?object\nWHERE {\n" +
- " ?subject ?predicate ?object\n}\n" +
- "LIMIT 25"
- },
- { "name": "Selection of classes",
- "query": "SELECT DISTINCT ?class ?label ?description\nWHERE {\n" +
- " ?class a owl:Class.\n" +
- " OPTIONAL { ?class rdfs:label ?label}\n" +
- " OPTIONAL { ?class rdfs:comment ?description}\n}\n" +
- "LIMIT 25",
- "prefixes": ["owl", "rdfs"]
- }
- ]
- };
-} );
diff --git a/triplestores/fuseki/webapp/js/app/routers/.svnkeep b/triplestores/fuseki/webapp/js/app/routers/.svnkeep
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/triplestores/fuseki/webapp/js/app/services/ping-service.js b/triplestores/fuseki/webapp/js/app/services/ping-service.js
deleted file mode 100644
index 75ef6a4047..0000000000
--- a/triplestores/fuseki/webapp/js/app/services/ping-service.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * The ping service checks the status of the attached server and sets the light in the
- * control bar accordingly.
- */
-define( ['jquery', 'underscore', 'sprintf'],
- function( $, _, sprintf ) {
-
- var PING_URL = "$/ping"
- var DEFAULT_PING_TIME = 500000; // TODO slowed down during debugging phase
- var _startTime = 0;
-
- var onBeforeSend = function() {
- _startTime = new Date().getTime();
- };
-
- var duration = function() {
- return new Date().getTime() - _startTime;
- };
-
- var onPingSuccess = function( ) {
- setPingStatus( "server-up", sprintf( "Last ping returned OK in %dms", duration() ) );
- };
-
- var onPingFail = function( jqXHR, msg, errorThrown ) {
- setPingStatus( "server-down", sprintf( "Last ping returned '%s' in %dms", errorThrown || msg, duration() ) );
- };
-
- var setPingStatus = function( lampClass, statusText ) {
- $( "a#server-status-light span").removeClass()
- .addClass( lampClass )
- .attr( "title", statusText );
- };
-
- /** Return a cache-defeating ping URL */
- var ping_url = function() {
- return PING_URL + "?_=" + Math.random();
- };
-
- var start = function( period ) {
- ping( period || DEFAULT_PING_TIME );
- };
-
- var ping = function( period ) {
- onBeforeSend();
- $.get( ping_url() ).done( onPingSuccess )
- .fail( onPingFail );
- setTimeout( function() {ping( period );}, period );
- };
-
- return {
- start: start
- }
- }
-);
\ No newline at end of file
diff --git a/triplestores/fuseki/webapp/js/app/services/validation-service.js b/triplestores/fuseki/webapp/js/app/services/validation-service.js
deleted file mode 100644
index 1a5d9199c9..0000000000
--- a/triplestores/fuseki/webapp/js/app/services/validation-service.js
+++ /dev/null
@@ -1,98 +0,0 @@
-define( ['underscore', 'jquery', 'fui',
- 'lib/codemirror', 'mode/javascript/javascript', 'mode/sparql/sparql'],
- function( _, $, fui, CodeMirror ) {
-
- var ValidationService = function( editor_el, output_el ) {
- this.editor_el = editor_el;
- this.output_el = output_el;
- };
-
- _.extend( ValidationService.prototype, {
- init: function() {
- _.bindAll( this, "handleValidationOutput", "handleJsonValidationOutput" );
- this.editorElement();
- },
-
- /** Return the DOM node representing the query editor */
- editorElement: function() {
- if (!this._editor) {
- this._editor = new CodeMirror( $(this.editor_el).get(0), {
- lineNumbers: true,
- mode: "text"
- } );
- }
- return this._editor;
- },
-
- /** Return the DOM node representing the output editor */
- outputElement: function( mode, lineNumbers, data ) {
- $(this.output_el).empty();
-
- var cm = new CodeMirror( $(this.output_el).get(0), {
- lineNumbers: lineNumbers,
- mode: mode || "text",
- readOnly: true,
- value: data
- } );
-
- return cm;
- },
-
- /** Return the current code editor contents */
- editorContent: function() {
- return this.editorElement().getValue();
- },
-
- /** Perform the given action to validate the current content */
- performValidation: function( optionsModel ) {
- var context = {optionsModel: optionsModel};
- var self = this;
-
- var content = {};
- content[optionsModel.payloadParam()] = this.editorContent();
-
- var options = {
- data: _.extend( optionsModel.toJSON(), content ),
- type: "POST"
- };
-
- $.ajax( optionsModel.validationURL(), options )
- .done( function( data, status, xhr ) {
- self.handleValidationOutput( data, status, xhr, context );
- } );
- },
-
- /** Respond to validation output from the server */
- handleValidationOutput: function( data, status, xhr, context ) {
- var ct = xhr.getResponseHeader("content-type") || "";
- if (ct.match( /json/ )) {
- this.handleJsonValidationOutput( data, context );
- }
- else {
- // in HTML output, we look for a .error div
- var errors = $(data).find( "div.error" ).text();
- this.outputElement( "text", true, errors || "No warnings or errors reported." );
- }
- },
-
- handleJsonValidationOutput: function( json, context ) {
- var outputFormat = context.optionsModel.outputFormat();
- console.log( "output format = " + outputFormat );
- var jsonString = null;
-
- if (outputFormat && json[outputFormat]) {
- jsonString = json[outputFormat];
- }
- else {
- jsonString = JSON.stringify( json, null, ' ' );
- }
-
- this.outputElement( "application/json", false, jsonString );
- }
-
- } );
-
-
- return ValidationService;
- }
-);
\ No newline at end of file
diff --git a/triplestores/fuseki/webapp/js/app/templates/dataset-edit.tpl b/triplestores/fuseki/webapp/js/app/templates/dataset-edit.tpl
deleted file mode 100644
index 8202831859..0000000000
--- a/triplestores/fuseki/webapp/js/app/templates/dataset-edit.tpl
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-
-
-
-
- Available graphs
-
- <% if (countPerformed()) { %>
-
- <% } else { %>
- Click to list current graphs
- <% } %>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/triplestores/fuseki/webapp/js/app/templates/dataset-info.tpl b/triplestores/fuseki/webapp/js/app/templates/dataset-info.tpl
deleted file mode 100644
index c2c689138e..0000000000
--- a/triplestores/fuseki/webapp/js/app/templates/dataset-info.tpl
+++ /dev/null
@@ -1,40 +0,0 @@
- Available services
-
-
- <% _.each( servicesDescription(), function( serviceDescription ) { %>
- -
- <%= serviceDescription.label %>:
-
- -
- <%= serviceDescription.url %>
-
- <% } ); %>
-
-
- Statistics
-
-
- Dataset size
-
-Note this may be slow and impose a significant load on large datasets:
-
-
-<% if (countPerformed()) { %>
-
- - graph name:
- triples:
- <% _.each( counts(), function( n, g ) { %>
- -
- <%= g %>
-
- -
-
<%= n %>
-
- <% } ); %>
-
-
-<% } %>
-
- Ongoing operations
-
- TBD. Will list any long-lasting operations that are ongoing or recently completed,
-e.g. backups.
diff --git a/triplestores/fuseki/webapp/js/app/templates/dataset-management.tpl b/triplestores/fuseki/webapp/js/app/templates/dataset-management.tpl
deleted file mode 100644
index 9a01812e49..0000000000
--- a/triplestores/fuseki/webapp/js/app/templates/dataset-management.tpl
+++ /dev/null
@@ -1,62 +0,0 @@
-<% if (datasets.length === 0) { %>
- No datasets have been created yet.
- add one
-
-<% } else { %>
-
-
-
-
- Name |
-
- |
-
- <% _.each( datasets, function( ds ) { %>
-
-
- <%= ds.name() %>
- |
-
-
-
-
- |
-
- <% }) %>
-
-
-
-
-<% } %>
-
-
-
-
diff --git a/triplestores/fuseki/webapp/js/app/templates/dataset-selection-list.tpl b/triplestores/fuseki/webapp/js/app/templates/dataset-selection-list.tpl
deleted file mode 100644
index 7eda02dcae..0000000000
--- a/triplestores/fuseki/webapp/js/app/templates/dataset-selection-list.tpl
+++ /dev/null
@@ -1,22 +0,0 @@
-
- <% if (datasets.length > 0) { %>
-
- dataset name | actions |
- <% _.each( datasets, function( ds ) { %>
-
-
- <%= ds.name() %>
- |
-
- query
- add data
- info
- |
-
- <% }) %>
-
-
- <% } else { %>
- There are no datasets on this server yet. Add one.
- <% } %>
-
diff --git a/triplestores/fuseki/webapp/js/app/templates/dataset-selector.tpl b/triplestores/fuseki/webapp/js/app/templates/dataset-selector.tpl
deleted file mode 100644
index d684995cd5..0000000000
--- a/triplestores/fuseki/webapp/js/app/templates/dataset-selector.tpl
+++ /dev/null
@@ -1,15 +0,0 @@
-
- <% if (datasets.length == 0) { %>
- <% } else { %>
-
- <% } %>
-
diff --git a/triplestores/fuseki/webapp/js/app/templates/dataset-simple-create.tpl b/triplestores/fuseki/webapp/js/app/templates/dataset-simple-create.tpl
deleted file mode 100644
index 2611908c42..0000000000
--- a/triplestores/fuseki/webapp/js/app/templates/dataset-simple-create.tpl
+++ /dev/null
@@ -1,79 +0,0 @@
-
-
-
diff --git a/triplestores/fuseki/webapp/js/app/templates/dataset-stats.tpl b/triplestores/fuseki/webapp/js/app/templates/dataset-stats.tpl
deleted file mode 100644
index fc3d7d9027..0000000000
--- a/triplestores/fuseki/webapp/js/app/templates/dataset-stats.tpl
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
- <% _.each( headings, function( h ) { %>
- <%= h %> |
- <% } ); %>
-
- <% _.each( rows, function( row ) { %>
-
- <% _.each( row, function( cell ) { %>
- <%= cell %> |
- <% } ); %>
-
- <% } ) %>
-
\ No newline at end of file
diff --git a/triplestores/fuseki/webapp/js/app/templates/file-upload.tpl b/triplestores/fuseki/webapp/js/app/templates/file-upload.tpl
deleted file mode 100644
index 03d7dcc126..0000000000
--- a/triplestores/fuseki/webapp/js/app/templates/file-upload.tpl
+++ /dev/null
@@ -1,46 +0,0 @@
-
- Upload files
- Load data into the default graph of the currently selected dataset,
- or the given named graph.
- You may upload any RDF format, such as Turtle, RDF/XML or TRiG.
-
-
-
-
-
-
\ No newline at end of file
diff --git a/triplestores/fuseki/webapp/js/app/templates/uploadable-file.tpl b/triplestores/fuseki/webapp/js/app/templates/uploadable-file.tpl
deleted file mode 100644
index 83b844929c..0000000000
--- a/triplestores/fuseki/webapp/js/app/templates/uploadable-file.tpl
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
- <%= file.name %>
-
-
-
- <%= file.readableFileSize %>
-
-
-
-
-
-
-
-
-
-
diff --git a/triplestores/fuseki/webapp/js/app/util/page-utils.js b/triplestores/fuseki/webapp/js/app/util/page-utils.js
deleted file mode 100644
index 45b4ffc35b..0000000000
--- a/triplestores/fuseki/webapp/js/app/util/page-utils.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/** Utilities for managing HTML pages */
-
-define(
- function( require ) {
- "use strict";
-
- var _ = require( "underscore" );
-
- /** Return true if a given query parameter is defined, otherwise null */
- var hasQueryParam = function( param ) {
- return !!queryParam( param );
- };
-
- /** Return the value of a query parameter, or null */
- var queryParam = function( param ) {
- var p = param && queryParams()[param];
- return p ? p : null;
- };
-
- /** Return the current query params as a map */
- var queryParams = function() {
- return _.chain( document.location.search.slice(1).split('&') )
- .invoke('split', '=')
- .object()
- .value();
- };
-
- return {
- hasQueryParam: hasQueryParam,
- queryParam: queryParam
- };
- }
-);
\ No newline at end of file
diff --git a/triplestores/fuseki/webapp/js/app/views/.svnkeep b/triplestores/fuseki/webapp/js/app/views/.svnkeep
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/triplestores/fuseki/webapp/js/app/views/dataset-edit.js b/triplestores/fuseki/webapp/js/app/views/dataset-edit.js
deleted file mode 100644
index 017e0972c8..0000000000
--- a/triplestores/fuseki/webapp/js/app/views/dataset-edit.js
+++ /dev/null
@@ -1,205 +0,0 @@
-/** Component for showing detailed information about a dataset */
-
-define(
- function( require ) {
- var Backbone = require( "backbone" ),
- _ = require( "underscore" ),
- fui = require( "app/fui" ),
- DatasetEditTpl = require( "plugins/text!app/templates/dataset-edit.tpl" ),
- CodeMirror = require( "lib/codemirror" ),
- CodeMirrorTurtle = require( "mode/turtle/turtle" );
-
- var MAX_EDITABLE_SIZE = 10000;
-
- var DatasetEdit = Backbone.Marionette.ItemView.extend( {
-
- initialize: function() {
- _.bindAll( this, "onCountGraphs", "onModelChanged", "onSelectDataset",
- "onShownTab", "onShownEditTab", "onGraphContent",
- "onSaveEdit", "onCancelEdit" );
-
- this.model.on( "change", this.onModelChanged );
- this._editor = null;
-
- fui.vent.on( "shown.bs.tab", this.onShownTab );
- },
-
- template: _.template( DatasetEditTpl ),
-
- ui: {
- listGraphs: ".action.list-graphs",
- editor: "#graph-editor",
- graphName: "input.graph-name",
- saveButton: "button.save-edit",
- cancelButton: "button.cancel-edit"
- },
-
- el: "#edit .with-dataset",
-
- events: {
- "click .list-graphs": "onCountGraphs",
- "click .select-dataset": "onSelectDataset",
- "click .save-edit": "onSaveEdit",
- "click .cancel-edit": "onCancelEdit"
- },
-
- templateHelpers: {
- },
-
- serializeData: function() {
- return this.model;
- },
-
- /** Alias for the model */
- dataset: function() {
- return this.model;
- },
-
- // event handlers
-
- onModelChanged: function() {
- if (!this.model.counting) {
- this.render();
- }
- },
-
- onCountGraphs: function( e ) {
- e.preventDefault();
- this.model.count();
- },
-
- /** Event that triggers when any tab is shown */
- onShownTab: function( tab ) {
- if (tab.attr("href") === "#edit") {
- this.onShownEditTab();
- }
- },
-
- /** When the tab is show, ensure the editor element is initialised */
- onShownEditTab: function() {
- this.showEditor();
- },
-
- /** When rendering, only show the code mirror editor if the tab is visible */
- onRender: function() {
- this.showEditor();
- },
-
- /** Ensure the code mirror element is visible */
- showEditor: function() {
- if (this.editorElementVisible() && this.editorNotYetInitialised()) {
- this._editor = null;
- this.editorElement();
- }
- },
-
- /** Return true if the editor container element is visible */
- editorElementVisible: function() {
- return this.ui.editor.is( ":visible" );
- },
-
- /** Return true if the CodeMirror element has not yet been initialised */
- editorNotYetInitialised: function() {
- return this.ui.editor.is( ":not(:has(.CodeMirror))" );
- },
-
- /** User has (attempted to) select a dataset */
- onSelectDataset: function( e ) {
- e.preventDefault();
- var self = this;
- var elem = $(e.currentTarget);
- var graphName = elem.data( "graph-name" );
- var graphSize = parseInt( elem.data( "graph-size" ));
-
- if (graphSize > MAX_EDITABLE_SIZE) {
- alert( "Sorry, that dataset is too large to load into the editor" );
- }
- else {
- if (this.dirtyCheck()) {
- $(".nav.graphs").find( ".active" ).removeClass( "active" );
- elem.parent().addClass( "active" );
-
- var gn = this.setGraphName( graphName );
- this.dataset()
- .fetchGraph( gn )
- .done( self.onGraphContent );
- }
- }
- },
-
- /** Return true if the edit buffer is not dirty, or if the user says OK */
- dirtyCheck: function() {
- return true; // TODO
- },
-
- /** Return the DOM node representing the query editor */
- editorElement: function() {
- if (!this._editor) {
- this._editor = new CodeMirror( this.ui.editor.get(0), {
- lineNumbers: true,
- mode: "turtle"
- } );
- }
- return this._editor;
- },
-
- /** Set the graph name, return the actual name used */
- setGraphName: function( name ) {
- var text = (name === "default" || name === "default graph") ? "default" : name;
-
- this.ui.graphName.val( text );
-
- return text;
- },
-
- /** Get the graph name */
- graphName: function() {
- return this.ui.graphName.val();
- },
-
- /** Server has sent the content of the graph encoded as turtle */
- onGraphContent: function( data ) {
- this.editorElement().setValue( data );
- },
-
- /** User wants to save changes */
- onSaveEdit: function( e ) {
- e.preventDefault();
- var self = this;
-
- var turtle = this.editorElement().getValue();
- this.dataset()
- .putGraph( turtle, this.graphName() )
- .done( function( data ) {
- var nq = parseInt( data.quadCount );
- var nt = parseInt( data.tripleCount );
- var typ = (nq > nt) ? "quad" : "triple";
- var s = (nq + nt) === 1 ? "" : "s";
- var msg = sprintf( "Added %d %s%s", nq + nt, typ, s );
-
- self.showFeedback( msg, "" );
- } )
- .error( function( jqhxr, msg, err ) {
- self.showFeedback( err || msg, "text-warning" );
- } );
- },
-
- /** User wants to discard changes */
- onCancelEdit: function( e ) {
- e.preventDefault();
- this.ui.graphName.val( "" );
- this.editorElement().setValue( "" );
- },
-
- /** Show feedback from operations */
- showFeedback: function( msg, cls ) {
- $(".feedback").html( sprintf( " %s", cls, msg ) );
- }
-
-
- });
-
-
- return DatasetEdit;
- }
-);
diff --git a/triplestores/fuseki/webapp/js/app/views/dataset-info.js b/triplestores/fuseki/webapp/js/app/views/dataset-info.js
deleted file mode 100644
index 665725facf..0000000000
--- a/triplestores/fuseki/webapp/js/app/views/dataset-info.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/** Component for showing detailed information about a dataset */
-
-define(
- function( require ) {
- var Backbone = require( "backbone" ),
- _ = require( "underscore" ),
- fui = require( "app/fui" ),
- DatasetInfoTpl = require( "plugins/text!app/templates/dataset-info.tpl" ),
- DatasetStatsView = require( "app/views/dataset-stats" ),
- DatasetStatsModel = require( "app/models/dataset-stats" );
-
- var DatasetInfo = Backbone.Marionette.ItemView.extend( {
-
- initialize: function() {
- _.bindAll( this, "onModelChanged", "onCountGraphs" );
-
- this.showStatistics( true );
- this.model.on( "change", this.onModelChanged );
- },
-
- template: _.template( DatasetInfoTpl ),
-
- ui: {
- stats: "#statistics",
- count: ".count-graphs"
- },
-
- el: "#info .with-dataset",
-
- events: {
- "click .count-graphs": "onCountGraphs"
- },
-
- templateHelpers: {
- },
-
- serializeData: function() {
- return this.model;
- },
-
- /** Alias for the model */
- dataset: function() {
- return this.model;
- },
-
- // event handlers
-
- onModelChanged: function() {
- if (!this.model.counting) {
- this.render();
- this.showStatistics( false );
- }
- },
-
- onCountGraphs: function( e ) {
- e.preventDefault();
- this.model.count();
- },
-
- showStatistics: function( keep ) {
- var self = this;
-
- this.model
- .statistics( keep )
- .done( function( data ) {
- var statsModel = new DatasetStatsModel( self.dataset(), data );
- new DatasetStatsView( {model: statsModel} ).render();
- } );
- }
-
- });
-
-
- return DatasetInfo;
- }
-);
diff --git a/triplestores/fuseki/webapp/js/app/views/dataset-management.js b/triplestores/fuseki/webapp/js/app/views/dataset-management.js
deleted file mode 100644
index ca3af74882..0000000000
--- a/triplestores/fuseki/webapp/js/app/views/dataset-management.js
+++ /dev/null
@@ -1,173 +0,0 @@
-define(
- function( require ) {
- var Backbone = require( "backbone" ),
- _ = require( "underscore" ),
- fui = require( "app/fui" ),
- datasetManagementViewTpl = require( "plugins/text!app/templates/dataset-management.tpl" );
-
- var DataManagementView = Backbone.Marionette.ItemView.extend( {
-
- initialize: function(){
- _.bindAll( this, "onRemoveDataset", "onConfirmAction",
- "onDatasetRemoveSuccess", "onDatasetRemoveFail",
- "onTaskStatus", "onTaskFailed", "cleanup" );
-
- this.listenTo( this.model, "change", this.onModelChange, this );
-
- fui.vent.on( "action.delete.confirm", this.onConfirmRemoveDataset, this );
- fui.vent.on( "action.backup.confirm", this.onConfirmBackupDataset, this );
-
- fui.vent.on( "task.status", this.onTaskStatus, this );
- fui.vent.on( "task.failed", this.onTaskFailed, this );
- },
-
- template: _.template( datasetManagementViewTpl ),
-
- ui: {
- actionConfirmModal: "#actionConfirmModal"
- },
-
- el: "#dataset-management",
-
- events: {
- "click .action.remove": "onRemoveDataset",
- "click .action.confirm": "onConfirmAction",
- "click .action.backup": "onBackupDataset"
- },
-
- templateHelpers: {
- },
-
- cleanup: function() {
- this.unbind();
- this.undelegateEvents();
- this.model.unbind( 'change', this.onModelChange, this );
- fui.vent.unbind( 'action.delete.confirm', this.onConfirmRemoveDataset, this );
- },
-
- /** If the model changes, update the summary */
- onModelChange: function( event ) {
- this.cleanup();
- this.render();
- },
-
- /** User has requested a dataset be removed */
- onRemoveDataset: function( e ) {
- e.preventDefault();
- var elem = $(e.currentTarget);
- var dsId = elem.data( "ds-id" );
- var msg = sprintf( "Are you sure you want to delete dataset %s ? This action cannot be reversed.", dsId );
-
- this.showConfirmationModal( msg, dsId, "action.delete.confirm" );
- },
-
- /** User has requested a dataset be backed up */
- onBackupDataset: function( e ) {
- e.preventDefault();
- var elem = $(e.currentTarget);
- var dsId = elem.data( "ds-id" );
- var msg = sprintf( "Are you sure you want to create a backup of dataset %s ? This action may take some time to complete", dsId );
-
- this.showConfirmationModal( msg, dsId, "action.backup.confirm" );
- },
-
- /** Show a generic modal confirmation */
- showConfirmationModal: function( msg, dsId, eventId ) {
- this.ui.actionConfirmModal
- .find( ".modal-body p" )
- .html( msg );
-
- this.ui.actionConfirmModal
- .find( ".action.confirm" )
- .data( "ds-id", dsId )
- .data( "event-id", eventId );
-
- this.clearFeedback();
- this.ui.actionConfirmModal.modal( 'show' );
- },
-
- /** Generic response to confirming the current modal dialogue */
- onConfirmAction: function( e ) {
- e.preventDefault();
- var elem = $(e.currentTarget);
- var dsId = elem.data( "ds-id" );
- var eventId = elem.data( "event-id" );
-
- //this.ui.actionConfirmModal.modal( 'hide' );
- $('.modal.in').modal('hide');
- $('body').removeClass('modal-open');
- $('.modal-backdrop').remove();
- _.delay( function() {
- fui.vent.trigger( eventId, dsId );
- }, 100 );
- },
-
- /** User has confirmed that the dataset can be deleted */
- onConfirmRemoveDataset: function( dsId ) {
- var self = this;
-
- fui.models
- .fusekiServer
- .dataset( dsId )
- .deleteDataset()
- .done( function( data ) {self.onDatasetRemoveSuccess( data, dsId );} )
- .error( function( jqxhr, msg, err ) {self.onDatasetRemoveFail( jqxhr, msg, err, dsId );} );
- },
-
- /** Callback after successfully removing a dataset */
- onDatasetRemoveSuccess: function( data, dsId ) {
- this.model.loadServerDescription();
- },
-
- /** Removing the dataset did not work: notify the user */
- onDatasetRemoveFail: function( jqxhr, msg, err, dsId ) {
- this.feedbackArea( dsId )
- .html( sprintf( " Sorry, removing dataset %s did not work, because: '%s' ", dsId, err || msg ) );
- },
-
- /** User has confirmed backing up the dataset */
- onConfirmBackupDataset: function( dsId ) {
- var self = this;
-
- fui.models
- .fusekiServer
- .dataset( dsId )
- .backupDataset();
- },
-
- /** Remove any current feedback content */
- clearFeedback: function() {
- $(".action.feedback").empty();
- },
-
- /** Long running task has updated status */
- onTaskStatus: function( status ) {
- var task = status.task;
- var msg = sprintf( " Task %s started at %s%s ",
- task.operationType,
- task.taskDescription.started,
- status.finished ? sprintf( ", finished at %s", status.finished ) : " – ongoing" );
-
- this.feedbackArea( status.dsId )
- .html( msg );
- },
-
- /** Long running task has failed to start */
- onTaskFailed: function( status ) {
- this.feedbackArea( status.dsId )
- .html( sprintf( " Task %s failed: '%s' ", task.operationType, task.errorMessage ));
- },
-
- /** Find the feedback area for a particular dataset */
- feedbackArea: function( dsId ) {
- return $(sprintf( ".action[data-ds-id='%s']", dsId ) )
- .parent()
- .siblings(".action.feedback");
- }
-
- });
-
-
- return DataManagementView;
- }
-);
diff --git a/triplestores/fuseki/webapp/js/app/views/dataset-selection-list.js b/triplestores/fuseki/webapp/js/app/views/dataset-selection-list.js
deleted file mode 100644
index ccad19d6e6..0000000000
--- a/triplestores/fuseki/webapp/js/app/views/dataset-selection-list.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * This view presents a list of the available datasets for the user to interact
- * with.
- */
-
-define(
- function( require ) {
- var Backbone = require( "backbone" ),
- _ = require( "underscore" ),
- fui = require( "app/fui" ),
- datasetSelectionListTemplate = require( "plugins/text!app/templates/dataset-selection-list.tpl" );
-
- var DatasetSelectionListView = Backbone.Marionette.ItemView.extend( {
- initialize: function(){
-// _.bindAll(this, "onFilter", "onModelChange");
- this.listenTo( this.model, "change", this.onModelChange, this );
- },
-
- template: _.template( datasetSelectionListTemplate ),
-
- el: "#dataset-selection-list",
-
- ui: {
- },
-
- events: {
-// "change #independent-variable-selection": "selectVariable",
-// "click a.action.filter": "onFilter"
- },
-
- templateHelpers: {
- },
-
-// /** Update the model when the user changes the selection */
-// selectVariable: function( event ) {
-// this.model.set( "independentVarSelection", this.ui.variableSelection.val() );
-// },
-//
-// /** User wants to open the filter dialog */
-// onFilter: function( event ) {
-// var varModel = bgViz.models.variablesConfig.independentVar();
-// var rangeType = varModel.component.range().rangeType();
-// var viewName = rangeType.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
-//
-// bgViz.layouts.filterDialog.showFilter( viewName, varModel );
-// },
-
- /** If the model changes, update the summary */
- onModelChange: function( event ) {
-// this.ui.summary.html( this.model.independentVar().component.range().summarise() );
- }
-
- });
-
-
- return DatasetSelectionListView;
- }
-);
diff --git a/triplestores/fuseki/webapp/js/app/views/dataset-selector.js b/triplestores/fuseki/webapp/js/app/views/dataset-selector.js
deleted file mode 100644
index f14a74730d..0000000000
--- a/triplestores/fuseki/webapp/js/app/views/dataset-selector.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * Reusable component that encapsulates selecting a dataset to work on in a given page.
- * Takes the FusekiServer as a model, and populates a select control to choose one of the
- * current datasets. If the dataset changes, this view will update the `selectedDatasetName`
- * on the model, and trigger the event `dataset.changed`.
- **/
-
-define(
- function( require ) {
- "use strict";
-
- var Marionette = require( "marionette" ),
- Backbone = require( "backbone" ),
- _ = require( "underscore" ),
- fui = require( "app/fui" ),
- sprintf = require( "sprintf" ),
- datasetSelectorTemplate = require( "plugins/text!app/templates/dataset-selector.tpl" );
-
- var DatasetSelectorView = Backbone.Marionette.ItemView.extend( {
-
- initialize: function(){
- this.listenTo( this.model, "change", this.render, this );
- },
-
- template: _.template( datasetSelectorTemplate ),
-
- el: ".dataset-selector-container",
-
- ui: {
- select: ".dataset-selector select"
- },
-
- events: {
- "change .dataset-selector select": "onChangeDataset"
- },
-
- /**
- * After rendering, set up the dataset picker and notify the rest of the
- * app if the default dataset name is known.
- */
- onRender: function() {
- var selector = $('.selectpicker');
- selector.selectpicker('refresh');
-
- if (selector.val()) {
- this.unHideDatasetElements();
- this.onChangeDataset();
- }
- },
-
- /**
- * Respond to a change in the dataset name selection by updating
- * the underlying model. TODO: should also update the application
- * URL.
- */
- onChangeDataset: function( e ) {
- var newDatasetName = this.ui.select.val();
- this.model.set( "selectedDatasetName", newDatasetName );
- this.notifyDatasetName( newDatasetName );
- },
-
- /**
- * Ensure that elements that should be visible when a dataset is known
- * are not hidden, and vice-versa.
- */
- unHideDatasetElements: function() {
- $(".no-dataset").addClass( "hidden" );
- $(".with-dataset").removeClass( "hidden" );
- },
-
- /** Trigger an event to notify other components that the dataset
- * name has been selected.
- */
- notifyDatasetName: function( dsName ) {
- fui.vent.trigger( "dataset.changed", dsName || this.ui.select.val() );
- }
-
-
- });
-
-
- return DatasetSelectorView;
- }
-);
diff --git a/triplestores/fuseki/webapp/js/app/views/dataset-simple-create.js b/triplestores/fuseki/webapp/js/app/views/dataset-simple-create.js
deleted file mode 100644
index b7a591bda0..0000000000
--- a/triplestores/fuseki/webapp/js/app/views/dataset-simple-create.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/** Component for creating a new dataset with a few simple options */
-
-define(
- function( require ) {
- var Backbone = require( "backbone" ),
- _ = require( "underscore" ),
- fui = require( "app/fui" ),
- DatasetSimpleCreateTpl = require( "plugins/text!app/templates/dataset-simple-create.tpl" );
-
- var DatasetSimpleCreate = Backbone.Marionette.ItemView.extend( {
-
- initialize: function() {
- _.bindAll( this, "onCommitSimple", "clearWarnings" );
- },
-
- template: _.template( DatasetSimpleCreateTpl ),
-
- ui: {
- },
-
- el: "#dataset-simple-create",
-
- events: {
- "click a.action.commit.simple": "onCommitSimple",
- "submit form": "onCommitSimple",
- "keydown input[name=dbName]": "clearWarnings"
- },
-
- templateHelpers: {
- },
-
- serializeData: function() {
- return this.model;
- },
-
- // event handlers
-
- onCommitSimple: function( e ) {
- e.preventDefault();
-
- if (this.validateSimpleForm()) {
- var datasetName = $("input[name=dbName]").val().trim();
- $("input[name=dbName]").val(datasetName);
- var options = $("#simple-edit form").serializeArray();
- fui.models.fusekiServer.updateOrCreateDataset( null, options )
- .done( this.showDataManagementPage )
- .fail( this.showFailureMessage );
- }
- },
-
-// onCommitUpload: function( e ) {
-// e.preventDefault();
-//
-// if (this.validateUploadForm()) {
-// $("#uploadForm").ajaxSubmit( {
-// success: this.showDataManagementPage,
-// error: this.showFailureMessage
-// });
-// }
-// },
-//
- showDataManagementPage: function( e ) {
- location = "?tab=datasets";
- },
-
- /** Todo: need to do a better job of responding to errors */
- showFailureMessage: function( jqXHR, textStatus, errorThrown ) {
- $(".errorOutput").html( sprintf( " Sorry, that didn't work because: %s ", errorThrown || textStatus ) );
- },
-
- /** Clear current warning states */
- clearWarnings: function() {
- this.clearValidation();
- $(".errorOutput").empty();
- },
-
- // validation
-
- validateSimpleForm: function() {
- this.clearValidation();
-
- if (! $("input[name=dbName]").val() || 0 === $("input[name=dbName]").val().trim().length) {
- $(".dbNameValidation").removeClass("hidden")
- .parents(".form-group" )
- .addClass( "has-error" );
- return false;
- }
-
- return true;
- },
-
- clearValidation: function() {
- $(".has-error").removeClass( "has-error" );
- $(".has-warning").removeClass( "has-warning" );
- }
-
- });
-
-
- return DatasetSimpleCreate;
- }
-);
diff --git a/triplestores/fuseki/webapp/js/app/views/dataset-stats.js b/triplestores/fuseki/webapp/js/app/views/dataset-stats.js
deleted file mode 100644
index f2dc198eab..0000000000
--- a/triplestores/fuseki/webapp/js/app/views/dataset-stats.js
+++ /dev/null
@@ -1,41 +0,0 @@
-define(
- function( require ) {
- var Backbone = require( "backbone" ),
- _ = require( "underscore" ),
- fui = require( "app/fui" ),
- datasetStatsViewTpl = require( "plugins/text!app/templates/dataset-stats.tpl" );
-
- var DatasetStatsView = Backbone.Marionette.ItemView.extend( {
- initialize: function() {
- _.bindAll( this, "onShowTab" );
-
- fui.vent.on( "shown.bs.tab", this.onShowTab );
- },
-
- template: _.template( datasetStatsViewTpl ),
-
- ui: {
- },
-
- el: "#statistics",
-
- modelEvents: {
- 'change': "modelChanged"
- },
-
- modelChanged: function() {
- this.render();
- },
-
- onShowTab: function( tab ) {
- if (tab.attr("href") === "#info") {
- this.model.refresh();
- }
- }
-
- });
-
-
- return DatasetStatsView;
- }
-);
diff --git a/triplestores/fuseki/webapp/js/app/views/datasets-dropdown-list.js b/triplestores/fuseki/webapp/js/app/views/datasets-dropdown-list.js
deleted file mode 100644
index 92b2bf41ee..0000000000
--- a/triplestores/fuseki/webapp/js/app/views/datasets-dropdown-list.js
+++ /dev/null
@@ -1,43 +0,0 @@
-define(
- function( require ) {
- var Backbone = require( "backbone" ),
- _ = require( "underscore" ),
- fui = require( "app/fui" );
-
- var DatasetDropDownListView = Backbone.Marionette.ItemView.extend( {
- initialize: function(){
- },
-
- template:"",
-
- el: "ul.dropdown-menu.dataset-list",
-
- ui: {
- },
-
- events: {
- },
-
- render: function() {
- var e = $(this.el).empty();
- _.each( this.model, function( ds ) {
- e.append( sprintf( " - %s
", ds.name(), ds.name() ));
- } );
- },
-
- /** Change the currently selected dataset name. If required, notify other units via an event */
- setCurrentDatasetName: function( dsName, notify ) {
- if (dsName) {
- $(".current-dataset").text( dsName );
- }
-
- if (notify) {
- fui.vent.trigger( "views.datasets-dropdown-list.dataset-changed", dsName )
- }
- }
- });
-
-
- return DatasetDropDownListView;
- }
-);
diff --git a/triplestores/fuseki/webapp/js/app/views/file-upload.js b/triplestores/fuseki/webapp/js/app/views/file-upload.js
deleted file mode 100644
index f16e544c79..0000000000
--- a/triplestores/fuseki/webapp/js/app/views/file-upload.js
+++ /dev/null
@@ -1,225 +0,0 @@
-/**
- * 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( " Result: success. %s ", 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( " Result: failed with message "%s" ", 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;
- }
-);
diff --git a/triplestores/fuseki/webapp/js/app/views/tabbed-view-manager.js b/triplestores/fuseki/webapp/js/app/views/tabbed-view-manager.js
deleted file mode 100644
index 5bba26d25b..0000000000
--- a/triplestores/fuseki/webapp/js/app/views/tabbed-view-manager.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * 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;
- }
-);
diff --git a/triplestores/fuseki/webapp/js/app/views/uploadable-file.js b/triplestores/fuseki/webapp/js/app/views/uploadable-file.js
deleted file mode 100644
index 382a92ffc8..0000000000
--- a/triplestores/fuseki/webapp/js/app/views/uploadable-file.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * 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;
- }
-);
diff --git a/triplestores/fuseki/webapp/js/app/views/validation-options.js b/triplestores/fuseki/webapp/js/app/views/validation-options.js
deleted file mode 100644
index ef0f723d35..0000000000
--- a/triplestores/fuseki/webapp/js/app/views/validation-options.js
+++ /dev/null
@@ -1,54 +0,0 @@
-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;
- }
-);
diff --git a/triplestores/fuseki/webapp/js/common-config.js b/triplestores/fuseki/webapp/js/common-config.js
deleted file mode 100644
index eac4b27182..0000000000
--- a/triplestores/fuseki/webapp/js/common-config.js
+++ /dev/null
@@ -1,94 +0,0 @@
-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'],
- deps: ['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']}
- }
-});
diff --git a/triplestores/fuseki/webapp/js/lib/addon/fold/brace-fold.js b/triplestores/fuseki/webapp/js/lib/addon/fold/brace-fold.js
deleted file mode 100644
index 1605f6c2a9..0000000000
--- a/triplestores/fuseki/webapp/js/lib/addon/fold/brace-fold.js
+++ /dev/null
@@ -1,105 +0,0 @@
-// 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))};
-});
-
-});
diff --git a/triplestores/fuseki/webapp/js/lib/addon/fold/comment-fold.js b/triplestores/fuseki/webapp/js/lib/addon/fold/comment-fold.js
deleted file mode 100644
index b75db7ea25..0000000000
--- a/triplestores/fuseki/webapp/js/lib/addon/fold/comment-fold.js
+++ /dev/null
@@ -1,57 +0,0 @@
-// 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)};
-});
-
-});
diff --git a/triplestores/fuseki/webapp/js/lib/addon/fold/foldcode.js b/triplestores/fuseki/webapp/js/lib/addon/fold/foldcode.js
deleted file mode 100644
index 3abeb83e76..0000000000
--- a/triplestores/fuseki/webapp/js/lib/addon/fold/foldcode.js
+++ /dev/null
@@ -1,145 +0,0 @@
-// 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];
- }
-});
diff --git a/triplestores/fuseki/webapp/js/lib/addon/fold/foldgutter.js b/triplestores/fuseki/webapp/js/lib/addon/fold/foldgutter.js
deleted file mode 100644
index bd31ec4d9b..0000000000
--- a/triplestores/fuseki/webapp/js/lib/addon/fold/foldgutter.js
+++ /dev/null
@@ -1,134 +0,0 @@
-// 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);
- }
-});
diff --git a/triplestores/fuseki/webapp/js/lib/addon/fold/xml-fold.js b/triplestores/fuseki/webapp/js/lib/addon/fold/xml-fold.js
deleted file mode 100644
index a45da58422..0000000000
--- a/triplestores/fuseki/webapp/js/lib/addon/fold/xml-fold.js
+++ /dev/null
@@ -1,181 +0,0 @@
-// 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);
- };
-});
diff --git a/triplestores/fuseki/webapp/js/lib/backbone-min.js b/triplestores/fuseki/webapp/js/lib/backbone-min.js
deleted file mode 100644
index 3b2593dd26..0000000000
--- a/triplestores/fuseki/webapp/js/lib/backbone-min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-(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 ").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.setRequestHeader("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.apply(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.match(/#(.*)$/);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.$('').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.getFragment(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)}else{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
diff --git a/triplestores/fuseki/webapp/js/lib/backbone.js b/triplestores/fuseki/webapp/js/lib/backbone.js
deleted file mode 100644
index f7783c2c19..0000000000
--- a/triplestores/fuseki/webapp/js/lib/backbone.js
+++ /dev/null
@@ -1,1581 +0,0 @@
-// Backbone.js 1.1.0
-
-// (c) 2010-2011 Jeremy Ashkenas, DocumentCloud Inc.
-// (c) 2011-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
-// Backbone may be freely distributed under the MIT license.
-// For all details and documentation:
-// http://backbonejs.org
-
-(function(){
-
- // Initial Setup
- // -------------
-
- // Save a reference to the global object (`window` in the browser, `exports`
- // on the server).
- var root = this;
-
- // Save the previous value of the `Backbone` variable, so that it can be
- // restored later on, if `noConflict` is used.
- var previousBackbone = root.Backbone;
-
- // Create local references to array methods we'll want to use later.
- var array = [];
- var push = array.push;
- var slice = array.slice;
- var splice = array.splice;
-
- // The top-level namespace. All public Backbone classes and modules will
- // be attached to this. Exported for both the browser and the server.
- var Backbone;
- if (typeof exports !== 'undefined') {
- Backbone = exports;
- } else {
- Backbone = root.Backbone = {};
- }
-
- // Current version of the library. Keep in sync with `package.json`.
- Backbone.VERSION = '1.1.0';
-
- // Require Underscore, if we're on the server, and it's not already present.
- var _ = root._;
- if (!_ && (typeof require !== 'undefined')) _ = require('underscore');
-
- // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
- // the `$` variable.
- Backbone.$ = root.jQuery || root.Zepto || root.ender || root.$;
-
- // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
- // to its previous owner. Returns a reference to this Backbone object.
- Backbone.noConflict = function() {
- root.Backbone = previousBackbone;
- return this;
- };
-
- // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option
- // will fake `"PATCH"`, `"PUT"` and `"DELETE"` requests via the `_method` parameter and
- // set a `X-Http-Method-Override` header.
- Backbone.emulateHTTP = false;
-
- // Turn on `emulateJSON` to support legacy servers that can't deal with direct
- // `application/json` requests ... will encode the body as
- // `application/x-www-form-urlencoded` instead and will send the model in a
- // form param named `model`.
- Backbone.emulateJSON = false;
-
- // Backbone.Events
- // ---------------
-
- // A module that can be mixed in to *any object* in order to provide it with
- // custom events. You may bind with `on` or remove with `off` callback
- // functions to an event; `trigger`-ing an event fires all callbacks in
- // succession.
- //
- // var object = {};
- // _.extend(object, Backbone.Events);
- // object.on('expand', function(){ alert('expanded'); });
- // object.trigger('expand');
- //
- var Events = Backbone.Events = {
-
- // Bind an event to a `callback` function. Passing `"all"` will bind
- // the callback to all events fired.
- on: function(name, callback, context) {
- if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this;
- this._events || (this._events = {});
- var events = this._events[name] || (this._events[name] = []);
- events.push({callback: callback, context: context, ctx: context || this});
- return this;
- },
-
- // Bind an event to only be triggered a single time. After the first time
- // the callback is invoked, it will be removed.
- once: function(name, callback, context) {
- if (!eventsApi(this, 'once', name, [callback, context]) || !callback) return this;
- var self = this;
- var once = _.once(function() {
- self.off(name, once);
- callback.apply(this, arguments);
- });
- once._callback = callback;
- return this.on(name, once, context);
- },
-
- // Remove one or many callbacks. If `context` is null, removes all
- // callbacks with that function. If `callback` is null, removes all
- // callbacks for the event. If `name` is null, removes all bound
- // callbacks for all events.
- off: function(name, callback, context) {
- var retain, ev, events, names, i, l, j, k;
- if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this;
- if (!name && !callback && !context) {
- this._events = {};
- return this;
- }
- names = name ? [name] : _.keys(this._events);
- for (i = 0, l = names.length; i < l; i++) {
- name = names[i];
- if (events = this._events[name]) {
- this._events[name] = retain = [];
- if (callback || context) {
- for (j = 0, k = events.length; j < k; j++) {
- ev = events[j];
- if ((callback && callback !== ev.callback && callback !== ev.callback._callback) ||
- (context && context !== ev.context)) {
- retain.push(ev);
- }
- }
- }
- if (!retain.length) delete this._events[name];
- }
- }
-
- return this;
- },
-
- // Trigger one or many events, firing all bound callbacks. Callbacks are
- // passed the same arguments as `trigger` is, apart from the event name
- // (unless you're listening on `"all"`, which will cause your callback to
- // receive the true name of the event as the first argument).
- trigger: function(name) {
- if (!this._events) return this;
- var args = slice.call(arguments, 1);
- if (!eventsApi(this, 'trigger', name, args)) return this;
- var events = this._events[name];
- var allEvents = this._events.all;
- if (events) triggerEvents(events, args);
- if (allEvents) triggerEvents(allEvents, arguments);
- return this;
- },
-
- // Tell this object to stop listening to either specific events ... or
- // to every object it's currently listening to.
- stopListening: function(obj, name, callback) {
- var listeningTo = this._listeningTo;
- if (!listeningTo) return this;
- var remove = !name && !callback;
- if (!callback && typeof name === 'object') callback = this;
- if (obj) (listeningTo = {})[obj._listenId] = obj;
- for (var id in listeningTo) {
- obj = listeningTo[id];
- obj.off(name, callback, this);
- if (remove || _.isEmpty(obj._events)) delete this._listeningTo[id];
- }
- return this;
- }
-
- };
-
- // Regular expression used to split event strings.
- var eventSplitter = /\s+/;
-
- // Implement fancy features of the Events API such as multiple event
- // names `"change blur"` and jQuery-style event maps `{change: action}`
- // in terms of the existing API.
- var eventsApi = function(obj, action, name, rest) {
- if (!name) return true;
-
- // Handle event maps.
- if (typeof name === 'object') {
- for (var key in name) {
- obj[action].apply(obj, [key, name[key]].concat(rest));
- }
- return false;
- }
-
- // Handle space separated event names.
- if (eventSplitter.test(name)) {
- var names = name.split(eventSplitter);
- for (var i = 0, l = names.length; i < l; i++) {
- obj[action].apply(obj, [names[i]].concat(rest));
- }
- return false;
- }
-
- return true;
- };
-
- // A difficult-to-believe, but optimized internal dispatch function for
- // triggering events. Tries to keep the usual cases speedy (most internal
- // Backbone events have 3 arguments).
- var triggerEvents = function(events, args) {
- var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
- switch (args.length) {
- case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
- case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
- case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
- case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
- default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args);
- }
- };
-
- var listenMethods = {listenTo: 'on', listenToOnce: 'once'};
-
- // Inversion-of-control versions of `on` and `once`. Tell *this* object to
- // listen to an event in another object ... keeping track of what it's
- // listening to.
- _.each(listenMethods, function(implementation, method) {
- Events[method] = function(obj, name, callback) {
- var listeningTo = this._listeningTo || (this._listeningTo = {});
- var id = obj._listenId || (obj._listenId = _.uniqueId('l'));
- listeningTo[id] = obj;
- if (!callback && typeof name === 'object') callback = this;
- obj[implementation](name, callback, this);
- return this;
- };
- });
-
- // Aliases for backwards compatibility.
- Events.bind = Events.on;
- Events.unbind = Events.off;
-
- // Allow the `Backbone` object to serve as a global event bus, for folks who
- // want global "pubsub" in a convenient place.
- _.extend(Backbone, Events);
-
- // Backbone.Model
- // --------------
-
- // Backbone **Models** are the basic data object in the framework --
- // frequently representing a row in a table in a database on your server.
- // A discrete chunk of data and a bunch of useful, related methods for
- // performing computations and transformations on that data.
-
- // Create a new model with the specified attributes. A client id (`cid`)
- // is automatically generated and assigned for you.
- var Model = Backbone.Model = function(attributes, options) {
- var attrs = attributes || {};
- options || (options = {});
- this.cid = _.uniqueId('c');
- this.attributes = {};
- if (options.collection) this.collection = options.collection;
- if (options.parse) attrs = this.parse(attrs, options) || {};
- attrs = _.defaults({}, attrs, _.result(this, 'defaults'));
- this.set(attrs, options);
- this.changed = {};
- this.initialize.apply(this, arguments);
- };
-
- // Attach all inheritable methods to the Model prototype.
- _.extend(Model.prototype, Events, {
-
- // A hash of attributes whose current and previous value differ.
- changed: null,
-
- // The value returned during the last failed validation.
- validationError: null,
-
- // The default name for the JSON `id` attribute is `"id"`. MongoDB and
- // CouchDB users may want to set this to `"_id"`.
- idAttribute: 'id',
-
- // Initialize is an empty function by default. Override it with your own
- // initialization logic.
- initialize: function(){},
-
- // Return a copy of the model's `attributes` object.
- toJSON: function(options) {
- return _.clone(this.attributes);
- },
-
- // Proxy `Backbone.sync` by default -- but override this if you need
- // custom syncing semantics for *this* particular model.
- sync: function() {
- return Backbone.sync.apply(this, arguments);
- },
-
- // Get the value of an attribute.
- get: function(attr) {
- return this.attributes[attr];
- },
-
- // Get the HTML-escaped value of an attribute.
- escape: function(attr) {
- return _.escape(this.get(attr));
- },
-
- // Returns `true` if the attribute contains a value that is not null
- // or undefined.
- has: function(attr) {
- return this.get(attr) != null;
- },
-
- // Set a hash of model attributes on the object, firing `"change"`. This is
- // the core primitive operation of a model, updating the data and notifying
- // anyone who needs to know about the change in state. The heart of the beast.
- set: function(key, val, options) {
- var attr, attrs, unset, changes, silent, changing, prev, current;
- if (key == null) return this;
-
- // Handle both `"key", value` and `{key: value}` -style arguments.
- if (typeof key === 'object') {
- attrs = key;
- options = val;
- } else {
- (attrs = {})[key] = val;
- }
-
- options || (options = {});
-
- // Run validation.
- if (!this._validate(attrs, options)) return false;
-
- // Extract attributes and options.
- unset = options.unset;
- silent = options.silent;
- changes = [];
- changing = this._changing;
- this._changing = true;
-
- if (!changing) {
- this._previousAttributes = _.clone(this.attributes);
- this.changed = {};
- }
- current = this.attributes, prev = this._previousAttributes;
-
- // Check for changes of `id`.
- if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
-
- // For each `set` attribute, update or delete the current value.
- for (attr in attrs) {
- val = attrs[attr];
- if (!_.isEqual(current[attr], val)) changes.push(attr);
- if (!_.isEqual(prev[attr], val)) {
- this.changed[attr] = val;
- } else {
- delete this.changed[attr];
- }
- unset ? delete current[attr] : current[attr] = val;
- }
-
- // Trigger all relevant attribute changes.
- if (!silent) {
- if (changes.length) this._pending = true;
- for (var i = 0, l = changes.length; i < l; i++) {
- this.trigger('change:' + changes[i], this, current[changes[i]], options);
- }
- }
-
- // You might be wondering why there's a `while` loop here. Changes can
- // be recursively nested within `"change"` events.
- if (changing) return this;
- if (!silent) {
- while (this._pending) {
- this._pending = false;
- this.trigger('change', this, options);
- }
- }
- this._pending = false;
- this._changing = false;
- return this;
- },
-
- // Remove an attribute from the model, firing `"change"`. `unset` is a noop
- // if the attribute doesn't exist.
- unset: function(attr, options) {
- return this.set(attr, void 0, _.extend({}, options, {unset: true}));
- },
-
- // Clear all attributes on the model, firing `"change"`.
- clear: function(options) {
- var attrs = {};
- for (var key in this.attributes) attrs[key] = void 0;
- return this.set(attrs, _.extend({}, options, {unset: true}));
- },
-
- // Determine if the model has changed since the last `"change"` event.
- // If you specify an attribute name, determine if that attribute has changed.
- hasChanged: function(attr) {
- if (attr == null) return !_.isEmpty(this.changed);
- return _.has(this.changed, attr);
- },
-
- // Return an object containing all the attributes that have changed, or
- // false if there are no changed attributes. Useful for determining what
- // parts of a view need to be updated and/or what attributes need to be
- // persisted to the server. Unset attributes will be set to undefined.
- // You can also pass an attributes object to diff against the model,
- // determining if there *would be* a change.
- changedAttributes: function(diff) {
- if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
- var val, changed = false;
- var old = this._changing ? this._previousAttributes : this.attributes;
- for (var attr in diff) {
- if (_.isEqual(old[attr], (val = diff[attr]))) continue;
- (changed || (changed = {}))[attr] = val;
- }
- return changed;
- },
-
- // Get the previous value of an attribute, recorded at the time the last
- // `"change"` event was fired.
- previous: function(attr) {
- if (attr == null || !this._previousAttributes) return null;
- return this._previousAttributes[attr];
- },
-
- // Get all of the attributes of the model at the time of the previous
- // `"change"` event.
- previousAttributes: function() {
- return _.clone(this._previousAttributes);
- },
-
- // Fetch the model from the server. If the server's representation of the
- // model differs from its current attributes, they will be overridden,
- // triggering a `"change"` event.
- fetch: function(options) {
- options = options ? _.clone(options) : {};
- if (options.parse === void 0) options.parse = true;
- var model = this;
- var success = options.success;
- options.success = function(resp) {
- if (!model.set(model.parse(resp, options), options)) return false;
- if (success) success(model, resp, options);
- model.trigger('sync', model, resp, options);
- };
- wrapError(this, options);
- return this.sync('read', this, options);
- },
-
- // Set a hash of model attributes, and sync the model to the server.
- // If the server returns an attributes hash that differs, the model's
- // state will be `set` again.
- save: function(key, val, options) {
- var attrs, method, xhr, attributes = this.attributes;
-
- // Handle both `"key", value` and `{key: value}` -style arguments.
- if (key == null || typeof key === 'object') {
- attrs = key;
- options = val;
- } else {
- (attrs = {})[key] = val;
- }
-
- options = _.extend({validate: true}, options);
-
- // If we're not waiting and attributes exist, save acts as
- // `set(attr).save(null, opts)` with validation. Otherwise, check if
- // the model will be valid when the attributes, if any, are set.
- if (attrs && !options.wait) {
- if (!this.set(attrs, options)) return false;
- } else {
- if (!this._validate(attrs, options)) return false;
- }
-
- // Set temporary attributes if `{wait: true}`.
- if (attrs && options.wait) {
- this.attributes = _.extend({}, attributes, attrs);
- }
-
- // After a successful server-side save, the client is (optionally)
- // updated with the server-side state.
- if (options.parse === void 0) options.parse = true;
- var model = this;
- var success = options.success;
- options.success = function(resp) {
- // Ensure attributes are restored during synchronous saves.
- model.attributes = attributes;
- var serverAttrs = model.parse(resp, options);
- if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs);
- if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) {
- return false;
- }
- if (success) success(model, resp, options);
- model.trigger('sync', model, resp, options);
- };
- wrapError(this, options);
-
- method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
- if (method === 'patch') options.attrs = attrs;
- xhr = this.sync(method, this, options);
-
- // Restore attributes.
- if (attrs && options.wait) this.attributes = attributes;
-
- return xhr;
- },
-
- // Destroy this model on the server if it was already persisted.
- // Optimistically removes the model from its collection, if it has one.
- // If `wait: true` is passed, waits for the server to respond before removal.
- destroy: function(options) {
- options = options ? _.clone(options) : {};
- var model = this;
- var success = options.success;
-
- var destroy = function() {
- model.trigger('destroy', model, model.collection, options);
- };
-
- options.success = function(resp) {
- if (options.wait || model.isNew()) destroy();
- if (success) success(model, resp, options);
- if (!model.isNew()) model.trigger('sync', model, resp, options);
- };
-
- if (this.isNew()) {
- options.success();
- return false;
- }
- wrapError(this, options);
-
- var xhr = this.sync('delete', this, options);
- if (!options.wait) destroy();
- return xhr;
- },
-
- // Default URL for the model's representation on the server -- if you're
- // using Backbone's restful methods, override this to change the endpoint
- // that will be called.
- url: function() {
- var base = _.result(this, 'urlRoot') || _.result(this.collection, 'url') || urlError();
- if (this.isNew()) return base;
- return base + (base.charAt(base.length - 1) === '/' ? '' : '/') + encodeURIComponent(this.id);
- },
-
- // **parse** converts a response into the hash of attributes to be `set` on
- // the model. The default implementation is just to pass the response along.
- parse: function(resp, options) {
- return resp;
- },
-
- // Create a new model with identical attributes to this one.
- clone: function() {
- return new this.constructor(this.attributes);
- },
-
- // A model is new if it has never been saved to the server, and lacks an id.
- isNew: function() {
- return this.id == null;
- },
-
- // Check if the model is currently in a valid state.
- isValid: function(options) {
- return this._validate({}, _.extend(options || {}, { validate: true }));
- },
-
- // Run validation against the next complete set of model attributes,
- // returning `true` if all is well. Otherwise, fire an `"invalid"` event.
- _validate: function(attrs, options) {
- if (!options.validate || !this.validate) return true;
- attrs = _.extend({}, this.attributes, attrs);
- var error = this.validationError = this.validate(attrs, options) || null;
- if (!error) return true;
- this.trigger('invalid', this, error, _.extend(options, {validationError: error}));
- return false;
- }
-
- });
-
- // Underscore methods that we want to implement on the Model.
- var modelMethods = ['keys', 'values', 'pairs', 'invert', 'pick', 'omit'];
-
- // Mix in each Underscore method as a proxy to `Model#attributes`.
- _.each(modelMethods, function(method) {
- Model.prototype[method] = function() {
- var args = slice.call(arguments);
- args.unshift(this.attributes);
- return _[method].apply(_, args);
- };
- });
-
- // Backbone.Collection
- // -------------------
-
- // If models tend to represent a single row of data, a Backbone Collection is
- // more analagous to a table full of data ... or a small slice or page of that
- // table, or a collection of rows that belong together for a particular reason
- // -- all of the messages in this particular folder, all of the documents
- // belonging to this particular author, and so on. Collections maintain
- // indexes of their models, both in order, and for lookup by `id`.
-
- // Create a new **Collection**, perhaps to contain a specific type of `model`.
- // If a `comparator` is specified, the Collection will maintain
- // its models in sort order, as they're added and removed.
- var Collection = Backbone.Collection = function(models, options) {
- options || (options = {});
- if (options.model) this.model = options.model;
- if (options.comparator !== void 0) this.comparator = options.comparator;
- this._reset();
- this.initialize.apply(this, arguments);
- if (models) this.reset(models, _.extend({silent: true}, options));
- };
-
- // Default options for `Collection#set`.
- var setOptions = {add: true, remove: true, merge: true};
- var addOptions = {add: true, remove: false};
-
- // Define the Collection's inheritable methods.
- _.extend(Collection.prototype, Events, {
-
- // The default model for a collection is just a **Backbone.Model**.
- // This should be overridden in most cases.
- model: Model,
-
- // Initialize is an empty function by default. Override it with your own
- // initialization logic.
- initialize: function(){},
-
- // The JSON representation of a Collection is an array of the
- // models' attributes.
- toJSON: function(options) {
- return this.map(function(model){ return model.toJSON(options); });
- },
-
- // Proxy `Backbone.sync` by default.
- sync: function() {
- return Backbone.sync.apply(this, arguments);
- },
-
- // Add a model, or list of models to the set.
- add: function(models, options) {
- return this.set(models, _.extend({merge: false}, options, addOptions));
- },
-
- // Remove a model, or a list of models from the set.
- remove: function(models, options) {
- var singular = !_.isArray(models);
- models = singular ? [models] : _.clone(models);
- options || (options = {});
- var i, l, index, model;
- for (i = 0, l = models.length; i < l; i++) {
- model = models[i] = this.get(models[i]);
- if (!model) continue;
- delete this._byId[model.id];
- delete this._byId[model.cid];
- index = this.indexOf(model);
- this.models.splice(index, 1);
- this.length--;
- if (!options.silent) {
- options.index = index;
- model.trigger('remove', model, this, options);
- }
- this._removeReference(model);
- }
- return singular ? models[0] : models;
- },
-
- // Update a collection by `set`-ing a new list of models, adding new ones,
- // removing models that are no longer present, and merging models that
- // already exist in the collection, as necessary. Similar to **Model#set**,
- // the core operation for updating the data contained by the collection.
- set: function(models, options) {
- options = _.defaults({}, options, setOptions);
- if (options.parse) models = this.parse(models, options);
- var singular = !_.isArray(models);
- models = singular ? (models ? [models] : []) : _.clone(models);
- var i, l, id, model, attrs, existing, sort;
- var at = options.at;
- var targetModel = this.model;
- var sortable = this.comparator && (at == null) && options.sort !== false;
- var sortAttr = _.isString(this.comparator) ? this.comparator : null;
- var toAdd = [], toRemove = [], modelMap = {};
- var add = options.add, merge = options.merge, remove = options.remove;
- var order = !sortable && add && remove ? [] : false;
-
- // Turn bare objects into model references, and prevent invalid models
- // from being added.
- for (i = 0, l = models.length; i < l; i++) {
- attrs = models[i];
- if (attrs instanceof Model) {
- id = model = attrs;
- } else {
- id = attrs[targetModel.prototype.idAttribute];
- }
-
- // If a duplicate is found, prevent it from being added and
- // optionally merge it into the existing model.
- if (existing = this.get(id)) {
- if (remove) modelMap[existing.cid] = true;
- if (merge) {
- attrs = attrs === model ? model.attributes : attrs;
- if (options.parse) attrs = existing.parse(attrs, options);
- existing.set(attrs, options);
- if (sortable && !sort && existing.hasChanged(sortAttr)) sort = true;
- }
- models[i] = existing;
-
- // If this is a new, valid model, push it to the `toAdd` list.
- } else if (add) {
- model = models[i] = this._prepareModel(attrs, options);
- if (!model) continue;
- toAdd.push(model);
-
- // Listen to added models' events, and index models for lookup by
- // `id` and by `cid`.
- model.on('all', this._onModelEvent, this);
- this._byId[model.cid] = model;
- if (model.id != null) this._byId[model.id] = model;
- }
- if (order) order.push(existing || model);
- }
-
- // Remove nonexistent models if appropriate.
- if (remove) {
- for (i = 0, l = this.length; i < l; ++i) {
- if (!modelMap[(model = this.models[i]).cid]) toRemove.push(model);
- }
- if (toRemove.length) this.remove(toRemove, options);
- }
-
- // See if sorting is needed, update `length` and splice in new models.
- if (toAdd.length || (order && order.length)) {
- if (sortable) sort = true;
- this.length += toAdd.length;
- if (at != null) {
- for (i = 0, l = toAdd.length; i < l; i++) {
- this.models.splice(at + i, 0, toAdd[i]);
- }
- } else {
- if (order) this.models.length = 0;
- var orderedModels = order || toAdd;
- for (i = 0, l = orderedModels.length; i < l; i++) {
- this.models.push(orderedModels[i]);
- }
- }
- }
-
- // Silently sort the collection if appropriate.
- if (sort) this.sort({silent: true});
-
- // Unless silenced, it's time to fire all appropriate add/sort events.
- if (!options.silent) {
- for (i = 0, l = toAdd.length; i < l; i++) {
- (model = toAdd[i]).trigger('add', model, this, options);
- }
- if (sort || (order && order.length)) this.trigger('sort', this, options);
- }
-
- // Return the added (or merged) model (or models).
- return singular ? models[0] : models;
- },
-
- // When you have more items than you want to add or remove individually,
- // you can reset the entire set with a new list of models, without firing
- // any granular `add` or `remove` events. Fires `reset` when finished.
- // Useful for bulk operations and optimizations.
- reset: function(models, options) {
- options || (options = {});
- for (var i = 0, l = this.models.length; i < l; i++) {
- this._removeReference(this.models[i]);
- }
- options.previousModels = this.models;
- this._reset();
- models = this.add(models, _.extend({silent: true}, options));
- if (!options.silent) this.trigger('reset', this, options);
- return models;
- },
-
- // Add a model to the end of the collection.
- push: function(model, options) {
- return this.add(model, _.extend({at: this.length}, options));
- },
-
- // Remove a model from the end of the collection.
- pop: function(options) {
- var model = this.at(this.length - 1);
- this.remove(model, options);
- return model;
- },
-
- // Add a model to the beginning of the collection.
- unshift: function(model, options) {
- return this.add(model, _.extend({at: 0}, options));
- },
-
- // Remove a model from the beginning of the collection.
- shift: function(options) {
- var model = this.at(0);
- this.remove(model, options);
- return model;
- },
-
- // Slice out a sub-array of models from the collection.
- slice: function() {
- return slice.apply(this.models, arguments);
- },
-
- // Get a model from the set by id.
- get: function(obj) {
- if (obj == null) return void 0;
- return this._byId[obj.id] || this._byId[obj.cid] || this._byId[obj];
- },
-
- // Get the model at the given index.
- at: function(index) {
- return this.models[index];
- },
-
- // Return models with matching attributes. Useful for simple cases of
- // `filter`.
- where: function(attrs, first) {
- if (_.isEmpty(attrs)) return first ? void 0 : [];
- return this[first ? 'find' : 'filter'](function(model) {
- for (var key in attrs) {
- if (attrs[key] !== model.get(key)) return false;
- }
- return true;
- });
- },
-
- // Return the first model with matching attributes. Useful for simple cases
- // of `find`.
- findWhere: function(attrs) {
- return this.where(attrs, true);
- },
-
- // Force the collection to re-sort itself. You don't need to call this under
- // normal circumstances, as the set will maintain sort order as each item
- // is added.
- sort: function(options) {
- if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
- options || (options = {});
-
- // Run sort based on type of `comparator`.
- if (_.isString(this.comparator) || this.comparator.length === 1) {
- this.models = this.sortBy(this.comparator, this);
- } else {
- this.models.sort(_.bind(this.comparator, this));
- }
-
- if (!options.silent) this.trigger('sort', this, options);
- return this;
- },
-
- // Pluck an attribute from each model in the collection.
- pluck: function(attr) {
- return _.invoke(this.models, 'get', attr);
- },
-
- // Fetch the default set of models for this collection, resetting the
- // collection when they arrive. If `reset: true` is passed, the response
- // data will be passed through the `reset` method instead of `set`.
- fetch: function(options) {
- options = options ? _.clone(options) : {};
- if (options.parse === void 0) options.parse = true;
- var success = options.success;
- var collection = this;
- options.success = function(resp) {
- var method = options.reset ? 'reset' : 'set';
- collection[method](resp, options);
- if (success) success(collection, resp, options);
- collection.trigger('sync', collection, resp, options);
- };
- wrapError(this, options);
- return this.sync('read', this, options);
- },
-
- // Create a new instance of a model in this collection. Add the model to the
- // collection immediately, unless `wait: true` is passed, in which case we
- // wait for the server to agree.
- create: function(model, options) {
- options = options ? _.clone(options) : {};
- if (!(model = this._prepareModel(model, options))) return false;
- if (!options.wait) this.add(model, options);
- var collection = this;
- var success = options.success;
- options.success = function(model, resp, options) {
- if (options.wait) collection.add(model, options);
- if (success) success(model, resp, options);
- };
- model.save(null, options);
- return model;
- },
-
- // **parse** converts a response into a list of models to be added to the
- // collection. The default implementation is just to pass it through.
- parse: function(resp, options) {
- return resp;
- },
-
- // Create a new collection with an identical list of models as this one.
- clone: function() {
- return new this.constructor(this.models);
- },
-
- // Private method to reset all internal state. Called when the collection
- // is first initialized or reset.
- _reset: function() {
- this.length = 0;
- this.models = [];
- this._byId = {};
- },
-
- // Prepare a hash of attributes (or other model) to be added to this
- // collection.
- _prepareModel: function(attrs, options) {
- if (attrs instanceof Model) {
- if (!attrs.collection) attrs.collection = this;
- return attrs;
- }
- options = options ? _.clone(options) : {};
- options.collection = this;
- var model = new this.model(attrs, options);
- if (!model.validationError) return model;
- this.trigger('invalid', this, model.validationError, options);
- return false;
- },
-
- // Internal method to sever a model's ties to a collection.
- _removeReference: function(model) {
- if (this === model.collection) delete model.collection;
- model.off('all', this._onModelEvent, this);
- },
-
- // Internal method called every time a model in the set fires an event.
- // Sets need to update their indexes when models change ids. All other
- // events simply proxy through. "add" and "remove" events that originate
- // in other collections are ignored.
- _onModelEvent: function(event, model, collection, options) {
- if ((event === 'add' || event === 'remove') && collection !== this) return;
- if (event === 'destroy') this.remove(model, options);
- if (model && event === 'change:' + model.idAttribute) {
- delete this._byId[model.previous(model.idAttribute)];
- if (model.id != null) this._byId[model.id] = model;
- }
- this.trigger.apply(this, arguments);
- }
-
- });
-
- // Underscore methods that we want to implement on the Collection.
- // 90% of the core usefulness of Backbone Collections is actually implemented
- // right here:
- var methods = ['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'];
-
- // Mix in each Underscore method as a proxy to `Collection#models`.
- _.each(methods, function(method) {
- Collection.prototype[method] = function() {
- var args = slice.call(arguments);
- args.unshift(this.models);
- return _[method].apply(_, args);
- };
- });
-
- // Underscore methods that take a property name as an argument.
- var attributeMethods = ['groupBy', 'countBy', 'sortBy'];
-
- // Use attributes instead of properties.
- _.each(attributeMethods, function(method) {
- Collection.prototype[method] = function(value, context) {
- var iterator = _.isFunction(value) ? value : function(model) {
- return model.get(value);
- };
- return _[method](this.models, iterator, context);
- };
- });
-
- // Backbone.View
- // -------------
-
- // Backbone Views are almost more convention than they are actual code. A View
- // is simply a JavaScript object that represents a logical chunk of UI in the
- // DOM. This might be a single item, an entire list, a sidebar or panel, or
- // even the surrounding frame which wraps your whole app. Defining a chunk of
- // UI as a **View** allows you to define your DOM events declaratively, without
- // having to worry about render order ... and makes it easy for the view to
- // react to specific changes in the state of your models.
-
- // Creating a Backbone.View creates its initial element outside of the DOM,
- // if an existing element is not provided...
- var View = Backbone.View = function(options) {
- this.cid = _.uniqueId('view');
- options || (options = {});
- _.extend(this, _.pick(options, viewOptions));
- this._ensureElement();
- this.initialize.apply(this, arguments);
- this.delegateEvents();
- };
-
- // Cached regex to split keys for `delegate`.
- var delegateEventSplitter = /^(\S+)\s*(.*)$/;
-
- // List of view options to be merged as properties.
- var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
-
- // Set up all inheritable **Backbone.View** properties and methods.
- _.extend(View.prototype, Events, {
-
- // The default `tagName` of a View's element is `"div"`.
- tagName: 'div',
-
- // jQuery delegate for element lookup, scoped to DOM elements within the
- // current view. This should be preferred to global lookups where possible.
- $: function(selector) {
- return this.$el.find(selector);
- },
-
- // Initialize is an empty function by default. Override it with your own
- // initialization logic.
- initialize: function(){},
-
- // **render** is the core function that your view should override, in order
- // to populate its element (`this.el`), with the appropriate HTML. The
- // convention is for **render** to always return `this`.
- render: function() {
- return this;
- },
-
- // Remove this view by taking the element out of the DOM, and removing any
- // applicable Backbone.Events listeners.
- remove: function() {
- this.$el.remove();
- this.stopListening();
- return this;
- },
-
- // Change the view's element (`this.el` property), including event
- // re-delegation.
- setElement: function(element, delegate) {
- if (this.$el) this.undelegateEvents();
- this.$el = element instanceof Backbone.$ ? element : Backbone.$(element);
- this.el = this.$el[0];
- if (delegate !== false) this.delegateEvents();
- return this;
- },
-
- // Set callbacks, where `this.events` is a hash of
- //
- // *{"event selector": "callback"}*
- //
- // {
- // 'mousedown .title': 'edit',
- // 'click .button': 'save',
- // 'click .open': function(e) { ... }
- // }
- //
- // pairs. Callbacks will be bound to the view, with `this` set properly.
- // Uses event delegation for efficiency.
- // Omitting the selector binds the event to `this.el`.
- // This only works for delegate-able events: not `focus`, `blur`, and
- // not `change`, `submit`, and `reset` in Internet Explorer.
- delegateEvents: function(events) {
- if (!(events || (events = _.result(this, 'events')))) return this;
- this.undelegateEvents();
- for (var key in events) {
- var method = events[key];
- if (!_.isFunction(method)) method = this[events[key]];
- if (!method) continue;
-
- var match = key.match(delegateEventSplitter);
- var eventName = match[1], selector = match[2];
- method = _.bind(method, this);
- eventName += '.delegateEvents' + this.cid;
- if (selector === '') {
- this.$el.on(eventName, method);
- } else {
- this.$el.on(eventName, selector, method);
- }
- }
- return this;
- },
-
- // Clears all callbacks previously bound to the view with `delegateEvents`.
- // You usually don't need to use this, but may wish to if you have multiple
- // Backbone views attached to the same DOM element.
- undelegateEvents: function() {
- this.$el.off('.delegateEvents' + this.cid);
- return this;
- },
-
- // Ensure that the View has a DOM element to render into.
- // If `this.el` is a string, pass it through `$()`, take the first
- // matching element, and re-assign it to `el`. Otherwise, create
- // an element from the `id`, `className` and `tagName` properties.
- _ensureElement: function() {
- if (!this.el) {
- var attrs = _.extend({}, _.result(this, 'attributes'));
- if (this.id) attrs.id = _.result(this, 'id');
- if (this.className) attrs['class'] = _.result(this, 'className');
- var $el = Backbone.$('<' + _.result(this, 'tagName') + '>').attr(attrs);
- this.setElement($el, false);
- } else {
- this.setElement(_.result(this, 'el'), false);
- }
- }
-
- });
-
- // Backbone.sync
- // -------------
-
- // Override this function to change the manner in which Backbone persists
- // models to the server. You will be passed the type of request, and the
- // model in question. By default, makes a RESTful Ajax request
- // to the model's `url()`. Some possible customizations could be:
- //
- // * Use `setTimeout` to batch rapid-fire updates into a single request.
- // * Send up the models as XML instead of JSON.
- // * Persist models via WebSockets instead of Ajax.
- //
- // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
- // as `POST`, with a `_method` parameter containing the true HTTP method,
- // as well as all requests with the body as `application/x-www-form-urlencoded`
- // instead of `application/json` with the model in a param named `model`.
- // Useful when interfacing with server-side languages like **PHP** that make
- // it difficult to read the body of `PUT` requests.
- Backbone.sync = function(method, model, options) {
- var type = methodMap[method];
-
- // Default options, unless specified.
- _.defaults(options || (options = {}), {
- emulateHTTP: Backbone.emulateHTTP,
- emulateJSON: Backbone.emulateJSON
- });
-
- // Default JSON-request options.
- var params = {type: type, dataType: 'json'};
-
- // Ensure that we have a URL.
- if (!options.url) {
- params.url = _.result(model, 'url') || urlError();
- }
-
- // Ensure that we have the appropriate request data.
- if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
- params.contentType = 'application/json';
- params.data = JSON.stringify(options.attrs || model.toJSON(options));
- }
-
- // For older servers, emulate JSON by encoding the request into an HTML-form.
- if (options.emulateJSON) {
- params.contentType = 'application/x-www-form-urlencoded';
- params.data = params.data ? {model: params.data} : {};
- }
-
- // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
- // And an `X-HTTP-Method-Override` header.
- if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
- params.type = 'POST';
- if (options.emulateJSON) params.data._method = type;
- var beforeSend = options.beforeSend;
- options.beforeSend = function(xhr) {
- xhr.setRequestHeader('X-HTTP-Method-Override', type);
- if (beforeSend) return beforeSend.apply(this, arguments);
- };
- }
-
- // Don't process data on a non-GET request.
- if (params.type !== 'GET' && !options.emulateJSON) {
- params.processData = false;
- }
-
- // If we're sending a `PATCH` request, and we're in an old Internet Explorer
- // that still has ActiveX enabled by default, override jQuery to use that
- // for XHR instead. Remove this line when jQuery supports `PATCH` on IE8.
- if (params.type === 'PATCH' && noXhrPatch) {
- params.xhr = function() {
- return new ActiveXObject("Microsoft.XMLHTTP");
- };
- }
-
- // Make the request, allowing the user to override any Ajax options.
- var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
- model.trigger('request', model, xhr, options);
- return xhr;
- };
-
- var noXhrPatch = typeof window !== 'undefined' && !!window.ActiveXObject && !(window.XMLHttpRequest && (new XMLHttpRequest).dispatchEvent);
-
- // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
- var methodMap = {
- 'create': 'POST',
- 'update': 'PUT',
- 'patch': 'PATCH',
- 'delete': 'DELETE',
- 'read': 'GET'
- };
-
- // Set the default implementation of `Backbone.ajax` to proxy through to `$`.
- // Override this if you'd like to use a different library.
- Backbone.ajax = function() {
- return Backbone.$.ajax.apply(Backbone.$, arguments);
- };
-
- // Backbone.Router
- // ---------------
-
- // Routers map faux-URLs to actions, and fire events when routes are
- // matched. Creating a new one sets its `routes` hash, if not set statically.
- var Router = Backbone.Router = function(options) {
- options || (options = {});
- if (options.routes) this.routes = options.routes;
- this._bindRoutes();
- this.initialize.apply(this, arguments);
- };
-
- // Cached regular expressions for matching named param parts and splatted
- // parts of route strings.
- var optionalParam = /\((.*?)\)/g;
- var namedParam = /(\(\?)?:\w+/g;
- var splatParam = /\*\w+/g;
- var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g;
-
- // Set up all inheritable **Backbone.Router** properties and methods.
- _.extend(Router.prototype, Events, {
-
- // Initialize is an empty function by default. Override it with your own
- // initialization logic.
- initialize: function(){},
-
- // Manually bind a single named route to a callback. For example:
- //
- // this.route('search/:query/p:num', 'search', function(query, num) {
- // ...
- // });
- //
- route: function(route, name, callback) {
- if (!_.isRegExp(route)) route = this._routeToRegExp(route);
- if (_.isFunction(name)) {
- callback = name;
- name = '';
- }
- if (!callback) callback = this[name];
- var router = this;
- Backbone.history.route(route, function(fragment) {
- var args = router._extractParameters(route, fragment);
- callback && callback.apply(router, args);
- router.trigger.apply(router, ['route:' + name].concat(args));
- router.trigger('route', name, args);
- Backbone.history.trigger('route', router, name, args);
- });
- return this;
- },
-
- // Simple proxy to `Backbone.history` to save a fragment into the history.
- navigate: function(fragment, options) {
- Backbone.history.navigate(fragment, options);
- return this;
- },
-
- // Bind all defined routes to `Backbone.history`. We have to reverse the
- // order of the routes here to support behavior where the most general
- // routes can be defined at the bottom of the route map.
- _bindRoutes: function() {
- if (!this.routes) return;
- this.routes = _.result(this, 'routes');
- var route, routes = _.keys(this.routes);
- while ((route = routes.pop()) != null) {
- this.route(route, this.routes[route]);
- }
- },
-
- // Convert a route string into a regular expression, suitable for matching
- // against the current location hash.
- _routeToRegExp: function(route) {
- route = route.replace(escapeRegExp, '\\$&')
- .replace(optionalParam, '(?:$1)?')
- .replace(namedParam, function(match, optional) {
- return optional ? match : '([^\/]+)';
- })
- .replace(splatParam, '(.*?)');
- return new RegExp('^' + route + '$');
- },
-
- // Given a route, and a URL fragment that it matches, return the array of
- // extracted decoded parameters. Empty or unmatched parameters will be
- // treated as `null` to normalize cross-browser behavior.
- _extractParameters: function(route, fragment) {
- var params = route.exec(fragment).slice(1);
- return _.map(params, function(param) {
- return param ? decodeURIComponent(param) : null;
- });
- }
-
- });
-
- // Backbone.History
- // ----------------
-
- // Handles cross-browser history management, based on either
- // [pushState](http://diveintohtml5.info/history.html) and real URLs, or
- // [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange)
- // and URL fragments. If the browser supports neither (old IE, natch),
- // falls back to polling.
- var History = Backbone.History = function() {
- this.handlers = [];
- _.bindAll(this, 'checkUrl');
-
- // Ensure that `History` can be used outside of the browser.
- if (typeof window !== 'undefined') {
- this.location = window.location;
- this.history = window.history;
- }
- };
-
- // Cached regex for stripping a leading hash/slash and trailing space.
- var routeStripper = /^[#\/]|\s+$/g;
-
- // Cached regex for stripping leading and trailing slashes.
- var rootStripper = /^\/+|\/+$/g;
-
- // Cached regex for detecting MSIE.
- var isExplorer = /msie [\w.]+/;
-
- // Cached regex for removing a trailing slash.
- var trailingSlash = /\/$/;
-
- // Cached regex for stripping urls of hash and query.
- var pathStripper = /[?#].*$/;
-
- // Has the history handling already been started?
- History.started = false;
-
- // Set up all inheritable **Backbone.History** properties and methods.
- _.extend(History.prototype, Events, {
-
- // The default interval to poll for hash changes, if necessary, is
- // twenty times a second.
- interval: 50,
-
- // Gets the true hash value. Cannot use location.hash directly due to bug
- // in Firefox where location.hash will always be decoded.
- getHash: function(window) {
- var match = (window || this).location.href.match(/#(.*)$/);
- return match ? match[1] : '';
- },
-
- // Get the cross-browser normalized URL fragment, either from the URL,
- // the hash, or the override.
- getFragment: function(fragment, forcePushState) {
- if (fragment == null) {
- if (this._hasPushState || !this._wantsHashChange || forcePushState) {
- fragment = this.location.pathname;
- var root = this.root.replace(trailingSlash, '');
- if (!fragment.indexOf(root)) fragment = fragment.slice(root.length);
- } else {
- fragment = this.getHash();
- }
- }
- return fragment.replace(routeStripper, '');
- },
-
- // Start the hash change handling, returning `true` if the current URL matches
- // an existing route, and `false` otherwise.
- start: function(options) {
- if (History.started) throw new Error("Backbone.history has already been started");
- History.started = true;
-
- // Figure out the initial configuration. Do we need an iframe?
- // Is pushState desired ... is it available?
- this.options = _.extend({root: '/'}, this.options, options);
- 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 fragment = this.getFragment();
- var docMode = document.documentMode;
- var oldIE = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7));
-
- // Normalize root to always include a leading and trailing slash.
- this.root = ('/' + this.root + '/').replace(rootStripper, '/');
-
- if (oldIE && this._wantsHashChange) {
- this.iframe = Backbone.$('').hide().appendTo('body')[0].contentWindow;
- this.navigate(fragment);
- }
-
- // Depending on whether we're using pushState or hashes, and whether
- // 'onhashchange' is supported, determine how we check the URL state.
- if (this._hasPushState) {
- Backbone.$(window).on('popstate', this.checkUrl);
- } else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) {
- Backbone.$(window).on('hashchange', this.checkUrl);
- } else if (this._wantsHashChange) {
- this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
- }
-
- // Determine if we need to change the base url, for a pushState link
- // opened by a non-pushState browser.
- this.fragment = fragment;
- var loc = this.location;
- var atRoot = loc.pathname.replace(/[^\/]$/, '$&/') === this.root;
-
- // Transition from hashChange to pushState or vice versa if both are
- // requested.
- if (this._wantsHashChange && this._wantsPushState) {
-
- // If we've started off with a route from a `pushState`-enabled
- // browser, but we're currently in a browser that doesn't support it...
- if (!this._hasPushState && !atRoot) {
- this.fragment = this.getFragment(null, true);
- this.location.replace(this.root + this.location.search + '#' + this.fragment);
- // Return immediately as browser will do redirect to new url
- return true;
-
- // Or if we've started out with a hash-based route, but we're currently
- // in a browser where it could be `pushState`-based instead...
- } else if (this._hasPushState && atRoot && loc.hash) {
- this.fragment = this.getHash().replace(routeStripper, '');
- this.history.replaceState({}, document.title, this.root + this.fragment + loc.search);
- }
-
- }
-
- if (!this.options.silent) return this.loadUrl();
- },
-
- // Disable Backbone.history, perhaps temporarily. Not useful in a real app,
- // but possibly useful for unit testing Routers.
- stop: function() {
- Backbone.$(window).off('popstate', this.checkUrl).off('hashchange', this.checkUrl);
- clearInterval(this._checkUrlInterval);
- History.started = false;
- },
-
- // Add a route to be tested when the fragment changes. Routes added later
- // may override previous routes.
- route: function(route, callback) {
- this.handlers.unshift({route: route, callback: callback});
- },
-
- // Checks the current URL to see if it has changed, and if it has,
- // calls `loadUrl`, normalizing across the hidden iframe.
- checkUrl: function(e) {
- var current = this.getFragment();
- if (current === this.fragment && this.iframe) {
- current = this.getFragment(this.getHash(this.iframe));
- }
- if (current === this.fragment) return false;
- if (this.iframe) this.navigate(current);
- this.loadUrl();
- },
-
- // Attempt to load the current URL fragment. If a route succeeds with a
- // match, returns `true`. If no defined routes matches the fragment,
- // returns `false`.
- loadUrl: function(fragment) {
- fragment = this.fragment = this.getFragment(fragment);
- return _.any(this.handlers, function(handler) {
- if (handler.route.test(fragment)) {
- handler.callback(fragment);
- return true;
- }
- });
- },
-
- // Save a fragment into the hash history, or replace the URL state if the
- // 'replace' option is passed. You are responsible for properly URL-encoding
- // the fragment in advance.
- //
- // The options object can contain `trigger: true` if you wish to have the
- // route callback be fired (not usually desirable), or `replace: true`, if
- // you wish to modify the current URL without adding an entry to the history.
- navigate: function(fragment, options) {
- if (!History.started) return false;
- if (!options || options === true) options = {trigger: !!options};
-
- var url = this.root + (fragment = this.getFragment(fragment || ''));
-
- // Strip the fragment of the query and hash for matching.
- fragment = fragment.replace(pathStripper, '');
-
- if (this.fragment === fragment) return;
- this.fragment = fragment;
-
- // Don't include a trailing slash on the root.
- if (fragment === '' && url !== '/') url = url.slice(0, -1);
-
- // If pushState is available, we use it to set the fragment as a real URL.
- if (this._hasPushState) {
- this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url);
-
- // If hash changes haven't been explicitly disabled, update the hash
- // fragment to store history.
- } else if (this._wantsHashChange) {
- this._updateHash(this.location, fragment, options.replace);
- if (this.iframe && (fragment !== this.getFragment(this.getHash(this.iframe)))) {
- // Opening and closing the iframe tricks IE7 and earlier to push a
- // history entry on hash-tag change. When replace is true, we don't
- // want this.
- if(!options.replace) this.iframe.document.open().close();
- this._updateHash(this.iframe.location, fragment, options.replace);
- }
-
- // If you've told us that you explicitly don't want fallback hashchange-
- // based history, then `navigate` becomes a page refresh.
- } else {
- return this.location.assign(url);
- }
- if (options.trigger) return this.loadUrl(fragment);
- },
-
- // Update the hash location, either replacing the current entry, or adding
- // a new one to the browser history.
- _updateHash: function(location, fragment, replace) {
- if (replace) {
- var href = location.href.replace(/(javascript:|#).*$/, '');
- location.replace(href + '#' + fragment);
- } else {
- // Some browsers require that `hash` contains a leading #.
- location.hash = '#' + fragment;
- }
- }
-
- });
-
- // Create the default Backbone.history.
- Backbone.history = new History;
-
- // Helpers
- // -------
-
- // Helper function to correctly set up the prototype chain, for subclasses.
- // Similar to `goog.inherits`, but uses a hash of prototype properties and
- // class properties to be extended.
- var extend = function(protoProps, staticProps) {
- var parent = this;
- var child;
-
- // The constructor function for the new subclass is either defined by you
- // (the "constructor" property in your `extend` definition), or defaulted
- // by us to simply call the parent's constructor.
- if (protoProps && _.has(protoProps, 'constructor')) {
- child = protoProps.constructor;
- } else {
- child = function(){ return parent.apply(this, arguments); };
- }
-
- // Add static properties to the constructor function, if supplied.
- _.extend(child, parent, staticProps);
-
- // Set the prototype chain to inherit from `parent`, without calling
- // `parent`'s constructor function.
- var Surrogate = function(){ this.constructor = child; };
- Surrogate.prototype = parent.prototype;
- child.prototype = new Surrogate;
-
- // Add prototype properties (instance properties) to the subclass,
- // if supplied.
- if (protoProps) _.extend(child.prototype, protoProps);
-
- // Set a convenience property in case the parent's prototype is needed
- // later.
- child.__super__ = parent.prototype;
-
- return child;
- };
-
- // Set up inheritance for the model, collection, router, view and history.
- Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
-
- // Throw an error when a URL is needed, and none is supplied.
- var urlError = function() {
- throw new Error('A "url" property or function must be specified');
- };
-
- // Wrap an optional error callback with a fallback error event.
- var wrapError = function(model, options) {
- var error = options.error;
- options.error = function(resp) {
- if (error) error(model, resp, options);
- model.trigger('error', model, resp, options);
- };
- };
-
-}).call(this);
diff --git a/triplestores/fuseki/webapp/js/lib/backbone.marionette.js b/triplestores/fuseki/webapp/js/lib/backbone.marionette.js
deleted file mode 100644
index a4f6ccf665..0000000000
--- a/triplestores/fuseki/webapp/js/lib/backbone.marionette.js
+++ /dev/null
@@ -1,2385 +0,0 @@
-// MarionetteJS (Backbone.Marionette)
-// ----------------------------------
-// v1.2.2
-//
-// Copyright (c)2013 Derick Bailey, Muted Solutions, LLC.
-// Distributed under MIT license
-//
-// http://marionettejs.com
-
-
-
-/*!
- * Includes BabySitter
- * https://github.com/marionettejs/backbone.babysitter/
- *
- * Includes Wreqr
- * https://github.com/marionettejs/backbone.wreqr/
- */
-
-// Backbone.BabySitter
-// -------------------
-// v0.0.6
-//
-// Copyright (c)2013 Derick Bailey, Muted Solutions, LLC.
-// Distributed under MIT license
-//
-// http://github.com/babysitterjs/backbone.babysitter
-
-// Backbone.ChildViewContainer
-// ---------------------------
-//
-// Provide a container to store, retrieve and
-// shut down child views.
-
-Backbone.ChildViewContainer = (function(Backbone, _){
-
- // Container Constructor
- // ---------------------
-
- var Container = function(views){
- this._views = {};
- this._indexByModel = {};
- this._indexByCustom = {};
- this._updateLength();
-
- _.each(views, this.add, this);
- };
-
- // Container Methods
- // -----------------
-
- _.extend(Container.prototype, {
-
- // Add a view to this container. Stores the view
- // by `cid` and makes it searchable by the model
- // cid (and model itself). Optionally specify
- // a custom key to store an retrieve the view.
- add: function(view, customIndex){
- var viewCid = view.cid;
-
- // store the view
- this._views[viewCid] = view;
-
- // index it by model
- if (view.model){
- this._indexByModel[view.model.cid] = viewCid;
- }
-
- // index by custom
- if (customIndex){
- this._indexByCustom[customIndex] = viewCid;
- }
-
- this._updateLength();
- },
-
- // Find a view by the model that was attached to
- // it. Uses the model's `cid` to find it.
- findByModel: function(model){
- return this.findByModelCid(model.cid);
- },
-
- // Find a view by the `cid` of the model that was attached to
- // it. Uses the model's `cid` to find the view `cid` and
- // retrieve the view using it.
- findByModelCid: function(modelCid){
- var viewCid = this._indexByModel[modelCid];
- return this.findByCid(viewCid);
- },
-
- // Find a view by a custom indexer.
- findByCustom: function(index){
- var viewCid = this._indexByCustom[index];
- return this.findByCid(viewCid);
- },
-
- // Find by index. This is not guaranteed to be a
- // stable index.
- findByIndex: function(index){
- return _.values(this._views)[index];
- },
-
- // retrieve a view by it's `cid` directly
- findByCid: function(cid){
- return this._views[cid];
- },
-
- // Remove a view
- remove: function(view){
- var viewCid = view.cid;
-
- // delete model index
- if (view.model){
- delete this._indexByModel[view.model.cid];
- }
-
- // delete custom index
- _.any(this._indexByCustom, function(cid, key) {
- if (cid === viewCid) {
- delete this._indexByCustom[key];
- return true;
- }
- }, this);
-
- // remove the view from the container
- delete this._views[viewCid];
-
- // update the length
- this._updateLength();
- },
-
- // Call a method on every view in the container,
- // passing parameters to the call method one at a
- // time, like `function.call`.
- call: function(method){
- this.apply(method, _.tail(arguments));
- },
-
- // Apply a method on every view in the container,
- // passing parameters to the call method one at a
- // time, like `function.apply`.
- apply: function(method, args){
- _.each(this._views, function(view){
- if (_.isFunction(view[method])){
- view[method].apply(view, args || []);
- }
- });
- },
-
- // Update the `.length` attribute on this container
- _updateLength: function(){
- this.length = _.size(this._views);
- }
- });
-
- // Borrowing this code from Backbone.Collection:
- // http://backbonejs.org/docs/backbone.html#section-106
- //
- // Mix in methods from Underscore, for iteration, and other
- // collection related features.
- var methods = ['forEach', 'each', 'map', 'find', 'detect', 'filter',
- 'select', 'reject', 'every', 'all', 'some', 'any', 'include',
- 'contains', 'invoke', 'toArray', 'first', 'initial', 'rest',
- 'last', 'without', 'isEmpty', 'pluck'];
-
- _.each(methods, function(method) {
- Container.prototype[method] = function() {
- var views = _.values(this._views);
- var args = [views].concat(_.toArray(arguments));
- return _[method].apply(_, args);
- };
- });
-
- // return the public API
- return Container;
-})(Backbone, _);
-
-// Backbone.Wreqr (Backbone.Marionette)
-// ----------------------------------
-// v0.2.0
-//
-// Copyright (c)2013 Derick Bailey, Muted Solutions, LLC.
-// Distributed under MIT license
-//
-// http://github.com/marionettejs/backbone.wreqr
-
-
-Backbone.Wreqr = (function(Backbone, Marionette, _){
- "use strict";
- var Wreqr = {};
-
- // Handlers
-// --------
-// A registry of functions to call, given a name
-
-Wreqr.Handlers = (function(Backbone, _){
- "use strict";
-
- // Constructor
- // -----------
-
- var Handlers = function(options){
- this.options = options;
- this._wreqrHandlers = {};
-
- if (_.isFunction(this.initialize)){
- this.initialize(options);
- }
- };
-
- Handlers.extend = Backbone.Model.extend;
-
- // Instance Members
- // ----------------
-
- _.extend(Handlers.prototype, Backbone.Events, {
-
- // Add multiple handlers using an object literal configuration
- setHandlers: function(handlers){
- _.each(handlers, function(handler, name){
- var context = null;
-
- if (_.isObject(handler) && !_.isFunction(handler)){
- context = handler.context;
- handler = handler.callback;
- }
-
- this.setHandler(name, handler, context);
- }, this);
- },
-
- // Add a handler for the given name, with an
- // optional context to run the handler within
- setHandler: function(name, handler, context){
- var config = {
- callback: handler,
- context: context
- };
-
- this._wreqrHandlers[name] = config;
-
- this.trigger("handler:add", name, handler, context);
- },
-
- // Determine whether or not a handler is registered
- hasHandler: function(name){
- return !! this._wreqrHandlers[name];
- },
-
- // Get the currently registered handler for
- // the specified name. Throws an exception if
- // no handler is found.
- getHandler: function(name){
- var config = this._wreqrHandlers[name];
-
- if (!config){
- throw new Error("Handler not found for '" + name + "'");
- }
-
- return function(){
- var args = Array.prototype.slice.apply(arguments);
- return config.callback.apply(config.context, args);
- };
- },
-
- // Remove a handler for the specified name
- removeHandler: function(name){
- delete this._wreqrHandlers[name];
- },
-
- // Remove all handlers from this registry
- removeAllHandlers: function(){
- this._wreqrHandlers = {};
- }
- });
-
- return Handlers;
-})(Backbone, _);
-
- // Wreqr.CommandStorage
-// --------------------
-//
-// Store and retrieve commands for execution.
-Wreqr.CommandStorage = (function(){
- "use strict";
-
- // Constructor function
- var CommandStorage = function(options){
- this.options = options;
- this._commands = {};
-
- if (_.isFunction(this.initialize)){
- this.initialize(options);
- }
- };
-
- // Instance methods
- _.extend(CommandStorage.prototype, Backbone.Events, {
-
- // Get an object literal by command name, that contains
- // the `commandName` and the `instances` of all commands
- // represented as an array of arguments to process
- getCommands: function(commandName){
- var commands = this._commands[commandName];
-
- // we don't have it, so add it
- if (!commands){
-
- // build the configuration
- commands = {
- command: commandName,
- instances: []
- };
-
- // store it
- this._commands[commandName] = commands;
- }
-
- return commands;
- },
-
- // Add a command by name, to the storage and store the
- // args for the command
- addCommand: function(commandName, args){
- var command = this.getCommands(commandName);
- command.instances.push(args);
- },
-
- // Clear all commands for the given `commandName`
- clearCommands: function(commandName){
- var command = this.getCommands(commandName);
- command.instances = [];
- }
- });
-
- return CommandStorage;
-})();
-
- // Wreqr.Commands
-// --------------
-//
-// A simple command pattern implementation. Register a command
-// handler and execute it.
-Wreqr.Commands = (function(Wreqr){
- "use strict";
-
- return Wreqr.Handlers.extend({
- // default storage type
- storageType: Wreqr.CommandStorage,
-
- constructor: function(options){
- this.options = options || {};
-
- this._initializeStorage(this.options);
- this.on("handler:add", this._executeCommands, this);
-
- var args = Array.prototype.slice.call(arguments);
- Wreqr.Handlers.prototype.constructor.apply(this, args);
- },
-
- // Execute a named command with the supplied args
- execute: function(name, args){
- name = arguments[0];
- args = Array.prototype.slice.call(arguments, 1);
-
- if (this.hasHandler(name)){
- this.getHandler(name).apply(this, args);
- } else {
- this.storage.addCommand(name, args);
- }
-
- },
-
- // Internal method to handle bulk execution of stored commands
- _executeCommands: function(name, handler, context){
- var command = this.storage.getCommands(name);
-
- // loop through and execute all the stored command instances
- _.each(command.instances, function(args){
- handler.apply(context, args);
- });
-
- this.storage.clearCommands(name);
- },
-
- // Internal method to initialize storage either from the type's
- // `storageType` or the instance `options.storageType`.
- _initializeStorage: function(options){
- var storage;
-
- var StorageType = options.storageType || this.storageType;
- if (_.isFunction(StorageType)){
- storage = new StorageType();
- } else {
- storage = StorageType;
- }
-
- this.storage = storage;
- }
- });
-
-})(Wreqr);
-
- // Wreqr.RequestResponse
-// ---------------------
-//
-// A simple request/response implementation. Register a
-// request handler, and return a response from it
-Wreqr.RequestResponse = (function(Wreqr){
- "use strict";
-
- return Wreqr.Handlers.extend({
- request: function(){
- var name = arguments[0];
- var args = Array.prototype.slice.call(arguments, 1);
-
- return this.getHandler(name).apply(this, args);
- }
- });
-
-})(Wreqr);
-
- // Event Aggregator
-// ----------------
-// A pub-sub object that can be used to decouple various parts
-// of an application through event-driven architecture.
-
-Wreqr.EventAggregator = (function(Backbone, _){
- "use strict";
- var EA = function(){};
-
- // Copy the `extend` function used by Backbone's classes
- EA.extend = Backbone.Model.extend;
-
- // Copy the basic Backbone.Events on to the event aggregator
- _.extend(EA.prototype, Backbone.Events);
-
- return EA;
-})(Backbone, _);
-
-
- return Wreqr;
-})(Backbone, Backbone.Marionette, _);
-
-var Marionette = (function(global, Backbone, _){
- "use strict";
-
- // Define and export the Marionette namespace
- var Marionette = {};
- Backbone.Marionette = Marionette;
-
- // Get the DOM manipulator for later use
- Marionette.$ = Backbone.$;
-
-// Helpers
-// -------
-
-// For slicing `arguments` in functions
-var protoSlice = Array.prototype.slice;
-function slice(args) {
- return protoSlice.call(args);
-}
-
-function throwError(message, name) {
- var error = new Error(message);
- error.name = name || 'Error';
- throw error;
-}
-
-// Marionette.extend
-// -----------------
-
-// Borrow the Backbone `extend` method so we can use it as needed
-Marionette.extend = Backbone.Model.extend;
-
-// Marionette.getOption
-// --------------------
-
-// Retrieve an object, function or other value from a target
-// object or its `options`, with `options` taking precedence.
-Marionette.getOption = function(target, optionName){
- if (!target || !optionName){ return; }
- var value;
-
- if (target.options && (optionName in target.options) && (target.options[optionName] !== undefined)){
- value = target.options[optionName];
- } else {
- value = target[optionName];
- }
-
- return value;
-};
-
-// Trigger an event and/or a corresponding method name. Examples:
-//
-// `this.triggerMethod("foo")` will trigger the "foo" event and
-// call the "onFoo" method.
-//
-// `this.triggerMethod("foo:bar") will trigger the "foo:bar" event and
-// call the "onFooBar" method.
-Marionette.triggerMethod = (function(){
-
- // split the event name on the :
- var splitter = /(^|:)(\w)/gi;
-
- // take the event section ("section1:section2:section3")
- // and turn it in to uppercase name
- function getEventName(match, prefix, eventName) {
- return eventName.toUpperCase();
- }
-
- // actual triggerMethod name
- var triggerMethod = function(event) {
- // get the method name from the event name
- var methodName = 'on' + event.replace(splitter, getEventName);
- var method = this[methodName];
-
- // trigger the event, if a trigger method exists
- if(_.isFunction(this.trigger)) {
- this.trigger.apply(this, arguments);
- }
-
- // call the onMethodName if it exists
- if (_.isFunction(method)) {
- // pass all arguments, except the event name
- return method.apply(this, _.tail(arguments));
- }
- };
-
- return triggerMethod;
-})();
-
-// DOMRefresh
-// ----------
-//
-// Monitor a view's state, and after it has been rendered and shown
-// in the DOM, trigger a "dom:refresh" event every time it is
-// re-rendered.
-
-Marionette.MonitorDOMRefresh = (function(){
- // track when the view has been shown in the DOM,
- // using a Marionette.Region (or by other means of triggering "show")
- function handleShow(view){
- view._isShown = true;
- triggerDOMRefresh(view);
- }
-
- // track when the view has been rendered
- function handleRender(view){
- view._isRendered = true;
- triggerDOMRefresh(view);
- }
-
- // Trigger the "dom:refresh" event and corresponding "onDomRefresh" method
- function triggerDOMRefresh(view){
- if (view._isShown && view._isRendered){
- if (_.isFunction(view.triggerMethod)){
- view.triggerMethod("dom:refresh");
- }
- }
- }
-
- // Export public API
- return function(view){
- view.listenTo(view, "show", function(){
- handleShow(view);
- });
-
- view.listenTo(view, "render", function(){
- handleRender(view);
- });
- };
-})();
-
-
-// Marionette.bindEntityEvents & unbindEntityEvents
-// ---------------------------
-//
-// These methods are used to bind/unbind a backbone "entity" (collection/model)
-// to methods on a target object.
-//
-// The first parameter, `target`, must have a `listenTo` method from the
-// EventBinder object.
-//
-// The second parameter is the entity (Backbone.Model or Backbone.Collection)
-// to bind the events from.
-//
-// The third parameter is a hash of { "event:name": "eventHandler" }
-// configuration. Multiple handlers can be separated by a space. A
-// function can be supplied instead of a string handler name.
-
-(function(Marionette){
- "use strict";
-
- // Bind the event to handlers specified as a string of
- // handler names on the target object
- function bindFromStrings(target, entity, evt, methods){
- var methodNames = methods.split(/\s+/);
-
- _.each(methodNames,function(methodName) {
-
- var method = target[methodName];
- if(!method) {
- throwError("Method '"+ methodName +"' was configured as an event handler, but does not exist.");
- }
-
- target.listenTo(entity, evt, method, target);
- });
- }
-
- // Bind the event to a supplied callback function
- function bindToFunction(target, entity, evt, method){
- target.listenTo(entity, evt, method, target);
- }
-
- // Bind the event to handlers specified as a string of
- // handler names on the target object
- function unbindFromStrings(target, entity, evt, methods){
- var methodNames = methods.split(/\s+/);
-
- _.each(methodNames,function(methodName) {
- var method = target[methodName];
- target.stopListening(entity, evt, method, target);
- });
- }
-
- // Bind the event to a supplied callback function
- function unbindToFunction(target, entity, evt, method){
- target.stopListening(entity, evt, method, target);
- }
-
-
- // generic looping function
- function iterateEvents(target, entity, bindings, functionCallback, stringCallback){
- if (!entity || !bindings) { return; }
-
- // allow the bindings to be a function
- if (_.isFunction(bindings)){
- bindings = bindings.call(target);
- }
-
- // iterate the bindings and bind them
- _.each(bindings, function(methods, evt){
-
- // allow for a function as the handler,
- // or a list of event names as a string
- if (_.isFunction(methods)){
- functionCallback(target, entity, evt, methods);
- } else {
- stringCallback(target, entity, evt, methods);
- }
-
- });
- }
-
- // Export Public API
- Marionette.bindEntityEvents = function(target, entity, bindings){
- iterateEvents(target, entity, bindings, bindToFunction, bindFromStrings);
- };
-
- Marionette.unbindEntityEvents = function(target, entity, bindings){
- iterateEvents(target, entity, bindings, unbindToFunction, unbindFromStrings);
- };
-
-})(Marionette);
-
-
-// Callbacks
-// ---------
-
-// A simple way of managing a collection of callbacks
-// and executing them at a later point in time, using jQuery's
-// `Deferred` object.
-Marionette.Callbacks = function(){
- this._deferred = Marionette.$.Deferred();
- this._callbacks = [];
-};
-
-_.extend(Marionette.Callbacks.prototype, {
-
- // Add a callback to be executed. Callbacks added here are
- // guaranteed to execute, even if they are added after the
- // `run` method is called.
- add: function(callback, contextOverride){
- this._callbacks.push({cb: callback, ctx: contextOverride});
-
- this._deferred.done(function(context, options){
- if (contextOverride){ context = contextOverride; }
- callback.call(context, options);
- });
- },
-
- // Run all registered callbacks with the context specified.
- // Additional callbacks can be added after this has been run
- // and they will still be executed.
- run: function(options, context){
- this._deferred.resolve(context, options);
- },
-
- // Resets the list of callbacks to be run, allowing the same list
- // to be run multiple times - whenever the `run` method is called.
- reset: function(){
- var callbacks = this._callbacks;
- this._deferred = Marionette.$.Deferred();
- this._callbacks = [];
-
- _.each(callbacks, function(cb){
- this.add(cb.cb, cb.ctx);
- }, this);
- }
-});
-
-
-// Marionette Controller
-// ---------------------
-//
-// A multi-purpose object to use as a controller for
-// modules and routers, and as a mediator for workflow
-// and coordination of other objects, views, and more.
-Marionette.Controller = function(options){
- this.triggerMethod = Marionette.triggerMethod;
- this.options = options || {};
-
- if (_.isFunction(this.initialize)){
- this.initialize(this.options);
- }
-};
-
-Marionette.Controller.extend = Marionette.extend;
-
-// Controller Methods
-// --------------
-
-// Ensure it can trigger events with Backbone.Events
-_.extend(Marionette.Controller.prototype, Backbone.Events, {
- close: function(){
- this.stopListening();
- this.triggerMethod("close");
- this.unbind();
- }
-});
-
-// Region
-// ------
-//
-// Manage the visual regions of your composite application. See
-// http://lostechies.com/derickbailey/2011/12/12/composite-js-apps-regions-and-region-managers/
-
-Marionette.Region = function(options){
- this.options = options || {};
-
- this.el = Marionette.getOption(this, "el");
-
- if (!this.el){
- var err = new Error("An 'el' must be specified for a region.");
- err.name = "NoElError";
- throw err;
- }
-
- if (this.initialize){
- var args = Array.prototype.slice.apply(arguments);
- this.initialize.apply(this, args);
- }
-};
-
-
-// Region Type methods
-// -------------------
-
-_.extend(Marionette.Region, {
-
- // Build an instance of a region by passing in a configuration object
- // and a default region type to use if none is specified in the config.
- //
- // The config object should either be a string as a jQuery DOM selector,
- // a Region type directly, or an object literal that specifies both
- // a selector and regionType:
- //
- // ```js
- // {
- // selector: "#foo",
- // regionType: MyCustomRegion
- // }
- // ```
- //
- buildRegion: function(regionConfig, defaultRegionType){
-
- var regionIsString = (typeof regionConfig === "string");
- var regionSelectorIsString = (typeof regionConfig.selector === "string");
- var regionTypeIsUndefined = (typeof regionConfig.regionType === "undefined");
- var regionIsType = (typeof regionConfig === "function");
-
- if (!regionIsType && !regionIsString && !regionSelectorIsString) {
- throw new Error("Region must be specified as a Region type, a selector string or an object with selector property");
- }
-
- var selector, RegionType;
-
- // get the selector for the region
-
- if (regionIsString) {
- selector = regionConfig;
- }
-
- if (regionConfig.selector) {
- selector = regionConfig.selector;
- }
-
- // get the type for the region
-
- if (regionIsType){
- RegionType = regionConfig;
- }
-
- if (!regionIsType && regionTypeIsUndefined) {
- RegionType = defaultRegionType;
- }
-
- if (regionConfig.regionType) {
- RegionType = regionConfig.regionType;
- }
-
- // build the region instance
- var region = new RegionType({
- el: selector
- });
-
- // override the `getEl` function if we have a parentEl
- // this must be overridden to ensure the selector is found
- // on the first use of the region. if we try to assign the
- // region's `el` to `parentEl.find(selector)` in the object
- // literal to build the region, the element will not be
- // guaranteed to be in the DOM already, and will cause problems
- if (regionConfig.parentEl){
-
- region.getEl = function(selector) {
- var parentEl = regionConfig.parentEl;
- if (_.isFunction(parentEl)){
- parentEl = parentEl();
- }
- return parentEl.find(selector);
- };
- }
-
- return region;
- }
-
-});
-
-// Region Instance Methods
-// -----------------------
-
-_.extend(Marionette.Region.prototype, Backbone.Events, {
-
- // Displays a backbone view instance inside of the region.
- // Handles calling the `render` method for you. Reads content
- // directly from the `el` attribute. Also calls an optional
- // `onShow` and `close` method on your view, just after showing
- // or just before closing the view, respectively.
- show: function(view){
-
- this.ensureEl();
-
- var isViewClosed = view.isClosed || _.isUndefined(view.$el);
-
- var isDifferentView = view !== this.currentView;
-
- if (isDifferentView) {
- this.close();
- }
-
- view.render();
-
- if (isDifferentView || isViewClosed) {
- this.open(view);
- }
-
- this.currentView = view;
-
- Marionette.triggerMethod.call(this, "show", view);
- Marionette.triggerMethod.call(view, "show");
- },
-
- ensureEl: function(){
- if (!this.$el || this.$el.length === 0){
- this.$el = this.getEl(this.el);
- }
- },
-
- // Override this method to change how the region finds the
- // DOM element that it manages. Return a jQuery selector object.
- getEl: function(selector){
- return Marionette.$(selector);
- },
-
- // Override this method to change how the new view is
- // appended to the `$el` that the region is managing
- open: function(view){
- this.$el.empty().append(view.el);
- },
-
- // Close the current view, if there is one. If there is no
- // current view, it does nothing and returns immediately.
- close: function(){
- var view = this.currentView;
- if (!view || view.isClosed){ return; }
-
- // call 'close' or 'remove', depending on which is found
- if (view.close) { view.close(); }
- else if (view.remove) { view.remove(); }
-
- Marionette.triggerMethod.call(this, "close");
-
- delete this.currentView;
- },
-
- // Attach an existing view to the region. This
- // will not call `render` or `onShow` for the new view,
- // and will not replace the current HTML for the `el`
- // of the region.
- attachView: function(view){
- this.currentView = view;
- },
-
- // Reset the region by closing any existing view and
- // clearing out the cached `$el`. The next time a view
- // is shown via this region, the region will re-query the
- // DOM for the region's `el`.
- reset: function(){
- this.close();
- delete this.$el;
- }
-});
-
-// Copy the `extend` function used by Backbone's classes
-Marionette.Region.extend = Marionette.extend;
-
-// Marionette.RegionManager
-// ------------------------
-//
-// Manage one or more related `Marionette.Region` objects.
-Marionette.RegionManager = (function(Marionette){
-
- var RegionManager = Marionette.Controller.extend({
- constructor: function(options){
- this._regions = {};
- Marionette.Controller.prototype.constructor.call(this, options);
- },
-
- // Add multiple regions using an object literal, where
- // each key becomes the region name, and each value is
- // the region definition.
- addRegions: function(regionDefinitions, defaults){
- var regions = {};
-
- _.each(regionDefinitions, function(definition, name){
- if (typeof definition === "string"){
- definition = { selector: definition };
- }
-
- if (definition.selector){
- definition = _.defaults({}, definition, defaults);
- }
-
- var region = this.addRegion(name, definition);
- regions[name] = region;
- }, this);
-
- return regions;
- },
-
- // Add an individual region to the region manager,
- // and return the region instance
- addRegion: function(name, definition){
- var region;
-
- var isObject = _.isObject(definition);
- var isString = _.isString(definition);
- var hasSelector = !!definition.selector;
-
- if (isString || (isObject && hasSelector)){
- region = Marionette.Region.buildRegion(definition, Marionette.Region);
- } else if (_.isFunction(definition)){
- region = Marionette.Region.buildRegion(definition, Marionette.Region);
- } else {
- region = definition;
- }
-
- this._store(name, region);
- this.triggerMethod("region:add", name, region);
- return region;
- },
-
- // Get a region by name
- get: function(name){
- return this._regions[name];
- },
-
- // Remove a region by name
- removeRegion: function(name){
- var region = this._regions[name];
- this._remove(name, region);
- },
-
- // Close all regions in the region manager, and
- // remove them
- removeRegions: function(){
- _.each(this._regions, function(region, name){
- this._remove(name, region);
- }, this);
- },
-
- // Close all regions in the region manager, but
- // leave them attached
- closeRegions: function(){
- _.each(this._regions, function(region, name){
- region.close();
- }, this);
- },
-
- // Close all regions and shut down the region
- // manager entirely
- close: function(){
- this.removeRegions();
- var args = Array.prototype.slice.call(arguments);
- Marionette.Controller.prototype.close.apply(this, args);
- },
-
- // internal method to store regions
- _store: function(name, region){
- this._regions[name] = region;
- this._setLength();
- },
-
- // internal method to remove a region
- _remove: function(name, region){
- region.close();
- delete this._regions[name];
- this._setLength();
- this.triggerMethod("region:remove", name, region);
- },
-
- // set the number of regions current held
- _setLength: function(){
- this.length = _.size(this._regions);
- }
-
- });
-
- // Borrowing this code from Backbone.Collection:
- // http://backbonejs.org/docs/backbone.html#section-106
- //
- // Mix in methods from Underscore, for iteration, and other
- // collection related features.
- var methods = ['forEach', 'each', 'map', 'find', 'detect', 'filter',
- 'select', 'reject', 'every', 'all', 'some', 'any', 'include',
- 'contains', 'invoke', 'toArray', 'first', 'initial', 'rest',
- 'last', 'without', 'isEmpty', 'pluck'];
-
- _.each(methods, function(method) {
- RegionManager.prototype[method] = function() {
- var regions = _.values(this._regions);
- var args = [regions].concat(_.toArray(arguments));
- return _[method].apply(_, args);
- };
- });
-
- return RegionManager;
-})(Marionette);
-
-
-// Template Cache
-// --------------
-
-// Manage templates stored in `
-
-
-
-
-
-
-
-
-
-
-
- Manage datasets
-
- Perform management actions on existing datasets, including backup,
- or add a new dataset.
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/triplestores/fuseki/webapp/services.html b/triplestores/fuseki/webapp/services.html
deleted file mode 100644
index 91aab57da8..0000000000
--- a/triplestores/fuseki/webapp/services.html
+++ /dev/null
@@ -1,76 +0,0 @@
-
-
-
- Apache Jena Fuseki - services
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Inspect dataset
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/triplestores/fuseki/webapp/test/test-fuseki-config.ttl b/triplestores/fuseki/webapp/test/test-fuseki-config.ttl
deleted file mode 100644
index 190676a642..0000000000
--- a/triplestores/fuseki/webapp/test/test-fuseki-config.ttl
+++ /dev/null
@@ -1,27 +0,0 @@
-# Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0
-
-@prefix : <#> .
-@prefix fuseki: .
-@prefix rdf: .
-
-@prefix rdfs: .
-@prefix tdb: .
-@prefix ja: .
-
-## ---------------------------------------------------------------
-## Updatable in-memory dataset.
-
-<#service1> rdf:type fuseki:Service ;
- # URI of the dataset -- http://host:port/ds
- fuseki:name "test-service" ;
- fuseki:serviceQuery "sparql" ;
- fuseki:serviceQuery "query" ;
- fuseki:serviceUpdate "update" ;
- fuseki:serviceUpload "upload" ;
- fuseki:serviceReadWriteGraphStore "data" ;
- fuseki:serviceReadGraphStore "get" ;
- fuseki:dataset <#dataset> ;
- .
-
-## In-memory, initially empty.
-<#dataset> rdf:type ja:RDFDataset .
diff --git a/triplestores/fuseki/webapp/validate.html b/triplestores/fuseki/webapp/validate.html
deleted file mode 100644
index d206576909..0000000000
--- a/triplestores/fuseki/webapp/validate.html
+++ /dev/null
@@ -1,147 +0,0 @@
-
-
-
- Apache Jena Fuseki - validation
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Fuseki – validation
- Use this page to validate SPARQL queries or RDF data.
- Forthcoming feature – not yet working.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/triplestores/graphdb/.gitignore b/triplestores/graphdb/.gitignore
deleted file mode 100644
index b07ba2c4d2..0000000000
--- a/triplestores/graphdb/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-# Ignore everything in this directory
-*
-# Except this file
-!.gitignore
-!README.md
\ No newline at end of file
diff --git a/triplestores/graphdb/README.md b/triplestores/graphdb/README.md
deleted file mode 100644
index 3c20b59f43..0000000000
--- a/triplestores/graphdb/README.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# GraphDB
-
-The latest version of **GraphDB-Free** and **GraphDB-SE** supported by Knora is **8.5.0**.
-
-**GraphDB-Free** is the Free Edition of the triplestore from Ontotext (http://ontotext.com). GraphDB-Free must be licensed
-separately by the user, by registering with Ontotext, i.e. filling out the form for downloading the free edition.
-
-**GraphDB-SE** is the Standard Edition of the triplestore from Ontotext (http://ontotext.com). GraphDB-SE must be licensed separately by the user.
-
-
-## Usage for GraphDB-Free
-
-Download distribution from Ontotext. Unzip ``graphdb-free-x.x.x-dist.zip`` to a place of your choosing and run the following:
-
-```
-$ cd /to/unziped/location
-$ ./bin/graphdb
-```
-
-## Usage for GraphDB-SE
-
-Download distribution from Ontotext. Unzip ``graphdb-se-x.x.x-dist.zip`` to a place of your choosing and run the following:
-
-```
-$ cd /to/unziped/location
-$ ./bin/graphdb -Dgraphdb.license.file=/path/to/GRAPHDB_SE.license
\ No newline at end of file
diff --git a/vars.mk b/vars.mk
index dedffb0000..215bbcce7c 100644
--- a/vars.mk
+++ b/vars.mk
@@ -1,18 +1,16 @@
SIPI_VERSION := 2.0.1
-GRAPHDB_SE_VERSION := 9.0.0
-GRAPHDB_FREE_VERSION := 9.0.0
-_GRAPHDB_HEAP_SIZE := 5G
+
+FUSEKI_HEAP_SIZE := 3G
REPO_PREFIX := daschswiss
KNORA_API_REPO := knora-api
-KNORA_GRAPHDB_SE_REPO := knora-graphdb-se
-KNORA_GRAPHDB_FREE_REPO := knora-graphdb-free
+KNORA_FUSEKI_REPO := knora-jena-fuseki
KNORA_SIPI_REPO := knora-sipi
KNORA_ASSETS_REPO := knora-assets
KNORA_UPGRADE_REPO := knora-upgrade
KNORA_SALSAH1_REPO := knora-salsah1
KNORA_WEBAPI_DB_CONNECTIONS := 2
-KNORA_GRAPHDB_REPOSITORY_NAME := knora-test
+KNORA_DB_REPOSITORY_NAME := knora-test
ifeq ($(BUILD_TAG),)
BUILD_TAG := $(shell git describe --tag --dirty --abbrev=7)
@@ -25,12 +23,8 @@ ifeq ($(KNORA_API_IMAGE),)
KNORA_API_IMAGE := $(REPO_PREFIX)/$(KNORA_API_REPO):$(BUILD_TAG)
endif
-ifeq ($(KNORA_GRAPHDB_SE_IMAGE),)
- KNORA_GRAPHDB_SE_IMAGE := $(REPO_PREFIX)/$(KNORA_GRAPHDB_SE_REPO):$(BUILD_TAG)
-endif
-
-ifeq ($(KNORA_GRAPHDB_FREE_IMAGE),)
- KNORA_GRAPHDB_FREE_IMAGE := $(REPO_PREFIX)/$(KNORA_GRAPHDB_FREE_REPO):$(BUILD_TAG)
+ifeq ($(KNORA_FUSEKI_IMAGE),)
+ KNORA_FUSEKI_IMAGE := $(REPO_PREFIX)/$(KNORA_FUSEKI_REPO):$(BUILD_TAG)
endif
ifeq ($(KNORA_SIPI_IMAGE),)
@@ -53,22 +47,12 @@ ifeq ($(GIT_EMAIL),)
GIT_EMAIL := $(shell git config user.email)
endif
-ifeq ($(KNORA_GDB_LICENSE),)
- KNORA_GDB_LICENSE := unknown
-endif
-
-ifeq ($(KNORA_GDB_IMPORT),)
- KNORA_GDB_IMPORT := unknown
-endif
-
-ifeq ($(KNORA_GDB_HOME),)
- KNORA_GDB_HOME := unknown
+ifeq ($(KNORA_DB_IMPORT),)
+ KNORA_DB_IMPORT := unknown
endif
-ifeq ($(GRAPHDB_HEAP_SIZE),)
- KNORA_GDB_HEAP_SIZE := $(_GRAPHDB_HEAP_SIZE)
-else
- KNORA_GDB_HEAP_SIZE := $(GRAPHDB_HEAP_SIZE)
+ifeq ($(KNORA_DB_HOME),)
+ KNORA_DB_HOME := unknown
endif
UNAME := $(shell uname)
diff --git a/webapi/scripts/Makefile b/webapi/scripts/Makefile
index 64feb50f74..c5239f9790 100644
--- a/webapi/scripts/Makefile
+++ b/webapi/scripts/Makefile
@@ -1,43 +1,18 @@
-.PHONY: graphdb-se-docker-init-knora-test
-graphdb-se-docker-init-knora-test: ## initializes docker GraphDB-SE with the knora-test repository
- ./graphdb-se-docker-init-knora-test.sh
+.PHONY: fuseki-init-knora-test
+fuseki-init-knora-test: ## initializes Fuseki with the knora-test repository and data
+ ./fuseki-init-knora-test.sh
-.PHONY: graphdb-se-docker-init-knora-test-minimal
-graphdb-se-docker-init-knora-test-minimal: ## initializes docker GraphDB-SE with the knora-test repository and minimal data
- ./graphdb-se-docker-init-knora-test-minimal.sh
+.PHONY: fuseki-init-knora-test-minimal
+fuseki-init-knora-test-minimal: ## initializes Fuseki with the knora-test repository and minimal data
+ ./fuseki-init-knora-test-minimal.sh
-.PHONY: graphdb-se-docker-init-knora-test-unit
-graphdb-se-docker-init-knora-test-unit: ## initializes docker GraphDB-SE with the knora-test-unit repository
- ./graphdb-se-docker-init-knora-test-unit.sh
-
-.PHONY: graphdb-se-docker-init-knora-test-unit-minimal
-graphdb-se-docker-init-knora-test-unit-minimal: ## initializes docker GraphDB-SE with the knora-test-unit repository and minimal data
- ./graphdb-se-docker-init-knora-test-unit-minimal.sh
-
-.PHONY: graphdb-free-docker-init-knora-test
-graphdb-free-docker-init-knora-test: ## initializes docker GraphDB-Free with the knora-test repository
- ./graphdb-free-docker-init-knora-test.sh
-
-.PHONY: graphdb-free-docker-init-knora-test-minimal
-graphdb-free-docker-init-knora-test-minimal: ## initializes docker GraphDB-Free with the knora-test repository and minimal data
- ./graphdb-free-docker-init-knora-test-minimal.sh
-
-.PHONY: graphdb-free-docker-init-knora-test-unit
-graphdb-free-docker-init-knora-test-unit: ## initializes docker GraphDB-Free with the knora-test-unit repository
- ./graphdb-free-docker-init-knora-test-unit.sh
-
-.PHONY: graphdb-se-local-init-knora-test
-graphdb-se-local-init-knora-test: ## initializes local GraphDB-SE with the knora-test repository
- ./graphdb-se-local-init-knora-test.sh
-
-.PHONY: graphdb-se-local-init-knora-test-minimal
-graphdb-se-local-init-knora-test-minimal: ## initializes local GraphDB-SE with the knora-test repository and minimal data
- ./graphdb-se-local-init-knora-test-minimal.sh
-
-.PHONY: graphdb-se-local-init-knora-test-unit
-graphdb-se-local-init-knora-test-unit: ## initializes local GraphDB-SE with the knora-test-unit repository
- ./graphdb-se-local-init-knora-test-unit.sh
+.PHONY: fuseki-init-knora-test-unit
+fuseki-init-knora-test-unit: ## initializes Fuseki with the knora-test-unit repository and no data
+ ./fuseki-init-knora-test-unit.sh
+.PHONY: fuseki-init-knora-test-unit-minimal
+fuseki-init-knora-test-unit-minimal: ## initializes Fuseki with the knora-test-unit repository and minimal data
+ ./fuseki-init-knora-test-unit-minimal.sh
.PHONY: help
help: ## this help
diff --git a/webapi/scripts/Readme.md b/webapi/scripts/Readme.md
index f93050efda..1b07795652 100644
--- a/webapi/scripts/Readme.md
+++ b/webapi/scripts/Readme.md
@@ -1,5 +1,19 @@
# Triplestore initialization scripts
+## Fuseki
+
+### Initialize for CI (continuous integration) and unit testing (running tests inside sbt)
+```
+$ make fuseki-init-knora-test-unit
+$ make fuseki-init-knora-test-unit-minimal
+```
+
+### Initialize for using in the test / staging environment
+```
+$ make fuseki-init-knora-test
+$ make fuseki-init-knora-test-minimal
+```
+
## GraphDB
### Initialize for CI (continuous integration) and unit testing (running tests inside sbt)
@@ -32,9 +46,3 @@ This script will create the ``knora-prod`` repository and load data specified in
- with GraphDB running locally, e.g., graphdb distribution:
```$ graphdb-se-local-init-knora-prod.sh ```
-
-
-## Fuseki
-
-Simply run Fuseki, either in a docker container or locally by using the supplied distribution.
-
diff --git a/webapi/scripts/fuseki-empty-repository.sh b/webapi/scripts/fuseki-empty-repository.sh
index 237f2a34c6..b62385ea57 100755
--- a/webapi/scripts/fuseki-empty-repository.sh
+++ b/webapi/scripts/fuseki-empty-repository.sh
@@ -51,4 +51,4 @@ if [[ -z "${HOST}" ]]; then
HOST="localhost:8080"
fi
-curl -sS -X POST -H "Content-Type: application/sparql-update" -d "DROP ALL" -u "${USERNAME}:${PASSWORD}" "http://${HOST}/fuseki/${REPOSITORY}"
+curl -sS -X POST -H "Content-Type: application/sparql-update" -d "DROP ALL" -u "${USERNAME}:${PASSWORD}" "http://${HOST}/${REPOSITORY}"
diff --git a/webapi/scripts/fuseki-init-knora-test-minimal.sh b/webapi/scripts/fuseki-init-knora-test-minimal.sh
new file mode 100755
index 0000000000..e4a9bfda31
--- /dev/null
+++ b/webapi/scripts/fuseki-init-knora-test-minimal.sh
@@ -0,0 +1,97 @@
+#!/usr/bin/env bash
+
+#set -x
+
+POSITIONAL=()
+while [[ $# -gt 0 ]]; do
+ key="$1"
+
+ case $key in
+ -u | --username)
+ USERNAME="$2"
+ shift # past argument
+ shift # past value
+ ;;
+ -p | --password)
+ PASSWORD="$2"
+ shift # past argument
+ shift # past value
+ ;;
+ -h | --host)
+ HOST="$2"
+ shift # past argument
+ shift # past value
+ ;;
+ *) # unknown option
+ POSITIONAL+=("$1") # save it in an array for later
+ shift # past argument
+ ;;
+ esac
+done
+set -- "${POSITIONAL[@]}" # restore positional parameters
+
+FILE="$1"
+
+REPOSITORY="knora-test"
+
+if [[ -z "${HOST}" ]]; then
+ HOST="localhost:3030"
+fi
+
+if [[ -z "${USERNAME}" ]]; then
+ USERNAME="admin"
+fi
+
+if [[ -z "${PASSWORD}" ]]; then
+ PASSWORD="test"
+fi
+
+delete-repository() {
+ STATUS=$(curl -s -o /dev/null -w '%{http_code}' -u ${USERNAME}:${PASSWORD} -X DELETE http://${HOST}/\$/datasets/${REPOSITORY})
+
+ if [ "${STATUS}" -eq 200 ]; then
+ echo "==> delete repository done"
+ return 0
+ else
+ echo "==> delete repository failed"
+ return 1
+ fi
+}
+
+create-repository() {
+ STATUS=$(curl -s -o /dev/null -w '%{http_code}' -u ${USERNAME}:${PASSWORD} -F data=@./fuseki-knora-test-repository-config.ttl http://${HOST}/\$/datasets)
+
+ if [ "${STATUS}" -eq 200 ]; then
+ echo "==> create repository done"
+ return 0
+ else
+ echo "==> create repository failed"
+ return 1
+ fi
+}
+
+upload-graph() {
+ STATUS=$(curl -s -o /dev/null -w '%{http_code}' -u ${USERNAME}:${PASSWORD} -H "Content-Type:text/turtle" -d @$1 -X PUT http://${HOST}/${REPOSITORY}\?graph\="$2")
+
+ if [ "${STATUS}" -eq 201 ]; then
+ echo "==> 201 Created: $1 -> $2"
+ return 0
+ elif [ "${STATUS}" -eq 200 ]; then
+ echo "==> 200 OK: $1 -> $2"
+ return 0
+ else
+ echo "==> failed with status code ${STATUS}: $1 -> $2"
+ return 1
+ fi
+}
+
+# delete-repository // delete dos not work correctly. need to delete database manually.
+create-repository
+upload-graph ../../knora-ontologies/knora-admin.ttl http://www.knora.org/ontology/knora-admin
+upload-graph ../../knora-ontologies/knora-base.ttl http://www.knora.org/ontology/knora-base
+upload-graph ../../knora-ontologies/standoff-onto.ttl http://www.knora.org/ontology/standoff
+upload-graph ../../knora-ontologies/standoff-data.ttl http://www.knora.org/data/standoff
+upload-graph ../../knora-ontologies/salsah-gui.ttl http://www.knora.org/ontology/salsah-gui
+upload-graph ../_test_data/all_data/admin-data.ttl http://www.knora.org/data/admin
+upload-graph ../_test_data/all_data/permissions-data.ttl http://www.knora.org/data/permissions
+upload-graph ../_test_data/all_data/system-data.ttl http://www.knora.org/data/0000/SystemProject
diff --git a/webapi/scripts/fuseki-init-knora-test-unit-minimal.sh b/webapi/scripts/fuseki-init-knora-test-unit-minimal.sh
new file mode 100755
index 0000000000..e7eac0b06d
--- /dev/null
+++ b/webapi/scripts/fuseki-init-knora-test-unit-minimal.sh
@@ -0,0 +1,97 @@
+#!/usr/bin/env bash
+
+#set -x
+
+POSITIONAL=()
+while [[ $# -gt 0 ]]; do
+ key="$1"
+
+ case $key in
+ -u | --username)
+ USERNAME="$2"
+ shift # past argument
+ shift # past value
+ ;;
+ -p | --password)
+ PASSWORD="$2"
+ shift # past argument
+ shift # past value
+ ;;
+ -h | --host)
+ HOST="$2"
+ shift # past argument
+ shift # past value
+ ;;
+ *) # unknown option
+ POSITIONAL+=("$1") # save it in an array for later
+ shift # past argument
+ ;;
+ esac
+done
+set -- "${POSITIONAL[@]}" # restore positional parameters
+
+FILE="$1"
+
+REPOSITORY="knora-test-unit"
+
+if [[ -z "${HOST}" ]]; then
+ HOST="localhost:3030"
+fi
+
+if [[ -z "${USERNAME}" ]]; then
+ USERNAME="admin"
+fi
+
+if [[ -z "${PASSWORD}" ]]; then
+ PASSWORD="test"
+fi
+
+delete-repository() {
+ STATUS=$(curl -s -o /dev/null -w '%{http_code}' -u ${USERNAME}:${PASSWORD} -X DELETE http://${HOST}/\$/datasets/${REPOSITORY})
+
+ if [ "${STATUS}" -eq 200 ]; then
+ echo "==> delete repository done"
+ return 0
+ else
+ echo "==> delete repository failed"
+ return 1
+ fi
+}
+
+create-repository() {
+ STATUS=$(curl -s -o /dev/null -w '%{http_code}' -u ${USERNAME}:${PASSWORD} -F data=@./fuseki-knora-test-unit-repository-config.ttl http://${HOST}/\$/datasets)
+
+ if [ "${STATUS}" -eq 200 ]; then
+ echo "==> create repository done"
+ return 0
+ else
+ echo "==> create repository failed"
+ return 1
+ fi
+}
+
+upload-graph() {
+ STATUS=$(curl -s -o /dev/null -w '%{http_code}' -u ${USERNAME}:${PASSWORD} -H "Content-Type:text/turtle" -d @$1 -X PUT http://${HOST}/${REPOSITORY}\?graph\="$2")
+
+ if [ "${STATUS}" -eq 201 ]; then
+ echo "==> 201 Created: $1 -> $2"
+ return 0
+ elif [ "${STATUS}" -eq 200 ]; then
+ echo "==> 200 OK: $1 -> $2"
+ return 0
+ else
+ echo "==> failed with status code ${STATUS}: $1 -> $2"
+ return 1
+ fi
+}
+
+# delete-repository // delete dos not work correctly. need to delete database manually.
+create-repository
+upload-graph ../../knora-ontologies/knora-admin.ttl http://www.knora.org/ontology/knora-admin
+upload-graph ../../knora-ontologies/knora-base.ttl http://www.knora.org/ontology/knora-base
+upload-graph ../../knora-ontologies/standoff-onto.ttl http://www.knora.org/ontology/standoff
+upload-graph ../../knora-ontologies/standoff-data.ttl http://www.knora.org/data/standoff
+upload-graph ../../knora-ontologies/salsah-gui.ttl http://www.knora.org/ontology/salsah-gui
+upload-graph ../_test_data/all_data/admin-data.ttl http://www.knora.org/data/admin
+upload-graph ../_test_data/all_data/permissions-data.ttl http://www.knora.org/data/permissions
+upload-graph ../_test_data/all_data/system-data.ttl http://www.knora.org/data/0000/SystemProject
diff --git a/webapi/scripts/fuseki-init-knora-test-unit.sh b/webapi/scripts/fuseki-init-knora-test-unit.sh
new file mode 100755
index 0000000000..35ba00bb2e
--- /dev/null
+++ b/webapi/scripts/fuseki-init-knora-test-unit.sh
@@ -0,0 +1,113 @@
+#!/usr/bin/env bash
+
+#set -x
+
+POSITIONAL=()
+while [[ $# -gt 0 ]]; do
+ key="$1"
+
+ case $key in
+ -u | --username)
+ USERNAME="$2"
+ shift # past argument
+ shift # past value
+ ;;
+ -p | --password)
+ PASSWORD="$2"
+ shift # past argument
+ shift # past value
+ ;;
+ -h | --host)
+ HOST="$2"
+ shift # past argument
+ shift # past value
+ ;;
+ *) # unknown option
+ POSITIONAL+=("$1") # save it in an array for later
+ shift # past argument
+ ;;
+ esac
+done
+set -- "${POSITIONAL[@]}" # restore positional parameters
+
+FILE="$1"
+
+REPOSITORY="knora-test-unit"
+
+if [[ -z "${HOST}" ]]; then
+ HOST="localhost:3030"
+fi
+
+if [[ -z "${USERNAME}" ]]; then
+ USERNAME="admin"
+fi
+
+if [[ -z "${PASSWORD}" ]]; then
+ PASSWORD="test"
+fi
+
+delete-repository() {
+ STATUS=$(curl -s -o /dev/null -w '%{http_code}' -u ${USERNAME}:${PASSWORD} -X DELETE http://${HOST}/\$/datasets/${REPOSITORY})
+
+ if [ "${STATUS}" -eq 200 ]; then
+ echo "==> delete repository done"
+ return 0
+ else
+ echo "==> delete repository failed"
+ return 1
+ fi
+}
+
+create-repository() {
+ STATUS=$(curl -s -o /dev/null -w '%{http_code}' -u ${USERNAME}:${PASSWORD} -F data=@./fuseki-knora-test-unit-repository-config.ttl http://${HOST}/\$/datasets)
+
+ if [ "${STATUS}" -eq 200 ]; then
+ echo "==> create repository done"
+ return 0
+ else
+ echo "==> create repository failed"
+ return 1
+ fi
+}
+
+upload-graph() {
+ STATUS=$(curl -s -o /dev/null -w '%{http_code}' -u ${USERNAME}:${PASSWORD} -H "Content-Type:text/turtle" -d @$1 -X PUT http://${HOST}/${REPOSITORY}\?graph\="$2")
+
+ if [ "${STATUS}" -eq 201 ]; then
+ echo "==> 201 Created: $1 -> $2"
+ return 0
+ elif [ "${STATUS}" -eq 200 ]; then
+ echo "==> 200 OK: $1 -> $2"
+ return 0
+ else
+ echo "==> failed with status code ${STATUS}: $1 -> $2"
+ return 1
+ fi
+}
+
+# delete-repository // delete dos not work correctly. need to delete database manually.
+create-repository
+upload-graph ../../knora-ontologies/knora-admin.ttl http://www.knora.org/ontology/knora-admin
+upload-graph ../../knora-ontologies/knora-base.ttl http://www.knora.org/ontology/knora-base
+upload-graph ../../knora-ontologies/standoff-onto.ttl http://www.knora.org/ontology/standoff
+upload-graph ../../knora-ontologies/standoff-data.ttl http://www.knora.org/data/standoff
+upload-graph ../../knora-ontologies/salsah-gui.ttl http://www.knora.org/ontology/salsah-gui
+upload-graph ../_test_data/all_data/admin-data.ttl http://www.knora.org/data/admin
+upload-graph ../_test_data/all_data/permissions-data.ttl http://www.knora.org/data/permissions
+upload-graph ../_test_data/all_data/system-data.ttl http://www.knora.org/data/0000/SystemProject
+upload-graph ../_test_data/ontologies/incunabula-onto.ttl http://www.knora.org/ontology/0803/incunabula
+upload-graph ../_test_data/all_data/incunabula-data.ttl http://www.knora.org/data/0803/incunabula
+upload-graph ../_test_data/ontologies/dokubib-onto.ttl http://www.knora.org/ontology/0804/dokubib
+upload-graph ../_test_data/ontologies/images-onto.ttl http://www.knora.org/ontology/00FF/images
+upload-graph ../_test_data/demo_data/images-demo-data.ttl http://www.knora.org/data/00FF/images
+upload-graph ../_test_data/ontologies/anything-onto.ttl http://www.knora.org/ontology/0001/anything
+upload-graph ../_test_data/all_data/anything-data.ttl http://www.knora.org/data/0001/anything
+upload-graph ../_test_data/ontologies/something-onto.ttl http://www.knora.org/ontology/0001/something
+upload-graph ../_test_data/ontologies/beol-onto.ttl http://www.knora.org/ontology/0801/beol
+upload-graph ../_test_data/ontologies/biblio-onto.ttl http://www.knora.org/ontology/0801/biblio
+upload-graph ../_test_data/ontologies/newton-onto.ttl http://www.knora.org/ontology/0801/newton
+upload-graph ../_test_data/ontologies/leibniz-onto.ttl http://www.knora.org/ontology/0801/leibniz
+upload-graph ../_test_data/all_data/biblio-data.ttl http://www.knora.org/data/0801/biblio
+upload-graph ../_test_data/all_data/beol-data.ttl http://www.knora.org/data/0801/beol
+upload-graph ../_test_data/ontologies/webern-onto.ttl http://www.knora.org/ontology/08AE/webern
+upload-graph ../_test_data/all_data/webern-data.ttl http://www.knora.org/data/08AE/webern
diff --git a/webapi/scripts/fuseki-init-knora-test.sh b/webapi/scripts/fuseki-init-knora-test.sh
new file mode 100755
index 0000000000..0c3ec0ef8f
--- /dev/null
+++ b/webapi/scripts/fuseki-init-knora-test.sh
@@ -0,0 +1,113 @@
+#!/usr/bin/env bash
+
+#set -x
+
+POSITIONAL=()
+while [[ $# -gt 0 ]]; do
+ key="$1"
+
+ case $key in
+ -u | --username)
+ USERNAME="$2"
+ shift # past argument
+ shift # past value
+ ;;
+ -p | --password)
+ PASSWORD="$2"
+ shift # past argument
+ shift # past value
+ ;;
+ -h | --host)
+ HOST="$2"
+ shift # past argument
+ shift # past value
+ ;;
+ *) # unknown option
+ POSITIONAL+=("$1") # save it in an array for later
+ shift # past argument
+ ;;
+ esac
+done
+set -- "${POSITIONAL[@]}" # restore positional parameters
+
+FILE="$1"
+
+REPOSITORY="knora-test"
+
+if [[ -z "${HOST}" ]]; then
+ HOST="localhost:3030"
+fi
+
+if [[ -z "${USERNAME}" ]]; then
+ USERNAME="admin"
+fi
+
+if [[ -z "${PASSWORD}" ]]; then
+ PASSWORD="test"
+fi
+
+delete-repository() {
+ STATUS=$(curl -s -o /dev/null -w '%{http_code}' -u ${USERNAME}:${PASSWORD} -X DELETE http://${HOST}/\$/datasets/${REPOSITORY})
+
+ if [ "${STATUS}" -eq 200 ]; then
+ echo "==> delete repository done"
+ return 0
+ else
+ echo "==> delete repository failed"
+ return 1
+ fi
+}
+
+create-repository() {
+ STATUS=$(curl -s -o /dev/null -w '%{http_code}' -u ${USERNAME}:${PASSWORD} -F data=@./fuseki-knora-test-repository-config.ttl http://${HOST}/\$/datasets)
+
+ if [ "${STATUS}" -eq 200 ]; then
+ echo "==> create repository done"
+ return 0
+ else
+ echo "==> create repository failed"
+ return 1
+ fi
+}
+
+upload-graph() {
+ STATUS=$(curl -s -o /dev/null -w '%{http_code}' -u ${USERNAME}:${PASSWORD} -H "Content-Type:text/turtle" -d @$1 -X PUT http://${HOST}/${REPOSITORY}\?graph\="$2")
+
+ if [ "${STATUS}" -eq 201 ]; then
+ echo "==> 201 Created: $1 -> $2"
+ return 0
+ elif [ "${STATUS}" -eq 200 ]; then
+ echo "==> 200 OK: $1 -> $2"
+ return 0
+ else
+ echo "==> failed with status code ${STATUS}: $1 -> $2"
+ return 1
+ fi
+}
+
+# delete-repository // delete dos not work correctly. need to delete database manually.
+create-repository
+upload-graph ../../knora-ontologies/knora-admin.ttl http://www.knora.org/ontology/knora-admin
+upload-graph ../../knora-ontologies/knora-base.ttl http://www.knora.org/ontology/knora-base
+upload-graph ../../knora-ontologies/standoff-onto.ttl http://www.knora.org/ontology/standoff
+upload-graph ../../knora-ontologies/standoff-data.ttl http://www.knora.org/data/standoff
+upload-graph ../../knora-ontologies/salsah-gui.ttl http://www.knora.org/ontology/salsah-gui
+upload-graph ../_test_data/all_data/admin-data.ttl http://www.knora.org/data/admin
+upload-graph ../_test_data/all_data/permissions-data.ttl http://www.knora.org/data/permissions
+upload-graph ../_test_data/all_data/system-data.ttl http://www.knora.org/data/0000/SystemProject
+upload-graph ../_test_data/ontologies/incunabula-onto.ttl http://www.knora.org/ontology/0803/incunabula
+upload-graph ../_test_data/all_data/incunabula-data.ttl http://www.knora.org/data/0803/incunabula
+upload-graph ../_test_data/ontologies/dokubib-onto.ttl http://www.knora.org/ontology/0804/dokubib
+upload-graph ../_test_data/ontologies/images-onto.ttl http://www.knora.org/ontology/00FF/images
+upload-graph ../_test_data/demo_data/images-demo-data.ttl http://www.knora.org/data/00FF/images
+upload-graph ../_test_data/ontologies/anything-onto.ttl http://www.knora.org/ontology/0001/anything
+upload-graph ../_test_data/all_data/anything-data.ttl http://www.knora.org/data/0001/anything
+upload-graph ../_test_data/ontologies/something-onto.ttl http://www.knora.org/ontology/0001/something
+upload-graph ../_test_data/ontologies/beol-onto.ttl http://www.knora.org/ontology/0801/beol
+upload-graph ../_test_data/ontologies/biblio-onto.ttl http://www.knora.org/ontology/0801/biblio
+upload-graph ../_test_data/ontologies/newton-onto.ttl http://www.knora.org/ontology/0801/newton
+upload-graph ../_test_data/ontologies/leibniz-onto.ttl http://www.knora.org/ontology/0801/leibniz
+upload-graph ../_test_data/all_data/biblio-data.ttl http://www.knora.org/data/0801/biblio
+upload-graph ../_test_data/all_data/beol-data.ttl http://www.knora.org/data/0801/beol
+upload-graph ../_test_data/ontologies/webern-onto.ttl http://www.knora.org/ontology/08AE/webern
+upload-graph ../_test_data/all_data/webern-data.ttl http://www.knora.org/data/08AE/webern
diff --git a/triplestores/fuseki-tomcat/configuration/knora-test.ttl b/webapi/scripts/fuseki-knora-test-repository-config.ttl
similarity index 81%
rename from triplestores/fuseki-tomcat/configuration/knora-test.ttl
rename to webapi/scripts/fuseki-knora-test-repository-config.ttl
index fd78f1fac6..54cf472a4d 100644
--- a/triplestores/fuseki-tomcat/configuration/knora-test.ttl
+++ b/webapi/scripts/fuseki-knora-test-repository-config.ttl
@@ -1,14 +1,18 @@
@prefix : .
-@prefix tdb: .
-@prefix rdf: .
+@prefix fuseki: .
@prefix ja: .
+@prefix tdb2: .
+@prefix rdf: .
@prefix rdfs: .
-@prefix fuseki: .
@prefix text: .
@prefix knora-base: .
+[] rdf:type fuseki:Server ;
+ fuseki:services :service_tdb_all ;
+ ja:loadClass "org.apache.jena.query.text.TextQuery" .
+
:service_tdb_all a fuseki:Service ;
- rdfs:label "TDB knora-test" ;
+ rdfs:label "TDB2 knora-test" ;
fuseki:dataset :text_dataset ;
fuseki:name "knora-test" ;
fuseki:serviceQuery "query" , "sparql" ;
@@ -25,14 +29,14 @@
text:index :indexLucene .
# A TDB datset used for RDF storage
-:tdb_dataset_readwrite a tdb:DatasetTDB ;
- tdb:unionDefaultGraph true ;
- tdb:location "/etc/fuseki/databases/knora-test" .
+:tdb_dataset_readwrite a tdb2:DatasetTDB2 ;
+ tdb2:unionDefaultGraph true ;
+ tdb2:location "/fuseki/databases/knora-test" .
# Text index description
:indexLucene a text:TextIndexLucene ;
- text:directory "/etc/fuseki/lucene/knora-test" ;
- ##text:directory "mem" ;
+ text:directory "/fuseki/lucene/knora-test" ;
+##text:directory "mem" ;
text:entityMap :entMap .
# Mapping in the index
diff --git a/triplestores/fuseki-tomcat/configuration/knora-test-unit.ttl b/webapi/scripts/fuseki-knora-test-unit-repository-config.ttl
similarity index 82%
rename from triplestores/fuseki-tomcat/configuration/knora-test-unit.ttl
rename to webapi/scripts/fuseki-knora-test-unit-repository-config.ttl
index 51401e8a3d..f3eac89986 100644
--- a/triplestores/fuseki-tomcat/configuration/knora-test-unit.ttl
+++ b/webapi/scripts/fuseki-knora-test-unit-repository-config.ttl
@@ -1,14 +1,19 @@
@prefix : .
-@prefix tdb: .
-@prefix rdf: .
+@prefix fuseki: .
@prefix ja: .
+@prefix tdb2: .
+@prefix rdf: .
@prefix rdfs: .
-@prefix fuseki: .
@prefix text: .
@prefix knora-base: .
+[] rdf:type fuseki:Server ;
+ fuseki:services :service_tdb_all ;
+ ja:loadClass "org.apache.jena.query.text.TextQuery" .
+
+
:service_tdb_all a fuseki:Service ;
- rdfs:label "TDB knora-test-unit" ;
+ rdfs:label "TDB2 knora-test-unit" ;
fuseki:dataset :text_dataset ;
fuseki:name "knora-test-unit" ;
fuseki:serviceQuery "query" , "sparql" ;
@@ -25,13 +30,13 @@
text:index :indexLucene .
# A TDB datset used for RDF storage
-:tdb_dataset_readwrite a tdb:DatasetTDB ;
- tdb:unionDefaultGraph true ;
- tdb:location "/etc/fuseki/databases/knora-test-unit" .
+:tdb_dataset_readwrite a tdb2:DatasetTDB2 ;
+ tdb2:unionDefaultGraph true ;
+ tdb2:location "/fuseki/databases/knora-test-unit" .
# Text index description
:indexLucene a text:TextIndexLucene ;
- text:directory "/etc/fuseki/lucene/knora-test-unit" ;
+ text:directory "/fuseki/lucene/knora-test-unit" ;
##text:directory "mem" ;
text:entityMap :entMap .
diff --git a/webapi/scripts/fuseki-load-test-data.sh b/webapi/scripts/fuseki-load-test-data.sh
deleted file mode 100755
index 825da8fccb..0000000000
--- a/webapi/scripts/fuseki-load-test-data.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-
-curl -X POST -H "Content-type:application/x-www-form-urlencoded"?update='DROP ALL' http://localhost:8080/fuseki/knora-test/update > /dev/null
-curl -F filedata=@../../knora-ontologies/knora-admin.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/ontology/knora-admin > /dev/null
-curl -F filedata=@../../knora-ontologies/knora-base.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/ontology/knora-base > /dev/null
-curl -F filedata=@../../knora-ontologies/standoff-onto.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/ontology/standoff > /dev/null
-curl -F filedata=@../../knora-ontologies/standoff-data.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/data/standoff > /dev/null
-curl -F filedata=@../../knora-ontologies/salsah-gui.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/ontology/salsah-gui > /dev/null
-curl -F filedata=@../_test_data/all_data/admin-data.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/data/admin > /dev/null
-curl -F filedata=@../_test_data/all_data/permissions-data.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/data/permissions > /dev/null
-curl -F filedata=@../_test_data/all_data/system-data.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/data/0000/SystemProject > /dev/null
-curl -F filedata=@../_test_data/ontologies/incunabula-onto.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/ontology/0803/incunabula > /dev/null
-curl -F filedata=@../_test_data/all_data/incunabula-data.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/data/0803/incunabula > /dev/null
-curl -F filedata=@../_test_data/ontologies/dokubib-onto.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/ontology/0804/dokubib > /dev/null
-curl -F filedata=@../_test_data/ontologies/images-onto.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/ontology/00FF/images > /dev/null
-curl -F filedata=@../_test_data/demo_data/images-demo-data.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/data/00FF/images > /dev/null
-curl -F filedata=@../_test_data/ontologies/anything-onto.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/ontology/0001/anything > /dev/null
-curl -F filedata=@../_test_data/all_data/anything-data.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/data/0001/anything > /dev/null
-curl -F filedata=@../_test_data/ontologies/something-onto.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/ontology/0001/something > /dev/null
-curl -F filedata=@../_test_data/ontologies/beol-onto.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/ontology/0801/beol > /dev/null
-curl -F filedata=@../_test_data/ontologies/biblio-onto.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/ontology/0801/biblio > /dev/null
-curl -F filedata=@../_test_data/ontologies/newton-onto.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/ontology/0801/newton > /dev/null
-curl -F filedata=@../_test_data/ontologies/leibniz-onto.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/ontology/0801/leibniz > /dev/null
-curl -F filedata=@../_test_data/all_data/biblio-data.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/data/0801/biblio > /dev/null
-curl -F filedata=@../_test_data/all_data/beol-data.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/data/0801/beol > /dev/null
-curl -F filedata=@../_test_data/ontologies/webern-onto.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/ontology/08AE/webern > /dev/null
-curl -F filedata=@../_test_data/all_data/webern-data.ttl http://localhost:8080/fuseki/knora-test/data?graph=http://www.knora.org/data/08AE/webern > /dev/null
-curl -F filedata=@../_test_data/ontologies/newton-onto.ttl http://localhost:8080/knora-test/data?graph=http://www.knora.org/ontology/0801/newton > /dev/null
-curl -F filedata=@../_test_data/ontologies/leibniz-onto.ttl http://localhost:8080/knora-test/data?graph=http://www.knora.org/ontology/0801/leibniz > /dev/null
diff --git a/webapi/scripts/fuseki-upload-repository.sh b/webapi/scripts/fuseki-upload-repository.sh
index 18d3fed9c4..927a15c464 100755
--- a/webapi/scripts/fuseki-upload-repository.sh
+++ b/webapi/scripts/fuseki-upload-repository.sh
@@ -53,4 +53,4 @@ if [[ -z "${HOST}" ]]; then
HOST="localhost:8080"
fi
-curl -sS -X POST -H "Content-Type: application/trig" --data-binary "@${FILE}" -u "${USERNAME}:${PASSWORD}" "http://${HOST}/fuseki/${REPOSITORY}" | tee /dev/null
+curl -sS -X POST -H "Content-Type: application/trig" --data-binary "@${FILE}" -u "${USERNAME}:${PASSWORD}" "http://${HOST}/${REPOSITORY}" | tee /dev/null
diff --git a/webapi/scripts/wait-for-db.sh b/webapi/scripts/wait-for-db.sh
index effb7e7b24..93e5fee5ac 100755
--- a/webapi/scripts/wait-for-db.sh
+++ b/webapi/scripts/wait-for-db.sh
@@ -3,70 +3,78 @@
#set -x
POSITIONAL=()
-while [[ $# -gt 0 ]]
-do
-key="$1"
-
-case $key in
-
- -h|--host)
- HOST="$2"
- shift # past argument
- shift # past value
- ;;
-
- -t|--timeout)
- TIMEOUT="$2"
- shift # past argument
- shift # past value
- ;;
-
- -n|--name)
- NAME="$3"
- shift # past argument
- shift # past value
- ;;
-
- *) # unknown option
- POSITIONAL+=("$1") # save it in an array for later
- shift # past argument
- ;;
-esac
+while [[ $# -gt 0 ]]; do
+ key="$1"
+
+ case $key in
+
+ -h | --host)
+ HOST="$2"
+ shift # past argument
+ shift # past value
+ ;;
+
+ -t | --timeout)
+ TIMEOUT="$2"
+ shift # past argument
+ shift # past value
+ ;;
+
+ -u | --username)
+ USERNAME="$2"
+ shift # past argument
+ shift # past value
+ ;;
+
+ -p | --password)
+ PASSWORD="$2"
+ shift # past argument
+ shift # past value
+ ;;
+
+ *) # unknown option
+ POSITIONAL+=("$1") # save it in an array for later
+ shift # past argument
+ ;;
+ esac
done
set -- "${POSITIONAL[@]}" # restore positional parameters
if [[ -z "${HOST}" ]]; then
- HOST="localhost:7200"
+ HOST="localhost:3030"
fi
if [[ -z "${TIMEOUT}" ]]; then
- TIMEOUT=360
+ TIMEOUT=360
fi
-if [[ -z "${NAME}" ]]; then
- NAME="knora-test-unit"
+if [[ -z "${USERNAME}" ]]; then
+ USERNAME="admin"
+fi
+
+if [[ -z "${PASSWORD}" ]]; then
+ PASSWORD="test"
fi
poll-db() {
- # STATUS=$(curl -s -o /dev/null -w '%{http_code}' http://${HOST}/repositories/${NAME}/health?)
- STATUS=$(curl -s -o /dev/null -w '%{http_code}' http://${HOST}/rest/repositories)
-
- if [ "${STATUS}" -eq 200 ]; then
- echo "==> DB started"
- return 0
- else
- return 1
- fi
+ STATUS=$(curl -s -o /dev/null -w '%{http_code}' -u ${USERNAME}:${PASSWORD} http://${HOST}/\$/server)
+
+ if [ "${STATUS}" -eq 200 ]; then
+ echo "==> DB started"
+ return 0
+ else
+ return 1
+ fi
}
attempt_counter=0
until poll-db; do
- if [ ${attempt_counter} -eq ${TIMEOUT} ]; then
- echo "Timed out waiting for DB to start"
- exit 1
- fi
-
- attempt_counter=$((attempt_counter+1))
- sleep 1
-done
\ No newline at end of file
+ if [ ${attempt_counter} -eq ${TIMEOUT} ]; then
+ echo "Timed out waiting for DB to start"
+ exit 1
+ fi
+
+ attempt_counter=$((attempt_counter + 1))
+ sleep 1
+done
diff --git a/webapi/src/it/resources/fuseki.conf b/webapi/src/it/resources/fuseki.conf
index 2e9d185361..1f0a924cac 100644
--- a/webapi/src/it/resources/fuseki.conf
+++ b/webapi/src/it/resources/fuseki.conf
@@ -5,10 +5,10 @@ app {
dbtype = "fuseki"
fuseki {
- port = 8080
+ port = 3030
repository-name = "knora-test-unit"
- tomcat = true
- tomcat-context = "fuseki"
+ username = "admin"
+ password = "test"
}
reload-on-start = false
diff --git a/webapi/src/it/resources/test.conf b/webapi/src/it/resources/test.conf
index 1314d9bd3c..38aa317d0c 100644
--- a/webapi/src/it/resources/test.conf
+++ b/webapi/src/it/resources/test.conf
@@ -1,3 +1,4 @@
include "application"
-app.print-short-config = false
\ No newline at end of file
+app.print-short-config = false
+app.triplestore.auto-init = true
\ No newline at end of file
diff --git a/webapi/src/it/scala/org/knora/webapi/ITKnoraFakeSpec.scala b/webapi/src/it/scala/org/knora/webapi/ITKnoraFakeSpec.scala
index 026d6b2e4c..0ac35461f9 100644
--- a/webapi/src/it/scala/org/knora/webapi/ITKnoraFakeSpec.scala
+++ b/webapi/src/it/scala/org/knora/webapi/ITKnoraFakeSpec.scala
@@ -48,10 +48,10 @@ object ITKnoraFakeSpec {
class ITKnoraFakeSpec(_system: ActorSystem) extends Core with KnoraFakeCore with Suite with AnyWordSpecLike with Matchers with BeforeAndAfterAll with RequestBuilding {
/* constructors */
- def this(name: String, config: Config) = this(ActorSystem(name, config.withFallback(ITKnoraFakeSpec.defaultConfig)))
- def this(config: Config) = this(ActorSystem("IntegrationTests", config.withFallback(ITKnoraFakeSpec.defaultConfig)))
- def this(name: String) = this(ActorSystem(name, ITKnoraFakeSpec.defaultConfig))
- def this() = this(ActorSystem("IntegrationTests", ITKnoraFakeSpec.defaultConfig))
+ def this(name: String, config: Config) = this(ActorSystem(name, TestContainers.PortConfig.withFallback(config.withFallback(ITKnoraFakeSpec.defaultConfig))))
+ def this(config: Config) = this(ActorSystem("IntegrationTests", TestContainers.PortConfig.withFallback(config.withFallback(ITKnoraFakeSpec.defaultConfig))))
+ def this(name: String) = this(ActorSystem(name, TestContainers.PortConfig.withFallback(ITKnoraFakeSpec.defaultConfig)))
+ def this() = this(ActorSystem("IntegrationTests", TestContainers.PortConfig.withFallback(ITKnoraFakeSpec.defaultConfig)))
/* needed by the core trait */
implicit lazy val system: ActorSystem = _system
@@ -65,7 +65,8 @@ class ITKnoraFakeSpec(_system: ActorSystem) extends Core with KnoraFakeCore with
val log = akka.event.Logging(system, this.getClass)
protected val baseApiUrl: String = settings.internalKnoraApiBaseUrl
- protected val baseSipiUrl: String = settings.internalSipiBaseUrl
+ protected val baseInternalSipiUrl: String = settings.internalSipiBaseUrl
+ protected val baseExternalSipiUrl: String = settings.externalSipiBaseUrl
override def beforeAll: Unit = {
/* Set the startup flags and start the Knora Server */
diff --git a/webapi/src/it/scala/org/knora/webapi/ITKnoraLiveSpec.scala b/webapi/src/it/scala/org/knora/webapi/ITKnoraLiveSpec.scala
index 7de34f7e0f..26f126b40b 100644
--- a/webapi/src/it/scala/org/knora/webapi/ITKnoraLiveSpec.scala
+++ b/webapi/src/it/scala/org/knora/webapi/ITKnoraLiveSpec.scala
@@ -51,10 +51,10 @@ object ITKnoraLiveSpec {
class ITKnoraLiveSpec(_system: ActorSystem) extends Core with StartupUtils with Suite with AnyWordSpecLike with Matchers with BeforeAndAfterAll with RequestBuilding with TriplestoreJsonProtocol with LazyLogging {
/* constructors */
- def this(name: String, config: Config) = this(ActorSystem(name, config.withFallback(ITKnoraLiveSpec.defaultConfig)))
- def this(config: Config) = this(ActorSystem("IntegrationTests", config.withFallback(ITKnoraLiveSpec.defaultConfig)))
- def this(name: String) = this(ActorSystem(name, ITKnoraLiveSpec.defaultConfig))
- def this() = this(ActorSystem("IntegrationTests", ITKnoraLiveSpec.defaultConfig))
+ def this(name: String, config: Config) = this(ActorSystem(name, TestContainers.PortConfig.withFallback(config.withFallback(ITKnoraLiveSpec.defaultConfig))))
+ def this(config: Config) = this(ActorSystem("IntegrationTests", TestContainers.PortConfig.withFallback(config.withFallback(ITKnoraLiveSpec.defaultConfig))))
+ def this(name: String) = this(ActorSystem(name, TestContainers.PortConfig.withFallback(ITKnoraLiveSpec.defaultConfig)))
+ def this() = this(ActorSystem("IntegrationTests", TestContainers.PortConfig.withFallback(ITKnoraLiveSpec.defaultConfig)))
/* needed by the core trait (represents the KnoraTestCore trait)*/
implicit lazy val system: ActorSystem = _system
@@ -73,7 +73,10 @@ class ITKnoraLiveSpec(_system: ActorSystem) extends Core with StartupUtils with
lazy val appActor: ActorRef = system.actorOf(Props(new ApplicationActor with LiveManagers), name = APPLICATION_MANAGER_ACTOR_NAME)
protected val baseApiUrl: String = settings.internalKnoraApiBaseUrl
- protected val baseSipiUrl: String = settings.internalSipiBaseUrl
+ protected val baseInternalSipiUrl: String = settings.internalSipiBaseUrl
+ protected val baseExternalSipiUrl: String = settings.externalSipiBaseUrl
+
+
override def beforeAll: Unit = {
@@ -100,7 +103,7 @@ class ITKnoraLiveSpec(_system: ActorSystem) extends Core with StartupUtils with
protected def checkIfSipiIsRunning(): Unit = {
// This requires that (1) fileserver.docroot is set in Sipi's config file and (2) it contains a file test.html.
- val request = Get(baseSipiUrl + "/server/test.html")
+ val request = Get(baseInternalSipiUrl + "/server/test.html")
val response = singleAwaitingRequest(request)
assert(response.status == StatusCodes.OK, s"Sipi is probably not running: ${response.status}")
if (response.status.isSuccess()) logger.info("Sipi is running.")
@@ -111,7 +114,7 @@ class ITKnoraLiveSpec(_system: ActorSystem) extends Core with StartupUtils with
logger.info("Loading test data started ...")
val request = Post(baseApiUrl + "/admin/store/ResetTriplestoreContent", HttpEntity(ContentTypes.`application/json`, rdfDataObjects.toJson.compactPrint))
singleAwaitingRequest(request, 479999.milliseconds)
- logger.info("Loading test data done.")
+ logger.info("... loading test data done.")
}
protected def getResponseString(request: HttpRequest): String = {
diff --git a/webapi/src/it/scala/org/knora/webapi/TestContainers.scala b/webapi/src/it/scala/org/knora/webapi/TestContainers.scala
new file mode 100644
index 0000000000..1479a8d834
--- /dev/null
+++ b/webapi/src/it/scala/org/knora/webapi/TestContainers.scala
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2015-2019 the contributors (see Contributors.md).
+ *
+ * This file is part of Knora.
+ *
+ * Knora is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Knora is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with Knora. If not, see .
+ */
+
+package org.knora.webapi
+
+import com.typesafe.config.{Config, ConfigFactory}
+import org.testcontainers.containers.{BindMode, GenericContainer}
+
+/**
+ * Provides all containers necessary for running tests.
+ */
+object TestContainers {
+
+ val FusekiContainer = new GenericContainer("daschswiss/knora-jena-fuseki:latest")
+ FusekiContainer.withExposedPorts(3030)
+ FusekiContainer.withEnv("ADMIN_PASSWORD", "test")
+ FusekiContainer.withEnv("JVM_ARGS", "-Xmx3G")
+ FusekiContainer.start()
+
+ val SipiContainer = new GenericContainer("daschswiss/knora-sipi:latest")
+ SipiContainer.withExposedPorts(1024)
+ SipiContainer.withEnv("SIPI_WEBAPI_HOSTNAME", "api")
+ SipiContainer.withEnv("SIPI_WEBAPI_PORT", "3333")
+ SipiContainer.withCommand("--config=/sipi/config/sipi.knora-docker-config.lua")
+ SipiContainer.withClasspathResourceMapping("/sipi/config/sipi.knora-docker-config.lua",
+ "/sipi/config/sipi.knora-docker-config.lua",
+ BindMode.READ_ONLY)
+ SipiContainer.withClasspathResourceMapping("/sipi/config/sipi.knora-docker-config.lua",
+ "/sipi/config/sipi.init-knora.lua",
+ BindMode.READ_ONLY)
+ SipiContainer.start()
+
+ // Container needs to be started to get the random IP
+ val sipiIp: IRI = SipiContainer.getHost
+ val sipiPort: Int = SipiContainer.getFirstMappedPort
+
+ val RedisContainer = new GenericContainer("redis:5")
+ RedisContainer.withExposedPorts(6379)
+ RedisContainer.start()
+
+ import scala.collection.JavaConverters._
+ private val portMap = Map(
+ "app.triplestore.fuseki.port" -> FusekiContainer.getFirstMappedPort,
+ "app.sipi.external-host" -> sipiIp,
+ "app.sipi.external-port" -> sipiPort,
+ "app.sipi.internal-host" -> sipiIp,
+ "app.sipi.internal-port" -> sipiPort,
+ "app.cache-service.redis.port" -> RedisContainer.getFirstMappedPort
+ ).asJava
+
+ // all tests need to be configured with these ports.
+ val PortConfig: Config = ConfigFactory.parseMap(portMap, "Ports from ContainerizedSpec")
+}
diff --git a/webapi/src/it/scala/org/knora/webapi/e2e/v1/KnoraSipiIntegrationV1ITSpec.scala b/webapi/src/it/scala/org/knora/webapi/e2e/v1/KnoraSipiIntegrationV1ITSpec.scala
index 4c1a7726f5..6cad44677e 100644
--- a/webapi/src/it/scala/org/knora/webapi/e2e/v1/KnoraSipiIntegrationV1ITSpec.scala
+++ b/webapi/src/it/scala/org/knora/webapi/e2e/v1/KnoraSipiIntegrationV1ITSpec.scala
@@ -154,7 +154,8 @@ class KnoraSipiIntegrationV1ITSpec extends ITKnoraLiveSpec(KnoraSipiIntegrationV
"Knora and Sipi" should {
- "create an 'incunabula:page' with binary data" in {
+ // TODO: fix as part of https://github.com/dasch-swiss/knora-api/pull/1233
+ "create an 'incunabula:page' with binary data" ignore {
// JSON describing the resource to be created.
val paramsPageWithBinaries =
@@ -209,7 +210,6 @@ class KnoraSipiIntegrationV1ITSpec extends ITKnoraLiveSpec(KnoraSipiIntegrationV
)
)
-
// Send the multipart/form-data request to the Knora API server.
val knoraPostRequest = Post(baseApiUrl + "/v1/resources", formData) ~> addCredentials(BasicHttpCredentials(username, password))
val knoraPostResponseJson = getResponseJson(knoraPostRequest)
@@ -247,7 +247,8 @@ class KnoraSipiIntegrationV1ITSpec extends ITKnoraLiveSpec(KnoraSipiIntegrationV
checkResponseOK(sipiGetRequest)
}
- "change an 'incunabula:page' with binary data" in {
+ // TODO: fix as part of https://github.com/dasch-swiss/knora-api/pull/1233
+ "change an 'incunabula:page' with binary data" ignore {
// The image to be uploaded.
val fileToSend = new File(pathToMarbles)
assert(fileToSend.exists(), s"File $pathToMarbles does not exist")
@@ -305,13 +306,13 @@ class KnoraSipiIntegrationV1ITSpec extends ITKnoraLiveSpec(KnoraSipiIntegrationV
)
// Send a POST request to Sipi, asking it to make a thumbnail of the image.
- val sipiRequest = Post(baseSipiUrl + "/make_thumbnail", sipiFormData) ~> addCredentials(BasicHttpCredentials(username, password))
+ val sipiRequest = Post(baseInternalSipiUrl + "/make_thumbnail", sipiFormData) ~> addCredentials(BasicHttpCredentials(username, password))
val sipiResponseJson = getResponseJson(sipiRequest)
// Request the thumbnail from Sipi.
val jsonFields = sipiResponseJson.fields
val previewUrl = jsonFields("preview_path").asInstanceOf[JsString].value
- val sipiGetRequest = Get(previewUrl) ~> addCredentials(BasicHttpCredentials(username, password))
+ val sipiGetRequest = Get(previewUrl.replace("http://0.0.0.0:1024", baseExternalSipiUrl)) ~> addCredentials(BasicHttpCredentials(username, password))
checkResponseOK(sipiGetRequest)
val fileParams = JsObject(
@@ -372,13 +373,13 @@ class KnoraSipiIntegrationV1ITSpec extends ITKnoraLiveSpec(KnoraSipiIntegrationV
)
// Send a POST request to Sipi, asking it to make a thumbnail of the image.
- val sipiRequest = Post(baseSipiUrl + "/make_thumbnail", sipiFormData) ~> addCredentials(BasicHttpCredentials(username, password))
+ val sipiRequest = Post(baseInternalSipiUrl + "/make_thumbnail", sipiFormData) ~> addCredentials(BasicHttpCredentials(username, password))
val sipiResponseJson = getResponseJson(sipiRequest)
// Request the thumbnail from Sipi.
val jsonFields = sipiResponseJson.fields
val previewUrl = jsonFields("preview_path").asInstanceOf[JsString].value
- val sipiGetRequest = Get(previewUrl) ~> addCredentials(BasicHttpCredentials(username, password))
+ val sipiGetRequest = Get(previewUrl.replace("http://0.0.0.0:1024", baseExternalSipiUrl)) ~> addCredentials(BasicHttpCredentials(username, password))
checkResponseOK(sipiGetRequest)
// JSON describing the new image to Knora.
@@ -441,7 +442,8 @@ class KnoraSipiIntegrationV1ITSpec extends ITKnoraLiveSpec(KnoraSipiIntegrationV
checkResponseOK(knoraPostRequest)
}
- "create an 'p0803-incunabula:book' and an 'p0803-incunabula:page' with file parameters via XML import" in {
+ // TODO: fix as part of https://github.com/dasch-swiss/knora-api/pull/1233
+ "create an 'p0803-incunabula:book' and an 'p0803-incunabula:page' with file parameters via XML import" ignore {
val fileToUpload = new File(pathToChlaus)
// To be able to run packaged tests inside Docker, we need to copy
@@ -509,7 +511,8 @@ class KnoraSipiIntegrationV1ITSpec extends ITKnoraLiveSpec(KnoraSipiIntegrationV
checkResponseOK(sipiGetRequest)
}
- "create a TextRepresentation of type XSLTransformation and refer to it in a mapping" in {
+ // TODO: fix as part of https://github.com/dasch-swiss/knora-api/pull/1233
+ "create a TextRepresentation of type XSLTransformation and refer to it in a mapping" ignore {
// create an XSL transformation
val knoraParams = JsObject(
@@ -625,7 +628,8 @@ class KnoraSipiIntegrationV1ITSpec extends ITKnoraLiveSpec(KnoraSipiIntegrationV
}
- "create a mapping for standoff conversion to TEI referring to an XSLT and also create a Gravsearch template and an XSLT for transforming TEI header data" in {
+ // TODO: fix as part of https://github.com/dasch-swiss/knora-api/pull/1233
+ "create a mapping for standoff conversion to TEI referring to an XSLT and also create a Gravsearch template and an XSLT for transforming TEI header data" ignore {
// create an XSL transformation
val standoffXSLTParams = JsObject(
@@ -835,7 +839,8 @@ class KnoraSipiIntegrationV1ITSpec extends ITKnoraLiveSpec(KnoraSipiIntegrationV
}
- "provide a helpful error message if an XSLT file is not found" in {
+ // TODO: fix as part of https://github.com/dasch-swiss/knora-api/pull/1233
+ "provide a helpful error message if an XSLT file is not found" ignore {
val missingHeaderXSLTIri = "http://rdfh.ch/0801/608NfPLCRpeYnkXKABC5mg"
val letterTEIRequest: HttpRequest = Get(baseApiUrl + "/v2/tei/" + URLEncoder.encode(letterIri.get, "UTF-8") +
diff --git a/webapi/src/it/scala/org/knora/webapi/e2e/v1/KnoraSipiScriptsV1ITSpec.scala b/webapi/src/it/scala/org/knora/webapi/e2e/v1/KnoraSipiScriptsV1ITSpec.scala
index ef2986088c..bb3bcf5af7 100644
--- a/webapi/src/it/scala/org/knora/webapi/e2e/v1/KnoraSipiScriptsV1ITSpec.scala
+++ b/webapi/src/it/scala/org/knora/webapi/e2e/v1/KnoraSipiScriptsV1ITSpec.scala
@@ -57,17 +57,17 @@ class KnoraSipiScriptsV1ITSpec extends ITKnoraFakeSpec(KnoraSipiScriptsV1ITSpec.
"Calling Knora Sipi Scripts" should {
"successfully call C++ functions from Lua scripts" in {
- val request = Get(baseSipiUrl + "/test_functions" )
+ val request = Get(baseInternalSipiUrl + "/test_functions" )
getResponseString(request)
}
"successfully call Lua functions for mediatype handling" in {
- val request = Get(baseSipiUrl + "/test_file_type" )
+ val request = Get(baseInternalSipiUrl + "/test_file_type" )
getResponseString(request)
}
"successfully call Lua function that gets the Knora session id from the cookie header sent to Sipi" in {
- val request = Get(baseSipiUrl + "/test_knora_session_cookie" )
+ val request = Get(baseInternalSipiUrl + "/test_knora_session_cookie" )
getResponseString(request)
}
@@ -87,7 +87,7 @@ class KnoraSipiScriptsV1ITSpec extends ITKnoraFakeSpec(KnoraSipiScriptsV1ITSpec.
)
// Send a POST request to Sipi, asking it to make a thumbnail of the image.
- val sipiPostRequest = Post(baseSipiUrl + "/make_thumbnail", sipiFormData) ~> addCredentials(BasicHttpCredentials(username, password))
+ val sipiPostRequest = Post(baseInternalSipiUrl + "/make_thumbnail", sipiFormData) ~> addCredentials(BasicHttpCredentials(username, password))
val sipiPostResponseJson = getResponseJson(sipiPostRequest)
/* sipiResponseJson will be something like this
@@ -109,13 +109,24 @@ class KnoraSipiScriptsV1ITSpec extends ITKnoraFakeSpec(KnoraSipiScriptsV1ITSpec.
// get the filename
val filename = sipiPostResponseJson.fields("filename").asInstanceOf[JsString].value
- // Send a GET request to Sipi, asking for the preview image
- val sipiGetRequest01 = Get(previewPath)
- val sipiGetResponseJson01 = getResponseString(sipiGetRequest01)
+ /**
+ * Send a GET request to Sipi, asking for the preview image.
+ * With testcontainers it is not possible to know the random port
+ * in advance, so that we can provide it to Sipi at startup.
+ * Instead we need to replace the standard port configured
+ * and returned by sipi to the random port known after sipi has
+ * already started.
+ */
+ val sipiGetRequest01 = Get(previewPath.replace("http://0.0.0.0:1024", baseExternalSipiUrl))
+ val sipiGetResponse01: HttpResponse = singleAwaitingRequest(sipiGetRequest01)
+ log.debug(s"sipiGetResponse01: ${sipiGetResponse01.toString}")
+ sipiGetResponse01.status should be(StatusCodes.OK)
// Send a GET request to Sipi, asking for the info.json of the image
- val sipiGetRequest02 = Get(baseSipiUrl + "/thumbs/" + filename + ".jpg/info.json" )
- val sipiGetResponseJson = getResponseJson(sipiGetRequest02)
+ val sipiGetRequest02 = Get(baseInternalSipiUrl + "/thumbs/" + filename + ".jpg/info.json" )
+ val sipiGetResponse02: HttpResponse = singleAwaitingRequest(sipiGetRequest02)
+ log.debug(s"sipiGetResponse02: ${sipiGetResponse02.toString}")
+ sipiGetResponse02.status should be(StatusCodes.OK)
}
"successfully call convert_from_file.lua sipi script" in {
@@ -136,9 +147,10 @@ class KnoraSipiScriptsV1ITSpec extends ITKnoraFakeSpec(KnoraSipiScriptsV1ITSpec.
)
// Send a POST request to Sipi, asking it to make a thumbnail of the image.
- val sipiMakeThumbnailRequest = Post(baseSipiUrl + "/make_thumbnail", sipiFormData)
- val sipiMakeThumbnailResponseJson = getResponseJson(sipiMakeThumbnailRequest)
+ val sipiMakeThumbnailRequest = Post(baseInternalSipiUrl + "/make_thumbnail", sipiFormData)
+ val sipiMakeThumbnailResponse: HttpResponse = singleAwaitingRequest(sipiMakeThumbnailRequest)
+ val sipiMakeThumbnailResponseJson = getResponseJson(sipiMakeThumbnailRequest)
val originalFilename = sipiMakeThumbnailResponseJson.fields("original_filename").asInstanceOf[JsString].value
val originalMimetype = sipiMakeThumbnailResponseJson.fields("original_mimetype").asInstanceOf[JsString].value
val filename = sipiMakeThumbnailResponseJson.fields("filename").asInstanceOf[JsString].value
@@ -153,7 +165,7 @@ class KnoraSipiScriptsV1ITSpec extends ITKnoraFakeSpec(KnoraSipiScriptsV1ITSpec.
)
)
- val convertFromFileRequest = Post(baseSipiUrl + "/convert_from_file", sipiFormData02)
+ val convertFromFileRequest = Post(baseInternalSipiUrl + "/convert_from_file", sipiFormData02)
val convertFromFileResponseJson = getResponseJson(convertFromFileRequest)
val filenameFull = convertFromFileResponseJson.fields("filename_full").asInstanceOf[JsString].value
@@ -161,16 +173,17 @@ class KnoraSipiScriptsV1ITSpec extends ITKnoraFakeSpec(KnoraSipiScriptsV1ITSpec.
// Running with KnoraFakeService which always allows access to files.
// Send a GET request to Sipi, asking for full image
// not possible as authentication is required and file needs to be known by knora to be able to authenticate the request
- val sipiGetImageRequest = Get(baseSipiUrl + "/0001/" + filenameFull + "/full/full/0/default.jpg") ~> addCredentials(BasicHttpCredentials(username, password))
+ val sipiGetImageRequest = Get(baseInternalSipiUrl + "/0001/" + filenameFull + "/full/full/0/default.jpg") ~> addCredentials(BasicHttpCredentials(username, password))
checkResponseOK(sipiGetImageRequest)
// Send a GET request to Sipi, asking for the info.json of the image
- val sipiGetInfoRequest = Get(baseSipiUrl + "/0001/" + filenameFull + "/info.json" ) ~> addCredentials(BasicHttpCredentials(username, password))
+ val sipiGetInfoRequest = Get(baseInternalSipiUrl + "/0001/" + filenameFull + "/info.json" ) ~> addCredentials(BasicHttpCredentials(username, password))
val sipiGetInfoResponseJson = getResponseJson(sipiGetInfoRequest)
log.debug("sipiGetInfoResponseJson: {}", sipiGetInfoResponseJson)
}
- "successfully call convert_from_path.lua sipi script" in {
+ // TODO: fix as part of https://github.com/dasch-swiss/knora-api/pull/1233
+ "successfully call convert_from_path.lua sipi script" ignore {
// The image to be uploaded.
val fileToSend = new File(pathToChlaus)
@@ -198,7 +211,7 @@ class KnoraSipiScriptsV1ITSpec extends ITKnoraFakeSpec(KnoraSipiScriptsV1ITSpec.
)
// Send a POST request to Sipi, asking it to make a thumbnail of the image.
- val sipiConvertFromPathPostRequest = Post(baseSipiUrl + "/convert_from_path", sipiFormData)
+ val sipiConvertFromPathPostRequest = Post(baseInternalSipiUrl + "/convert_from_path", sipiFormData)
val sipiConvertFromPathPostResponseJson = getResponseJson(sipiConvertFromPathPostRequest)
val filenameFull = sipiConvertFromPathPostResponseJson.fields("filename_full").asInstanceOf[JsString].value
@@ -206,11 +219,11 @@ class KnoraSipiScriptsV1ITSpec extends ITKnoraFakeSpec(KnoraSipiScriptsV1ITSpec.
//log.debug("sipiConvertFromPathPostResponseJson: {}", sipiConvertFromPathPostResponseJson)
// Running with KnoraFakeService which always allows access to files.
- val sipiGetImageRequest = Get(baseSipiUrl + "/0001/" + filenameFull + "/full/full/0/default.jpg") ~> addCredentials(BasicHttpCredentials(username, password))
+ val sipiGetImageRequest = Get(baseInternalSipiUrl + "/0001/" + filenameFull + "/full/full/0/default.jpg") ~> addCredentials(BasicHttpCredentials(username, password))
checkResponseOK(sipiGetImageRequest)
// Send a GET request to Sipi, asking for the info.json of the image
- val sipiGetInfoRequest = Get(baseSipiUrl + "/0001/" + filenameFull + "/info.json" ) ~> addCredentials(BasicHttpCredentials(username, password))
+ val sipiGetInfoRequest = Get(baseInternalSipiUrl + "/0001/" + filenameFull + "/info.json" ) ~> addCredentials(BasicHttpCredentials(username, password))
val sipiGetInfoResponseJson = getResponseJson(sipiGetInfoRequest)
log.debug("sipiGetInfoResponseJson: {}", sipiGetInfoResponseJson)
}
diff --git a/webapi/src/it/scala/org/knora/webapi/e2e/v2/KnoraSipiIntegrationV2ITSpec.scala b/webapi/src/it/scala/org/knora/webapi/e2e/v2/KnoraSipiIntegrationV2ITSpec.scala
index 1f130c8295..51d21ea3bb 100644
--- a/webapi/src/it/scala/org/knora/webapi/e2e/v2/KnoraSipiIntegrationV2ITSpec.scala
+++ b/webapi/src/it/scala/org/knora/webapi/e2e/v2/KnoraSipiIntegrationV2ITSpec.scala
@@ -9,7 +9,7 @@ import akka.http.scaladsl.model.headers.BasicHttpCredentials
import akka.http.scaladsl.unmarshalling.Unmarshal
import com.typesafe.config.{Config, ConfigFactory}
import org.knora.webapi._
-import org.knora.webapi.messages.store.triplestoremessages.{RdfDataObject, TriplestoreJsonProtocol}
+import org.knora.webapi.messages.store.triplestoremessages.TriplestoreJsonProtocol
import org.knora.webapi.messages.v2.routing.authenticationmessages._
import org.knora.webapi.util.IriConversions._
import org.knora.webapi.util.jsonld._
@@ -156,18 +156,19 @@ class KnoraSipiIntegrationV2ITSpec extends ITKnoraLiveSpec(KnoraSipiIntegrationV
val sipiFormData = Multipart.FormData(formDataParts: _*)
// Send Sipi the file in a POST request.
- val sipiRequest = Post(s"$baseSipiUrl/upload?token=$loginToken", sipiFormData)
+ val sipiRequest = Post(s"$baseInternalSipiUrl/upload?token=$loginToken", sipiFormData)
val sipiUploadResponseJson: JsObject = getResponseJson(sipiRequest)
// println(sipiUploadResponseJson.prettyPrint)
val sipiUploadResponse: SipiUploadResponse = sipiUploadResponseJson.convertTo[SipiUploadResponse]
+ // println(s"sipiUploadResponse: $sipiUploadResponse")
// Request the temporary file from Sipi.
for (responseEntry <- sipiUploadResponse.uploadedFiles) {
val sipiGetTmpFileRequest: HttpRequest = if (responseEntry.fileType == "image") {
- Get(responseEntry.temporaryUrl + "/full/full/0/default.jpg")
+ Get(responseEntry.temporaryUrl.replace("http://0.0.0.0:1024", baseExternalSipiUrl) + "/full/full/0/default.jpg")
} else {
- Get(responseEntry.temporaryUrl)
+ Get(responseEntry.temporaryUrl.replace("http://0.0.0.0:1024", baseExternalSipiUrl))
}
checkResponseOK(sipiGetTmpFileRequest)
@@ -293,7 +294,7 @@ class KnoraSipiIntegrationV2ITSpec extends ITKnoraLiveSpec(KnoraSipiIntegrationV
)
// Send a POST request to Sipi, asking it to convert the image to JPEG 2000 and store it in a temporary file.
- val sipiRequest = Post(s"$baseSipiUrl/upload?token=$invalidToken", sipiFormData)
+ val sipiRequest = Post(s"$baseInternalSipiUrl/upload?token=$invalidToken", sipiFormData)
val sipiResponse = singleAwaitingRequest(sipiRequest)
assert(sipiResponse.status == StatusCodes.Unauthorized)
}
@@ -461,7 +462,7 @@ class KnoraSipiIntegrationV2ITSpec extends ITKnoraLiveSpec(KnoraSipiIntegrationV
)
val internalFilename = sipiUploadResponse.uploadedFiles.head.internalFilename
- val temporaryBaseIIIFUrl = sipiUploadResponse.uploadedFiles.head.temporaryUrl
+ val temporaryBaseIIIFUrl = sipiUploadResponse.uploadedFiles.head.temporaryUrl.replace("http://0.0.0.0:1024", baseExternalSipiUrl)
// JSON describing the new image to Knora.
val jsonLdEntity =
diff --git a/webapi/src/it/scala/org/knora/webapi/other/v1/DrawingsGodsV1ITSpec.scala b/webapi/src/it/scala/org/knora/webapi/other/v1/DrawingsGodsV1ITSpec.scala
index c2e913e959..57e350ea0f 100644
--- a/webapi/src/it/scala/org/knora/webapi/other/v1/DrawingsGodsV1ITSpec.scala
+++ b/webapi/src/it/scala/org/knora/webapi/other/v1/DrawingsGodsV1ITSpec.scala
@@ -55,8 +55,8 @@ class DrawingsGodsV1ITSpec extends ITKnoraLiveSpec(DrawingsGodsV1ITSpec.config)
val testPass = "test"
val pathToChlaus = "_test_data/test_route/images/Chlaus.jpg"
-
- "be able to create a resource, only find one DOAP (with combined resource class / property), and have permission to access the image" in {
+ // TODO: fix as part of https://github.com/dasch-swiss/knora-api/pull/1233
+ "be able to create a resource, only find one DOAP (with combined resource class / property), and have permission to access the image" ignore {
val params =
s"""
diff --git a/webapi/src/main/resources/application.conf b/webapi/src/main/resources/application.conf
index c9c37663d4..8472b532dd 100644
--- a/webapi/src/main/resources/application.conf
+++ b/webapi/src/main/resources/application.conf
@@ -1,5 +1,5 @@
akka {
- log-config-on-start = "off"
+ log-config-on-start = off
log-config-on-start = ${?KNORA_AKKA_LOG_CONFIG_ON_START}
loggers = ["akka.event.slf4j.Slf4jLogger"]
loglevel = "INFO"
@@ -472,13 +472,13 @@ app {
]
triplestore {
- dbtype = "graphdb-se"
+ dbtype = "fuseki"
dbtype = ${?KNORA_WEBAPI_TRIPLESTORE_DBTYPE}
+ // dbtype = "graphdb-se"
// dbtype = "graphdb-free"
// dbtype = "embedded-jena-tdb"
// dbtype = "embedded-jena-graphdb"
// dbtype = "fake-triplestore"
- // dbtype = "fuseki"
use-https = false
use-https = ${?KNORA_WEBAPI_TRIPLESTORE_USE_HTTPS}
@@ -492,6 +492,10 @@ app {
// timeout for tripelstore updates. can be same or lower then akka.http.server.request-timeout.
update-timeout = 30 minutes
+ // triplestore auto init. initialize triplestore at startup if necessary.
+ auto-init = false
+ auto-init = ${?KNORA_WEBAPI_TRIPLESTORE_AUTOINIT}
+
graphdb {
port = 7200
port = ${?KNORA_WEBAPI_TRIPLESTORE_GRAPHDB_PORT}
@@ -504,12 +508,14 @@ app {
}
fuseki {
- port = 8080
+ port = 3030
port = ${?KNORA_WEBAPI_TRIPLESTORE_FUSEKI_PORT}
repository-name = "knora-test"
repository-name = ${?KNORA_WEBAPI_TRIPLESTORE_FUSEKI_REPOSITORY_NAME}
- tomcat = true
- tomcat-context = "fuseki"
+ username = "admin"
+ username = ${?KNORA_WEBAPI_TRIPLESTORE_FUSEKI_USERNAME}
+ password = "test"
+ password = ${?KNORA_WEBAPI_TRIPLESTORE_FUSEKI_PASSWORD}
}
embedded-jena-tdb {
diff --git a/webapi/src/main/scala/org/knora/webapi/KnoraSettings.scala b/webapi/src/main/scala/org/knora/webapi/KnoraSettings.scala
index 9b04aa99d5..7d08440bcb 100644
--- a/webapi/src/main/scala/org/knora/webapi/KnoraSettings.scala
+++ b/webapi/src/main/scala/org/knora/webapi/KnoraSettings.scala
@@ -155,6 +155,8 @@ class KnoraSettingsImpl(config: Config) extends Extension {
val triplestoreUseHttps: Boolean = config.getBoolean("app.triplestore.use-https")
+ val triplestoreAutoInit: Boolean = config.getBoolean("app.triplestore.auto-init")
+
val triplestorePort: Int = triplestoreType match {
case TriplestoreTypes.HttpGraphDBSE | TriplestoreTypes.HttpGraphDBFree => config.getInt("app.triplestore.graphdb.port")
case TriplestoreTypes.HttpFuseki => config.getInt("app.triplestore.fuseki.port")
@@ -169,23 +171,19 @@ class KnoraSettingsImpl(config: Config) extends Extension {
val triplestoreUsername: String = triplestoreType match {
case TriplestoreTypes.HttpGraphDBSE | TriplestoreTypes.HttpGraphDBFree => config.getString("app.triplestore.graphdb.username")
+ case TriplestoreTypes.HttpFuseki => config.getString("app.triplestore.fuseki.username")
case _ => ""
}
val triplestorePassword: String = triplestoreType match {
case TriplestoreTypes.HttpGraphDBSE | TriplestoreTypes.HttpGraphDBFree => config.getString("app.triplestore.graphdb.password")
+ case TriplestoreTypes.HttpFuseki => config.getString("app.triplestore.fuseki.password")
case _ => ""
}
//used in the store package
val tripleStoreConfig: Config = config.getConfig("app.triplestore")
- val (fusekiTomcat: Boolean, fusekiTomcatContext: String) = if (triplestoreType == TriplestoreTypes.HttpFuseki) {
- (config.getBoolean("app.triplestore.fuseki.tomcat"), config.getString("app.triplestore.fuseki.tomcat-context"))
- } else {
- (false, "")
- }
-
private val fakeTriplestore: String = config.getString("app.triplestore.fake-triplestore")
val prepareFakeTriplestore: Boolean = fakeTriplestore == "prepare"
val useFakeTriplestore: Boolean = fakeTriplestore == "use"
diff --git a/webapi/src/main/scala/org/knora/webapi/app/ApplicationActor.scala b/webapi/src/main/scala/org/knora/webapi/app/ApplicationActor.scala
index 42d170c181..dd8f4bc065 100644
--- a/webapi/src/main/scala/org/knora/webapi/app/ApplicationActor.scala
+++ b/webapi/src/main/scala/org/knora/webapi/app/ApplicationActor.scala
@@ -158,13 +158,13 @@ class ApplicationActor extends Actor with Stash with LazyLogging with AroundDire
def initializing(): Receive = {
/* Called from main. Initiates application startup. */
case appStartMsg: AppStart =>
- println("==> AppStart")
+ logger.info("==> AppStart")
appStart(appStartMsg.ignoreRepository, appStartMsg.requiresIIIFService, appStartMsg.retryCnt)
case AppStop() =>
- println("==> AppStop")
+ logger.info("==> AppStop")
appStop()
case AppReady() =>
- println("==> AppReady")
+ logger.info("==> AppReady")
unstashAll() // unstash any messages, so that they can be processed
context.become(ready(), discardOld = true)
case _ =>
@@ -178,7 +178,7 @@ class ApplicationActor extends Actor with Stash with LazyLogging with AroundDire
/* Called from the "appStart" method. Entry point for startup sequence. */
case initStartUp: InitStartUp =>
- logger.info("Startup initiated, please wait ...")
+ logger.info("=> InitStartUp")
if (appState == AppStates.Stopped) {
ignoreRepository = initStartUp.ignoreRepository
@@ -264,6 +264,7 @@ class ApplicationActor extends Actor with Stash with LazyLogging with AroundDire
self ! SetAppState(AppStates.Running)
case AppStates.Running =>
+ logger.info("=> Running")
printBanner()
case AppStates.MaintenanceMode =>
@@ -516,28 +517,25 @@ class ApplicationActor extends Actor with Stash with LazyLogging with AroundDire
var msg =
"""
- | _ __ ___ ______ _____
- || | / / / _ \ | ___ \_ _|
- || |/ / _ __ ___ _ __ __ _ ______/ /_\ \| |_/ / | |
- || \| '_ \ / _ \| '__/ _` |______| _ || __/ | |
- || |\ \ | | | (_) | | | (_| | | | | || | _| |_
- |\_| \_/_| |_|\___/|_| \__,_| \_| |_/\_| \___/
+ | ____ ____ ____ _ ____ ___
+ | | _ \/ ___|| _ \ / \ | _ \_ _|
+ | | | | \___ \| |_) |____ / _ \ | |_) | |
+ | | |_| |___) | __/_____/ ___ \| __/| |
+ | |____/|____/|_| /_/ \_\_| |___|
""".stripMargin
-
msg += "\n"
- msg += s"Knora API Server started at http://${knoraSettings.internalKnoraApiHost}:${knoraSettings.internalKnoraApiPort}\n"
- msg += "----------------------------------------------------------------\n"
+ msg += s"DSP-API Server started: http://${knoraSettings.internalKnoraApiHost}:${knoraSettings.internalKnoraApiPort}\n"
+ msg += "------------------------------------------------\n"
if (allowReloadOverHTTPState | knoraSettings.allowReloadOverHTTP) {
- msg += "WARNING: Resetting Triplestore Content over HTTP is turned ON.\n"
- msg += "----------------------------------------------------------------\n"
+ msg += "WARNING: Resetting DB over HTTP is turned ON.\n"
+ msg += "------------------------------------------------\n"
}
// which repository are we using
- msg += s"DB-Name: ${knoraSettings.triplestoreDatabaseName}\n"
- msg += s"DB-Type: ${knoraSettings.triplestoreType}\n"
- msg += s"DB Server: ${knoraSettings.triplestoreHost}, DB Port: ${knoraSettings.triplestorePort}\n"
+ msg += s"DB-Name: ${knoraSettings.triplestoreDatabaseName}\t DB-Type: ${knoraSettings.triplestoreType}\n"
+ msg += s"DB-Server: ${knoraSettings.triplestoreHost}\t\t DB Port: ${knoraSettings.triplestorePort}\n"
if (printConfigState) {
@@ -552,7 +550,7 @@ class ApplicationActor extends Actor with Stash with LazyLogging with AroundDire
msg += s"Sipi external URL: ${knoraSettings.externalSipiBaseUrl}\n"
}
- msg += "================================================================\n"
+ msg += "================================================\n"
println(msg)
}
diff --git a/webapi/src/main/scala/org/knora/webapi/store/triplestore/http/GraphProtocolAccessor.scala b/webapi/src/main/scala/org/knora/webapi/store/triplestore/http/GraphProtocolAccessor.scala
index 65d61b47a0..0caa5a551b 100644
--- a/webapi/src/main/scala/org/knora/webapi/store/triplestore/http/GraphProtocolAccessor.scala
+++ b/webapi/src/main/scala/org/knora/webapi/store/triplestore/http/GraphProtocolAccessor.scala
@@ -103,8 +103,7 @@ object GraphProtocolAccessor {
// HTTP paths for the SPARQL 1.1 Graph Store HTTP Protocol
val requestPath = settings.triplestoreType match {
case TriplestoreTypes.HttpGraphDBSE | TriplestoreTypes.HttpGraphDBFree => s"/repositories/${settings.triplestoreDatabaseName}/rdf-graphs/service"
- case TriplestoreTypes.HttpFuseki if !settings.fusekiTomcat => s"/${settings.triplestoreDatabaseName}/data"
- case TriplestoreTypes.HttpFuseki if settings.fusekiTomcat => s"/${settings.fusekiTomcatContext}/${settings.triplestoreDatabaseName}/data"
+ case TriplestoreTypes.HttpFuseki => s"/${settings.triplestoreDatabaseName}/data"
case ts_type => throw TriplestoreUnsupportedFeatureException(s"GraphProtocolAccessor does not support: $ts_type")
}
diff --git a/webapi/src/main/scala/org/knora/webapi/store/triplestore/http/HttpTriplestoreConnector.scala b/webapi/src/main/scala/org/knora/webapi/store/triplestore/http/HttpTriplestoreConnector.scala
index 396e655942..d1bb652f11 100644
--- a/webapi/src/main/scala/org/knora/webapi/store/triplestore/http/HttpTriplestoreConnector.scala
+++ b/webapi/src/main/scala/org/knora/webapi/store/triplestore/http/HttpTriplestoreConnector.scala
@@ -49,7 +49,7 @@ import org.knora.webapi.messages.store.triplestoremessages._
import org.knora.webapi.store.triplestore.RdfDataObjectFactory
import org.knora.webapi.util.ActorUtil._
import org.knora.webapi.util.SparqlResultProtocol._
-import org.knora.webapi.util.{FakeTriplestore, InstrumentationSupport}
+import org.knora.webapi.util.{FakeTriplestore, FileUtil, InstrumentationSupport}
import spray.json._
import scala.collection.JavaConverters._
@@ -113,23 +113,15 @@ class HttpTriplestoreConnector extends Actor with ActorLogging with Instrumentat
private val queryPath: String = if (triplestoreType == TriplestoreTypes.HttpGraphDBSE | triplestoreType == TriplestoreTypes.HttpGraphDBFree) {
s"/repositories/${settings.triplestoreDatabaseName}"
} else if (triplestoreType == TriplestoreTypes.HttpFuseki) {
- if (settings.fusekiTomcat) {
- s"/${settings.fusekiTomcatContext}/${settings.triplestoreDatabaseName}/query"
- } else {
- s"/${settings.triplestoreDatabaseName}/query"
- }
+ s"/${settings.triplestoreDatabaseName}/query"
} else {
throw UnsuportedTriplestoreException(s"Unsupported triplestore type: $triplestoreType")
}
private val sparqlUpdatePath: String = if (triplestoreType == TriplestoreTypes.HttpGraphDBSE | triplestoreType == TriplestoreTypes.HttpGraphDBFree) {
s"/repositories/${settings.triplestoreDatabaseName}/statements"
- } else if (triplestoreType == TriplestoreTypes.HttpFuseki && settings.fusekiTomcat) {
- if (settings.fusekiTomcat) {
- s"/${settings.fusekiTomcatContext}/${settings.triplestoreDatabaseName}/update"
- } else {
- s"/${settings.triplestoreDatabaseName}/update"
- }
+ } else if (triplestoreType == TriplestoreTypes.HttpFuseki) {
+ s"/${settings.triplestoreDatabaseName}/update"
} else {
throw UnsuportedTriplestoreException(s"Unsupported triplestore type: $triplestoreType")
}
@@ -137,11 +129,7 @@ class HttpTriplestoreConnector extends Actor with ActorLogging with Instrumentat
private val checkRepositoryPath: String = if (triplestoreType == TriplestoreTypes.HttpGraphDBSE | triplestoreType == TriplestoreTypes.HttpGraphDBFree) {
"/rest/repositories"
} else if (triplestoreType == TriplestoreTypes.HttpFuseki) {
- if (settings.fusekiTomcat) {
- s"/${settings.fusekiTomcatContext}/$$/server"
- } else {
- "$/server"
- }
+ "/$/server"
} else {
throw UnsuportedTriplestoreException(s"Unsupported triplestore type: $triplestoreType")
}
@@ -149,11 +137,7 @@ class HttpTriplestoreConnector extends Actor with ActorLogging with Instrumentat
private val graphPath: String = if (triplestoreType == TriplestoreTypes.HttpGraphDBSE | triplestoreType == TriplestoreTypes.HttpGraphDBFree) {
s"/repositories/${settings.triplestoreDatabaseName}/statements"
} else if (triplestoreType == TriplestoreTypes.HttpFuseki) {
- if (settings.fusekiTomcat) {
- s"/${settings.fusekiTomcatContext}/${settings.triplestoreDatabaseName}/get"
- } else {
- s"/${settings.triplestoreDatabaseName}/get"
- }
+ s"/${settings.triplestoreDatabaseName}/get"
} else {
throw UnsuportedTriplestoreException(s"Unsupported triplestore type: $triplestoreType")
}
@@ -161,11 +145,7 @@ class HttpTriplestoreConnector extends Actor with ActorLogging with Instrumentat
private val repositoryDownloadPath = if (triplestoreType == TriplestoreTypes.HttpGraphDBSE | triplestoreType == TriplestoreTypes.HttpGraphDBFree) {
s"/repositories/${settings.triplestoreDatabaseName}/statements"
} else if (triplestoreType == TriplestoreTypes.HttpFuseki) {
- if (settings.fusekiTomcat) {
- s"/${settings.fusekiTomcatContext}/${settings.triplestoreDatabaseName}"
- } else {
- s"/${settings.triplestoreDatabaseName}"
- }
+ s"/${settings.triplestoreDatabaseName}"
} else {
throw UnsuportedTriplestoreException(s"Unsupported triplestore type: $triplestoreType")
}
@@ -556,7 +536,7 @@ class HttpTriplestoreConnector extends Actor with ActorLogging with Instrumentat
/**
* Checks the connection to a Fuseki triplestore.
*/
- private def checkFusekiTriplestore(): Try[CheckTriplestoreResponse] = {
+ private def checkFusekiTriplestore(afterAutoInit: Boolean = false): Try[CheckTriplestoreResponse] = {
import org.knora.webapi.messages.store.triplestoremessages.FusekiJsonProtocol._
try {
@@ -598,7 +578,20 @@ class HttpTriplestoreConnector extends Actor with ActorLogging with Instrumentat
Success(CheckTriplestoreResponse(triplestoreStatus = TriplestoreStatus.ServiceAvailable, msg = "Triplestore is available."))
} else {
// none of the available datasets meet our requirements
- Success(CheckTriplestoreResponse(triplestoreStatus = TriplestoreStatus.NotInitialized, msg = s"None of the active datasets meet our requirement of name: $nameShouldBe"))
+ log.info(s"None of the active datasets meet our requirement of name: $nameShouldBe")
+ if (settings.triplestoreAutoInit) {
+ // try to auto-init if we didn't tried it already
+ if (afterAutoInit) {
+ // we already tried to auto-init but it wasn't successful
+ Success(CheckTriplestoreResponse(triplestoreStatus = TriplestoreStatus.NotInitialized, msg = s"Sorry, we tried to auto-initialize and still none of the active datasets meet our requirement of name: $nameShouldBe"))
+ } else {
+ // try to auto-init
+ log.info("Triplestore auto-init is set. Trying to auto-initialize.")
+ initJenaFusekiTriplestore()
+ }
+ } else {
+ Success(CheckTriplestoreResponse(triplestoreStatus = TriplestoreStatus.NotInitialized, msg = s"None of the active datasets meet our requirement of name: $nameShouldBe"))
+ }
}
} catch {
case e: Exception =>
@@ -607,6 +600,68 @@ class HttpTriplestoreConnector extends Actor with ActorLogging with Instrumentat
}
}
+ /**
+ * Initialize the Jena Fuseki triplestore. Currently only works for
+ * 'knora-test' and 'knora-test-unit' repository names. To be used, the
+ * API needs to be started with 'KNORA_WEBAPI_TRIPLESTORE_AUTOINIT' set
+ * to 'true' (settings.triplestoreAutoInit). Usage is only recommended for automated testing and not for
+ * production use.
+ */
+ private def initJenaFusekiTriplestore(): Try[CheckTriplestoreResponse] = {
+
+ val configFileName = s"webapi/scripts/fuseki-${settings.triplestoreDatabaseName}-repository-config.ttl"
+
+ try {
+ // take config from the classpath and write to triplestore
+ val triplestoreConfig: String = FileUtil.readTextResource(configFileName)
+
+ val authCache: AuthCache = new BasicAuthCache
+ val basicAuth: BasicScheme = new BasicScheme
+ authCache.put(targetHost, basicAuth)
+
+ val httpContext: HttpClientContext = HttpClientContext.create
+ httpContext.setCredentialsProvider(credsProvider)
+ httpContext.setAuthCache(authCache)
+
+ val httpPost: HttpPost = new HttpPost("/$/datasets")
+ val stringEntity = new StringEntity(triplestoreConfig, ContentType.create(mimeTypeApplicationTrig))
+ httpPost.setEntity(stringEntity)
+
+ val start = System.currentTimeMillis()
+ var maybeResponse: Option[CloseableHttpResponse] = None
+
+ maybeResponse = Some(updateHttpClient.execute(targetHost, httpPost, httpContext))
+
+ val responseEntityStr: String = Option(maybeResponse.get.getEntity) match {
+ case Some(responseEntity) => EntityUtils.toString(responseEntity)
+ case None => ""
+ }
+
+ val statusCode: Int = maybeResponse.get.getStatusLine.getStatusCode
+ val statusCategory: Int = statusCode / 100
+
+ if (statusCategory != 2) {
+ log.error(s"Triplestore responded with HTTP code $statusCode: $responseEntityStr")
+ throw TriplestoreResponseException(s"Triplestore responded with HTTP code $statusCode: $responseEntityStr")
+ }
+
+ val took = System.currentTimeMillis() - start
+ metricsLogger.info(s"[$statusCode] Triplestore query took: ${took}ms")
+ RepositoryUploadedResponse()
+
+ } catch {
+ case e: NotFoundException =>
+ log.error(s"Cannot initialize repository. Config ${configFileName} not found.")
+ case tre: TriplestoreResponseException =>
+ log.error(tre.message)
+ case e: Exception =>
+ log.error(e, s"Failed to connect to triplestore: ${e.getMessage}")
+ }
+
+ // do the check again
+ checkFusekiTriplestore(true)
+ }
+
/**
* Checks the connection to a GraphDB triplestore.
*/
@@ -844,9 +899,11 @@ class HttpTriplestoreConnector extends Actor with ActorLogging with Instrumentat
httpContext.setAuthCache(authCache)
val uriBuilder: URIBuilder = new URIBuilder(repositoryDownloadPath)
-
+
if (triplestoreType == TriplestoreTypes.HttpGraphDBSE | triplestoreType == TriplestoreTypes.HttpGraphDBFree) {
uriBuilder.setParameter("infer", "false")
+ } else if (triplestoreType == TriplestoreTypes.HttpFuseki) {
+ // do nothing
} else {
throw UnsuportedTriplestoreException(s"Unsupported triplestore type: $triplestoreType")
}
diff --git a/webapi/src/test/resources/fuseki.conf b/webapi/src/test/resources/fuseki.conf
index cb4106bca0..ebc222d338 100644
--- a/webapi/src/test/resources/fuseki.conf
+++ b/webapi/src/test/resources/fuseki.conf
@@ -5,10 +5,10 @@ app {
dbtype = "fuseki"
fuseki {
- port = 8080
+ port = 3030
repository-name = "knora-test-unit"
- tomcat = true
- tomcat-context = "fuseki"
+ username = "admin"
+ password = "test"
}
reload-on-start = false
diff --git a/webapi/src/test/resources/test.conf b/webapi/src/test/resources/test.conf
index 803d2f2af0..8d63c4c049 100644
--- a/webapi/src/test/resources/test.conf
+++ b/webapi/src/test/resources/test.conf
@@ -1,6 +1,7 @@
include "application"
akka {
+ log-config-on-start = false
//loggers = ["akka.testkit.TestEventListener"]
loggers = ["akka.event.slf4j.Slf4jLogger"]
logging-filter = "akka.event.slf4j.Slf4jLoggingFilter"
@@ -21,4 +22,5 @@ akka {
}
}
-app.print-short-config = false
\ No newline at end of file
+app.print-short-config = false
+app.triplestore.auto-init = true
diff --git a/webapi/src/test/scala/org/knora/webapi/CoreSpec.scala b/webapi/src/test/scala/org/knora/webapi/CoreSpec.scala
index 7eb20a8721..066a88cc87 100644
--- a/webapi/src/test/scala/org/knora/webapi/CoreSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/CoreSpec.scala
@@ -66,10 +66,10 @@ object CoreSpec {
abstract class CoreSpec(_system: ActorSystem) extends TestKit(_system) with Core with StartupUtils with AnyWordSpecLike with Matchers with BeforeAndAfterAll with ImplicitSender {
/* constructors - individual tests can override the configuration by giving their own */
- def this(name: String, config: Config) = this(ActorSystem(name, ConfigFactory.load(config.withFallback(CoreSpec.defaultConfig))))
- def this(config: Config) = this(ActorSystem(CoreSpec.getCallerName(getClass), ConfigFactory.load(config.withFallback(CoreSpec.defaultConfig))))
- def this(name: String) = this(ActorSystem(name, ConfigFactory.load()))
- def this() = this(ActorSystem(CoreSpec.getCallerName(getClass), ConfigFactory.load()))
+ def this(name: String, config: Config) = this(ActorSystem(name, TestContainers.PortConfig.withFallback(ConfigFactory.load(config.withFallback(CoreSpec.defaultConfig)))))
+ def this(config: Config) = this(ActorSystem(CoreSpec.getCallerName(getClass), TestContainers.PortConfig.withFallback(ConfigFactory.load(config.withFallback(CoreSpec.defaultConfig)))))
+ def this(name: String) = this(ActorSystem(name, TestContainers.PortConfig.withFallback(ConfigFactory.load())))
+ def this() = this(ActorSystem(CoreSpec.getCallerName(getClass), TestContainers.PortConfig.withFallback(ConfigFactory.load())))
/* needed by the core trait */
implicit lazy val settings: KnoraSettingsImpl = KnoraSettings(system)
@@ -121,7 +121,7 @@ abstract class CoreSpec(_system: ActorSystem) extends TestKit(_system) with Core
Await.result(appActor ? ResetRepositoryContent(rdfDataObjects), 479999.milliseconds)
Await.result(appActor ? LoadOntologiesRequest(KnoraSystemInstances.Users.SystemUser), 1 minute)
Await.result(appActor ? CacheServiceFlushDB(KnoraSystemInstances.Users.SystemUser), 5 seconds)
- logger.info("Loading test data done.")
+ logger.info("... loading test data done.")
}
def memusage(): Unit = {
diff --git a/webapi/src/test/scala/org/knora/webapi/E2ESimSpec.scala b/webapi/src/test/scala/org/knora/webapi/E2ESimSpec.scala
index 92fa560cc5..322109000e 100644
--- a/webapi/src/test/scala/org/knora/webapi/E2ESimSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/E2ESimSpec.scala
@@ -57,10 +57,10 @@ object E2ESimSpec {
abstract class E2ESimSpec(_system: ActorSystem) extends Simulation with Core with TriplestoreJsonProtocol with RequestBuilding with LazyLogging {
/* constructors */
- def this(name: String, config: Config) = this(ActorSystem(name, config.withFallback(E2ESimSpec.defaultConfig)))
- def this(config: Config) = this(ActorSystem("PerfSpec", config.withFallback(E2ESimSpec.defaultConfig)))
- def this(name: String) = this(ActorSystem(name, E2ESimSpec.defaultConfig))
- def this() = this(ActorSystem("PerfSpec", E2ESimSpec.defaultConfig))
+ def this(name: String, config: Config) = this(ActorSystem(name, TestContainers.PortConfig.withFallback(config.withFallback(E2ESimSpec.defaultConfig))))
+ def this(config: Config) = this(ActorSystem("PerfSpec", TestContainers.PortConfig.withFallback(config.withFallback(E2ESimSpec.defaultConfig))))
+ def this(name: String) = this(ActorSystem(name, TestContainers.PortConfig.withFallback(E2ESimSpec.defaultConfig)))
+ def this() = this(ActorSystem("PerfSpec", TestContainers.PortConfig.withFallback(E2ESimSpec.defaultConfig)))
/* needed by the core trait */
implicit lazy val system: ActorSystem = _system
diff --git a/webapi/src/test/scala/org/knora/webapi/E2ESpec.scala b/webapi/src/test/scala/org/knora/webapi/E2ESpec.scala
index 80ea832d04..6da6846661 100644
--- a/webapi/src/test/scala/org/knora/webapi/E2ESpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/E2ESpec.scala
@@ -59,13 +59,13 @@ object E2ESpec {
class E2ESpec(_system: ActorSystem) extends Core with StartupUtils with TriplestoreJsonProtocol with Suite with AnyWordSpecLike with Matchers with BeforeAndAfterAll with RequestBuilding with LazyLogging {
/* constructors */
- def this(name: String, config: Config) = this(ActorSystem(name, config.withFallback(E2ESpec.defaultConfig)))
+ def this(name: String, config: Config) = this(ActorSystem(name, TestContainers.PortConfig.withFallback(config.withFallback(E2ESpec.defaultConfig))))
- def this(config: Config) = this(ActorSystem("E2ETest", config.withFallback(E2ESpec.defaultConfig)))
+ def this(config: Config) = this(ActorSystem("E2ETest", TestContainers.PortConfig.withFallback(config.withFallback(E2ESpec.defaultConfig))))
- def this(name: String) = this(ActorSystem(name, E2ESpec.defaultConfig))
+ def this(name: String) = this(ActorSystem(name, TestContainers.PortConfig.withFallback(E2ESpec.defaultConfig)))
- def this() = this(ActorSystem("E2ETest", E2ESpec.defaultConfig))
+ def this() = this(ActorSystem("E2ETest", TestContainers.PortConfig.withFallback(E2ESpec.defaultConfig)))
/* needed by the core trait */
@@ -110,7 +110,7 @@ class E2ESpec(_system: ActorSystem) extends Core with StartupUtils with Triplest
logger.info("Loading test data started ...")
val request = Post(baseApiUrl + "/admin/store/ResetTriplestoreContent", HttpEntity(ContentTypes.`application/json`, rdfDataObjects.toJson.compactPrint))
singleAwaitingRequest(request, 479999.milliseconds)
- logger.info("Loading test data done.")
+ logger.info("... loading test data done.")
}
// duration is intentionally like this, so that it could be found with search if seen in a stack trace
diff --git a/webapi/src/test/scala/org/knora/webapi/R2RSpec.scala b/webapi/src/test/scala/org/knora/webapi/R2RSpec.scala
index 4404f1ea43..f07ae54d8f 100644
--- a/webapi/src/test/scala/org/knora/webapi/R2RSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/R2RSpec.scala
@@ -27,38 +27,47 @@ import akka.http.scaladsl.server.ExceptionHandler
import akka.http.scaladsl.testkit.ScalatestRouteTest
import akka.pattern.ask
import akka.util.Timeout
+import com.typesafe.config.ConfigFactory
import com.typesafe.scalalogging.LazyLogging
import org.eclipse.rdf4j.model.Model
import org.eclipse.rdf4j.rio.{RDFFormat, Rio}
import org.knora.webapi.app.{APPLICATION_MANAGER_ACTOR_NAME, ApplicationActor, LiveManagers}
-import org.knora.webapi.messages.app.appmessages.AppReady
+import org.knora.webapi.messages.app.appmessages.{AppStart, AppStop, SetAllowReloadOverHTTPState}
import org.knora.webapi.messages.store.triplestoremessages.{RdfDataObject, ResetRepositoryContent}
import org.knora.webapi.messages.v1.responder.ontologymessages.LoadOntologiesRequest
import org.knora.webapi.routing.KnoraRouteData
import org.knora.webapi.util.jsonld.{JsonLDDocument, JsonLDUtil}
-import org.knora.webapi.util.{CacheUtil, FileUtil, StringFormatter}
+import org.knora.webapi.util.{FileUtil, StartupUtils, StringFormatter}
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpecLike
import org.scalatest.{BeforeAndAfterAll, Suite}
import scala.concurrent.duration._
-import scala.concurrent.{Await, Future}
+import scala.concurrent.{Await, ExecutionContext, Future}
import scala.language.postfixOps
+
/**
- * Created by subotic on 08.12.15.
+ * R(oute)2R(esponder) Spec base class. Please, for any new E2E tests, use E2ESpec.
*/
-class R2RSpec extends Suite with ScalatestRouteTest with AnyWordSpecLike with Matchers with BeforeAndAfterAll with LazyLogging {
+class R2RSpec extends Core with StartupUtils with Suite with ScalatestRouteTest with AnyWordSpecLike with Matchers with BeforeAndAfterAll with LazyLogging {
+
+ /* needed by the core trait */
+ implicit lazy val _system: ActorSystem = ActorSystem(actorSystemNameFrom(getClass), TestContainers.PortConfig.withFallback(ConfigFactory.load()))
+ implicit lazy val settings: KnoraSettingsImpl = KnoraSettings(_system)
+ lazy val executionContext: ExecutionContext = _system.dispatchers.lookup(KnoraDispatchers.KnoraActorDispatcher)
+
+ // override so that we can use our own system
+ override def createActorSystem(): ActorSystem = _system
- def actorRefFactory: ActorSystem = system
+ def actorRefFactory: ActorSystem = _system
- val settings: KnoraSettingsImpl = KnoraSettings(system)
StringFormatter.initForTest()
implicit val knoraExceptionHandler: ExceptionHandler = KnoraExceptionHandler(settings)
implicit val timeout: Timeout = Timeout(settings.defaultTimeout)
- protected lazy val appActor: ActorRef = system.actorOf(Props(new ApplicationActor with LiveManagers).withDispatcher(KnoraDispatchers.KnoraActorDispatcher), name = APPLICATION_MANAGER_ACTOR_NAME)
+ lazy val appActor: ActorRef = system.actorOf(Props(new ApplicationActor with LiveManagers).withDispatcher(KnoraDispatchers.KnoraActorDispatcher), name = APPLICATION_MANAGER_ACTOR_NAME)
// The main application actor forwards messages to the responder manager and the store manager.
val responderManager: ActorRef = appActor
@@ -72,14 +81,21 @@ class R2RSpec extends Suite with ScalatestRouteTest with AnyWordSpecLike with Ma
lazy val rdfDataObjects = List.empty[RdfDataObject]
override def beforeAll {
- // changes the state and behaviour of the ApplicationActor to Ready
- appActor ! AppReady()
- CacheUtil.createCaches(settings.caches)
+ // set allow reload over http
+ appActor ! SetAllowReloadOverHTTPState(true)
+
+ // start the knora service, loading data from the repository
+ appActor ! AppStart(ignoreRepository = true, requiresIIIFService = false)
+
+ // waits until knora is up and running
+ applicationStateRunning()
+
loadTestData(rdfDataObjects)
}
override def afterAll {
- CacheUtil.removeAllCaches()
+ /* Stop the server when everything else has finished */
+ appActor ! AppStop()
}
protected def responseToJsonLDDocument(httpResponse: HttpResponse): JsonLDDocument = {
diff --git a/webapi/src/test/scala/org/knora/webapi/SettingsSpec.scala b/webapi/src/test/scala/org/knora/webapi/SettingsSpec.scala
deleted file mode 100644
index 94c29c3331..0000000000
--- a/webapi/src/test/scala/org/knora/webapi/SettingsSpec.scala
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright © 2015-2019 the contributors (see Contributors.md).
- *
- * This file is part of Knora.
- *
- * Knora is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Knora is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public
- * License along with Knora. If not, see .
- */
-
-package org.knora.webapi
-
-import com.typesafe.config.{Config, ConfigFactory}
-
-object SettingsSpec {
- val config: Config = ConfigFactory.parseString(
- """
- akka {
- akka.loglevel = "DEBUG"
- akka.stdout-loglevel = "DEBUG"
- }
- """.stripMargin)
-}
-
-class SettingsSpec extends CoreSpec("SettingsActorTestSystem", SettingsSpec.config) {
-
- "The Settings Object" should {
-
- "provide access to all config values" in {
-
- // settings.internalKnoraApiHost should be ("0.0.0.0")
- settings.internalKnoraApiPort should be (3333)
- // settings.internalKnoraApiBaseUrl should be ("http://0.0.0.0:3333")
-
- settings.externalKnoraApiProtocol should be ("http")
- // settings.externalKnoraApiHost should be ("0.0.0.0")
- settings.externalKnoraApiPort should be (3333)
- // settings.externalKnoraApiBaseUrl should be ("http://0.0.0.0:3333")
-
- settings.internalSipiProtocol should be ("http")
- // settings.internalSipiHost should be ("0.0.0.0")
- settings.internalSipiPort should be (1024)
- // settings.internalSipiBaseUrl should be ("http://0.0.0.0:1024")
-
- settings.externalSipiProtocol should be ("http")
- // settings.externalSipiHost should be ("0.0.0.0")
- settings.externalSipiPort should be (1024)
- // settings.externalSipiBaseUrl should be ("http://0.0.0.0:1024")
-
- settings.sipiFileServerPrefix should be ("server")
-
- // settings.externalSipiIIIFGetUrl should be ("http://0.0.0.0:1024")
-
- // settings.internalSipiFileServerGetUrl should be ("http://0.0.0.0:1024/server")
- // settings.externalSipiFileServerGetUrl should be ("http://0.0.0.0:1024/server")
-
- // settings.internalSipiImageConversionUrlV1 should be ("http://0.0.0.0:1024")
- }
- }
-}
diff --git a/webapi/src/test/scala/org/knora/webapi/TestContainers.scala b/webapi/src/test/scala/org/knora/webapi/TestContainers.scala
new file mode 100644
index 0000000000..afa297d9dd
--- /dev/null
+++ b/webapi/src/test/scala/org/knora/webapi/TestContainers.scala
@@ -0,0 +1,65 @@
+/*
+ * Copyright © 2015-2019 the contributors (see Contributors.md).
+ *
+ * This file is part of Knora.
+ *
+ * Knora is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Knora is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with Knora. If not, see .
+ */
+
+package org.knora.webapi
+
+import com.typesafe.config.{Config, ConfigFactory}
+import org.testcontainers.containers.{BindMode, GenericContainer}
+
+/**
+ * Provides all containers necessary for running tests.
+ */
+object TestContainers {
+
+ val FusekiContainer = new GenericContainer("daschswiss/knora-jena-fuseki:latest")
+ FusekiContainer.withExposedPorts(3030)
+ FusekiContainer.withEnv("ADMIN_PASSWORD", "test")
+ FusekiContainer.withEnv("JVM_ARGS", "-Xmx3G")
+ FusekiContainer.start()
+
+ val SipiContainer = new GenericContainer("daschswiss/knora-sipi:latest")
+ SipiContainer.withExposedPorts(1024)
+ SipiContainer.withEnv("SIPI_EXTERNAL_PROTOCOL", "http")
+ SipiContainer.withEnv("SIPI_EXTERNAL_HOSTNAME", "sipi")
+ SipiContainer.withEnv("SIPI_EXTERNAL_PORT", "1024")
+ SipiContainer.withEnv("SIPI_WEBAPI_HOSTNAME", "api")
+ SipiContainer.withEnv("SIPI_WEBAPI_PORT", "3333")
+ SipiContainer.withCommand("--config=/sipi/config/sipi.knora-docker-config.lua")
+ SipiContainer.withClasspathResourceMapping("/sipi/config/sipi.knora-docker-config.lua",
+ "/sipi/config/sipi.knora-docker-config.lua",
+ BindMode.READ_ONLY)
+ SipiContainer.withClasspathResourceMapping("/sipi/config/sipi.knora-docker-config.lua",
+ "/sipi/config/sipi.init-knora.lua",
+ BindMode.READ_ONLY)
+ SipiContainer.start()
+
+ val RedisContainer = new GenericContainer("redis:5")
+ RedisContainer.withExposedPorts(6379)
+ RedisContainer.start()
+
+ import scala.collection.JavaConverters._
+ private val portMap = Map(
+ "app.triplestore.fuseki.port" -> FusekiContainer.getFirstMappedPort,
+ "app.sipi.internal-port" -> SipiContainer.getFirstMappedPort,
+ "app.cache-service.redis.port" -> RedisContainer.getFirstMappedPort
+ ).asJava
+
+ // all tests need to be configured with these ports.
+ val PortConfig: Config = ConfigFactory.parseMap(portMap, "Ports from ContainerizedSpec")
+}
diff --git a/webapi/src/test/scala/org/knora/webapi/e2e/v2/SearchRouteV2R2RSpec.scala b/webapi/src/test/scala/org/knora/webapi/e2e/v2/SearchRouteV2R2RSpec.scala
index c0ae84f975..e2707748a5 100644
--- a/webapi/src/test/scala/org/knora/webapi/e2e/v2/SearchRouteV2R2RSpec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/e2e/v2/SearchRouteV2R2RSpec.scala
@@ -8066,10 +8066,10 @@ class SearchRouteV2R2RSpec extends R2RSpec {
|} WHERE {
| ?thing a knora-api:Resource .
| ?thing a anything:Thing .
+ |
| {
| ?thing anything:hasRichtext ?richtext .
- | ?richtext knora-api:valueAsString ?richtextLiteral
- | FILTER knora-api:match(?richtextLiteral, "test")
+ | FILTER knora-api:matchText(?richtext, "test")
|
| ?thing anything:hasInteger ?int .
| ?int knora-api:intValueAsInt 1
@@ -8077,14 +8077,13 @@ class SearchRouteV2R2RSpec extends R2RSpec {
| UNION
| {
| ?thing anything:hasText ?text .
- | ?text knora-api:valueAsString ?textLiteral
- | FILTER knora-api:match(?textLiteral, "test")
+ | FILTER knora-api:matchText(?text, "test")
|
| ?thing anything:hasInteger ?int .
| ?int knora-api:intValueAsInt 1
| }
|}
- |order by (?int)""".stripMargin
+ |ORDER BY (?int)""".stripMargin
val expectedCount = 1
diff --git a/webapi/src/test/scala/org/knora/webapi/util/DateUtilV1Spec.scala b/webapi/src/test/scala/org/knora/webapi/util/DateUtilV1Spec.scala
index 857514f20c..88f21e4bab 100644
--- a/webapi/src/test/scala/org/knora/webapi/util/DateUtilV1Spec.scala
+++ b/webapi/src/test/scala/org/knora/webapi/util/DateUtilV1Spec.scala
@@ -24,12 +24,13 @@ import java.util.{Calendar, GregorianCalendar}
import org.knora.webapi.BadRequestException
import org.knora.webapi.messages.v1.responder.valuemessages.{DateValueV1, JulianDayNumberValueV1, KnoraCalendarV1, KnoraPrecisionV1}
import org.knora.webapi.util.DateUtilV1.DateRange
-import org.scalatest._
+import org.scalatest.matchers.should.Matchers
+import org.scalatest.wordspec.AnyWordSpecLike
/**
* Tests [[DateUtilV1]].
*/
-class DateUtilV1Spec extends WordSpec with Matchers {
+class DateUtilV1Spec extends AnyWordSpecLike with Matchers {
"The DateUtilV1 class" should {
"convert a date in YYYY-MM-DD format, in the Julian calendar, into a Julian day count, and back again" in {
val bundesbriefDateValueV1 = DateValueV1(
|