var app = angular.module('plunker',
['ngGrid', 'ui.bootstrap', 'bDatepicker', 'schemaForm', 'xtForm']);
//Home contoller - demo of field types
app.controller('HomeCtrl', ['$scope', 'schema', 'requestResult', 'dataService',
function($scope, schema, requestResult, dataService) {
$scope.modelSchema = schema.product;
$scope.xtform = {
onSubmit: function (isValid) {
if (isValid) {
alert('The form was submitted, model contains: ' +
JSON.stringify($scope.model));
} else {
alert('The form was invalid.');
}
}
};
$scope.model = {
factoryDate: '20160506'
};
// field name arrays - one array per column in sample layout
$scope.side1Fields = [
'productName',
'factoryDate',
'productType',
'timeValue'
];
$scope.side2Fields = [
'factoryCountry1',
'factoryCountry2',
'factoryCountry3',
'factoryCountry4'
];
// enhance 'searchableText' schema with search dialog elements
// TODO: move this into the directive proper, all except for the
// searchFn and data assignment
//
// TODO: expand to support searchableNumber, and other
// searchable types
// TODO: support separation of displayProperty from resultProperty
// i.e. use property 'longName' in view, while model receives
// property 'code'
for (var p in $scope.modelSchema.properties) {
var s = $scope.modelSchema.properties[p];
if (s.control && s.control === "searchableText") {
// schema of lookup data for grid
s.searchSchema = angular.copy(schema[s.searchSchemaName]);
// override default button settings
if (typeof s.searchButtons !== 'undefined') {
s.searchSchema.buttons = s.searchButtons;
}
// query function for remote data service
// will receive arguemnts 'type' and 'criteria'
// filtering fallsback to 'local' mode if not provided
s.searchFn = dataService.get;
// if searchType is 'local' data must be provided
if (s.searchType === 'local' ||
typeof s.searchFn !== 'function') {
// TODO: throw exception if data is not an array
// with length > 0
s.data = requestResult.results[s.searchSchemaName].data;
}
}
}
}
]);
// Sample data service -- normally calls remote data server
app.factory('dataService', ['$q', 'requestResult', '$timeout',
function($q, requestResult, $timeout) {
return {
get: function(type, criteria) {
var returnValue;
var deferred = $q.defer();
function propertyFilter(data, field, value) {
return data.filter(function(el) {
return (
el[field].toLowerCase()
.indexOf(value.toLowerCase()) !== -1
);
})
}
function dataFilter(data, criteria) {
var results = data;
for (var p in criteria) {
results = propertyFilter(results, p, criteria[p]);
}
return results;
}
// emulate remote server call
$timeout(function() {
returnValue = dataFilter(requestResult.results[type].data, criteria);
deferred.resolve(returnValue);
}, 2000);
return deferred.promise;
}
}
}
]);
app.value('schema', {
"country": {
"type": "object",
"title": "Select Country",
"usage": ["table", "form"],
"displayProperty": "name",
"searchSchemaName": "country",
"searchFn": undefined,
"buttons": {
"search": {
"label": "Search",
"visible": true
},
"select": {
"label": "Ok",
"visible": true
},
"cancel": {
"label": "Cancel",
"visible": true
},
"new": {
"label": "New",
"visible": false
}
},
"properties": {
"code": {
"gridColumnDefinition": {
"width": '*',
"minWidth": 50,
"maxWidth": 9000,
"visible": true,
"displayName": undefined,
"sortable": true,
"resizable": true,
"groupable": true,
"pinnable": false,
"editableCellTemplate": undefined,
"enableCellEdit": false,
"cellEditableCondition": undefined,
"sortFn": undefined,
"cellTemplate": undefined,
"cellClass": undefined,
"headerClass": undefined,
"headerCellTemplate": undefined,
"cellFilter": undefined,
"aggLabelFilter": undefined
},
"title": "Code",
"filterType": "text",
"visible": true,
"filterable": true,
"readonly": false,
"required": true
},
"code3": {
"gridColumnDefinition": {
"width": '*',
"minWidth": 50,
"maxWidth": 9000,
"visible": true,
"displayName": undefined,
"sortable": true,
"resizable": true,
"groupable": true,
"pinnable": false,
"editableCellTemplate": undefined,
"enableCellEdit": false,
"cellEditableCondition": undefined,
"sortFn": undefined,
"cellTemplate": undefined,
"cellClass": undefined,
"headerClass": undefined,
"headerCellTemplate": undefined,
"cellFilter": undefined,
"aggLabelFilter": undefined
},
"title": "ISO Code",
"filterType": "text",
"visible": true,
"filterable": true,
"readonly": false,
"required": true
},
"fiscalYearEnd": {
"gridColumnDefinition": {
"width": '*',
"minWidth": 50,
"maxWidth": 9000,
"visible": false,
"displayName": undefined,
"sortable": true,
"resizable": true,
"groupable": true,
"pinnable": false,
"editableCellTemplate": undefined,
"enableCellEdit": false,
"cellEditableCondition": undefined,
"sortFn": undefined,
"cellTemplate": undefined,
"cellClass": undefined,
"headerClass": undefined,
"headerCellTemplate": undefined,
"cellFilter": undefined,
"aggLabelFilter": undefined
},
"title": "Fiscal Year End (MMDD)",
"filterType": "text",
"visible": true,
"filterable": true,
"readonly": false,
"required": true
},
"majorIndex": {
"gridColumnDefinition": {
"width": '*',
"minWidth": 82,
"maxWidth": 9000,
"visible": true,
"displayName": undefined,
"sortable": true,
"resizable": true,
"groupable": true,
"pinnable": false,
"editableCellTemplate": undefined,
"enableCellEdit": false,
"cellEditableCondition": undefined,
"sortFn": undefined,
"cellTemplate": undefined,
"cellClass": undefined,
"headerClass": undefined,
"headerCellTemplate": undefined,
"cellFilter": undefined,
"aggLabelFilter": undefined
},
"title": "Major Index",
"filterType": "text",
"visible": true,
"filterable": true,
"readonly": false,
"required": true
},
"name": {
"gridColumnDefinition": {
"width": '***',
"minWidth": 50,
"maxWidth": 9000,
"visible": true,
"displayName": undefined,
"sortable": true,
"resizable": true,
"groupable": true,
"pinnable": false,
"editableCellTemplate": undefined,
"enableCellEdit": false,
"cellEditableCondition": undefined,
"sortFn": undefined,
"cellTemplate": undefined,
"cellClass": undefined,
"headerClass": undefined,
"headerCellTemplate": undefined,
"cellFilter": undefined,
"aggLabelFilter": undefined
},
"title": "Name",
"filterType": "text",
"visible": true,
"filterable": true,
"readonly": false,
"required": true
},
"taxDate": {
"gridColumnDefinition": {
"width": '*',
"minWidth": 50,
"maxWidth": 9000,
"visible": false,
"displayName": undefined,
"sortable": true,
"resizable": true,
"groupable": true,
"pinnable": false,
"editableCellTemplate": undefined,
"enableCellEdit": false,
"cellEditableCondition": undefined,
"sortFn": undefined,
"cellTemplate": undefined,
"cellClass": undefined,
"headerClass": undefined,
"headerCellTemplate": undefined,
"cellFilter": undefined,
"aggLabelFilter": undefined
},
"title": "Tax Date (MMDD)",
"filterType": "text",
"visible": true,
"filterable": true,
"readonly": false,
"required": true
}
}
},
"product": {
"type": "object",
"title": "Product Schema",
"properties": {
"factoryCountry1": {
"title": "Source Country (Live Remote Filtering)",
"type": "string",
"control": "searchableText",
"searchType": "remote",
"searchSchemaName": "country",
"showLabel": true,
"tooltip": "Country of manufacture",
"readonly": false,
"required": true,
"searchButtons": {
"search": {
"label": "Search",
"visible": false
},
"select": {
"label": "Ok",
"visible": true
},
"cancel": {
"label": "Cancel",
"visible": true
},
"new": {
"label": "New",
"visible": false
}
}
},
"factoryCountry2": {
"title": "Source Country (On Demand Remote Filtering)",
"type": "string",
"control": "searchableText",
"searchType": "request",
"searchSchemaName": "country",
"showLabel": true,
"tooltip": "Country of manufacture",
"readonly": false,
"required": true,
"searchButtons": {
"search": {
"label": "Search",
"visible": true
},
"select": {
"label": "Ok",
"visible": true
},
"cancel": {
"label": "Cancel",
"visible": true
},
"new": {
"label": "New",
"visible": false
}
}
},
"factoryCountry3": {
"title": "Source Country (Remote Initialize, Local Filtering)",
"type": "string",
"control": "searchableText",
"searchType": "initial",
"showLabel": true,
"searchSchemaName": "country",
"tooltip": "Country of manufacture",
"readonly": false,
"required": true,
"searchButtons": {
"search": {
"label": "Search",
"visible": false
},
"select": {
"label": "Ok",
"visible": true
},
"cancel": {
"label": "Cancel",
"visible": true
},
"new": {
"label": "New",
"visible": false
}
}
},
"factoryCountry4": {
"title": "Source Country (Local Filtering)",
"type": "string",
"control": "searchableText",
"searchType": "local",
"showLabel": true,
"searchSchemaName": "country",
"tooltip": "Country of manufacture",
"readonly": false,
"required": true,
"searchButtons": {
"search": {
"label": "Search",
"visible": false
},
"select": {
"label": "Ok",
"visible": true
},
"cancel": {
"label": "Cancel",
"visible": true
},
"new": {
"label": "New",
"visible": false
}
}
},
"productType": {
"type": "string",
"title": "Product Type",
"showLabel": true,
"tooltip": "Product classification",
"readonly": false,
"required": true,
"class": "custom-select",
"enum": ['Bike', 'Car', 'Airplane', 'Glider', 'Stilts']
},
"productName": {
"title": "Product Name",
"showLabel": true,
"type": "string",
"tooltip": "A more descriptive name for the modeled structure.",
"readonly": false,
"required": true
},
"factoryDate": {
"title": "Factory Date",
"type": "string",
"showLabel": true,
"control": "date",
"dateFormat": "yyyymmdd", // TODO format as provided
"tooltip": "Date of manufacture.",
"dateOptions": {
autoclose: true
},
"readonly": false,
"required": true
},
"timeValue": {
"title": "Time (HHMM)",
"showLabel": true,
"type": "string",
"pattern": "([0-1]{1}[0-9]{1}|20|21|22|23)[0-5]{1}[0-9]{1}",
"timeFormat": "hhmm", // TODO format as provided
"tooltip": "Time entry.",
"readonly": false,
"required": true,
"validation": {
"constraints": {
"presence": {
"markup": "required",
"message": "is required"
},
"numericality": {
"markup": "numbers",
"message": "invalid characters, expected format is HHMM"
},
"format": {
"markup": "pattern",
"pattern": "([0-1]{1}[0-9]{1}|20|21|22|23)[0-5]{1}[0-9]{1}",
"flags": "i",
"message": "invalid format, expected format is HHMM"
}
},
"updateOnBlur": false
}
}
}
}
});
// sample data for testing, used by dataService
app.value('requestResult', {
results: {
country: {
"data": [{
"code": "AF",
"code3": "",
"name": "Afghanistan",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "AL",
"code3": "",
"name": "Albania",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "DZ",
"code3": "",
"name": "Algeria",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "AS",
"code3": "",
"name": "American Samoa",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "AD",
"code3": "",
"name": "Andorra",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "AO",
"code3": "",
"name": "Angola",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "AI",
"code3": "",
"name": "Anguilla",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "AQ",
"code3": "",
"name": "Antarctica",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "AG",
"code3": "",
"name": "Antigua and Barbuda",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "AR",
"code3": "",
"name": "Argentina",
"majorIndex": ".MERV",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "AM",
"code3": "",
"name": "Armenia",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "AW",
"code3": "",
"name": "Aruba",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "AU",
"code3": "",
"name": "Australia",
"majorIndex": ".AXJO",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "AT",
"code3": "",
"name": "Austria",
"majorIndex": ".ATX",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "AZ",
"code3": "",
"name": "Azerbaijan",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "BS",
"code3": "",
"name": "Bahamas",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "BH",
"code3": "",
"name": "Bahrain",
"majorIndex": ".BAX",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "BD",
"code3": "",
"name": "Bangladesh",
"majorIndex": ".DGEN",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "BB",
"code3": "",
"name": "Barbados",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "BY",
"code3": "",
"name": "Belarus",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "BE",
"code3": "",
"name": "Belgium",
"majorIndex": ".BFX",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "BZ",
"code3": "",
"name": "Belize",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "BJ",
"code3": "",
"name": "Benin",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "BM",
"code3": "",
"name": "Bermuda",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "BT",
"code3": "",
"name": "Bhutan",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "BO",
"code3": "",
"name": "Bolivia",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "BA",
"code3": "",
"name": "Bosnia and Herzegovina",
"majorIndex": ".SASX30",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "BW",
"code3": "",
"name": "Botswana",
"majorIndex": ".DCIBT",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "BV",
"code3": "",
"name": "Bouvet Island",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "BR",
"code3": "",
"name": "Brazil",
"majorIndex": ".BVSP",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "IO",
"code3": "",
"name": "British Indian Ocean Territory",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "BN",
"code3": "",
"name": "Brunei Darussalam",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "BG",
"code3": "",
"name": "Bulgaria",
"majorIndex": ".SOFIX",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "BF",
"code3": "",
"name": "Burkina Faso",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "BI",
"code3": "",
"name": "Burundi",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "KH",
"code3": "",
"name": "Cambodia",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "CM",
"code3": "",
"name": "Cameroon",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "CA",
"code3": "",
"name": "Canada",
"majorIndex": ".SPTSE",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "CV",
"code3": "",
"name": "Cape Verde",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "KY",
"code3": "",
"name": "Cayman Islands",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "CF",
"code3": "",
"name": "Central African Republic",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "TD",
"code3": "",
"name": "Chad",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "CL",
"code3": "",
"name": "Chile",
"majorIndex": ".IPSA",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "CN",
"code3": "",
"name": "China",
"majorIndex": ".SSEA",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "CX",
"code3": "",
"name": "Christmas Island",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "CC",
"code3": "",
"name": "Cocos (Keeling) Islands",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "CO",
"code3": "",
"name": "Colombia",
"majorIndex": ".IGBC",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "KM",
"code3": "",
"name": "Comoros",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "CG",
"code3": "",
"name": "Congo",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "CD",
"code3": "",
"name": "Congo The Democratic Re",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "CK",
"code3": "",
"name": "Cook Islands",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "CR",
"code3": "",
"name": "Costa Rica",
"majorIndex": ".IACR",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "HR",
"code3": "",
"name": "Croatia",
"majorIndex": ".CRBEX",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "CU",
"code3": "",
"name": "Cuba",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "CW",
"code3": "",
"name": "Curacao",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "CY",
"code3": "",
"name": "Cyprus",
"majorIndex": ".CYFT",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "CZ",
"code3": "",
"name": "Czech Republic",
"majorIndex": ".PX",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "DK",
"code3": "",
"name": "Denmark",
"majorIndex": ".KFMX",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "DJ",
"code3": "",
"name": "Djibouti",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "DM",
"code3": "",
"name": "Dominica",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "DO",
"code3": "",
"name": "Dominican Republic",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "TP",
"code3": "",
"name": "East Timor",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "EC",
"code3": "",
"name": "Ecuador",
"majorIndex": ".BVQA",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "EG",
"code3": "",
"name": "Egypt",
"majorIndex": ".EGX100",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "SV",
"code3": "",
"name": "El Salvador",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "GQ",
"code3": "",
"name": "Equatorial Guinea",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "ER",
"code3": "",
"name": "Eritrea",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "EE",
"code3": "",
"name": "Estonia",
"majorIndex": ".OMXTGI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "ET",
"code3": "",
"name": "Ethiopia",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "EU",
"code3": "",
"name": "European Union",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "FK",
"code3": "",
"name": "Falkland Islands (Malvinas)",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "FO",
"code3": "",
"name": "Faroe Islands",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "FJ",
"code3": "",
"name": "Fiji",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "FI",
"code3": "",
"name": "Finland",
"majorIndex": ".OMXH25",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "FR",
"code3": "",
"name": "France",
"majorIndex": ".FCHI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "GF",
"code3": "",
"name": "French Guiana",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "PF",
"code3": "",
"name": "French Polynesia",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "TF",
"code3": "",
"name": "French Southern Territories",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "GA",
"code3": "",
"name": "Gabon",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "GM",
"code3": "",
"name": "Gambia",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "GE",
"code3": "",
"name": "Georgia",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "DE",
"code3": "",
"name": "Germany",
"majorIndex": ".GDAX",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "GH",
"code3": "",
"name": "Ghana",
"majorIndex": ".GSECI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "GI",
"code3": "",
"name": "Gibraltar",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "GR",
"code3": "",
"name": "Greece",
"majorIndex": ".ATG",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "GL",
"code3": "",
"name": "Greenland",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "GD",
"code3": "",
"name": "Grenada",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "GP",
"code3": "",
"name": "Guadeloupe",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "GU",
"code3": "",
"name": "Guam",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "GT",
"code3": "",
"name": "Guatemala",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "GG",
"code3": "",
"name": "Guernsey",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "GN",
"code3": "",
"name": "Guinea",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "GW",
"code3": "",
"name": "Guinea-Bissau",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "GY",
"code3": "",
"name": "Guyana",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "HT",
"code3": "",
"name": "Haiti",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "HM",
"code3": "",
"name": "Heard Island and Mcdonald Islands",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "VA",
"code3": "",
"name": "Holy See (Vatican City State)",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "HN",
"code3": "",
"name": "Honduras",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "HK",
"code3": "",
"name": "Hong Kong",
"majorIndex": ".HSI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "HU",
"code3": "",
"name": "Hungary",
"majorIndex": ".BUX",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "IS",
"code3": "",
"name": "Iceland",
"majorIndex": ".OMXIPI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "IN",
"code3": "",
"name": "India",
"majorIndex": ".NSEI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "ID",
"code3": "",
"name": "Indonesia",
"majorIndex": ".JKSE",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "IR",
"code3": "",
"name": "Iran Islamic Republic O",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "IQ",
"code3": "",
"name": "Iraq",
"majorIndex": ".ISX",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "IE",
"code3": "",
"name": "Ireland",
"majorIndex": ".ISEQ",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "JE",
"code3": "",
"name": "Island of Jersey",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "IM",
"code3": "",
"name": "Isle of Man",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "IL",
"code3": "",
"name": "Israel",
"majorIndex": ".TA25",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "IT",
"code3": "",
"name": "Italy",
"majorIndex": ".FTMIB",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "CI",
"code3": "",
"name": "Ivory Coast",
"majorIndex": ".BRVMCI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "JM",
"code3": "",
"name": "Jamaica",
"majorIndex": ".JSEAJC",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "JP",
"code3": "",
"name": "Japan",
"majorIndex": ".N225",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "JO",
"code3": "",
"name": "Jordan",
"majorIndex": ".AMMAN",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "KZ",
"code3": "",
"name": "Kazakhstan",
"majorIndex": ".KASE",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "KE",
"code3": "",
"name": "Kenya",
"majorIndex": ".NASI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "KI",
"code3": "",
"name": "Kiribati",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "KR",
"code3": "",
"name": "Korea",
"majorIndex": ".KS200",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "KP",
"code3": "",
"name": "Korea Democratic People",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "KW",
"code3": "",
"name": "Kuwait",
"majorIndex": ".KWSE",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "KG",
"code3": "",
"name": "Kyrgyzstan",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "LA",
"code3": "",
"name": "Lao People's Democratic Republic",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "LV",
"code3": "",
"name": "Latvia",
"majorIndex": ".OMXRGI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "LB",
"code3": "",
"name": "Lebanon",
"majorIndex": ".BDLSI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "LS",
"code3": "",
"name": "Lesotho",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "LR",
"code3": "",
"name": "Liberia",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "LY",
"code3": "",
"name": "Libyan Arab Jamahiriya",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "LI",
"code3": "",
"name": "Liechtenstein",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "LT",
"code3": "",
"name": "Lithuania",
"majorIndex": ".OMXVGI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "LU",
"code3": "",
"name": "Luxembourg",
"majorIndex": ".LUXX",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "MO",
"code3": "",
"name": "Macau",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "MK",
"code3": "",
"name": "Macedonia/The Former Yu",
"majorIndex": ".MBID",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "MG",
"code3": "",
"name": "Madagascar",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "MW",
"code3": "",
"name": "Malawi",
"majorIndex": ".MALSMV",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "MY",
"code3": "",
"name": "Malaysia",
"majorIndex": ".KLSE",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "MV",
"code3": "",
"name": "Maldives",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "ML",
"code3": "",
"name": "Mali",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "MT",
"code3": "",
"name": "Malta",
"majorIndex": ".MSE",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "MH",
"code3": "",
"name": "Marshall Islands",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "MQ",
"code3": "",
"name": "Martinique",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "MR",
"code3": "",
"name": "Mauritania",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "MU",
"code3": "",
"name": "Mauritius",
"majorIndex": ".MDEX",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "YT",
"code3": "",
"name": "Mayotte",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "MX",
"code3": "",
"name": "Mexico",
"majorIndex": ".MXX",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "FM",
"code3": "",
"name": "Micronesia Federated St",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "MD",
"code3": "",
"name": "Moldova Republic Of",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "MC",
"code3": "",
"name": "Monaco",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "MN",
"code3": "",
"name": "Mongolia",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "ME",
"code3": "",
"name": "Montenegro",
"majorIndex": ".MONEX20",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "MS",
"code3": "",
"name": "Montserrat",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "MA",
"code3": "",
"name": "Morocco",
"majorIndex": ".MASI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "MZ",
"code3": "",
"name": "Mozambique",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "MM",
"code3": "",
"name": "Myanmar",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "NA",
"code3": "",
"name": "Namibia",
"majorIndex": ".FTN098",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "NR",
"code3": "",
"name": "Nauru",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "NP",
"code3": "",
"name": "Nepal",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "NL",
"code3": "",
"name": "Netherlands",
"majorIndex": ".AEX",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "AN",
"code3": "",
"name": "Netherlands Antilles",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "NC",
"code3": "",
"name": "New Caledonia",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "NZ",
"code3": "",
"name": "New Zealand",
"majorIndex": ".NZ50",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "NI",
"code3": "",
"name": "Nicaragua",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "NE",
"code3": "",
"name": "Niger",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "NG",
"code3": "",
"name": "Nigeria",
"majorIndex": ".NGSEINDEX",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "NU",
"code3": "",
"name": "Niue",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "NF",
"code3": "",
"name": "Norfolk Island",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "MP",
"code3": "",
"name": "Northern Mariana Islands",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "NO",
"code3": "",
"name": "Norway",
"majorIndex": ".OBX",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "OM",
"code3": "",
"name": "Oman",
"majorIndex": ".MSI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "Other",
"code3": "",
"name": "Other",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "O",
"code3": "",
"name": "Other/Unknown",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "PK",
"code3": "",
"name": "Pakistan",
"majorIndex": ".KSE",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "PW",
"code3": "",
"name": "Palau",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "PA",
"code3": "",
"name": "Panama",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "PG",
"code3": "",
"name": "Papua New Guinea",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "PY",
"code3": "",
"name": "Paraguay",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "PE",
"code3": "",
"name": "Peru",
"majorIndex": ".IGRA",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "PH",
"code3": "",
"name": "Philippines",
"majorIndex": ".PSI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "PN",
"code3": "",
"name": "Pitcairn",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "PL",
"code3": "",
"name": "Poland",
"majorIndex": ".WIG",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "PT",
"code3": "",
"name": "Portugal",
"majorIndex": ".PSI20",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "PR",
"code3": "",
"name": "Puerto Rico",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "QA",
"code3": "",
"name": "Qatar",
"majorIndex": ".QEAS",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "RE",
"code3": "",
"name": "Reunion",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "RO",
"code3": "",
"name": "Romania",
"majorIndex": ".BETI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "RU",
"code3": "",
"name": "Russian Federation",
"majorIndex": ".IRTS",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "RW",
"code3": "",
"name": "Rwanda",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "SH",
"code3": "",
"name": "Saint Helena",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "KN",
"code3": "",
"name": "Saint Kitts and Nevis",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "LC",
"code3": "",
"name": "Saint Lucia",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "PM",
"code3": "",
"name": "Saint Pierre and Miquelon",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "VC",
"code3": "",
"name": "Saint Vincent and The Grenadines",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "WS",
"code3": "",
"name": "Samoa",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "SM",
"code3": "",
"name": "San Marino",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "ST",
"code3": "",
"name": "Sao Tome and Principe",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "SA",
"code3": "",
"name": "Saudi Arabia",
"majorIndex": ".TASI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "SN",
"code3": "",
"name": "Senegal",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "RS",
"code3": "",
"name": "Serbia",
"majorIndex": ".BELEXLINE",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "CS",
"code3": "",
"name": "Serbia and Montenegro",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "SC",
"code3": "",
"name": "Seychelles",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "SL",
"code3": "",
"name": "Sierra Leone",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "SG",
"code3": "",
"name": "Singapore",
"majorIndex": ".ASIN",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "SK",
"code3": "",
"name": "Slovakia",
"majorIndex": ".SAX",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "SI",
"code3": "",
"name": "Slovenia",
"majorIndex": ".SBITOP",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "SB",
"code3": "",
"name": "Solomon Islands",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "SO",
"code3": "",
"name": "Somalia",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "ZA",
"code3": "",
"name": "South Africa",
"majorIndex": ".JTOPI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "GS",
"code3": "",
"name": "South Georgia and The South Sandwich Isl",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "SU",
"code3": "",
"name": "Soviet Union",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "ES",
"code3": "",
"name": "Spain",
"majorIndex": ".IBEX",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "LK",
"code3": "",
"name": "Sri Lanka",
"majorIndex": ".CSE",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "SD",
"code3": "",
"name": "Sudan",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "SR",
"code3": "",
"name": "Suriname",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "SJ",
"code3": "",
"name": "Svalbard and Jan Mayen",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "SZ",
"code3": "",
"name": "Swaziland",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "SE",
"code3": "",
"name": "Sweden",
"majorIndex": ".OMXS30",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "CH",
"code3": "",
"name": "Switzerland",
"majorIndex": ".SSMI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "SY",
"code3": "",
"name": "Syrian Arab Republic",
"majorIndex": ".DSDWX",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "TW",
"code3": "",
"name": "Taiwan",
"majorIndex": ".TWII",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "TJ",
"code3": "",
"name": "Tajikistan",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "TZ",
"code3": "",
"name": "Tanzania United Republi",
"majorIndex": ".DSEI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "TH",
"code3": "",
"name": "Thailand",
"majorIndex": ".SETI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "TG",
"code3": "",
"name": "Togo",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "TK",
"code3": "",
"name": "Tokelau",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "TO",
"code3": "",
"name": "Tonga",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "TT",
"code3": "",
"name": "Trinidad and Tobago",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "TN",
"code3": "",
"name": "Tunisia",
"majorIndex": ".TUNINDEX",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "TR",
"code3": "",
"name": "Turkey",
"majorIndex": ".XU100",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "TM",
"code3": "",
"name": "Turkmenistan",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "TC",
"code3": "",
"name": "Turks and Caicos Islands",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "TV",
"code3": "",
"name": "Tuvalu",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "US",
"code3": "",
"name": "USA",
"majorIndex": ".SPX",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "UG",
"code3": "",
"name": "Uganda",
"majorIndex": ".ALSIUG",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "UA",
"code3": "",
"name": "Ukraine",
"majorIndex": ".PFTSI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "AE",
"code3": "",
"name": "United Arab Emirates",
"majorIndex": ".ADI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "GB",
"code3": "",
"name": "United Kingdom",
"majorIndex": ".FTSE",
"taxDate": "1231",
"fiscalYearEnd": "1231"
}, {
"code": "UM",
"code3": "",
"name": "United States Minor Outlying Islands",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "N/A",
"code3": "",
"name": "Unknown",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "UY",
"code3": "",
"name": "Uruguay",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "UZ",
"code3": "",
"name": "Uzbekistan",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "VU",
"code3": "",
"name": "Vanuatu",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "VE",
"code3": "",
"name": "Venezuela",
"majorIndex": ".IBC",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "VN",
"code3": "",
"name": "Vietnam",
"majorIndex": ".VNI",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "VG",
"code3": "",
"name": "Virgin Islands British",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "VI",
"code3": "",
"name": "Virgin Islands U.S.",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "WF",
"code3": "",
"name": "Wallis and Futuna",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "EH",
"code3": "",
"name": "Western Sahara",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "YE",
"code3": "",
"name": "Yemen",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "YU",
"code3": "",
"name": "Yugoslavia",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "ZM",
"code3": "",
"name": "Zambia",
"majorIndex": ".ALSLZ",
"taxDate": "0",
"fiscalYearEnd": "0"
}, {
"code": "ZW",
"code3": "",
"name": "Zimbabwe",
"majorIndex": "",
"taxDate": "0",
"fiscalYearEnd": "0"
}],
"settings": {
"filter": "A"
}
}
},
});
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<!-- styles -->
<link rel="stylesheet" type="text/css" href="http://angular-ui.github.com/ng-grid/css/ng-grid.css" />
<link rel="stylesheet" href="other-styles.css" />
<link rel="stylesheet" href="style.css" />
<link rel="stylesheet" type="text/css" href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css"/>
<!-- 3rd party scripts -->
<script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular-route.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular-animate.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular-resource.min.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>
<script type="text/javascript" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.4.0.js"></script>
<script src="other-scripts.js"></script>
<script type="text/javascript" src="http://angular-ui.github.com/ng-grid/lib/ng-grid.debug.js"></script>
<!-- scripts under development -->
<script src="mfmUtils.js"></script>
<script src="schema-form.js"></script>
<script src="app.js"></script>
</head>
<body id="ng-app" data-ng-app="plunker" class="preview" data-spy="scroll" data-target=".subnav" data-offset="80">
<header>
</header>
<div class="container-fluid">
<div ng-controller="HomeCtrl">
<form class="form-inline" name="form" xt-form="xtform" novalidate role="form">
<div class="row-fluid clearfix">
<h2>Sample Form</h2>
</div>
<div class="row-fluid clearfix">
<hr>
<div class="span12">
<fieldset class="span6">
<schema-form-fields
fields="side1Fields"
model="model"
schema="modelSchema"
data="requestResult"
schema-list="schema">
</schema-form-fields>
</fieldset>
<fieldset class="span6">
<schema-form-fields
fields="side2Fields"
model="model"
schema="modelSchema"
data="requestResult"
schema-list="schema">
</schema-form-fields>
</fieldset>
</div>
</div>
<div class="row-fluid clearfix">
<button
class="btn btn-primary span2 offset10"
type="submit">
Submit
</button>
</div>
</form>
</div>
<hr>
<footer id="footer">
</footer>
</div>
</body>
</html>
@import url('//fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700');
@import url('//fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic');
.clearfix {
*zoom: 1
}
.clearfix: before, .clearfix: after {
display: table;
content: '';
line-height: 0
}
.clearfix: after {
clear: both
}
.hide-text {
font: 0/0 a;
color: transparent;
text-shadow: none;
background-color: transparent;
border: 0
}
.input-block-level {
display: block;
width: 100%;
min-height: 28px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box
}
body {
font-weight: 300
}
h1 {
font-size: 50px
}
h2,
h3 {
font-size: 26px
}
h4 {
font-size: 14px
}
h5,
h6 {
font-size: 11px
}
blockquote {
padding: 10px 15px;
background-color: #eee;
border-left-color: #bbb
}
blockquote.pull-right {
padding: 10px 15px;
border-right-color: #bbb
}
blockquote small {
color: #bbb
}
.muted {
color: #bbb
}
.text-warning {
color: #ff7518
}
a.text-warning: hover {
color: #e45c00
}
.text-error {
color: #ff0039
}
a.text-error: hover {
color: #cc002e
}
.text-info {
color: #9954bb
}
a.text-info: hover {
color: #7e3f9d
}
.text-success {
color: #3fb618
}
a.text-success: hover {
color: #2f8912
}
.navbar .navbar-inner {
background-image: none;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0
}
.navbar .brand: hover {
color: #bbb
}
.navbar .nav>.active>a,
.navbar .nav>.active>a: hover, .navbar .nav>.active>a: focus {
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
background-color: rgba(0, 0, 0, 0.05)
}
.navbar .nav li.dropdown.open>.dropdown-toggle,
.navbar .nav li.dropdown.active>.dropdown-toggle,
.navbar .nav li.dropdown.open.active>.dropdown-toggle {
color: #fff
}
.navbar .nav li.dropdown.open>.dropdown-toggle: hover, .navbar .nav li.dropdown.active>.dropdown-toggle: hover, .navbar .nav li.dropdown.open.active>.dropdown-toggle: hover {
color: #eee
}
.navbar .navbar-search .search-query {
line-height: normal
}
.navbar-inverse .brand,
.navbar-inverse .nav>li>a {
text-shadow: none
}
.navbar-inverse .brand: hover, .navbar-inverse .nav>.active>a, .navbar-inverse .nav>.active>a: hover, .navbar-inverse .nav>.active>a: focus {
background-color: rgba(0, 0, 0, 0.05);
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
color: #fff
}
.navbar-inverse .navbar-search .search-query {
color: #080808
}
div.subnav {
margin: 0 1px;
background: #dfdfdf none;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
border: 0;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0
}
div.subnav .nav {
background-color: transparent
}
div.subnav .nav>li>a {
border-color: transparent
}
div.subnav .nav>.active>a,
div.subnav .nav>.active>a: hover {
border-color: transparent;
background-color: #000;
color: #fff;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none
}
div.subnav-fixed {
top: 51px;
margin: 0
}
.nav .open .dropdown-toggle,
.nav>li.dropdown.open.active>a: hover {
color: #007fff
}
.nav-tabs>li>a {
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0
}
.nav-tabs.nav-stacked>li>a: hover {
background-color: #007fff;
color: #fff
}
.nav-tabs.nav-stacked>.active>a,
.nav-tabs.nav-stacked>.active>a: hover {
background-color: #fff;
color: #bbb
}
.nav-tabs.nav-stacked>li: first-child>a, .nav-tabs.nav-stacked>li: last-child>a {
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0
}
.tabs-below>.nav-tabs>li>a,
.tabs-left>.nav-tabs>li>a,
.tabs-right>.nav-tabs>li>a {
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0
}
.nav-pills>li>a {
background-color: #dfdfdf;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
color: #000
}
.nav-pills>li>a: hover {
background-color: #000;
color: #fff
}
.nav-pills>.disabled>a,
.nav-pills>.disabled>a: hover {
background-color: #eee;
color: #999
}
.nav-list>li>a {
color: #080808
}
.nav-list>li>a: hover {
background-color: #007fff;
color: #fff;
text-shadow: none
}
.nav-list .nav-header {
color: #080808
}
.nav-list .divider {
background-color: #bbb;
border-bottom: 0
}
.pagination ul {
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none
}
.pagination ul>li>a,
.pagination ul>li>span {
margin-right: 6px;
color: #080808
}
.pagination ul>li>a: hover, .pagination ul>li>span: hover {
background-color: #080808;
color: #fff
}
.pagination ul>li: last-child>a, .pagination ul>li: last-child>span {
margin-right: 0
}
.pagination ul>.active>a,
.pagination ul>.active>span {
color: #fff
}
.pagination ul>.disabled>span,
.pagination ul>.disabled>a,
.pagination ul>.disabled>a: hover {
background-color: #eee;
color: #999
}
.pager li>a,
.pager li>span {
background-color: #dfdfdf;
border: 0;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
color: #080808
}
.pager li>a: hover, .pager li>span: hover {
background-color: #080808;
color: #fff
}
.pager .disabled>a,
.pager .disabled>a: hover, .pager .disabled>span {
background-color: #eee;
color: #999
}
.breadcrumb {
background-color: #dfdfdf
}
.breadcrumb li {
text-shadow: none
}
.breadcrumb .divider,
.breadcrumb .active {
color: #080808;
text-shadow: none
}
.btn {
padding: 5px 12px;
background-image: none;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
border: 0;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
text-shadow: none
}
.btn.disabled {
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)
}
.btn-large {
padding: 22px 30px
}
.btn-small {
padding: 2px 10px
}
.btn-mini {
padding: 2px 6px
}
.btn-group>.btn: first-child, .btn-group>.btn: last-child, .btn-group>.dropdown-toggle {
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0
}
.btn-group>.btn+.dropdown-toggle {
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none
}
.table tbody tr.success td {
color: #fff
}
.table tbody tr.error td {
color: #fff
}
.table tbody tr.info td {
color: #fff
}
.table-bordered {
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0
}
.table-bordered thead: first-child tr: first-child th: first-child, .table-bordered tbody: first-child tr: first-child td: first-child {
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0
}
.table-bordered thead: last-child tr: last-child th: first-child, .table-bordered tbody: last-child tr: last-child td: first-child, .table-bordered tfoot: last-child tr: last-child td: first-child {
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0
}
select,
textarea,
input[type="text"],
input[type="password"],
input[type="datetime"],
input[type="datetime-local"],
input[type="date"],
input[type="month"],
input[type="time"],
input[type="week"],
input[type="number"],
input[type="email"],
input[type="url"],
input[type="search"],
input[type="tel"],
input[type="color"] {
color: #080808
}
.control-group.warning .control-label,
.control-group.warning .help-block,
.control-group.warning .help-inline {
color: #ff7518
}
.control-group.warning input,
.control-group.warning select,
.control-group.warning textarea {
border-color: #ff7518;
color: #080808
}
.control-group.error .control-label,
.control-group.error .help-block,
.control-group.error .help-inline {
color: #ff0039
}
.control-group.error input,
.control-group.error select,
.control-group.error textarea {
border-color: #ff0039;
color: #080808
}
.control-group.success .control-label,
.control-group.success .help-block,
.control-group.success .help-inline {
color: #3fb618
}
.control-group.success input,
.control-group.success select,
.control-group.success textarea {
border-color: #3fb618;
color: #080808
}
legend {
border-bottom: 0;
color: #080808
}
.form-actions {
border-top: 0;
background-color: #eee
}
.dropdown-menu {
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0
}
.alert {
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
text-shadow: none
}
.alert-heading,
.alert h1,
.alert h2,
.alert h3,
.alert h4,
.alert h5,
.alert h6 {
color: #fff
}
.label {
min-width: 80px;
min-height: 80px;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
font-weight: 300;
text-shadow: none
}
.label-success {
background-color: #3fb618
}
.label-important {
background-color: #ff0039
}
.label-info {
background-color: #9954bb
}
.label-inverse {
background-color: #000
}
.badge {
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
font-weight: 300;
text-shadow: none
}
.badge-success {
background-color: #3fb618
}
.badge-important {
background-color: #ff0039
}
.badge-info {
background-color: #9954bb
}
.badge-inverse {
background-color: #000
}
.hero-unit {
border: 0;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none
}
.well {
border: 0;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none
}
[class^="icon-"],
[class*=" icon-"] {
margin: 0 2px;
vertical-align: -2px
}
a.thumbnail {
background-color: #dfdfdf
}
a.thumbnail: hover {
background-color: #bbb;
border-color: transparent
}
.progress {
height: 6px;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
background-color: #eee;
background-image: none
}
.progress .bar {
background-color: #007fff;
background-image: none
}
.progress-info {
background-color: #9954bb
}
.progress-success {
background-color: #3fb618
}
.progress-warning {
background-color: #ff7518
}
.progress-danger {
background-color: #ff0039
}
.modal {
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0
}
.modal-header {
border-bottom: 0
}
.modal-footer {
border-top: 0;
background-color: transparent
}
.popover {
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
color: #fff
}
.popover-title {
border-bottom: 0;
color: #fff
}
body {
padding-top: 50px;
padding-bottom: 20px;
font-size: 12px
}
body .modal {
width: 660px;
margin-left: -360px;
top: 5%
}
body .modal span {
margin-left: 10px
}
body .modal-body {
padding: 0 15px 15px 15px
}
.ng-table {
border: 1px solid #000
}
div.modal table>tfoot {
display: none
}
div.subnav .nav>li>a,
div.subnav .nav>.active>a,
div.subnav .nav>.active>a: hover {
color: #555
}
div.subnav-fixed {
top: 50px
}
.navbar a>i {
opacity: .5
}
.navbar a: hover>i {
opacity: 1
}
section {
margin-top: 100px
}
.subhead {
padding-bottom: 0;
margin-bottom: 9px
}
.subhead h1 {
font-size: 54px
}
.subnav {
margin-bottom: 60px;
width: 100%;
height: 36px;
background-color: #eee;
background-color: #f2f2f2;
background-image: -moz-linear-gradient(top, #f5f5f5, #eee);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#eee));
background-image: -webkit-linear-gradient(top, #f5f5f5, #eee);
background-image: -o-linear-gradient(top, #f5f5f5, #eee);
background-image: linear-gradient(to bottom, #f5f5f5, #eee);
background-repeat: repeat-x;
filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffeeeeee', GradientType=0);
border: 1px solid #e5e5e5;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0
}
.subnav .nav {
margin-bottom: 0
}
.subnav .nav>li>a {
margin: 0;
padding-top: 11px;
padding-bottom: 11px;
border-left: 1px solid #f5f5f5;
border-right: 1px solid #e5e5e5;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0
}
.subnav .nav>.active>a,
.subnav .nav>.active>a: hover {
padding-left: 13px;
color: #777;
background-color: #e9e9e9;
border-right-color: #ddd;
border-left: 0;
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.05);
-moz-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.05);
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.05)
}
.subnav .nav>.active>a .caret,
.subnav .nav>.active>a: hover .caret {
border-top-color: #777
}
.subnav .nav>li: first-child>a, .subnav .nav>li: first-child>a: hover {
border-left: 0;
padding-left: 12px;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0
}
.subnav .nav>li: last-child>a {
border-right: 0
}
.subnav .dropdown-menu {
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0
}
.ngGrid {
height: 300px
}
input[type="radio"],
input[type="checkbox"] {
margin: 1px 9px
}
.form-group.required .control-label: after {
content: "*";
color: red
}
.form-control {
width: 100%
}
.show-hide.ng-hide-add,
.show-hide.ng-hide-remove {
-webkit-transition: all linear .2s;
-moz-transition: all linear .2s;
transition: all linear .2s;
display: block!important;
position: absolute
}
.show-hide.ng-hide-add.ng-hide-add-active,
.show-hide.ng-hide-remove {
top: -8px;
display: block!important;
position: absolute;
opacity: 0
}
.show-hide.ng-hide-add,
.show-hide.ng-hide-remove.ng-hide-remove-active {
top: -16px;
opacity: 1;
display: block!important;
position: absolute
}
.field {
position: relative;
margin-bottom: 1em;
padding-bottom: 1em
}
.field>label {
position: absolute;
top: -16px;
color: #428bca;
font-size: .8em
}
.short-input {
max-width: 400px;
display: block
}
.input-append.input-block-level,
.input-prepend.input-block-level {
display: table
}
.input-append.input-block-level .add-on,
.input-prepend.input-block-level .add-on {
display: table-cell;
width: 1%
}
.input-append.input-block-level>input,
.input-prepend.input-block-level>input {
box-sizing: border-box;
display: table;
min-height: inherit;
width: 100%
}
.input-append.input-block-level>input {
border-right: 0
}
.input-prepend.input-block-level>input {
border-left: 0
}
.hero-unit h1,
.hero-unit h2,
.hero-unit h3,
.hero-unit h4,
.hero-unit h5,
.hero-unit h6 {
margin: 13px 0
}
.done-true {
text-decoration: line-through;
color: #bbb
}
ul.striped li: nth-child(odd) {
background-color: #f9f9f9
}
#loading {
background-color: #1f26b6;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
color: #fff;
font-weight: bold;
margin: 0;
max-width: 270px;
overflow: hidden;
padding: 4px 16px;
position: fixed;
right: 4px;
-webkit-box-shadow: 0 1px rgba(0, 0, 0, 0.4);
-moz-box-shadow: 0 1px rgba(0, 0, 0, 0.4);
box-shadow: 0 1px rgba(0, 0, 0, 0.4);
bottom: 4px;
z-index: 19
}
@media(max-width: 767px) {
body {
padding-top: 0
}
.subnav {
position: static;
top: auto;
z-index: auto;
width: auto;
height: auto;
background: #fff;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none
}
.subnav .nav>li {
float: none
}
.subnav .nav>li>a {
border: 0
}
.subnav .nav>li+li>a {
border-top: 1px solid #e5e5e5
}
.subnav .nav>li: first-child>a, .subnav .nav>li: first-child>a: hover {
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0
}
}
@media(min-width: 980px) {
.subnav-fixed {
position: fixed;
top: 40px;
left: 0;
right: 0;
z-index: 1020;
border-color: #d5d5d5;
border-width: 0 0 1px;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
-webkit-box-shadow: inset 0 1px 5px rgba(0, 0, 0, 0.1);
-moz-box-shadow: inset 0 1px 5px rgba(0, 0, 0, 0.1);
box-shadow: inset 0 1px 5px rgba(0, 0, 0, 0.1);
filter: progid: DXImageTransform.Microsoft.gradient(enabled=false)
}
.subnav-fixed .nav {
width: 938px;
margin: 0 auto;
padding: 0 1px
}
.subnav .nav>li: first-child>a, .subnav .nav>li: first-child>a: hover {
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0
}
}
@media(min-width: 768px) and (max-width: 979px) {
body {
padding-top: 0
}
}
@media(min-width: 1210px) {
.subnav-fixed .nav {
width: 1168px
}
}
/* responsive input-append icons */
.input-append.input-block-level,
.form-group.select .btn-group.input-block-level,
.input-prepend.input-block-level {
display: table;
}
.input-append.input-block-level .add-on,
.form-group.select .btn-group.input-block-level .dropdown-toggle,
.input-prepend.input-block-level .add-on {
display: table-cell;
width: 1%;
/* remove this if you want default bootstrap button width */
}
.input-append.input-block-level > input,
.form-group.select .btn-group.input-block-level .btn.input-block-level,
.input-prepend.input-block-level > input {
box-sizing: border-box;
/* use bootstrap mixin or include vendor variants */
display: table;
/* table-cell is not working well in Chrome for small widths */
min-height: inherit;
width: 100%;
}
.form-group.select .btn-group > .dropdown-menu {
box-sizing: border-box;
/* use bootstrap mixin or include vendor variants */
min-height: inherit;
width: 95%;
}
.form-group.select .btn-group.input-block-level .dropdown-arrow,
.form-group.select .btn-group.input-block-level .btn.input-block-level {
border: 1px solid #ccc;
-webkit-border-after: 1px solid #ccc;
-webkit-border-before: 1px solid #ccc;
-webkit-border-end: 1px solid #ccc;
-webkit-border-start: 1px solid #ccc;
}
.form-group.select .btn-group.input-block-level .dropdown-arrow {
background-color: #eee;
color: #999;
padding: 4px 7px;
}
.form-group.select .btn-group.input-block-level .btn.input-block-level {
display: table;
text-align: left;
background-color: white;
border-right: 0px none;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
transition: border linear .2s, box-shadow linear .2s;
padding: 4px 6px;
color: #080808;
}
.form-group.select .btn-group.input-block-level > input,
.input-append.input-block-level > input {
border-right: 0;
}
.input-prepend.input-block-level > input {
border-left: 0;
}
.form-group.select .btn-group.input-block-level.empty .btn.input-block-level {
color: #ccc;
text-transform: uppercase;
}
.form-group.control-group.field.error .well {
min-height: 1px;
padding: 0px;
margin-bottom: 0;
background-color: #eee;
border: 1px solid #dcdcdc;
}
input: : -webkit-input-placeholder {
color: #ccc;
text-transform: uppercase;
}
input: : -moz-placeholder {
color: #ccc;
text-transform: uppercase;
}
input: -moz-placeholder {
/* Older versions of Firefox */
color: #ccc;
text-transform: uppercase;
}
input: -ms-input-placeholder {
color: #ccc;
text-transform: uppercase;
}
.form-inline > .row-fluid > .span12 {
margin-left: 0;
}
.search.selection input[readonly],
.search.selection textarea[readonly] {
cursor: auto;
pointer-events: none;
background-color: inherit;
}
.search.selection > span {
margin: 0;
}
.gridStyle {
border: 1px solid rgb(212, 212, 212);
height: 300px;
}
.modal form {
margin: 0;
}
.modal-backdrop,
.modal-backdrop.fade.in {
opacity: 0.7;
filter: alpha(opacity=70);
background: #7A7979;
}
.ngHeaderButton {
background-color: #CFCFCF;
}
.ngHeaderButtonArrow {
border-color: #999 transparent transparent transparent;
}
.ngTopPanel {
background-color: #eee;
color: #999;
}
.ngColMenu {
background-color: #eee;
}
.input-block-level.xt-error {
border: 1px solid red;
color: red;
}
.input-block-level.xt-error: focus {
border: 1px solid red;
box-shadow: 0 0 2px red;
}
/*!
* Datepicker for Bootstrap
*
* Copyright 2012 Stefan Petre
* Improvements by Andrew Rowls
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
*/
.datepicker {
padding: 4px;
-webkit-border-radius: 0px;
-moz-border-radius: 0px;
border-radius: 0px;
direction: ltr;
/*.dow {
border-top: 1px solid #ddd !important;
}*/
}
.datepicker-inline {
width: 220px;
}
.datepicker.datepicker-rtl {
direction: rtl;
}
.datepicker.datepicker-rtl table tr td span {
float: right;
}
.datepicker-dropdown {
top: 0;
left: 0;
}
.datepicker-dropdown: before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid #ccc;
border-bottom-color: rgba(0, 0, 0, 0.2);
position: absolute;
top: -7px;
left: 6px;
}
.datepicker-dropdown: after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #ffffff;
position: absolute;
top: -6px;
left: 7px;
}
.datepicker > div {
display: none;
}
.datepicker.days div.datepicker-days {
display: block;
}
.datepicker.months div.datepicker-months {
display: block;
}
.datepicker.years div.datepicker-years {
display: block;
}
.datepicker table {
margin: 0;
}
.datepicker td,
.datepicker th {
text-align: center;
width: 20px;
height: 20px;
-webkit-border-radius: 0px;
-moz-border-radius: 0px;
border-radius: 0px;
border: none;
}
.table-striped .datepicker table tr td,
.table-striped .datepicker table tr th {
background-color: transparent;
}
.datepicker table tr td.day: hover {
background: #eeeeee;
cursor: pointer;
}
.datepicker table tr td.old,
.datepicker table tr td.new {
color: #999999;
}
.datepicker table tr td.disabled,
.datepicker table tr td.disabled: hover {
background: none;
color: #999999;
cursor: default;
}
.datepicker table tr td.today,
.datepicker table tr td.today: hover, .datepicker table tr td.today.disabled, .datepicker table tr td.today.disabled: hover {
background-color: #fde19a;
background-image: -moz-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));
background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -o-linear-gradient(top, #fdd49a, #fdf59a);
background-image: linear-gradient(top, #fdd49a, #fdf59a);
background-repeat: repeat-x;
filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);
border-color: #fdf59a #fdf59a #fbed50;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid: DXImageTransform.Microsoft.gradient(enabled=false);
color: #000;
}
.datepicker table tr td.today: hover, .datepicker table tr td.today: hover: hover, .datepicker table tr td.today.disabled: hover, .datepicker table tr td.today.disabled: hover: hover, .datepicker table tr td.today: active, .datepicker table tr td.today: hover: active, .datepicker table tr td.today.disabled: active, .datepicker table tr td.today.disabled: hover: active, .datepicker table tr td.today.active, .datepicker table tr td.today: hover.active, .datepicker table tr td.today.disabled.active, .datepicker table tr td.today.disabled: hover.active, .datepicker table tr td.today.disabled, .datepicker table tr td.today: hover.disabled, .datepicker table tr td.today.disabled.disabled, .datepicker table tr td.today.disabled: hover.disabled, .datepicker table tr td.today[disabled], .datepicker table tr td.today: hover[disabled], .datepicker table tr td.today.disabled[disabled], .datepicker table tr td.today.disabled: hover[disabled] {
background-color: #fdf59a;
}
.datepicker table tr td.today: active, .datepicker table tr td.today: hover: active, .datepicker table tr td.today.disabled: active, .datepicker table tr td.today.disabled: hover: active, .datepicker table tr td.today.active, .datepicker table tr td.today: hover.active, .datepicker table tr td.today.disabled.active, .datepicker table tr td.today.disabled: hover.active {
background-color: #fbf069 \9;
}
.datepicker table tr td.today: hover: hover {
color: #000;
}
.datepicker table tr td.today.active: hover {
color: #fff;
}
.datepicker table tr td.range,
.datepicker table tr td.range: hover, .datepicker table tr td.range.disabled, .datepicker table tr td.range.disabled: hover {
background: #eeeeee;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
}
.datepicker table tr td.range.today,
.datepicker table tr td.range.today: hover, .datepicker table tr td.range.today.disabled, .datepicker table tr td.range.today.disabled: hover {
background-color: #f3d17a;
background-image: -moz-linear-gradient(top, #f3c17a, #f3e97a);
background-image: -ms-linear-gradient(top, #f3c17a, #f3e97a);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a));
background-image: -webkit-linear-gradient(top, #f3c17a, #f3e97a);
background-image: -o-linear-gradient(top, #f3c17a, #f3e97a);
background-image: linear-gradient(top, #f3c17a, #f3e97a);
background-repeat: repeat-x;
filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#f3c17a', endColorstr='#f3e97a', GradientType=0);
border-color: #f3e97a #f3e97a #edde34;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid: DXImageTransform.Microsoft.gradient(enabled=false);
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
}
.datepicker table tr td.range.today: hover, .datepicker table tr td.range.today: hover: hover, .datepicker table tr td.range.today.disabled: hover, .datepicker table tr td.range.today.disabled: hover: hover, .datepicker table tr td.range.today: active, .datepicker table tr td.range.today: hover: active, .datepicker table tr td.range.today.disabled: active, .datepicker table tr td.range.today.disabled: hover: active, .datepicker table tr td.range.today.active, .datepicker table tr td.range.today: hover.active, .datepicker table tr td.range.today.disabled.active, .datepicker table tr td.range.today.disabled: hover.active, .datepicker table tr td.range.today.disabled, .datepicker table tr td.range.today: hover.disabled, .datepicker table tr td.range.today.disabled.disabled, .datepicker table tr td.range.today.disabled: hover.disabled, .datepicker table tr td.range.today[disabled], .datepicker table tr td.range.today: hover[disabled], .datepicker table tr td.range.today.disabled[disabled], .datepicker table tr td.range.today.disabled: hover[disabled] {
background-color: #f3e97a;
}
.datepicker table tr td.range.today: active, .datepicker table tr td.range.today: hover: active, .datepicker table tr td.range.today.disabled: active, .datepicker table tr td.range.today.disabled: hover: active, .datepicker table tr td.range.today.active, .datepicker table tr td.range.today: hover.active, .datepicker table tr td.range.today.disabled.active, .datepicker table tr td.range.today.disabled: hover.active {
background-color: #efe24b \9;
}
.datepicker table tr td.selected,
.datepicker table tr td.selected: hover, .datepicker table tr td.selected.disabled, .datepicker table tr td.selected.disabled: hover {
background-color: #9e9e9e;
background-repeat: repeat-x;
color: #fff;
}
.datepicker table tr td.selected: hover, .datepicker table tr td.selected: hover: hover, .datepicker table tr td.selected.disabled: hover, .datepicker table tr td.selected.disabled: hover: hover, .datepicker table tr td.selected: active, .datepicker table tr td.selected: hover: active, .datepicker table tr td.selected.disabled: active, .datepicker table tr td.selected.disabled: hover: active, .datepicker table tr td.selected.active, .datepicker table tr td.selected: hover.active, .datepicker table tr td.selected.disabled.active, .datepicker table tr td.selected.disabled: hover.active, .datepicker table tr td.selected.disabled, .datepicker table tr td.selected: hover.disabled, .datepicker table tr td.selected.disabled.disabled, .datepicker table tr td.selected.disabled: hover.disabled, .datepicker table tr td.selected[disabled], .datepicker table tr td.selected: hover[disabled], .datepicker table tr td.selected.disabled[disabled], .datepicker table tr td.selected.disabled: hover[disabled] {
background-color: #808080;
}
.datepicker table tr td.selected: active, .datepicker table tr td.selected: hover: active, .datepicker table tr td.selected.disabled: active, .datepicker table tr td.selected.disabled: hover: active, .datepicker table tr td.selected.active, .datepicker table tr td.selected: hover.active, .datepicker table tr td.selected.disabled.active, .datepicker table tr td.selected.disabled: hover.active {
background-color: #666666 \9;
}
.datepicker table tr td.active,
.datepicker table tr td.active: hover, .datepicker table tr td.active.disabled, .datepicker table tr td.active.disabled: hover {
background-color: #0f82f5;
background-repeat: repeat-x;
color: #fff;
}
.datepicker table tr td.active: hover, .datepicker table tr td.active: hover: hover, .datepicker table tr td.active.disabled: hover, .datepicker table tr td.active.disabled: hover: hover, .datepicker table tr td.active: active, .datepicker table tr td.active: hover: active, .datepicker table tr td.active.disabled: active, .datepicker table tr td.active.disabled: hover: active, .datepicker table tr td.active.active, .datepicker table tr td.active: hover.active, .datepicker table tr td.active.disabled.active, .datepicker table tr td.active.disabled: hover.active, .datepicker table tr td.active.disabled, .datepicker table tr td.active: hover.disabled, .datepicker table tr td.active.disabled.disabled, .datepicker table tr td.active.disabled: hover.disabled, .datepicker table tr td.active[disabled], .datepicker table tr td.active: hover[disabled], .datepicker table tr td.active.disabled[disabled], .datepicker table tr td.active.disabled: hover[disabled] {
background-color: #0044cc;
}
.datepicker table tr td.active: active, .datepicker table tr td.active: hover: active, .datepicker table tr td.active.disabled: active, .datepicker table tr td.active.disabled: hover: active, .datepicker table tr td.active.active, .datepicker table tr td.active: hover.active, .datepicker table tr td.active.disabled.active, .datepicker table tr td.active.disabled: hover.active {
background-color: #003399 \9;
}
.datepicker table tr td span {
display: block;
width: 23%;
height: 54px;
line-height: 54px;
float: left;
margin: 1%;
cursor: pointer;
-webkit-border-radius: 0px;
-moz-border-radius: 0px;
border-radius: 0px;
}
.datepicker table tr td span: hover {
background: #eeeeee;
}
.datepicker table tr td span.disabled,
.datepicker table tr td span.disabled: hover {
background: none;
color: #999999;
cursor: default;
}
.datepicker table tr td span.active,
.datepicker table tr td span.active: hover, .datepicker table tr td span.active.disabled, .datepicker table tr td span.active.disabled: hover {
background-color: #006dcc;
background-repeat: repeat-x;
color: #fff;
}
.datepicker table tr td span.active: hover, .datepicker table tr td span.active: hover: hover, .datepicker table tr td span.active.disabled: hover, .datepicker table tr td span.active.disabled: hover: hover, .datepicker table tr td span.active: active, .datepicker table tr td span.active: hover: active, .datepicker table tr td span.active.disabled: active, .datepicker table tr td span.active.disabled: hover: active, .datepicker table tr td span.active.active, .datepicker table tr td span.active: hover.active, .datepicker table tr td span.active.disabled.active, .datepicker table tr td span.active.disabled: hover.active, .datepicker table tr td span.active.disabled, .datepicker table tr td span.active: hover.disabled, .datepicker table tr td span.active.disabled.disabled, .datepicker table tr td span.active.disabled: hover.disabled, .datepicker table tr td span.active[disabled], .datepicker table tr td span.active: hover[disabled], .datepicker table tr td span.active.disabled[disabled], .datepicker table tr td span.active.disabled: hover[disabled] {
background-color: #0044cc;
}
.datepicker table tr td span.active: active, .datepicker table tr td span.active: hover: active, .datepicker table tr td span.active.disabled: active, .datepicker table tr td span.active.disabled: hover: active, .datepicker table tr td span.active.active, .datepicker table tr td span.active: hover.active, .datepicker table tr td span.active.disabled.active, .datepicker table tr td span.active.disabled: hover.active {
background-color: #003399 \9;
}
.datepicker table tr td span.old,
.datepicker table tr td span.new {
color: #999999;
}
.datepicker th.datepicker-switch {
width: 145px;
}
.datepicker thead tr: first-child th, .datepicker tfoot tr th {
cursor: pointer;
}
.datepicker thead tr: first-child th: hover, .datepicker tfoot tr th: hover {
background: #eeeeee;
}
.datepicker .cw {
font-size: 10px;
width: 12px;
padding: 0 2px 0 5px;
vertical-align: middle;
}
.datepicker thead tr: first-child th.cw {
cursor: default;
background-color: transparent;
}
.input-append.date .add-on i,
.input-prepend.date .add-on i {
display: block;
cursor: pointer;
width: 16px;
height: 16px;
}
.input-daterange input {
text-align: center;
}
.input-daterange input: first-child {
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
}
.input-daterange input: last-child {
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
}
.input-daterange .add-on {
display: inline-block;
width: auto;
min-width: 16px;
height: 18px;
padding: 4px 5px;
font-weight: normal;
line-height: 18px;
text-align: center;
text-shadow: 0 1px 0 #ffffff;
vertical-align: middle;
background-color: #eeeeee;
border: 1px solid #ccc;
margin-left: -5px;
margin-right: -5px;
}
.search.selection input[readonly],
.search.selection textarea[readonly] {
cursor: auto;
background-color: inherit;
}
.search.selection > span {
margin: 0;
}
// <script type="text/javascript" src="/Scripts/angular-ui-select2/select2.js?3ba151" type="text/javascript"></script>
/*
Copyright 2012 Igor Vaynberg
Version: @@ver@@ Timestamp: @@timestamp@@
This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU
General Public License version 2 (the "GPL License"). You may choose either license to govern your
use of this software only upon the condition that you accept all of the terms of either the Apache
License or the GPL License.
You may obtain a copy of the Apache License and the GPL License at:
http://www.apache.org/licenses/LICENSE-2.0
http://www.gnu.org/licenses/gpl-2.0.html
Unless required by applicable law or agreed to in writing, software distributed under the
Apache License or the GPL Licesnse is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the Apache License and the GPL License for
the specific language governing permissions and limitations under the Apache License and the GPL License.
*/
(function ($) {
if(typeof $.fn.each2 == "undefined") {
$.fn.extend({
/*
* 4-10 times faster .each replacement
* use it carefully, as it overrides jQuery context of element on each iteration
*/
each2 : function (c) {
var j = $([0]), i = -1, l = this.length;
while (
++i < l
&& (j.context = j[0] = this[i])
&& c.call(j[0], i, j) !== false //"this"=DOM, i=index, j=jQuery object
);
return this;
}
});
}
})(jQuery);
(function ($, undefined) {
"use strict";
/*global document, window, jQuery, console */
if (window.Select2 !== undefined) {
return;
}
var KEY, AbstractSelect2, SingleSelect2, MultiSelect2, nextUid, sizer,
lastMousePosition={x:0,y:0}, $document, scrollBarDimensions,
KEY = {
TAB: 9,
ENTER: 13,
ESC: 27,
SPACE: 32,
LEFT: 37,
UP: 38,
RIGHT: 39,
DOWN: 40,
SHIFT: 16,
CTRL: 17,
ALT: 18,
PAGE_UP: 33,
PAGE_DOWN: 34,
HOME: 36,
END: 35,
BACKSPACE: 8,
DELETE: 46,
isArrow: function (k) {
k = k.which ? k.which : k;
switch (k) {
case KEY.LEFT:
case KEY.RIGHT:
case KEY.UP:
case KEY.DOWN:
return true;
}
return false;
},
isControl: function (e) {
var k = e.which;
switch (k) {
case KEY.SHIFT:
case KEY.CTRL:
case KEY.ALT:
return true;
}
if (e.metaKey) return true;
return false;
},
isFunctionKey: function (k) {
k = k.which ? k.which : k;
return k >= 112 && k <= 123;
}
},
MEASURE_SCROLLBAR_TEMPLATE = "<div class='select2-measure-scrollbar'></div>";
$document = $(document);
nextUid=(function() { var counter=1; return function() { return counter++; }; }());
function indexOf(value, array) {
var i = 0, l = array.length;
for (; i < l; i = i + 1) {
if (equal(value, array[i])) return i;
}
return -1;
}
function measureScrollbar () {
var $template = $( MEASURE_SCROLLBAR_TEMPLATE );
$template.appendTo('body');
var dim = {
width: $template.width() - $template[0].clientWidth,
height: $template.height() - $template[0].clientHeight
};
$template.remove();
return dim;
}
/**
* Compares equality of a and b
* @param a
* @param b
*/
function equal(a, b) {
if (a === b) return true;
if (a === undefined || b === undefined) return false;
if (a === null || b === null) return false;
// Check whether 'a' or 'b' is a string (primitive or object).
// The concatenation of an empty string (+'') converts its argument to a string's primitive.
if (a.constructor === String) return a+'' === b+''; // a+'' - in case 'a' is a String object
if (b.constructor === String) return b+'' === a+''; // b+'' - in case 'b' is a String object
return false;
}
/**
* Splits the string into an array of values, trimming each value. An empty array is returned for nulls or empty
* strings
* @param string
* @param separator
*/
function splitVal(string, separator) {
var val, i, l;
if (string === null || string.length < 1) return [];
val = string.split(separator);
for (i = 0, l = val.length; i < l; i = i + 1) val[i] = $.trim(val[i]);
return val;
}
function getSideBorderPadding(element) {
return element.outerWidth(false) - element.width();
}
function installKeyUpChangeEvent(element) {
var key="keyup-change-value";
element.on("keydown", function () {
if ($.data(element, key) === undefined) {
$.data(element, key, element.val());
}
});
element.on("keyup", function () {
var val= $.data(element, key);
if (val !== undefined && element.val() !== val) {
$.removeData(element, key);
element.trigger("keyup-change");
}
});
}
$document.on("mousemove", function (e) {
lastMousePosition.x = e.pageX;
lastMousePosition.y = e.pageY;
});
/**
* filters mouse events so an event is fired only if the mouse moved.
*
* filters out mouse events that occur when mouse is stationary but
* the elements under the pointer are scrolled.
*/
function installFilteredMouseMove(element) {
element.on("mousemove", function (e) {
var lastpos = lastMousePosition;
if (lastpos === undefined || lastpos.x !== e.pageX || lastpos.y !== e.pageY) {
$(e.target).trigger("mousemove-filtered", e);
}
});
}
/**
* Debounces a function. Returns a function that calls the original fn function only if no invocations have been made
* within the last quietMillis milliseconds.
*
* @param quietMillis number of milliseconds to wait before invoking fn
* @param fn function to be debounced
* @param ctx object to be used as this reference within fn
* @return debounced version of fn
*/
function debounce(quietMillis, fn, ctx) {
ctx = ctx || undefined;
var timeout;
return function () {
var args = arguments;
window.clearTimeout(timeout);
timeout = window.setTimeout(function() {
fn.apply(ctx, args);
}, quietMillis);
};
}
/**
* A simple implementation of a thunk
* @param formula function used to lazily initialize the thunk
* @return {Function}
*/
function thunk(formula) {
var evaluated = false,
value;
return function() {
if (evaluated === false) { value = formula(); evaluated = true; }
return value;
};
};
function installDebouncedScroll(threshold, element) {
var notify = debounce(threshold, function (e) { element.trigger("scroll-debounced", e);});
element.on("scroll", function (e) {
if (indexOf(e.target, element.get()) >= 0) notify(e);
});
}
function focus($el) {
if ($el[0] === document.activeElement) return;
/* set the focus in a 0 timeout - that way the focus is set after the processing
of the current event has finished - which seems like the only reliable way
to set focus */
window.setTimeout(function() {
var el=$el[0], pos=$el.val().length, range;
$el.focus();
/* make sure el received focus so we do not error out when trying to manipulate the caret.
sometimes modals or others listeners may steal it after its set */
if ($el.is(":visible") && el === document.activeElement) {
/* after the focus is set move the caret to the end, necessary when we val()
just before setting focus */
if(el.setSelectionRange)
{
el.setSelectionRange(pos, pos);
}
else if (el.createTextRange) {
range = el.createTextRange();
range.collapse(false);
range.select();
}
}
}, 0);
}
function getCursorInfo(el) {
el = $(el)[0];
var offset = 0;
var length = 0;
if ('selectionStart' in el) {
offset = el.selectionStart;
length = el.selectionEnd - offset;
} else if ('selection' in document) {
el.focus();
var sel = document.selection.createRange();
length = document.selection.createRange().text.length;
sel.moveStart('character', -el.value.length);
offset = sel.text.length - length;
}
return { offset: offset, length: length };
}
function killEvent(event) {
event.preventDefault();
event.stopPropagation();
}
function killEventImmediately(event) {
event.preventDefault();
event.stopImmediatePropagation();
}
function measureTextWidth(e) {
if (!sizer){
var style = e[0].currentStyle || window.getComputedStyle(e[0], null);
sizer = $(document.createElement("div")).css({
position: "absolute",
left: "-10000px",
top: "-10000px",
display: "none",
fontSize: style.fontSize,
fontFamily: style.fontFamily,
fontStyle: style.fontStyle,
fontWeight: style.fontWeight,
letterSpacing: style.letterSpacing,
textTransform: style.textTransform,
whiteSpace: "nowrap"
});
sizer.attr("class","select2-sizer");
$("body").append(sizer);
}
sizer.text(e.val());
return sizer.width();
}
function syncCssClasses(dest, src, adapter) {
var classes, replacements = [], adapted;
classes = dest.attr("class");
if (classes) {
classes = '' + classes; // for IE which returns object
$(classes.split(" ")).each2(function() {
if (this.indexOf("select2-") === 0) {
replacements.push(this);
}
});
}
classes = src.attr("class");
if (classes) {
classes = '' + classes; // for IE which returns object
$(classes.split(" ")).each2(function() {
if (this.indexOf("select2-") !== 0) {
adapted = adapter(this);
if (adapted) {
replacements.push(this);
}
}
});
}
dest.attr("class", replacements.join(" "));
}
function markMatch(text, term, markup, escapeMarkup) {
var match=text.toUpperCase().indexOf(term.toUpperCase()),
tl=term.length;
if (match<0) {
markup.push(escapeMarkup(text));
return;
}
markup.push(escapeMarkup(text.substring(0, match)));
markup.push("<span class='select2-match'>");
markup.push(escapeMarkup(text.substring(match, match + tl)));
markup.push("</span>");
markup.push(escapeMarkup(text.substring(match + tl, text.length)));
}
function defaultEscapeMarkup(markup) {
var replace_map = {
'\\': '\',
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
"/": '/'
};
return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
return replace_map[match];
});
}
/**
* Produces an ajax-based query function
*
* @param options object containing configuration paramters
* @param options.params parameter map for the transport ajax call, can contain such options as cache, jsonpCallback, etc. see $.ajax
* @param options.transport function that will be used to execute the ajax request. must be compatible with parameters supported by $.ajax
* @param options.url url for the data
* @param options.data a function(searchTerm, pageNumber, context) that should return an object containing query string parameters for the above url.
* @param options.dataType request data type: ajax, jsonp, other datatatypes supported by jQuery's $.ajax function or the transport function if specified
* @param options.quietMillis (optional) milliseconds to wait before making the ajaxRequest, helps debounce the ajax function if invoked too often
* @param options.results a function(remoteData, pageNumber) that converts data returned form the remote request to the format expected by Select2.
* The expected format is an object containing the following keys:
* results array of objects that will be used as choices
* more (optional) boolean indicating whether there are more results available
* Example: {results:[{id:1, text:'Red'},{id:2, text:'Blue'}], more:true}
*/
function ajax(options) {
var timeout, // current scheduled but not yet executed request
requestSequence = 0, // sequence used to drop out-of-order responses
handler = null,
quietMillis = options.quietMillis || 100,
ajaxUrl = options.url,
self = this;
return function (query) {
window.clearTimeout(timeout);
timeout = window.setTimeout(function () {
requestSequence += 1; // increment the sequence
var requestNumber = requestSequence, // this request's sequence number
data = options.data, // ajax data function
url = ajaxUrl, // ajax url string or function
transport = options.transport || $.fn.select2.ajaxDefaults.transport,
// deprecated - to be removed in 4.0 - use params instead
deprecated = {
type: options.type || 'GET', // set type of request (GET or POST)
cache: options.cache || false,
jsonpCallback: options.jsonpCallback||undefined,
dataType: options.dataType||"json"
},
params = $.extend({}, $.fn.select2.ajaxDefaults.params, deprecated);
data = data ? data.call(self, query.term, query.page, query.context) : null;
url = (typeof url === 'function') ? url.call(self, query.term, query.page, query.context) : url;
if (handler) { handler.abort(); }
if (options.params) {
if ($.isFunction(options.params)) {
$.extend(params, options.params.call(self));
} else {
$.extend(params, options.params);
}
}
$.extend(params, {
url: url,
dataType: options.dataType,
data: data,
success: function (data) {
if (requestNumber < requestSequence) {
return;
}
// TODO - replace query.page with query so users have access to term, page, etc.
var results = options.results(data, query.page);
query.callback(results);
}
});
handler = transport.call(self, params);
}, quietMillis);
};
}
/**
* Produces a query function that works with a local array
*
* @param options object containing configuration parameters. The options parameter can either be an array or an
* object.
*
* If the array form is used it is assumed that it contains objects with 'id' and 'text' keys.
*
* If the object form is used ti is assumed that it contains 'data' and 'text' keys. The 'data' key should contain
* an array of objects that will be used as choices. These objects must contain at least an 'id' key. The 'text'
* key can either be a String in which case it is expected that each element in the 'data' array has a key with the
* value of 'text' which will be used to match choices. Alternatively, text can be a function(item) that can extract
* the text.
*/
function local(options) {
var data = options, // data elements
dataText,
tmp,
text = function (item) { return ""+item.text; }; // function used to retrieve the text portion of a data item that is matched against the search
if ($.isArray(data)) {
tmp = data;
data = { results: tmp };
}
if ($.isFunction(data) === false) {
tmp = data;
data = function() { return tmp; };
}
var dataItem = data();
if (dataItem.text) {
text = dataItem.text;
// if text is not a function we assume it to be a key name
if (!$.isFunction(text)) {
dataText = dataItem.text; // we need to store this in a separate variable because in the next step data gets reset and data.text is no longer available
text = function (item) { return item[dataText]; };
}
}
return function (query) {
var t = query.term, filtered = { results: [] }, process;
if (t === "") {
query.callback(data());
return;
}
process = function(datum, collection) {
var group, attr;
datum = datum[0];
if (datum.children) {
group = {};
for (attr in datum) {
if (datum.hasOwnProperty(attr)) group[attr]=datum[attr];
}
group.children=[];
$(datum.children).each2(function(i, childDatum) { process(childDatum, group.children); });
if (group.children.length || query.matcher(t, text(group), datum)) {
collection.push(group);
}
} else {
if (query.matcher(t, text(datum), datum)) {
collection.push(datum);
}
}
};
$(data().results).each2(function(i, datum) { process(datum, filtered.results); });
query.callback(filtered);
};
}
// TODO javadoc
function tags(data) {
var isFunc = $.isFunction(data);
return function (query) {
var t = query.term, filtered = {results: []};
$(isFunc ? data() : data).each(function () {
var isObject = this.text !== undefined,
text = isObject ? this.text : this;
if (t === "" || query.matcher(t, text)) {
filtered.results.push(isObject ? this : {id: this, text: this});
}
});
query.callback(filtered);
};
}
/**
* Checks if the formatter function should be used.
*
* Throws an error if it is not a function. Returns true if it should be used,
* false if no formatting should be performed.
*
* @param formatter
*/
function checkFormatter(formatter, formatterName) {
if ($.isFunction(formatter)) return true;
if (!formatter) return false;
throw new Error(formatterName +" must be a function or a falsy value");
}
function evaluate(val) {
return $.isFunction(val) ? val() : val;
}
function countResults(results) {
var count = 0;
$.each(results, function(i, item) {
if (item.children) {
count += countResults(item.children);
} else {
count++;
}
});
return count;
}
/**
* Default tokenizer. This function uses breaks the input on substring match of any string from the
* opts.tokenSeparators array and uses opts.createSearchChoice to create the choice object. Both of those
* two options have to be defined in order for the tokenizer to work.
*
* @param input text user has typed so far or pasted into the search field
* @param selection currently selected choices
* @param selectCallback function(choice) callback tho add the choice to selection
* @param opts select2's opts
* @return undefined/null to leave the current input unchanged, or a string to change the input to the returned value
*/
function defaultTokenizer(input, selection, selectCallback, opts) {
var original = input, // store the original so we can compare and know if we need to tell the search to update its text
dupe = false, // check for whether a token we extracted represents a duplicate selected choice
token, // token
index, // position at which the separator was found
i, l, // looping variables
separator; // the matched separator
if (!opts.createSearchChoice || !opts.tokenSeparators || opts.tokenSeparators.length < 1) return undefined;
while (true) {
index = -1;
for (i = 0, l = opts.tokenSeparators.length; i < l; i++) {
separator = opts.tokenSeparators[i];
index = input.indexOf(separator);
if (index >= 0) break;
}
if (index < 0) break; // did not find any token separator in the input string, bail
token = input.substring(0, index);
input = input.substring(index + separator.length);
if (token.length > 0) {
token = opts.createSearchChoice.call(this, token, selection);
if (token !== undefined && token !== null && opts.id(token) !== undefined && opts.id(token) !== null) {
dupe = false;
for (i = 0, l = selection.length; i < l; i++) {
if (equal(opts.id(token), opts.id(selection[i]))) {
dupe = true; break;
}
}
if (!dupe) selectCallback(token);
}
}
}
if (original!==input) return input;
}
/**
* Creates a new class
*
* @param superClass
* @param methods
*/
function clazz(SuperClass, methods) {
var constructor = function () {};
constructor.prototype = new SuperClass;
constructor.prototype.constructor = constructor;
constructor.prototype.parent = SuperClass.prototype;
constructor.prototype = $.extend(constructor.prototype, methods);
return constructor;
}
AbstractSelect2 = clazz(Object, {
// abstract
bind: function (func) {
var self = this;
return function () {
func.apply(self, arguments);
};
},
// abstract
init: function (opts) {
var results, search, resultsSelector = ".select2-results", disabled, readonly;
// prepare options
this.opts = opts = this.prepareOpts(opts);
this.id=opts.id;
// destroy if called on an existing component
if (opts.element.data("select2") !== undefined &&
opts.element.data("select2") !== null) {
opts.element.data("select2").destroy();
}
this.container = this.createContainer();
this.containerId="s2id_"+(opts.element.attr("id") || "autogen"+nextUid());
this.containerSelector="#"+this.containerId.replace(/([;&,\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g, '\\$1');
this.container.attr("id", this.containerId);
// cache the body so future lookups are cheap
this.body = thunk(function() { return opts.element.closest("body"); });
syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass);
this.container.css(evaluate(opts.containerCss));
this.container.addClass(evaluate(opts.containerCssClass));
this.elementTabIndex = this.opts.element.attr("tabindex");
// swap container for the element
this.opts.element
.data("select2", this)
.attr("tabindex", "-1")
.before(this.container);
this.container.data("select2", this);
this.dropdown = this.container.find(".select2-drop");
this.dropdown.addClass(evaluate(opts.dropdownCssClass));
this.dropdown.data("select2", this);
this.results = results = this.container.find(resultsSelector);
this.search = search = this.container.find("input.select2-input");
this.resultsPage = 0;
this.context = null;
// initialize the container
this.initContainer();
installFilteredMouseMove(this.results);
this.dropdown.on("mousemove-filtered touchstart touchmove touchend", resultsSelector, this.bind(this.highlightUnderEvent));
installDebouncedScroll(80, this.results);
this.dropdown.on("scroll-debounced", resultsSelector, this.bind(this.loadMoreIfNeeded));
// do not propagate change event from the search field out of the component
$(this.container).on("change", ".select2-input", function(e) {e.stopPropagation();});
$(this.dropdown).on("change", ".select2-input", function(e) {e.stopPropagation();});
// if jquery.mousewheel plugin is installed we can prevent out-of-bounds scrolling of results via mousewheel
if ($.fn.mousewheel) {
results.mousewheel(function (e, delta, deltaX, deltaY) {
var top = results.scrollTop(), height;
if (deltaY > 0 && top - deltaY <= 0) {
results.scrollTop(0);
killEvent(e);
} else if (deltaY < 0 && results.get(0).scrollHeight - results.scrollTop() + deltaY <= results.height()) {
results.scrollTop(results.get(0).scrollHeight - results.height());
killEvent(e);
}
});
}
installKeyUpChangeEvent(search);
search.on("keyup-change input paste", this.bind(this.updateResults));
search.on("focus", function () { search.addClass("select2-focused"); });
search.on("blur", function () { search.removeClass("select2-focused");});
this.dropdown.on("mouseup", resultsSelector, this.bind(function (e) {
if ($(e.target).closest(".select2-result-selectable").length > 0) {
this.highlightUnderEvent(e);
this.selectHighlighted(e);
}
}));
// trap all mouse events from leaving the dropdown. sometimes there may be a modal that is listening
// for mouse events outside of itself so it can close itself. since the dropdown is now outside the select2's
// dom it will trigger the popup close, which is not what we want
this.dropdown.on("click mouseup mousedown", function (e) { e.stopPropagation(); });
if ($.isFunction(this.opts.initSelection)) {
// initialize selection based on the current value of the source element
this.initSelection();
// if the user has provided a function that can set selection based on the value of the source element
// we monitor the change event on the element and trigger it, allowing for two way synchronization
this.monitorSource();
}
if (opts.maximumInputLength !== null) {
this.search.attr("maxlength", opts.maximumInputLength);
}
var disabled = opts.element.prop("disabled");
if (disabled === undefined) disabled = false;
this.enable(!disabled);
var readonly = opts.element.prop("readonly");
if (readonly === undefined) readonly = false;
this.readonly(readonly);
// Calculate size of scrollbar
scrollBarDimensions = scrollBarDimensions || measureScrollbar();
this.autofocus = opts.element.prop("autofocus")
opts.element.prop("autofocus", false);
if (this.autofocus) this.focus();
},
// abstract
destroy: function () {
var element=this.opts.element, select2 = element.data("select2");
if (this.propertyObserver) { delete this.propertyObserver; this.propertyObserver = null; }
if (select2 !== undefined) {
select2.container.remove();
select2.dropdown.remove();
element
.removeClass("select2-offscreen")
.removeData("select2")
.off(".select2")
.prop("autofocus", this.autofocus || false);
if (this.elementTabIndex) {
element.attr({tabindex: this.elementTabIndex});
} else {
element.removeAttr("tabindex");
}
element.show();
}
},
// abstract
optionToData: function(element) {
if (element.is("option")) {
return {
id:element.prop("value"),
text:element.text(),
element: element.get(),
css: element.attr("class"),
disabled: element.prop("disabled"),
locked: equal(element.attr("locked"), "locked") || equal(element.data("locked"), true)
};
} else if (element.is("optgroup")) {
return {
text:element.attr("label"),
children:[],
element: element.get(),
css: element.attr("class")
};
}
},
// abstract
prepareOpts: function (opts) {
var element, select, idKey, ajaxUrl, self = this;
element = opts.element;
if (element.get(0).tagName.toLowerCase() === "select") {
this.select = select = opts.element;
}
if (select) {
// these options are not allowed when attached to a select because they are picked up off the element itself
$.each(["id", "multiple", "ajax", "query", "createSearchChoice", "initSelection", "data", "tags"], function () {
if (this in opts) {
throw new Error("Option '" + this + "' is not allowed for Select2 when attached to a <select> element.");
}
});
}
opts = $.extend({}, {
populateResults: function(container, results, query) {
var populate, data, result, children, id=this.opts.id;
populate=function(results, container, depth) {
var i, l, result, selectable, disabled, compound, node, label, innerContainer, formatted;
results = opts.sortResults(results, container, query);
for (i = 0, l = results.length; i < l; i = i + 1) {
result=results[i];
disabled = (result.disabled === true);
selectable = (!disabled) && (id(result) !== undefined);
compound=result.children && result.children.length > 0;
node=$("<li></li>");
node.addClass("select2-results-dept-"+depth);
node.addClass("select2-result");
node.addClass(selectable ? "select2-result-selectable" : "select2-result-unselectable");
if (disabled) { node.addClass("select2-disabled"); }
if (compound) { node.addClass("select2-result-with-children"); }
node.addClass(self.opts.formatResultCssClass(result));
label=$(document.createElement("div"));
label.addClass("select2-result-label");
formatted=opts.formatResult(result, label, query, self.opts.escapeMarkup);
if (formatted!==undefined) {
label.html(formatted);
}
node.append(label);
if (compound) {
innerContainer=$("<ul></ul>");
innerContainer.addClass("select2-result-sub");
populate(result.children, innerContainer, depth+1);
node.append(innerContainer);
}
node.data("select2-data", result);
container.append(node);
}
};
populate(results, container, 0);
}
}, $.fn.select2.defaults, opts);
if (typeof(opts.id) !== "function") {
idKey = opts.id;
opts.id = function (e) { return e[idKey]; };
}
if ($.isArray(opts.element.data("select2Tags"))) {
if ("tags" in opts) {
throw "tags specified as both an attribute 'data-select2-tags' and in options of Select2 " + opts.element.attr("id");
}
opts.tags=opts.element.data("select2Tags");
}
if (select) {
opts.query = this.bind(function (query) {
var data = { results: [], more: false },
term = query.term,
children, placeholderOption, process;
process=function(element, collection) {
var group;
if (element.is("option")) {
if (query.matcher(term, element.text(), element)) {
collection.push(self.optionToData(element));
}
} else if (element.is("optgroup")) {
group=self.optionToData(element);
element.children().each2(function(i, elm) { process(elm, group.children); });
if (group.children.length>0) {
collection.push(group);
}
}
};
children=element.children();
// ignore the placeholder option if there is one
if (this.getPlaceholder() !== undefined && children.length > 0) {
placeholderOption = this.getPlaceholderOption();
if (placeholderOption) {
children=children.not(placeholderOption);
}
}
children.each2(function(i, elm) { process(elm, data.results); });
query.callback(data);
});
// this is needed because inside val() we construct choices from options and there id is hardcoded
opts.id=function(e) { return e.id; };
opts.formatResultCssClass = function(data) { return data.css; };
} else {
if (!("query" in opts)) {
if ("ajax" in opts) {
ajaxUrl = opts.element.data("ajax-url");
if (ajaxUrl && ajaxUrl.length > 0) {
opts.ajax.url = ajaxUrl;
}
opts.query = ajax.call(opts.element, opts.ajax);
} else if ("data" in opts) {
opts.query = local(opts.data);
} else if ("tags" in opts) {
opts.query = tags(opts.tags);
if (opts.createSearchChoice === undefined) {
opts.createSearchChoice = function (term) { return {id: term, text: term}; };
}
if (opts.initSelection === undefined) {
opts.initSelection = function (element, callback) {
var data = [];
$(splitVal(element.val(), opts.separator)).each(function () {
var id = this, text = this, tags=opts.tags;
if ($.isFunction(tags)) tags=tags();
$(tags).each(function() { if (equal(this.id, id)) { text = this.text; return false; } });
data.push({id: id, text: text});
});
callback(data);
};
}
}
}
}
if (typeof(opts.query) !== "function") {
throw "query function not defined for Select2 " + opts.element.attr("id");
}
return opts;
},
/**
* Monitor the original element for changes and update select2 accordingly
*/
// abstract
monitorSource: function () {
var el = this.opts.element, sync;
el.on("change.select2", this.bind(function (e) {
if (this.opts.element.data("select2-change-triggered") !== true) {
this.initSelection();
}
}));
sync = this.bind(function () {
var enabled, readonly, self = this;
// sync enabled state
var disabled = el.prop("disabled");
if (disabled === undefined) disabled = false;
this.enable(!disabled);
var readonly = el.prop("readonly");
if (readonly === undefined) readonly = false;
this.readonly(readonly);
syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass);
this.container.addClass(evaluate(this.opts.containerCssClass));
syncCssClasses(this.dropdown, this.opts.element, this.opts.adaptDropdownCssClass);
this.dropdown.addClass(evaluate(this.opts.dropdownCssClass));
});
// mozilla and IE
el.on("propertychange.select2 DOMAttrModified.select2", sync);
// hold onto a reference of the callback to work around a chromium bug
if (this.mutationCallback === undefined) {
this.mutationCallback = function (mutations) {
mutations.forEach(sync);
}
}
// safari and chrome
if (typeof WebKitMutationObserver !== "undefined") {
if (this.propertyObserver) { delete this.propertyObserver; this.propertyObserver = null; }
this.propertyObserver = new WebKitMutationObserver(this.mutationCallback);
this.propertyObserver.observe(el.get(0), { attributes:true, subtree:false });
}
},
// abstract
triggerSelect: function(data) {
var evt = $.Event("select2-selecting", { val: this.id(data), object: data });
this.opts.element.trigger(evt);
return !evt.isDefaultPrevented();
},
/**
* Triggers the change event on the source element
*/
// abstract
triggerChange: function (details) {
details = details || {};
details= $.extend({}, details, { type: "change", val: this.val() });
// prevents recursive triggering
this.opts.element.data("select2-change-triggered", true);
this.opts.element.trigger(details);
this.opts.element.data("select2-change-triggered", false);
// some validation frameworks ignore the change event and listen instead to keyup, click for selects
// so here we trigger the click event manually
this.opts.element.click();
// ValidationEngine ignorea the change event and listens instead to blur
// so here we trigger the blur event manually if so desired
if (this.opts.blurOnChange)
this.opts.element.blur();
},
//abstract
isInterfaceEnabled: function()
{
return this.enabledInterface === true;
},
// abstract
enableInterface: function() {
var enabled = this._enabled && !this._readonly,
disabled = !enabled;
if (enabled === this.enabledInterface) return false;
this.container.toggleClass("select2-container-disabled", disabled);
this.close();
this.enabledInterface = enabled;
return true;
},
// abstract
enable: function(enabled) {
if (enabled === undefined) enabled = true;
if (this._enabled === enabled) return false;
this._enabled = enabled;
this.opts.element.prop("disabled", !enabled);
this.enableInterface();
return true;
},
// abstract
readonly: function(enabled) {
if (enabled === undefined) enabled = false;
if (this._readonly === enabled) return false;
this._readonly = enabled;
this.opts.element.prop("readonly", enabled);
this.enableInterface();
return true;
},
// abstract
opened: function () {
return this.container.hasClass("select2-dropdown-open");
},
// abstract
positionDropdown: function() {
var $dropdown = this.dropdown,
offset = this.container.offset(),
height = this.container.outerHeight(false),
width = this.container.outerWidth(false),
dropHeight = $dropdown.outerHeight(false),
viewPortRight = $(window).scrollLeft() + $(window).width(),
viewportBottom = $(window).scrollTop() + $(window).height(),
dropTop = offset.top + height,
dropLeft = offset.left,
enoughRoomBelow = dropTop + dropHeight <= viewportBottom,
enoughRoomAbove = (offset.top - dropHeight) >= this.body().scrollTop(),
dropWidth = $dropdown.outerWidth(false),
enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight,
aboveNow = $dropdown.hasClass("select2-drop-above"),
bodyOffset,
above,
css,
resultsListNode;
if (this.opts.dropdownAutoWidth) {
resultsListNode = $('.select2-results', $dropdown)[0];
$dropdown.addClass('select2-drop-auto-width');
$dropdown.css('width', '');
// Add scrollbar width to dropdown if vertical scrollbar is present
dropWidth = $dropdown.outerWidth(false) + (resultsListNode.scrollHeight === resultsListNode.clientHeight ? 0 : scrollBarDimensions.width);
dropWidth > width ? width = dropWidth : dropWidth = width;
enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight;
}
else {
this.container.removeClass('select2-drop-auto-width');
}
//console.log("below/ droptop:", dropTop, "dropHeight", dropHeight, "sum", (dropTop+dropHeight)+" viewport bottom", viewportBottom, "enough?", enoughRoomBelow);
//console.log("above/ offset.top", offset.top, "dropHeight", dropHeight, "top", (offset.top-dropHeight), "scrollTop", this.body().scrollTop(), "enough?", enoughRoomAbove);
// fix positioning when body has an offset and is not position: static
if (this.body().css('position') !== 'static') {
bodyOffset = this.body().offset();
dropTop -= bodyOffset.top;
dropLeft -= bodyOffset.left;
}
// always prefer the current above/below alignment, unless there is not enough room
if (aboveNow) {
above = true;
if (!enoughRoomAbove && enoughRoomBelow) above = false;
} else {
above = false;
if (!enoughRoomBelow && enoughRoomAbove) above = true;
}
if (!enoughRoomOnRight) {
dropLeft = offset.left + width - dropWidth;
}
if (above) {
dropTop = offset.top - dropHeight;
this.container.addClass("select2-drop-above");
$dropdown.addClass("select2-drop-above");
}
else {
this.container.removeClass("select2-drop-above");
$dropdown.removeClass("select2-drop-above");
}
css = $.extend({
top: dropTop,
left: dropLeft,
width: width
}, evaluate(this.opts.dropdownCss));
$dropdown.css(css);
},
// abstract
shouldOpen: function() {
var event;
if (this.opened()) return false;
if (this._enabled === false || this._readonly === true) return false;
event = $.Event("select2-opening");
this.opts.element.trigger(event);
return !event.isDefaultPrevented();
},
// abstract
clearDropdownAlignmentPreference: function() {
// clear the classes used to figure out the preference of where the dropdown should be opened
this.container.removeClass("select2-drop-above");
this.dropdown.removeClass("select2-drop-above");
},
/**
* Opens the dropdown
*
* @return {Boolean} whether or not dropdown was opened. This method will return false if, for example,
* the dropdown is already open, or if the 'open' event listener on the element called preventDefault().
*/
// abstract
open: function () {
if (!this.shouldOpen()) return false;
this.opening();
return true;
},
/**
* Performs the opening of the dropdown
*/
// abstract
opening: function() {
var cid = this.containerId,
scroll = "scroll." + cid,
resize = "resize."+cid,
orient = "orientationchange."+cid,
mask, maskCss;
this.container.addClass("select2-dropdown-open").addClass("select2-container-active");
this.clearDropdownAlignmentPreference();
if(this.dropdown[0] !== this.body().children().last()[0]) {
this.dropdown.detach().appendTo(this.body());
}
// create the dropdown mask if doesnt already exist
mask = $("#select2-drop-mask");
if (mask.length == 0) {
mask = $(document.createElement("div"));
mask.attr("id","select2-drop-mask").attr("class","select2-drop-mask");
mask.hide();
mask.appendTo(this.body());
mask.on("mousedown touchstart click", function (e) {
var dropdown = $("#select2-drop"), self;
if (dropdown.length > 0) {
self=dropdown.data("select2");
if (self.opts.selectOnBlur) {
self.selectHighlighted({noFocus: true});
}
self.close();
e.preventDefault();
e.stopPropagation();
}
});
}
// ensure the mask is always right before the dropdown
if (this.dropdown.prev()[0] !== mask[0]) {
this.dropdown.before(mask);
}
// move the global id to the correct dropdown
$("#select2-drop").removeAttr("id");
this.dropdown.attr("id", "select2-drop");
// show the elements
maskCss=_makeMaskCss();
mask.css(maskCss).show();
this.dropdown.show();
this.positionDropdown();
this.dropdown.addClass("select2-drop-active");
// attach listeners to events that can change the position of the container and thus require
// the position of the dropdown to be updated as well so it does not come unglued from the container
var that = this;
this.container.parents().add(window).each(function () {
$(this).on(resize+" "+scroll+" "+orient, function (e) {
var maskCss=_makeMaskCss();
$("#select2-drop-mask").css(maskCss);
that.positionDropdown();
});
});
function _makeMaskCss() {
return {
width : Math.max(document.documentElement.scrollWidth, $(window).width()),
height : Math.max(document.documentElement.scrollHeight, $(window).height())
}
}
},
// abstract
close: function () {
if (!this.opened()) return;
var cid = this.containerId,
scroll = "scroll." + cid,
resize = "resize."+cid,
orient = "orientationchange."+cid;
// unbind event listeners
this.container.parents().add(window).each(function () { $(this).off(scroll).off(resize).off(orient); });
this.clearDropdownAlignmentPreference();
$("#select2-drop-mask").hide();
this.dropdown.removeAttr("id"); // only the active dropdown has the select2-drop id
this.dropdown.hide();
this.container.removeClass("select2-dropdown-open");
this.results.empty();
this.clearSearch();
this.search.removeClass("select2-active");
this.opts.element.trigger($.Event("select2-close"));
},
/**
* Opens control, sets input value, and updates results.
*/
// abstract
externalSearch: function (term) {
this.open();
this.search.val(term);
this.updateResults(false);
},
// abstract
clearSearch: function () {
},
//abstract
getMaximumSelectionSize: function() {
return evaluate(this.opts.maximumSelectionSize);
},
// abstract
ensureHighlightVisible: function () {
var results = this.results, children, index, child, hb, rb, y, more;
index = this.highlight();
if (index < 0) return;
if (index == 0) {
// if the first element is highlighted scroll all the way to the top,
// that way any unselectable headers above it will also be scrolled
// into view
results.scrollTop(0);
return;
}
children = this.findHighlightableChoices().find('.select2-result-label');
child = $(children[index]);
hb = child.offset().top + child.outerHeight(true);
// if this is the last child lets also make sure select2-more-results is visible
if (index === children.length - 1) {
more = results.find("li.select2-more-results");
if (more.length > 0) {
hb = more.offset().top + more.outerHeight(true);
}
}
rb = results.offset().top + results.outerHeight(true);
if (hb > rb) {
results.scrollTop(results.scrollTop() + (hb - rb));
}
y = child.offset().top - results.offset().top;
// make sure the top of the element is visible
if (y < 0 && child.css('display') != 'none' ) {
results.scrollTop(results.scrollTop() + y); // y is negative
}
},
// abstract
findHighlightableChoices: function() {
return this.results.find(".select2-result-selectable:not(.select2-selected):not(.select2-disabled)");
},
// abstract
moveHighlight: function (delta) {
var choices = this.findHighlightableChoices(),
index = this.highlight();
while (index > -1 && index < choices.length) {
index += delta;
var choice = $(choices[index]);
if (choice.hasClass("select2-result-selectable") && !choice.hasClass("select2-disabled") && !choice.hasClass("select2-selected")) {
this.highlight(index);
break;
}
}
},
// abstract
highlight: function (index) {
var choices = this.findHighlightableChoices(),
choice,
data;
if (arguments.length === 0) {
return indexOf(choices.filter(".select2-highlighted")[0], choices.get());
}
if (index >= choices.length) index = choices.length - 1;
if (index < 0) index = 0;
this.results.find(".select2-highlighted").removeClass("select2-highlighted");
choice = $(choices[index]);
choice.addClass("select2-highlighted");
this.ensureHighlightVisible();
data = choice.data("select2-data");
if (data) {
this.opts.element.trigger({ type: "select2-highlight", val: this.id(data), choice: data });
}
},
// abstract
countSelectableResults: function() {
return this.findHighlightableChoices().length;
},
// abstract
highlightUnderEvent: function (event) {
var el = $(event.target).closest(".select2-result-selectable");
if (el.length > 0 && !el.is(".select2-highlighted")) {
var choices = this.findHighlightableChoices();
this.highlight(choices.index(el));
} else if (el.length == 0) {
// if we are over an unselectable item remove al highlights
this.results.find(".select2-highlighted").removeClass("select2-highlighted");
}
},
// abstract
loadMoreIfNeeded: function () {
var results = this.results,
more = results.find("li.select2-more-results"),
below, // pixels the element is below the scroll fold, below==0 is when the element is starting to be visible
offset = -1, // index of first element without data
page = this.resultsPage + 1,
self=this,
term=this.search.val(),
context=this.context;
if (more.length === 0) return;
below = more.offset().top - results.offset().top - results.height();
if (below <= this.opts.loadMorePadding) {
more.addClass("select2-active");
this.opts.query({
element: this.opts.element,
term: term,
page: page,
context: context,
matcher: this.opts.matcher,
callback: this.bind(function (data) {
// ignore a response if the select2 has been closed before it was received
if (!self.opened()) return;
self.opts.populateResults.call(this, results, data.results, {term: term, page: page, context:context});
self.postprocessResults(data, false, false);
if (data.more===true) {
more.detach().appendTo(results).text(self.opts.formatLoadMore(page+1));
window.setTimeout(function() { self.loadMoreIfNeeded(); }, 10);
} else {
more.remove();
}
self.positionDropdown();
self.resultsPage = page;
self.context = data.context;
})});
}
},
/**
* Default tokenizer function which does nothing
*/
tokenize: function() {
},
/**
* @param initial whether or not this is the call to this method right after the dropdown has been opened
*/
// abstract
updateResults: function (initial) {
var search = this.search,
results = this.results,
opts = this.opts,
data,
self = this,
input,
term = search.val(),
lastTerm=$.data(this.container, "select2-last-term");
// prevent duplicate queries against the same term
if (initial !== true && lastTerm && equal(term, lastTerm)) return;
$.data(this.container, "select2-last-term", term);
// if the search is currently hidden we do not alter the results
if (initial !== true && (this.showSearchInput === false || !this.opened())) {
return;
}
function postRender() {
search.removeClass("select2-active");
self.positionDropdown();
}
function render(html) {
results.html(html);
postRender();
}
var maxSelSize = this.getMaximumSelectionSize();
if (maxSelSize >=1) {
data = this.data();
if ($.isArray(data) && data.length >= maxSelSize && checkFormatter(opts.formatSelectionTooBig, "formatSelectionTooBig")) {
render("<li class='select2-selection-limit'>" + opts.formatSelectionTooBig(maxSelSize) + "</li>");
return;
}
}
if (search.val().length < opts.minimumInputLength) {
if (checkFormatter(opts.formatInputTooShort, "formatInputTooShort")) {
render("<li class='select2-no-results'>" + opts.formatInputTooShort(search.val(), opts.minimumInputLength) + "</li>");
} else {
render("");
}
if (initial && this.showSearch) this.showSearch(true);
return;
}
if (opts.maximumInputLength && search.val().length > opts.maximumInputLength) {
if (checkFormatter(opts.formatInputTooLong, "formatInputTooLong")) {
render("<li class='select2-no-results'>" + opts.formatInputTooLong(search.val(), opts.maximumInputLength) + "</li>");
} else {
render("");
}
return;
}
if (opts.formatSearching && this.findHighlightableChoices().length === 0) {
render("<li class='select2-searching'>" + opts.formatSearching() + "</li>");
}
search.addClass("select2-active");
// give the tokenizer a chance to pre-process the input
input = this.tokenize();
if (input != undefined && input != null) {
search.val(input);
}
this.resultsPage = 1;
opts.query({
element: opts.element,
term: search.val(),
page: this.resultsPage,
context: null,
matcher: opts.matcher,
callback: this.bind(function (data) {
var def; // default choice
// ignore a response if the select2 has been closed before it was received
if (!this.opened()) {
this.search.removeClass("select2-active");
return;
}
// save context, if any
this.context = (data.context===undefined) ? null : data.context;
// create a default choice and prepend it to the list
if (this.opts.createSearchChoice && search.val() !== "") {
def = this.opts.createSearchChoice.call(self, search.val(), data.results);
if (def !== undefined && def !== null && self.id(def) !== undefined && self.id(def) !== null) {
if ($(data.results).filter(
function () {
return equal(self.id(this), self.id(def));
}).length === 0) {
data.results.unshift(def);
}
}
}
if (data.results.length === 0 && checkFormatter(opts.formatNoMatches, "formatNoMatches")) {
render("<li class='select2-no-results'>" + opts.formatNoMatches(search.val()) + "</li>");
return;
}
results.empty();
self.opts.populateResults.call(this, results, data.results, {term: search.val(), page: this.resultsPage, context:null});
if (data.more === true && checkFormatter(opts.formatLoadMore, "formatLoadMore")) {
results.append("<li class='select2-more-results'>" + self.opts.escapeMarkup(opts.formatLoadMore(this.resultsPage)) + "</li>");
window.setTimeout(function() { self.loadMoreIfNeeded(); }, 10);
}
this.postprocessResults(data, initial);
postRender();
this.opts.element.trigger({ type: "select2-loaded", items: data });
})});
},
// abstract
cancel: function () {
this.close();
},
// abstract
blur: function () {
// if selectOnBlur == true, select the currently highlighted option
if (this.opts.selectOnBlur)
this.selectHighlighted({noFocus: true});
this.close();
this.container.removeClass("select2-container-active");
// synonymous to .is(':focus'), which is available in jquery >= 1.6
if (this.search[0] === document.activeElement) { this.search.blur(); }
this.clearSearch();
this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");
},
// abstract
focusSearch: function () {
focus(this.search);
},
// abstract
selectHighlighted: function (options) {
var index=this.highlight(),
highlighted=this.results.find(".select2-highlighted"),
data = highlighted.closest('.select2-result').data("select2-data");
if (data) {
this.highlight(index);
this.onSelect(data, options);
} else if (options && options.noFocus) {
this.close();
}
},
// abstract
getPlaceholder: function () {
var placeholderOption;
return this.opts.element.attr("placeholder") ||
this.opts.element.attr("data-placeholder") || // jquery 1.4 compat
this.opts.element.data("placeholder") ||
this.opts.placeholder ||
((placeholderOption = this.getPlaceholderOption()) !== undefined ? placeholderOption.text() : undefined);
},
// abstract
getPlaceholderOption: function() {
if (this.select) {
var firstOption = this.select.children().first();
if (this.opts.placeholderOption !== undefined ) {
//Determine the placeholder option based on the specified placeholderOption setting
return (this.opts.placeholderOption === "first" && firstOption) ||
(typeof this.opts.placeholderOption === "function" && this.opts.placeholderOption(this.select));
} else if (firstOption.text() === "" && firstOption.val() === "") {
//No explicit placeholder option specified, use the first if it's blank
return firstOption;
}
}
},
/**
* Get the desired width for the container element. This is
* derived first from option `width` passed to select2, then
* the inline 'style' on the original element, and finally
* falls back to the jQuery calculated element width.
*/
// abstract
initContainerWidth: function () {
function resolveContainerWidth() {
var style, attrs, matches, i, l;
if (this.opts.width === "off") {
return null;
} else if (this.opts.width === "element"){
return this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px';
} else if (this.opts.width === "copy" || this.opts.width === "resolve") {
// check if there is inline style on the element that contains width
style = this.opts.element.attr('style');
if (style !== undefined) {
attrs = style.split(';');
for (i = 0, l = attrs.length; i < l; i = i + 1) {
matches = attrs[i].replace(/\s/g, '')
.match(/width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i);
if (matches !== null && matches.length >= 1)
return matches[1];
}
}
if (this.opts.width === "resolve") {
// next check if css('width') can resolve a width that is percent based, this is sometimes possible
// when attached to input type=hidden or elements hidden via css
style = this.opts.element.css('width');
if (style.indexOf("%") > 0) return style;
// finally, fallback on the calculated width of the element
return (this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px');
}
return null;
} else if ($.isFunction(this.opts.width)) {
return this.opts.width();
} else {
return this.opts.width;
}
};
var width = resolveContainerWidth.call(this);
if (width !== null) {
this.container.css("width", width);
}
}
});
SingleSelect2 = clazz(AbstractSelect2, {
// single
createContainer: function () {
var container = $(document.createElement("div")).attr({
"class": "select2-container"
}).html([
"<a href='javascript:void(0)' onclick='return false;' class='select2-choice' tabindex='-1'>",
" <span class='select2-chosen'> </span><abbr class='select2-search-choice-close'></abbr>",
" <span class='select2-arrow'><b></b></span>",
"</a>",
"<input class='select2-focusser select2-offscreen' type='text'/>",
"<div class='select2-drop select2-display-none'>",
" <div class='select2-search'>",
" <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input'/>",
" </div>",
" <ul class='select2-results'>",
" </ul>",
"</div>"].join(""));
return container;
},
// single
enableInterface: function() {
if (this.parent.enableInterface.apply(this, arguments)) {
this.focusser.prop("disabled", !this.isInterfaceEnabled());
}
},
// single
opening: function () {
var el, range, len;
if (this.opts.minimumResultsForSearch >= 0) {
this.showSearch(true);
}
this.parent.opening.apply(this, arguments);
if (this.showSearchInput !== false) {
// IE appends focusser.val() at the end of field :/ so we manually insert it at the beginning using a range
// all other browsers handle this just fine
this.search.val(this.focusser.val());
}
this.search.focus();
// move the cursor to the end after focussing, otherwise it will be at the beginning and
// new text will appear *before* focusser.val()
el = this.search.get(0);
if (el.createTextRange) {
range = el.createTextRange();
range.collapse(false);
range.select();
} else if (el.setSelectionRange) {
len = this.search.val().length;
el.setSelectionRange(len, len);
}
this.focusser.prop("disabled", true).val("");
this.updateResults(true);
this.opts.element.trigger($.Event("select2-open"));
},
// single
close: function () {
if (!this.opened()) return;
this.parent.close.apply(this, arguments);
this.focusser.removeAttr("disabled");
this.focusser.focus();
},
// single
focus: function () {
if (this.opened()) {
this.close();
} else {
this.focusser.removeAttr("disabled");
this.focusser.focus();
}
},
// single
isFocused: function () {
return this.container.hasClass("select2-container-active");
},
// single
cancel: function () {
this.parent.cancel.apply(this, arguments);
this.focusser.removeAttr("disabled");
this.focusser.focus();
},
// single
initContainer: function () {
var selection,
container = this.container,
dropdown = this.dropdown;
if (this.opts.minimumResultsForSearch < 0) {
this.showSearch(false);
} else {
this.showSearch(true);
}
this.selection = selection = container.find(".select2-choice");
this.focusser = container.find(".select2-focusser");
// rewrite labels from original element to focusser
this.focusser.attr("id", "s2id_autogen"+nextUid());
$("label[for='" + this.opts.element.attr("id") + "']")
.attr('for', this.focusser.attr('id'));
this.focusser.attr("tabindex", this.elementTabIndex);
this.search.on("keydown", this.bind(function (e) {
if (!this.isInterfaceEnabled()) return;
if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) {
// prevent the page from scrolling
killEvent(e);
return;
}
switch (e.which) {
case KEY.UP:
case KEY.DOWN:
this.moveHighlight((e.which === KEY.UP) ? -1 : 1);
killEvent(e);
return;
case KEY.ENTER:
this.selectHighlighted();
killEvent(e);
return;
case KEY.TAB:
this.selectHighlighted({noFocus: true});
return;
case KEY.ESC:
this.cancel(e);
killEvent(e);
return;
}
}));
this.search.on("blur", this.bind(function(e) {
// a workaround for chrome to keep the search field focussed when the scroll bar is used to scroll the dropdown.
// without this the search field loses focus which is annoying
if (document.activeElement === this.body().get(0)) {
window.setTimeout(this.bind(function() {
this.search.focus();
}), 0);
}
}));
this.focusser.on("keydown", this.bind(function (e) {
if (!this.isInterfaceEnabled()) return;
if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) {
return;
}
if (this.opts.openOnEnter === false && e.which === KEY.ENTER) {
killEvent(e);
return;
}
if (e.which == KEY.DOWN || e.which == KEY.UP
|| (e.which == KEY.ENTER && this.opts.openOnEnter)) {
if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) return;
this.open();
killEvent(e);
return;
}
if (e.which == KEY.DELETE || e.which == KEY.BACKSPACE) {
if (this.opts.allowClear) {
this.clear();
}
killEvent(e);
return;
}
}));
installKeyUpChangeEvent(this.focusser);
this.focusser.on("keyup-change input", this.bind(function(e) {
if (this.opts.minimumResultsForSearch >= 0) {
e.stopPropagation();
if (this.opened()) return;
this.open();
}
}));
selection.on("mousedown", "abbr", this.bind(function (e) {
if (!this.isInterfaceEnabled()) return;
this.clear();
killEventImmediately(e);
this.close();
this.selection.focus();
}));
selection.on("mousedown", this.bind(function (e) {
if (!this.container.hasClass("select2-container-active")) {
this.opts.element.trigger($.Event("select2-focus"));
}
if (this.opened()) {
this.close();
} else if (this.isInterfaceEnabled()) {
this.open();
}
killEvent(e);
}));
dropdown.on("mousedown", this.bind(function() { this.search.focus(); }));
selection.on("focus", this.bind(function(e) {
killEvent(e);
}));
this.focusser.on("focus", this.bind(function(){
if (!this.container.hasClass("select2-container-active")) {
this.opts.element.trigger($.Event("select2-focus"));
}
this.container.addClass("select2-container-active");
})).on("blur", this.bind(function() {
if (!this.opened()) {
this.container.removeClass("select2-container-active");
this.opts.element.trigger($.Event("select2-blur"));
}
}));
this.search.on("focus", this.bind(function(){
if (!this.container.hasClass("select2-container-active")) {
this.opts.element.trigger($.Event("select2-focus"));
}
this.container.addClass("select2-container-active");
}));
this.initContainerWidth();
this.opts.element.addClass("select2-offscreen");
this.setPlaceholder();
},
// single
clear: function(triggerChange) {
var data=this.selection.data("select2-data");
if (data) { // guard against queued quick consecutive clicks
var placeholderOption = this.getPlaceholderOption();
this.opts.element.val(placeholderOption ? placeholderOption.val() : "");
this.selection.find(".select2-chosen").empty();
this.selection.removeData("select2-data");
this.setPlaceholder();
if (triggerChange !== false){
this.opts.element.trigger({ type: "select2-removed", val: this.id(data), choice: data });
this.triggerChange({removed:data});
}
}
},
/**
* Sets selection based on source element's value
*/
// single
initSelection: function () {
var selected;
if (this.isPlaceholderOptionSelected()) {
this.updateSelection([]);
this.close();
this.setPlaceholder();
} else {
var self = this;
this.opts.initSelection.call(null, this.opts.element, function(selected){
if (selected !== undefined && selected !== null) {
self.updateSelection(selected);
self.close();
self.setPlaceholder();
}
});
}
},
isPlaceholderOptionSelected: function() {
var placeholderOption;
return ((placeholderOption = this.getPlaceholderOption()) !== undefined && placeholderOption.is(':selected')) ||
(this.opts.element.val() === "") ||
(this.opts.element.val() === undefined) ||
(this.opts.element.val() === null);
},
// single
prepareOpts: function () {
var opts = this.parent.prepareOpts.apply(this, arguments),
self=this;
if (opts.element.get(0).tagName.toLowerCase() === "select") {
// install the selection initializer
opts.initSelection = function (element, callback) {
var selected = element.find(":selected");
// a single select box always has a value, no need to null check 'selected'
callback(self.optionToData(selected));
};
} else if ("data" in opts) {
// install default initSelection when applied to hidden input and data is local
opts.initSelection = opts.initSelection || function (element, callback) {
var id = element.val();
//search in data by id, storing the actual matching item
var match = null;
opts.query({
matcher: function(term, text, el){
var is_match = equal(id, opts.id(el));
if (is_match) {
match = el;
}
return is_match;
},
callback: !$.isFunction(callback) ? $.noop : function() {
callback(match);
}
});
};
}
return opts;
},
// single
getPlaceholder: function() {
// if a placeholder is specified on a single select without a valid placeholder option ignore it
if (this.select) {
if (this.getPlaceholderOption() === undefined) {
return undefined;
}
}
return this.parent.getPlaceholder.apply(this, arguments);
},
// single
setPlaceholder: function () {
var placeholder = this.getPlaceholder();
if (this.isPlaceholderOptionSelected() && placeholder !== undefined) {
// check for a placeholder option if attached to a select
if (this.select && this.getPlaceholderOption() === undefined) return;
this.selection.find(".select2-chosen").html(this.opts.escapeMarkup(placeholder));
this.selection.addClass("select2-default");
this.container.removeClass("select2-allowclear");
}
},
// single
postprocessResults: function (data, initial, noHighlightUpdate) {
var selected = 0, self = this, showSearchInput = true;
// find the selected element in the result list
this.findHighlightableChoices().each2(function (i, elm) {
if (equal(self.id(elm.data("select2-data")), self.opts.element.val())) {
selected = i;
return false;
}
});
// and highlight it
if (noHighlightUpdate !== false) {
if (initial === true && selected >= 0) {
this.highlight(selected);
} else {
this.highlight(0);
}
}
// hide the search box if this is the first we got the results and there are enough of them for search
if (initial === true) {
var min = this.opts.minimumResultsForSearch;
if (min >= 0) {
this.showSearch(countResults(data.results) >= min);
}
}
},
// single
showSearch: function(showSearchInput) {
if (this.showSearchInput === showSearchInput) return;
this.showSearchInput = showSearchInput;
this.dropdown.find(".select2-search").toggleClass("select2-search-hidden", !showSearchInput);
this.dropdown.find(".select2-search").toggleClass("select2-offscreen", !showSearchInput);
//add "select2-with-searchbox" to the container if search box is shown
$(this.dropdown, this.container).toggleClass("select2-with-searchbox", showSearchInput);
},
// single
onSelect: function (data, options) {
if (!this.triggerSelect(data)) { return; }
var old = this.opts.element.val(),
oldData = this.data();
this.opts.element.val(this.id(data));
this.updateSelection(data);
this.opts.element.trigger({ type: "select2-selected", val: this.id(data), choice: data });
this.close();
if (!options || !options.noFocus)
this.selection.focus();
if (!equal(old, this.id(data))) { this.triggerChange({added:data,removed:oldData}); }
},
// single
updateSelection: function (data) {
var container=this.selection.find(".select2-chosen"), formatted, cssClass;
this.selection.data("select2-data", data);
container.empty();
formatted=this.opts.formatSelection(data, container, this.opts.escapeMarkup);
if (formatted !== undefined) {
container.append(formatted);
}
cssClass=this.opts.formatSelectionCssClass(data, container);
if (cssClass !== undefined) {
container.addClass(cssClass);
}
this.selection.removeClass("select2-default");
if (this.opts.allowClear && this.getPlaceholder() !== undefined) {
this.container.addClass("select2-allowclear");
}
},
// single
val: function () {
var val,
triggerChange = false,
data = null,
self = this,
oldData = this.data();
if (arguments.length === 0) {
return this.opts.element.val();
}
val = arguments[0];
if (arguments.length > 1) {
triggerChange = arguments[1];
}
if (this.select) {
this.select
.val(val)
.find(":selected").each2(function (i, elm) {
data = self.optionToData(elm);
return false;
});
this.updateSelection(data);
this.setPlaceholder();
if (triggerChange) {
this.triggerChange({added: data, removed:oldData});
}
} else {
// val is an id. !val is true for [undefined,null,'',0] - 0 is legal
if (!val && val !== 0) {
this.clear(triggerChange);
return;
}
if (this.opts.initSelection === undefined) {
throw new Error("cannot call val() if initSelection() is not defined");
}
this.opts.element.val(val);
this.opts.initSelection(this.opts.element, function(data){
self.opts.element.val(!data ? "" : self.id(data));
self.updateSelection(data);
self.setPlaceholder();
if (triggerChange) {
self.triggerChange({added: data, removed:oldData});
}
});
}
},
// single
clearSearch: function () {
this.search.val("");
this.focusser.val("");
},
// single
data: function(value, triggerChange) {
var data;
if (arguments.length === 0) {
data = this.selection.data("select2-data");
if (data == undefined) data = null;
return data;
} else {
if (!value || value === "") {
this.clear(triggerChange);
} else {
data = this.data();
this.opts.element.val(!value ? "" : this.id(value));
this.updateSelection(value);
if (triggerChange) {
this.triggerChange({added: value, removed:data});
}
}
}
}
});
MultiSelect2 = clazz(AbstractSelect2, {
// multi
createContainer: function () {
var container = $(document.createElement("div")).attr({
"class": "select2-container select2-container-multi"
}).html([
"<ul class='select2-choices'>",
" <li class='select2-search-field'>",
" <input type='text' autocomplete='off' autocorrect='off' autocapitilize='off' spellcheck='false' class='select2-input'>",
" </li>",
"</ul>",
"<div class='select2-drop select2-drop-multi select2-display-none'>",
" <ul class='select2-results'>",
" </ul>",
"</div>"].join(""));
return container;
},
// multi
prepareOpts: function () {
var opts = this.parent.prepareOpts.apply(this, arguments),
self=this;
// TODO validate placeholder is a string if specified
if (opts.element.get(0).tagName.toLowerCase() === "select") {
// install sthe selection initializer
opts.initSelection = function (element, callback) {
var data = [];
element.find(":selected").each2(function (i, elm) {
data.push(self.optionToData(elm));
});
callback(data);
};
} else if ("data" in opts) {
// install default initSelection when applied to hidden input and data is local
opts.initSelection = opts.initSelection || function (element, callback) {
var ids = splitVal(element.val(), opts.separator);
//search in data by array of ids, storing matching items in a list
var matches = [];
opts.query({
matcher: function(term, text, el){
var is_match = $.grep(ids, function(id) {
return equal(id, opts.id(el));
}).length;
if (is_match) {
matches.push(el);
}
return is_match;
},
callback: !$.isFunction(callback) ? $.noop : function() {
// reorder matches based on the order they appear in the ids array because right now
// they are in the order in which they appear in data array
var ordered = [];
for (var i = 0; i < ids.length; i++) {
var id = ids[i];
for (var j = 0; j < matches.length; j++) {
var match = matches[j];
if (equal(id, opts.id(match))) {
ordered.push(match);
matches.splice(j, 1);
break;
}
}
}
callback(ordered);
}
});
};
}
return opts;
},
selectChoice: function (choice) {
var selected = this.container.find(".select2-search-choice-focus");
if (selected.length && choice && choice[0] == selected[0]) {
} else {
if (selected.length) {
this.opts.element.trigger("choice-deselected", selected);
}
selected.removeClass("select2-search-choice-focus");
if (choice && choice.length) {
this.close();
choice.addClass("select2-search-choice-focus");
this.opts.element.trigger("choice-selected", choice);
}
}
},
// multi
initContainer: function () {
var selector = ".select2-choices", selection;
this.searchContainer = this.container.find(".select2-search-field");
this.selection = selection = this.container.find(selector);
var _this = this;
this.selection.on("mousedown", ".select2-search-choice", function (e) {
//killEvent(e);
_this.search[0].focus();
_this.selectChoice($(this));
})
// rewrite labels from original element to focusser
this.search.attr("id", "s2id_autogen"+nextUid());
$("label[for='" + this.opts.element.attr("id") + "']")
.attr('for', this.search.attr('id'));
this.search.on("input paste", this.bind(function() {
if (!this.isInterfaceEnabled()) return;
if (!this.opened()) {
this.open();
}
}));
this.search.attr("tabindex", this.elementTabIndex);
this.keydowns = 0;
this.search.on("keydown", this.bind(function (e) {
if (!this.isInterfaceEnabled()) return;
++this.keydowns;
var selected = selection.find(".select2-search-choice-focus");
var prev = selected.prev(".select2-search-choice:not(.select2-locked)");
var next = selected.next(".select2-search-choice:not(.select2-locked)");
var pos = getCursorInfo(this.search);
if (selected.length &&
(e.which == KEY.LEFT || e.which == KEY.RIGHT || e.which == KEY.BACKSPACE || e.which == KEY.DELETE || e.which == KEY.ENTER)) {
var selectedChoice = selected;
if (e.which == KEY.LEFT && prev.length) {
selectedChoice = prev;
}
else if (e.which == KEY.RIGHT) {
selectedChoice = next.length ? next : null;
}
else if (e.which === KEY.BACKSPACE) {
this.unselect(selected.first());
this.search.width(10);
selectedChoice = prev.length ? prev : next;
} else if (e.which == KEY.DELETE) {
this.unselect(selected.first());
this.search.width(10);
selectedChoice = next.length ? next : null;
} else if (e.which == KEY.ENTER) {
selectedChoice = null;
}
this.selectChoice(selectedChoice);
killEvent(e);
if (!selectedChoice || !selectedChoice.length) {
this.open();
}
return;
} else if (((e.which === KEY.BACKSPACE && this.keydowns == 1)
|| e.which == KEY.LEFT) && (pos.offset == 0 && !pos.length)) {
this.selectChoice(selection.find(".select2-search-choice:not(.select2-locked)").last());
killEvent(e);
return;
} else {
this.selectChoice(null);
}
if (this.opened()) {
switch (e.which) {
case KEY.UP:
case KEY.DOWN:
this.moveHighlight((e.which === KEY.UP) ? -1 : 1);
killEvent(e);
return;
case KEY.ENTER:
this.selectHighlighted();
killEvent(e);
return;
case KEY.TAB:
this.selectHighlighted({noFocus:true});
this.close();
return;
case KEY.ESC:
this.cancel(e);
killEvent(e);
return;
}
}
if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e)
|| e.which === KEY.BACKSPACE || e.which === KEY.ESC) {
return;
}
if (e.which === KEY.ENTER) {
if (this.opts.openOnEnter === false) {
return;
} else if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) {
return;
}
}
this.open();
if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) {
// prevent the page from scrolling
killEvent(e);
}
if (e.which === KEY.ENTER) {
// prevent form from being submitted
killEvent(e);
}
}));
this.search.on("keyup", this.bind(function (e) {
this.keydowns = 0;
this.resizeSearch();
})
);
this.search.on("blur", this.bind(function(e) {
this.container.removeClass("select2-container-active");
this.search.removeClass("select2-focused");
this.selectChoice(null);
if (!this.opened()) this.clearSearch();
e.stopImmediatePropagation();
this.opts.element.trigger($.Event("select2-blur"));
}));
this.container.on("click", selector, this.bind(function (e) {
if (!this.isInterfaceEnabled()) return;
if ($(e.target).closest(".select2-search-choice").length > 0) {
// clicked inside a select2 search choice, do not open
return;
}
this.selectChoice(null);
this.clearPlaceholder();
if (!this.container.hasClass("select2-container-active")) {
this.opts.element.trigger($.Event("select2-focus"));
}
this.open();
this.focusSearch();
e.preventDefault();
}));
this.container.on("focus", selector, this.bind(function () {
if (!this.isInterfaceEnabled()) return;
if (!this.container.hasClass("select2-container-active")) {
this.opts.element.trigger($.Event("select2-focus"));
}
this.container.addClass("select2-container-active");
this.dropdown.addClass("select2-drop-active");
this.clearPlaceholder();
}));
this.initContainerWidth();
this.opts.element.addClass("select2-offscreen");
// set the placeholder if necessary
this.clearSearch();
},
// multi
enableInterface: function() {
if (this.parent.enableInterface.apply(this, arguments)) {
this.search.prop("disabled", !this.isInterfaceEnabled());
}
},
// multi
initSelection: function () {
var data;
if (this.opts.element.val() === "" && this.opts.element.text() === "") {
this.updateSelection([]);
this.close();
// set the placeholder if necessary
this.clearSearch();
}
if (this.select || this.opts.element.val() !== "") {
var self = this;
this.opts.initSelection.call(null, this.opts.element, function(data){
if (data !== undefined && data !== null) {
self.updateSelection(data);
self.close();
// set the placeholder if necessary
self.clearSearch();
}
});
}
},
// multi
clearSearch: function () {
var placeholder = this.getPlaceholder(),
maxWidth = this.getMaxSearchWidth();
if (placeholder !== undefined && this.getVal().length === 0 && this.search.hasClass("select2-focused") === false) {
this.search.val(placeholder).addClass("select2-default");
// stretch the search box to full width of the container so as much of the placeholder is visible as possible
// we could call this.resizeSearch(), but we do not because that requires a sizer and we do not want to create one so early because of a firefox bug, see #944
this.search.width(maxWidth > 0 ? maxWidth : this.container.css("width"));
} else {
this.search.val("").width(10);
}
},
// multi
clearPlaceholder: function () {
if (this.search.hasClass("select2-default")) {
this.search.val("").removeClass("select2-default");
}
},
// multi
opening: function () {
this.clearPlaceholder(); // should be done before super so placeholder is not used to search
this.resizeSearch();
this.parent.opening.apply(this, arguments);
this.focusSearch();
this.updateResults(true);
this.search.focus();
this.opts.element.trigger($.Event("select2-open"));
},
// multi
close: function () {
if (!this.opened()) return;
this.parent.close.apply(this, arguments);
},
// multi
focus: function () {
this.close();
this.search.focus();
},
// multi
isFocused: function () {
return this.search.hasClass("select2-focused");
},
// multi
updateSelection: function (data) {
var ids = [], filtered = [], self = this;
// filter out duplicates
$(data).each(function () {
if (indexOf(self.id(this), ids) < 0) {
ids.push(self.id(this));
filtered.push(this);
}
});
data = filtered;
this.selection.find(".select2-search-choice").remove();
$(data).each(function () {
self.addSelectedChoice(this);
});
self.postprocessResults();
},
// multi
tokenize: function() {
var input = this.search.val();
input = this.opts.tokenizer.call(this, input, this.data(), this.bind(this.onSelect), this.opts);
if (input != null && input != undefined) {
this.search.val(input);
if (input.length > 0) {
this.open();
}
}
},
// multi
onSelect: function (data, options) {
if (!this.triggerSelect(data)) { return; }
this.addSelectedChoice(data);
this.opts.element.trigger({ type: "selected", val: this.id(data), choice: data });
if (this.select || !this.opts.closeOnSelect) this.postprocessResults();
if (this.opts.closeOnSelect) {
this.close();
this.search.width(10);
} else {
if (this.countSelectableResults()>0) {
this.search.width(10);
this.resizeSearch();
if (this.getMaximumSelectionSize() > 0 && this.val().length >= this.getMaximumSelectionSize()) {
// if we reached max selection size repaint the results so choices
// are replaced with the max selection reached message
this.updateResults(true);
}
this.positionDropdown();
} else {
// if nothing left to select close
this.close();
this.search.width(10);
}
}
// since its not possible to select an element that has already been
// added we do not need to check if this is a new element before firing change
this.triggerChange({ added: data });
if (!options || !options.noFocus)
this.focusSearch();
},
// multi
cancel: function () {
this.close();
this.focusSearch();
},
addSelectedChoice: function (data) {
var enableChoice = !data.locked,
enabledItem = $(
"<li class='select2-search-choice'>" +
" <div></div>" +
" <a href='#' onclick='return false;' class='select2-search-choice-close' tabindex='-1'></a>" +
"</li>"),
disabledItem = $(
"<li class='select2-search-choice select2-locked'>" +
"<div></div>" +
"</li>");
var choice = enableChoice ? enabledItem : disabledItem,
id = this.id(data),
val = this.getVal(),
formatted,
cssClass;
formatted=this.opts.formatSelection(data, choice.find("div"), this.opts.escapeMarkup);
if (formatted != undefined) {
choice.find("div").replaceWith("<div>"+formatted+"</div>");
}
cssClass=this.opts.formatSelectionCssClass(data, choice.find("div"));
if (cssClass != undefined) {
choice.addClass(cssClass);
}
if(enableChoice){
choice.find(".select2-search-choice-close")
.on("mousedown", killEvent)
.on("click dblclick", this.bind(function (e) {
if (!this.isInterfaceEnabled()) return;
$(e.target).closest(".select2-search-choice").fadeOut('fast', this.bind(function(){
this.unselect($(e.target));
this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");
this.close();
this.focusSearch();
})).dequeue();
killEvent(e);
})).on("focus", this.bind(function () {
if (!this.isInterfaceEnabled()) return;
this.container.addClass("select2-container-active");
this.dropdown.addClass("select2-drop-active");
}));
}
choice.data("select2-data", data);
choice.insertBefore(this.searchContainer);
val.push(id);
this.setVal(val);
},
// multi
unselect: function (selected) {
var val = this.getVal(),
data,
index;
selected = selected.closest(".select2-search-choice");
if (selected.length === 0) {
throw "Invalid argument: " + selected + ". Must be .select2-search-choice";
}
data = selected.data("select2-data");
if (!data) {
// prevent a race condition when the 'x' is clicked really fast repeatedly the event can be queued
// and invoked on an element already removed
return;
}
index = indexOf(this.id(data), val);
if (index >= 0) {
val.splice(index, 1);
this.setVal(val);
if (this.select) this.postprocessResults();
}
selected.remove();
this.opts.element.trigger({ type: "removed", val: this.id(data), choice: data });
this.triggerChange({ removed: data });
},
// multi
postprocessResults: function (data, initial, noHighlightUpdate) {
var val = this.getVal(),
choices = this.results.find(".select2-result"),
compound = this.results.find(".select2-result-with-children"),
self = this;
choices.each2(function (i, choice) {
var id = self.id(choice.data("select2-data"));
if (indexOf(id, val) >= 0) {
choice.addClass("select2-selected");
// mark all children of the selected parent as selected
choice.find(".select2-result-selectable").addClass("select2-selected");
}
});
compound.each2(function(i, choice) {
// hide an optgroup if it doesnt have any selectable children
if (!choice.is('.select2-result-selectable')
&& choice.find(".select2-result-selectable:not(.select2-selected)").length === 0) {
choice.addClass("select2-selected");
}
});
if (this.highlight() == -1 && noHighlightUpdate !== false){
self.highlight(0);
}
//If all results are chosen render formatNoMAtches
if(!this.opts.createSearchChoice && !choices.filter('.select2-result:not(.select2-selected)').length > 0){
if(!data || data && !data.more && this.results.find(".select2-no-results").length === 0) {
if (checkFormatter(self.opts.formatNoMatches, "formatNoMatches")) {
this.results.append("<li class='select2-no-results'>" + self.opts.formatNoMatches(self.search.val()) + "</li>");
}
}
}
},
// multi
getMaxSearchWidth: function() {
return this.selection.width() - getSideBorderPadding(this.search);
},
// multi
resizeSearch: function () {
var minimumWidth, left, maxWidth, containerLeft, searchWidth,
sideBorderPadding = getSideBorderPadding(this.search);
minimumWidth = measureTextWidth(this.search) + 10;
left = this.search.offset().left;
maxWidth = this.selection.width();
containerLeft = this.selection.offset().left;
searchWidth = maxWidth - (left - containerLeft) - sideBorderPadding;
if (searchWidth < minimumWidth) {
searchWidth = maxWidth - sideBorderPadding;
}
if (searchWidth < 40) {
searchWidth = maxWidth - sideBorderPadding;
}
if (searchWidth <= 0) {
searchWidth = minimumWidth;
}
this.search.width(searchWidth);
},
// multi
getVal: function () {
var val;
if (this.select) {
val = this.select.val();
return val === null ? [] : val;
} else {
val = this.opts.element.val();
return splitVal(val, this.opts.separator);
}
},
// multi
setVal: function (val) {
var unique;
if (this.select) {
this.select.val(val);
} else {
unique = [];
// filter out duplicates
$(val).each(function () {
if (indexOf(this, unique) < 0) unique.push(this);
});
this.opts.element.val(unique.length === 0 ? "" : unique.join(this.opts.separator));
}
},
// multi
buildChangeDetails: function (old, current) {
var current = current.slice(0),
old = old.slice(0);
// remove intersection from each array
for (var i = 0; i < current.length; i++) {
for (var j = 0; j < old.length; j++) {
if (equal(this.opts.id(current[i]), this.opts.id(old[j]))) {
current.splice(i, 1);
i--;
old.splice(j, 1);
j--;
}
}
}
return {added: current, removed: old};
},
// multi
val: function (val, triggerChange) {
var oldData, self=this, changeDetails;
if (arguments.length === 0) {
return this.getVal();
}
oldData=this.data();
if (!oldData.length) oldData=[];
// val is an id. !val is true for [undefined,null,'',0] - 0 is legal
if (!val && val !== 0) {
this.opts.element.val("");
this.updateSelection([]);
this.clearSearch();
if (triggerChange) {
this.triggerChange({added: this.data(), removed: oldData});
}
return;
}
// val is a list of ids
this.setVal(val);
if (this.select) {
this.opts.initSelection(this.select, this.bind(this.updateSelection));
if (triggerChange) {
this.triggerChange(this.buildChangeDetails(oldData, this.data()));
}
} else {
if (this.opts.initSelection === undefined) {
throw new Error("val() cannot be called if initSelection() is not defined");
}
this.opts.initSelection(this.opts.element, function(data){
var ids=$.map(data, self.id);
self.setVal(ids);
self.updateSelection(data);
self.clearSearch();
if (triggerChange) {
self.triggerChange(this.buildChangeDetails(oldData, this.data()));
}
});
}
this.clearSearch();
},
// multi
onSortStart: function() {
if (this.select) {
throw new Error("Sorting of elements is not supported when attached to <select>. Attach to <input type='hidden'/> instead.");
}
// collapse search field into 0 width so its container can be collapsed as well
this.search.width(0);
// hide the container
this.searchContainer.hide();
},
// multi
onSortEnd:function() {
var val=[], self=this;
// show search and move it to the end of the list
this.searchContainer.show();
// make sure the search container is the last item in the list
this.searchContainer.appendTo(this.searchContainer.parent());
// since we collapsed the width in dragStarted, we resize it here
this.resizeSearch();
// update selection
this.selection.find(".select2-search-choice").each(function() {
val.push(self.opts.id($(this).data("select2-data")));
});
this.setVal(val);
this.triggerChange();
},
// multi
data: function(values, triggerChange) {
var self=this, ids, old;
if (arguments.length === 0) {
return this.selection
.find(".select2-search-choice")
.map(function() { return $(this).data("select2-data"); })
.get();
} else {
old = this.data();
if (!values) { values = []; }
ids = $.map(values, function(e) { return self.opts.id(e); });
this.setVal(ids);
this.updateSelection(values);
this.clearSearch();
if (triggerChange) {
this.triggerChange(this.buildChangeDetails(old, this.data()));
}
}
}
});
$.fn.select2 = function () {
var args = Array.prototype.slice.call(arguments, 0),
opts,
select2,
method, value, multiple,
allowedMethods = ["val", "destroy", "opened", "open", "close", "focus", "isFocused", "container", "dropdown", "onSortStart", "onSortEnd", "enable", "readonly", "positionDropdown", "data", "search"],
valueMethods = ["val", "opened", "isFocused", "container", "data"],
methodsMap = { search: "externalSearch" };
this.each(function () {
if (args.length === 0 || typeof(args[0]) === "object") {
opts = args.length === 0 ? {} : $.extend({}, args[0]);
opts.element = $(this);
if (opts.element.get(0).tagName.toLowerCase() === "select") {
multiple = opts.element.prop("multiple");
} else {
multiple = opts.multiple || false;
if ("tags" in opts) {opts.multiple = multiple = true;}
}
select2 = multiple ? new MultiSelect2() : new SingleSelect2();
select2.init(opts);
} else if (typeof(args[0]) === "string") {
if (indexOf(args[0], allowedMethods) < 0) {
throw "Unknown method: " + args[0];
}
value = undefined;
select2 = $(this).data("select2");
if (select2 === undefined) return;
method=args[0];
if (method === "container") {
value = select2.container;
} else if (method === "dropdown") {
value = select2.dropdown;
} else {
if (methodsMap[method]) method = methodsMap[method];
value = select2[method].apply(select2, args.slice(1));
}
if (indexOf(args[0], valueMethods) >= 0) {
return false;
}
} else {
throw "Invalid arguments to select2 plugin: " + args;
}
});
return (value === undefined) ? this : value;
};
// plugin defaults, accessible to users
$.fn.select2.defaults = {
width: "copy",
loadMorePadding: 0,
closeOnSelect: true,
openOnEnter: true,
containerCss: {},
dropdownCss: {},
containerCssClass: "",
dropdownCssClass: "",
formatResult: function(result, container, query, escapeMarkup) {
var markup=[];
markMatch(result.text, query.term, markup, escapeMarkup);
return markup.join("");
},
formatSelection: function (data, container, escapeMarkup) {
return data ? escapeMarkup(data.text) : undefined;
},
sortResults: function (results, container, query) {
return results;
},
formatResultCssClass: function(data) {return undefined;},
formatSelectionCssClass: function(data, container) {return undefined;},
formatNoMatches: function () { return "No matches found"; },
formatInputTooShort: function (input, min) { var n = min - input.length; return "Please enter " + n + " more character" + (n == 1? "" : "s"); },
formatInputTooLong: function (input, max) { var n = input.length - max; return "Please delete " + n + " character" + (n == 1? "" : "s"); },
formatSelectionTooBig: function (limit) { return "You can only select " + limit + " item" + (limit == 1 ? "" : "s"); },
formatLoadMore: function (pageNumber) { return "Loading more results..."; },
formatSearching: function () { return "Searching..."; },
minimumResultsForSearch: 0,
minimumInputLength: 0,
maximumInputLength: null,
maximumSelectionSize: 0,
id: function (e) { return e.id; },
matcher: function(term, text) {
return (''+text).toUpperCase().indexOf((''+term).toUpperCase()) >= 0;
},
separator: ",",
tokenSeparators: [],
tokenizer: defaultTokenizer,
escapeMarkup: defaultEscapeMarkup,
blurOnChange: false,
selectOnBlur: false,
adaptContainerCssClass: function(c) { return c; },
adaptDropdownCssClass: function(c) { return null; }
};
$.fn.select2.ajaxDefaults = {
transport: $.ajax,
params: {
type: "GET",
cache: false,
dataType: "json"
}
};
// exports
window.Select2 = {
query: {
ajax: ajax,
local: local,
tags: tags
}, util: {
debounce: debounce,
markMatch: markMatch,
escapeMarkup: defaultEscapeMarkup
}, "class": {
"abstract": AbstractSelect2,
"single": SingleSelect2,
"multi": MultiSelect2
}
};
}(jQuery));
// <script type="text/javascript" src="/Scripts/bootstrap-modal/bootstrap-modal.js?3ba151" type="text/javascript"></script>
/* ===========================================================
* bootstrap-modal.js v2.2.5
* ===========================================================
* Copyright 2012 Jordan Schroter
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */
!function ($) {
"use strict"; // jshint ;_;
/* MODAL CLASS DEFINITION
* ====================== */
var Modal = function (element, options) {
this.init(element, options);
};
Modal.prototype = {
constructor: Modal,
init: function (element, options) {
var that = this;
this.options = options;
this.$element = $(element)
.delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this));
this.options.remote && this.$element.find('.modal-body').load(this.options.remote, function () {
var e = $.Event('loaded');
that.$element.trigger(e);
});
var manager = typeof this.options.manager === 'function' ?
this.options.manager.call(this) : this.options.manager;
manager = manager.appendModal ?
manager : $(manager).modalmanager().data('modalmanager');
manager.appendModal(this);
},
toggle: function () {
return this[!this.isShown ? 'show' : 'hide']();
},
show: function () {
var e = $.Event('show');
if (this.isShown) return;
this.$element.trigger(e);
if (e.isDefaultPrevented()) return;
this.escape();
this.tab();
this.options.loading && this.loading();
},
hide: function (e) {
e && e.preventDefault();
e = $.Event('hide');
this.$element.trigger(e);
if (!this.isShown || e.isDefaultPrevented()) return;
this.isShown = false;
this.escape();
this.tab();
this.isLoading && this.loading();
$(document).off('focusin.modal');
this.$element
.removeClass('in')
.removeClass('animated')
.removeClass(this.options.attentionAnimation)
.removeClass('modal-overflow')
.attr('aria-hidden', true);
$.support.transition && this.$element.hasClass('fade') ?
this.hideWithTransition() :
this.hideModal();
},
layout: function () {
var prop = this.options.height ? 'height' : 'max-height',
value = this.options.height || this.options.maxHeight;
if (this.options.width){
this.$element.css('width', this.options.width);
var that = this;
this.$element.css('margin-left', function () {
if (/%/ig.test(that.options.width)){
return -(parseInt(that.options.width) / 2) + '%';
} else {
return -($(this).width() / 2) + 'px';
}
});
} else {
this.$element.css('width', '');
this.$element.css('margin-left', '');
}
this.$element.find('.modal-body')
.css('overflow', '')
.css(prop, '');
if (value){
this.$element.find('.modal-body')
.css('overflow', 'auto')
.css(prop, value);
}
var modalOverflow = $(window).height() - 10 < this.$element.height();
if (modalOverflow || this.options.modalOverflow) {
this.$element
.css('margin-top', 0)
.addClass('modal-overflow');
} else {
this.$element
.css('margin-top', 0 - this.$element.height() / 2)
.removeClass('modal-overflow');
}
},
tab: function () {
var that = this;
if (this.isShown && this.options.consumeTab) {
this.$element.on('keydown.tabindex.modal', '[data-tabindex]', function (e) {
if (e.keyCode && e.keyCode == 9){
var $next = $(this),
$rollover = $(this);
that.$element.find('[data-tabindex]:enabled:not([readonly])').each(function (e) {
if (!e.shiftKey){
$next = $next.data('tabindex') < $(this).data('tabindex') ?
$next = $(this) :
$rollover = $(this);
} else {
$next = $next.data('tabindex') > $(this).data('tabindex') ?
$next = $(this) :
$rollover = $(this);
}
});
$next[0] !== $(this)[0] ?
$next.focus() : $rollover.focus();
e.preventDefault();
}
});
} else if (!this.isShown) {
this.$element.off('keydown.tabindex.modal');
}
},
escape: function () {
var that = this;
if (this.isShown && this.options.keyboard) {
if (!this.$element.attr('tabindex')) this.$element.attr('tabindex', -1);
this.$element.on('keyup.dismiss.modal', function (e) {
e.which == 27 && that.hide();
});
} else if (!this.isShown) {
this.$element.off('keyup.dismiss.modal')
}
},
hideWithTransition: function () {
var that = this
, timeout = setTimeout(function () {
that.$element.off($.support.transition.end);
that.hideModal();
}, 500);
this.$element.one($.support.transition.end, function () {
clearTimeout(timeout);
that.hideModal();
});
},
hideModal: function () {
var prop = this.options.height ? 'height' : 'max-height';
var value = this.options.height || this.options.maxHeight;
if (value){
this.$element.find('.modal-body')
.css('overflow', '')
.css(prop, '');
}
this.$element
.hide()
.trigger('hidden');
},
removeLoading: function () {
this.$loading.remove();
this.$loading = null;
this.isLoading = false;
},
loading: function (callback) {
callback = callback || function () {};
var animate = this.$element.hasClass('fade') ? 'fade' : '';
if (!this.isLoading) {
var doAnimate = $.support.transition && animate;
this.$loading = $('<div class="loading-mask ' + animate + '">')
.append(this.options.spinner)
.appendTo(this.$element);
if (doAnimate) this.$loading[0].offsetWidth; // force reflow
this.$loading.addClass('in');
this.isLoading = true;
doAnimate ?
this.$loading.one($.support.transition.end, callback) :
callback();
} else if (this.isLoading && this.$loading) {
this.$loading.removeClass('in');
var that = this;
$.support.transition && this.$element.hasClass('fade')?
this.$loading.one($.support.transition.end, function () { that.removeLoading() }) :
that.removeLoading();
} else if (callback) {
callback(this.isLoading);
}
},
focus: function () {
var $focusElem = this.$element.find(this.options.focusOn);
$focusElem = $focusElem.length ? $focusElem : this.$element;
$focusElem.focus();
},
attention: function (){
// NOTE: transitionEnd with keyframes causes odd behaviour
if (this.options.attentionAnimation){
this.$element
.removeClass('animated')
.removeClass(this.options.attentionAnimation);
var that = this;
setTimeout(function () {
that.$element
.addClass('animated')
.addClass(that.options.attentionAnimation);
}, 0);
}
this.focus();
},
destroy: function () {
var e = $.Event('destroy');
this.$element.trigger(e);
if (e.isDefaultPrevented()) return;
this.$element
.off('.modal')
.removeData('modal')
.removeClass('in')
.attr('aria-hidden', true);
if (this.$parent !== this.$element.parent()) {
this.$element.appendTo(this.$parent);
} else if (!this.$parent.length) {
// modal is not part of the DOM so remove it.
this.$element.remove();
this.$element = null;
}
this.$element.trigger('destroyed');
}
};
/* MODAL PLUGIN DEFINITION
* ======================= */
$.fn.modal = function (option, args) {
return this.each(function () {
var $this = $(this),
data = $this.data('modal'),
options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option);
if (!data) $this.data('modal', (data = new Modal(this, options)));
if (typeof option == 'string') data[option].apply(data, [].concat(args));
else if (options.show) data.show()
})
};
$.fn.modal.defaults = {
keyboard: true,
backdrop: true,
loading: false,
show: true,
width: null,
height: null,
maxHeight: null,
modalOverflow: false,
consumeTab: true,
focusOn: null,
replace: false,
resize: false,
attentionAnimation: 'shake',
manager: 'body',
spinner: '<div class="loading-spinner" style="width: 200px; margin-left: -100px;"><div class="progress progress-striped active"><div class="bar" style="width: 100%;"></div></div></div>',
backdropTemplate: '<div class="modal-backdrop" />'
};
$.fn.modal.Constructor = Modal;
/* MODAL DATA-API
* ============== */
$(function () {
$(document).off('click.modal').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
var $this = $(this),
href = $this.attr('href'),
$target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))), //strip for ie7
option = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data());
e.preventDefault();
$target
.modal(option)
.one('hide', function () {
$this.focus();
})
});
});
}(window.jQuery);
// <script type="text/javascript" src="/Scripts/bootstrap-modal/bootstrap-modalmanager.js?3ba151" type="text/javascript"></script>
/* ===========================================================
* bootstrap-modalmanager.js v2.2.5
* ===========================================================
* Copyright 2012 Jordan Schroter.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */
!function ($) {
"use strict"; // jshint ;_;
/* MODAL MANAGER CLASS DEFINITION
* ====================== */
var ModalManager = function (element, options) {
this.init(element, options);
};
ModalManager.prototype = {
constructor: ModalManager,
init: function (element, options) {
this.$element = $(element);
this.options = $.extend({}, $.fn.modalmanager.defaults, this.$element.data(), typeof options == 'object' && options);
this.stack = [];
this.backdropCount = 0;
if (this.options.resize) {
var resizeTimeout,
that = this;
$(window).on('resize.modal', function(){
resizeTimeout && clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(function(){
for (var i = 0; i < that.stack.length; i++){
that.stack[i].isShown && that.stack[i].layout();
}
}, 10);
});
}
},
createModal: function (element, options) {
$(element).modal($.extend({ manager: this }, options));
},
appendModal: function (modal) {
this.stack.push(modal);
var that = this;
modal.$element.on('show.modalmanager', targetIsSelf(function (e) {
var showModal = function(){
modal.isShown = true;
var transition = $.support.transition && modal.$element.hasClass('fade');
that.$element
.toggleClass('modal-open', that.hasOpenModal())
.toggleClass('page-overflow', $(window).height() < that.$element.height());
modal.$parent = modal.$element.parent();
modal.$container = that.createContainer(modal);
modal.$element.appendTo(modal.$container);
that.backdrop(modal, function () {
modal.$element.show();
if (transition) {
//modal.$element[0].style.display = 'run-in';
modal.$element[0].offsetWidth;
//modal.$element.one($.support.transition.end, function () { modal.$element[0].style.display = 'block' });
}
modal.layout();
modal.$element
.addClass('in')
.attr('aria-hidden', false);
var complete = function () {
that.setFocus();
modal.$element.trigger('shown');
};
transition ?
modal.$element.one($.support.transition.end, complete) :
complete();
});
};
modal.options.replace ?
that.replace(showModal) :
showModal();
}));
modal.$element.on('hidden.modalmanager', targetIsSelf(function (e) {
that.backdrop(modal);
// handle the case when a modal may have been removed from the dom before this callback executes
if (!modal.$element.parent().length) {
that.destroyModal(modal);
} else if (modal.$backdrop){
var transition = $.support.transition && modal.$element.hasClass('fade');
// trigger a relayout due to firebox's buggy transition end event
if (transition) { modal.$element[0].offsetWidth; }
$.support.transition && modal.$element.hasClass('fade') ?
modal.$backdrop.one($.support.transition.end, function () { modal.destroy(); }) :
modal.destroy();
} else {
modal.destroy();
}
}));
modal.$element.on('destroyed.modalmanager', targetIsSelf(function (e) {
that.destroyModal(modal);
}));
},
getOpenModals: function () {
var openModals = [];
for (var i = 0; i < this.stack.length; i++){
if (this.stack[i].isShown) openModals.push(this.stack[i]);
}
return openModals;
},
hasOpenModal: function () {
return this.getOpenModals().length > 0;
},
setFocus: function () {
var topModal;
for (var i = 0; i < this.stack.length; i++){
if (this.stack[i].isShown) topModal = this.stack[i];
}
if (!topModal) return;
topModal.focus();
},
destroyModal: function (modal) {
modal.$element.off('.modalmanager');
if (modal.$backdrop) this.removeBackdrop(modal);
this.stack.splice(this.getIndexOfModal(modal), 1);
var hasOpenModal = this.hasOpenModal();
this.$element.toggleClass('modal-open', hasOpenModal);
if (!hasOpenModal){
this.$element.removeClass('page-overflow');
}
this.removeContainer(modal);
this.setFocus();
},
getModalAt: function (index) {
return this.stack[index];
},
getIndexOfModal: function (modal) {
for (var i = 0; i < this.stack.length; i++){
if (modal === this.stack[i]) return i;
}
},
replace: function (callback) {
var topModal;
for (var i = 0; i < this.stack.length; i++){
if (this.stack[i].isShown) topModal = this.stack[i];
}
if (topModal) {
this.$backdropHandle = topModal.$backdrop;
topModal.$backdrop = null;
callback && topModal.$element.one('hidden',
targetIsSelf( $.proxy(callback, this) ));
topModal.hide();
} else if (callback) {
callback();
}
},
removeBackdrop: function (modal) {
modal.$backdrop.remove();
modal.$backdrop = null;
},
createBackdrop: function (animate, tmpl) {
var $backdrop;
if (!this.$backdropHandle) {
$backdrop = $(tmpl)
.addClass(animate)
.appendTo(this.$element);
} else {
$backdrop = this.$backdropHandle;
$backdrop.off('.modalmanager');
this.$backdropHandle = null;
this.isLoading && this.removeSpinner();
}
return $backdrop;
},
removeContainer: function (modal) {
modal.$container.remove();
modal.$container = null;
},
createContainer: function (modal) {
var $container;
$container = $('<div class="modal-scrollable">')
.css('z-index', getzIndex('modal', this.getOpenModals().length))
.appendTo(this.$element);
if (modal && modal.options.backdrop != 'static') {
$container.on('click.modal', targetIsSelf(function (e) {
modal.hide();
}));
} else if (modal) {
$container.on('click.modal', targetIsSelf(function (e) {
modal.attention();
}));
}
return $container;
},
backdrop: function (modal, callback) {
var animate = modal.$element.hasClass('fade') ? 'fade' : '',
showBackdrop = modal.options.backdrop &&
this.backdropCount < this.options.backdropLimit;
if (modal.isShown && showBackdrop) {
var doAnimate = $.support.transition && animate && !this.$backdropHandle;
modal.$backdrop = this.createBackdrop(animate, modal.options.backdropTemplate);
modal.$backdrop.css('z-index', getzIndex( 'backdrop', this.getOpenModals().length ));
if (doAnimate) modal.$backdrop[0].offsetWidth; // force reflow
modal.$backdrop.addClass('in');
this.backdropCount += 1;
doAnimate ?
modal.$backdrop.one($.support.transition.end, callback) :
callback();
} else if (!modal.isShown && modal.$backdrop) {
modal.$backdrop.removeClass('in');
this.backdropCount -= 1;
var that = this;
$.support.transition && modal.$element.hasClass('fade')?
modal.$backdrop.one($.support.transition.end, function () { that.removeBackdrop(modal) }) :
that.removeBackdrop(modal);
} else if (callback) {
callback();
}
},
removeSpinner: function(){
this.$spinner && this.$spinner.remove();
this.$spinner = null;
this.isLoading = false;
},
removeLoading: function () {
this.$backdropHandle && this.$backdropHandle.remove();
this.$backdropHandle = null;
this.removeSpinner();
},
loading: function (callback) {
callback = callback || function () { };
this.$element
.toggleClass('modal-open', !this.isLoading || this.hasOpenModal())
.toggleClass('page-overflow', $(window).height() < this.$element.height());
if (!this.isLoading) {
this.$backdropHandle = this.createBackdrop('fade', this.options.backdropTemplate);
this.$backdropHandle[0].offsetWidth; // force reflow
var openModals = this.getOpenModals();
this.$backdropHandle
.css('z-index', getzIndex('backdrop', openModals.length + 1))
.addClass('in');
var $spinner = $(this.options.spinner)
.css('z-index', getzIndex('modal', openModals.length + 1))
.appendTo(this.$element)
.addClass('in');
this.$spinner = $(this.createContainer())
.append($spinner)
.on('click.modalmanager', $.proxy(this.loading, this));
this.isLoading = true;
$.support.transition ?
this.$backdropHandle.one($.support.transition.end, callback) :
callback();
} else if (this.isLoading && this.$backdropHandle) {
this.$backdropHandle.removeClass('in');
var that = this;
$.support.transition ?
this.$backdropHandle.one($.support.transition.end, function () { that.removeLoading() }) :
that.removeLoading();
} else if (callback) {
callback(this.isLoading);
}
}
};
/* PRIVATE METHODS
* ======================= */
// computes and caches the zindexes
var getzIndex = (function () {
var zIndexFactor,
baseIndex = {};
return function (type, pos) {
if (typeof zIndexFactor === 'undefined'){
var $baseModal = $('<div class="modal hide" />').appendTo('body'),
$baseBackdrop = $('<div class="modal-backdrop hide" />').appendTo('body');
baseIndex['modal'] = +$baseModal.css('z-index');
baseIndex['backdrop'] = +$baseBackdrop.css('z-index');
zIndexFactor = baseIndex['modal'] - baseIndex['backdrop'];
$baseModal.remove();
$baseBackdrop.remove();
$baseBackdrop = $baseModal = null;
}
return baseIndex[type] + (zIndexFactor * pos);
}
}());
// make sure the event target is the modal itself in order to prevent
// other components such as tabsfrom triggering the modal manager.
// if Boostsrap namespaced events, this would not be needed.
function targetIsSelf(callback){
return function (e) {
if (e && this === e.target){
return callback.apply(this, arguments);
}
}
}
/* MODAL MANAGER PLUGIN DEFINITION
* ======================= */
$.fn.modalmanager = function (option, args) {
return this.each(function () {
var $this = $(this),
data = $this.data('modalmanager');
if (!data) $this.data('modalmanager', (data = new ModalManager(this, option)));
if (typeof option === 'string') data[option].apply(data, [].concat(args))
})
};
$.fn.modalmanager.defaults = {
backdropLimit: 999,
resize: true,
spinner: '<div class="loading-spinner fade" style="width: 200px; margin-left: -100px;"><div class="progress progress-striped active"><div class="bar" style="width: 100%;"></div></div></div>',
backdropTemplate: '<div class="modal-backdrop" />'
};
$.fn.modalmanager.Constructor = ModalManager
// ModalManager handles the modal-open class so we need
// to remove conflicting bootstrap 3 event handlers
$(function () {
$(document).off('show.bs.modal').off('hidden.bs.modal');
});
}(jQuery);
// <script src="/Scripts/moment/moment.js" type="text/javascript"></script>
//! moment.js
//! version : 2.6.0
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
//! license : MIT
//! momentjs.com
(function (undefined) {
/************************************
Constants
************************************/
var moment,
VERSION = "2.6.0",
// the global-scope this is NOT the global object in Node.js
globalScope = typeof global !== 'undefined' ? global : this,
oldGlobalMoment,
round = Math.round,
i,
YEAR = 0,
MONTH = 1,
DATE = 2,
HOUR = 3,
MINUTE = 4,
SECOND = 5,
MILLISECOND = 6,
// internal storage for language config files
languages = {},
// moment internal properties
momentProperties = {
_isAMomentObject: null,
_i : null,
_f : null,
_l : null,
_strict : null,
_isUTC : null,
_offset : null, // optional. Combine with _isUTC
_pf : null,
_lang : null // optional
},
// check for nodeJS
hasModule = (typeof module !== 'undefined' && module.exports),
// ASP.NET json date format regex
aspNetJsonRegex = /^\/?Date\((\-?\d+)/i,
aspNetTimeSpanJsonRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,
// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/,
// format tokens
formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g,
localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,
// parsing token regexes
parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99
parseTokenOneToThreeDigits = /\d{1,3}/, // 0 - 999
parseTokenOneToFourDigits = /\d{1,4}/, // 0 - 9999
parseTokenOneToSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999
parseTokenDigits = /\d+/, // nonzero number of digits
parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic.
parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z
parseTokenT = /T/i, // T (ISO separator)
parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123
parseTokenOrdinal = /\d{1,2}/,
//strict parsing regexes
parseTokenOneDigit = /\d/, // 0 - 9
parseTokenTwoDigits = /\d\d/, // 00 - 99
parseTokenThreeDigits = /\d{3}/, // 000 - 999
parseTokenFourDigits = /\d{4}/, // 0000 - 9999
parseTokenSixDigits = /[+-]?\d{6}/, // -999,999 - 999,999
parseTokenSignedNumber = /[+-]?\d+/, // -inf - inf
// iso 8601 regex
// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
isoRegex = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,
isoFormat = 'YYYY-MM-DDTHH:mm:ssZ',
isoDates = [
['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/],
['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/],
['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/],
['GGGG-[W]WW', /\d{4}-W\d{2}/],
['YYYY-DDD', /\d{4}-\d{3}/]
],
// iso time formats and regexes
isoTimes = [
['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d+/],
['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/],
['HH:mm', /(T| )\d\d:\d\d/],
['HH', /(T| )\d\d/]
],
// timezone chunker "+10:00" > ["10", "00"] or "-1530" > ["-15", "30"]
parseTimezoneChunker = /([\+\-]|\d\d)/gi,
// getter and setter names
proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'),
unitMillisecondFactors = {
'Milliseconds' : 1,
'Seconds' : 1e3,
'Minutes' : 6e4,
'Hours' : 36e5,
'Days' : 864e5,
'Months' : 2592e6,
'Years' : 31536e6
},
unitAliases = {
ms : 'millisecond',
s : 'second',
m : 'minute',
h : 'hour',
d : 'day',
D : 'date',
w : 'week',
W : 'isoWeek',
M : 'month',
Q : 'quarter',
y : 'year',
DDD : 'dayOfYear',
e : 'weekday',
E : 'isoWeekday',
gg: 'weekYear',
GG: 'isoWeekYear'
},
camelFunctions = {
dayofyear : 'dayOfYear',
isoweekday : 'isoWeekday',
isoweek : 'isoWeek',
weekyear : 'weekYear',
isoweekyear : 'isoWeekYear'
},
// format function strings
formatFunctions = {},
// default relative time thresholds
relativeTimeThresholds = {
s: 45, //seconds to minutes
m: 45, //minutes to hours
h: 22, //hours to days
dd: 25, //days to month (month == 1)
dm: 45, //days to months (months > 1)
dy: 345 //days to year
},
// tokens to ordinalize and pad
ordinalizeTokens = 'DDD w W M D d'.split(' '),
paddedTokens = 'M D H h m s w W'.split(' '),
formatTokenFunctions = {
M : function () {
return this.month() + 1;
},
MMM : function (format) {
return this.lang().monthsShort(this, format);
},
MMMM : function (format) {
return this.lang().months(this, format);
},
D : function () {
return this.date();
},
DDD : function () {
return this.dayOfYear();
},
d : function () {
return this.day();
},
dd : function (format) {
return this.lang().weekdaysMin(this, format);
},
ddd : function (format) {
return this.lang().weekdaysShort(this, format);
},
dddd : function (format) {
return this.lang().weekdays(this, format);
},
w : function () {
return this.week();
},
W : function () {
return this.isoWeek();
},
YY : function () {
return leftZeroFill(this.year() % 100, 2);
},
YYYY : function () {
return leftZeroFill(this.year(), 4);
},
YYYYY : function () {
return leftZeroFill(this.year(), 5);
},
YYYYYY : function () {
var y = this.year(), sign = y >= 0 ? '+' : '-';
return sign + leftZeroFill(Math.abs(y), 6);
},
gg : function () {
return leftZeroFill(this.weekYear() % 100, 2);
},
gggg : function () {
return leftZeroFill(this.weekYear(), 4);
},
ggggg : function () {
return leftZeroFill(this.weekYear(), 5);
},
GG : function () {
return leftZeroFill(this.isoWeekYear() % 100, 2);
},
GGGG : function () {
return leftZeroFill(this.isoWeekYear(), 4);
},
GGGGG : function () {
return leftZeroFill(this.isoWeekYear(), 5);
},
e : function () {
return this.weekday();
},
E : function () {
return this.isoWeekday();
},
a : function () {
return this.lang().meridiem(this.hours(), this.minutes(), true);
},
A : function () {
return this.lang().meridiem(this.hours(), this.minutes(), false);
},
H : function () {
return this.hours();
},
h : function () {
return this.hours() % 12 || 12;
},
m : function () {
return this.minutes();
},
s : function () {
return this.seconds();
},
S : function () {
return toInt(this.milliseconds() / 100);
},
SS : function () {
return leftZeroFill(toInt(this.milliseconds() / 10), 2);
},
SSS : function () {
return leftZeroFill(this.milliseconds(), 3);
},
SSSS : function () {
return leftZeroFill(this.milliseconds(), 3);
},
Z : function () {
var a = -this.zone(),
b = "+";
if (a < 0) {
a = -a;
b = "-";
}
return b + leftZeroFill(toInt(a / 60), 2) + ":" + leftZeroFill(toInt(a) % 60, 2);
},
ZZ : function () {
var a = -this.zone(),
b = "+";
if (a < 0) {
a = -a;
b = "-";
}
return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2);
},
z : function () {
return this.zoneAbbr();
},
zz : function () {
return this.zoneName();
},
X : function () {
return this.unix();
},
Q : function () {
return this.quarter();
}
},
lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin'];
// Pick the first defined of two or three arguments. dfl comes from
// default.
function dfl(a, b, c) {
switch (arguments.length) {
case 2: return a != null ? a : b;
case 3: return a != null ? a : b != null ? b : c;
default: throw new Error("Implement me");
}
}
function defaultParsingFlags() {
// We need to deep clone this object, and es5 standard is not very
// helpful.
return {
empty : false,
unusedTokens : [],
unusedInput : [],
overflow : -2,
charsLeftOver : 0,
nullInput : false,
invalidMonth : null,
invalidFormat : false,
userInvalidated : false,
iso: false
};
}
function deprecate(msg, fn) {
var firstTime = true;
function printMsg() {
if (moment.suppressDeprecationWarnings === false &&
typeof console !== 'undefined' && console.warn) {
console.warn("Deprecation warning: " + msg);
}
}
return extend(function () {
if (firstTime) {
printMsg();
firstTime = false;
}
return fn.apply(this, arguments);
}, fn);
}
function padToken(func, count) {
return function (a) {
return leftZeroFill(func.call(this, a), count);
};
}
function ordinalizeToken(func, period) {
return function (a) {
return this.lang().ordinal(func.call(this, a), period);
};
}
while (ordinalizeTokens.length) {
i = ordinalizeTokens.pop();
formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i], i);
}
while (paddedTokens.length) {
i = paddedTokens.pop();
formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2);
}
formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3);
/************************************
Constructors
************************************/
function Language() {
}
// Moment prototype object
function Moment(config) {
checkOverflow(config);
extend(this, config);
}
// Duration Constructor
function Duration(duration) {
var normalizedInput = normalizeObjectUnits(duration),
years = normalizedInput.year || 0,
quarters = normalizedInput.quarter || 0,
months = normalizedInput.month || 0,
weeks = normalizedInput.week || 0,
days = normalizedInput.day || 0,
hours = normalizedInput.hour || 0,
minutes = normalizedInput.minute || 0,
seconds = normalizedInput.second || 0,
milliseconds = normalizedInput.millisecond || 0;
// representation for dateAddRemove
this._milliseconds = +milliseconds +
seconds * 1e3 + // 1000
minutes * 6e4 + // 1000 * 60
hours * 36e5; // 1000 * 60 * 60
// Because of dateAddRemove treats 24 hours as different from a
// day when working around DST, we need to store them separately
this._days = +days +
weeks * 7;
// It is impossible translate months into days without knowing
// which months you are are talking about, so we have to store
// it separately.
this._months = +months +
quarters * 3 +
years * 12;
this._data = {};
this._bubble();
}
/************************************
Helpers
************************************/
function extend(a, b) {
for (var i in b) {
if (b.hasOwnProperty(i)) {
a[i] = b[i];
}
}
if (b.hasOwnProperty("toString")) {
a.toString = b.toString;
}
if (b.hasOwnProperty("valueOf")) {
a.valueOf = b.valueOf;
}
return a;
}
function cloneMoment(m) {
var result = {}, i;
for (i in m) {
if (m.hasOwnProperty(i) && momentProperties.hasOwnProperty(i)) {
result[i] = m[i];
}
}
return result;
}
function absRound(number) {
if (number < 0) {
return Math.ceil(number);
} else {
return Math.floor(number);
}
}
// left zero fill a number
// see http://jsperf.com/left-zero-filling for performance comparison
function leftZeroFill(number, targetLength, forceSign) {
var output = '' + Math.abs(number),
sign = number >= 0;
while (output.length < targetLength) {
output = '0' + output;
}
return (sign ? (forceSign ? '+' : '') : '-') + output;
}
// helper function for _.addTime and _.subtractTime
function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) {
var milliseconds = duration._milliseconds,
days = duration._days,
months = duration._months;
updateOffset = updateOffset == null ? true : updateOffset;
if (milliseconds) {
mom._d.setTime(+mom._d + milliseconds * isAdding);
}
if (days) {
rawSetter(mom, 'Date', rawGetter(mom, 'Date') + days * isAdding);
}
if (months) {
rawMonthSetter(mom, rawGetter(mom, 'Month') + months * isAdding);
}
if (updateOffset) {
moment.updateOffset(mom, days || months);
}
}
// check if is an array
function isArray(input) {
return Object.prototype.toString.call(input) === '[object Array]';
}
function isDate(input) {
return Object.prototype.toString.call(input) === '[object Date]' ||
input instanceof Date;
}
// compare two arrays, return the number of differences
function compareArrays(array1, array2, dontConvert) {
var len = Math.min(array1.length, array2.length),
lengthDiff = Math.abs(array1.length - array2.length),
diffs = 0,
i;
for (i = 0; i < len; i++) {
if ((dontConvert && array1[i] !== array2[i]) ||
(!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
diffs++;
}
}
return diffs + lengthDiff;
}
function normalizeUnits(units) {
if (units) {
var lowered = units.toLowerCase().replace(/(.)s$/, '$1');
units = unitAliases[units] || camelFunctions[lowered] || lowered;
}
return units;
}
function normalizeObjectUnits(inputObject) {
var normalizedInput = {},
normalizedProp,
prop;
for (prop in inputObject) {
if (inputObject.hasOwnProperty(prop)) {
normalizedProp = normalizeUnits(prop);
if (normalizedProp) {
normalizedInput[normalizedProp] = inputObject[prop];
}
}
}
return normalizedInput;
}
function makeList(field) {
var count, setter;
if (field.indexOf('week') === 0) {
count = 7;
setter = 'day';
}
else if (field.indexOf('month') === 0) {
count = 12;
setter = 'month';
}
else {
return;
}
moment[field] = function (format, index) {
var i, getter,
method = moment.fn._lang[field],
results = [];
if (typeof format === 'number') {
index = format;
format = undefined;
}
getter = function (i) {
var m = moment().utc().set(setter, i);
return method.call(moment.fn._lang, m, format || '');
};
if (index != null) {
return getter(index);
}
else {
for (i = 0; i < count; i++) {
results.push(getter(i));
}
return results;
}
};
}
function toInt(argumentForCoercion) {
var coercedNumber = +argumentForCoercion,
value = 0;
if (coercedNumber !== 0 && isFinite(coercedNumber)) {
if (coercedNumber >= 0) {
value = Math.floor(coercedNumber);
} else {
value = Math.ceil(coercedNumber);
}
}
return value;
}
function daysInMonth(year, month) {
return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
}
function weeksInYear(year, dow, doy) {
return weekOfYear(moment([year, 11, 31 + dow - doy]), dow, doy).week;
}
function daysInYear(year) {
return isLeapYear(year) ? 366 : 365;
}
function isLeapYear(year) {
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
}
function checkOverflow(m) {
var overflow;
if (m._a && m._pf.overflow === -2) {
overflow =
m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH :
m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE :
m._a[HOUR] < 0 || m._a[HOUR] > 23 ? HOUR :
m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE :
m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND :
m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND :
-1;
if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
overflow = DATE;
}
m._pf.overflow = overflow;
}
}
function isValid(m) {
if (m._isValid == null) {
m._isValid = !isNaN(m._d.getTime()) &&
m._pf.overflow < 0 &&
!m._pf.empty &&
!m._pf.invalidMonth &&
!m._pf.nullInput &&
!m._pf.invalidFormat &&
!m._pf.userInvalidated;
if (m._strict) {
m._isValid = m._isValid &&
m._pf.charsLeftOver === 0 &&
m._pf.unusedTokens.length === 0;
}
}
return m._isValid;
}
function normalizeLanguage(key) {
return key ? key.toLowerCase().replace('_', '-') : key;
}
// Return a moment from input, that is local/utc/zone equivalent to model.
function makeAs(input, model) {
return model._isUTC ? moment(input).zone(model._offset || 0) :
moment(input).local();
}
/************************************
Languages
************************************/
extend(Language.prototype, {
set : function (config) {
var prop, i;
for (i in config) {
prop = config[i];
if (typeof prop === 'function') {
this[i] = prop;
} else {
this['_' + i] = prop;
}
}
},
_months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
months : function (m) {
return this._months[m.month()];
},
_monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
monthsShort : function (m) {
return this._monthsShort[m.month()];
},
monthsParse : function (monthName) {
var i, mom, regex;
if (!this._monthsParse) {
this._monthsParse = [];
}
for (i = 0; i < 12; i++) {
// make the regex if we don't have it already
if (!this._monthsParse[i]) {
mom = moment.utc([2000, i]);
regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
}
// test the regex
if (this._monthsParse[i].test(monthName)) {
return i;
}
}
},
_weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
weekdays : function (m) {
return this._weekdays[m.day()];
},
_weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
weekdaysShort : function (m) {
return this._weekdaysShort[m.day()];
},
_weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"),
weekdaysMin : function (m) {
return this._weekdaysMin[m.day()];
},
weekdaysParse : function (weekdayName) {
var i, mom, regex;
if (!this._weekdaysParse) {
this._weekdaysParse = [];
}
for (i = 0; i < 7; i++) {
// make the regex if we don't have it already
if (!this._weekdaysParse[i]) {
mom = moment([2000, 1]).day(i);
regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
}
// test the regex
if (this._weekdaysParse[i].test(weekdayName)) {
return i;
}
}
},
_longDateFormat : {
LT : "h:mm A",
L : "MM/DD/YYYY",
LL : "MMMM D YYYY",
LLL : "MMMM D YYYY LT",
LLLL : "dddd, MMMM D YYYY LT"
},
longDateFormat : function (key) {
var output = this._longDateFormat[key];
if (!output && this._longDateFormat[key.toUpperCase()]) {
output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) {
return val.slice(1);
});
this._longDateFormat[key] = output;
}
return output;
},
isPM : function (input) {
// IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
// Using charAt should be more compatible.
return ((input + '').toLowerCase().charAt(0) === 'p');
},
_meridiemParse : /[ap]\.?m?\.?/i,
meridiem : function (hours, minutes, isLower) {
if (hours > 11) {
return isLower ? 'pm' : 'PM';
} else {
return isLower ? 'am' : 'AM';
}
},
_calendar : {
sameDay : '[Today at] LT',
nextDay : '[Tomorrow at] LT',
nextWeek : 'dddd [at] LT',
lastDay : '[Yesterday at] LT',
lastWeek : '[Last] dddd [at] LT',
sameElse : 'L'
},
calendar : function (key, mom) {
var output = this._calendar[key];
return typeof output === 'function' ? output.apply(mom) : output;
},
_relativeTime : {
future : "in %s",
past : "%s ago",
s : "a few seconds",
m : "a minute",
mm : "%d minutes",
h : "an hour",
hh : "%d hours",
d : "a day",
dd : "%d days",
M : "a month",
MM : "%d months",
y : "a year",
yy : "%d years"
},
relativeTime : function (number, withoutSuffix, string, isFuture) {
var output = this._relativeTime[string];
return (typeof output === 'function') ?
output(number, withoutSuffix, string, isFuture) :
output.replace(/%d/i, number);
},
pastFuture : function (diff, output) {
var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);
},
ordinal : function (number) {
return this._ordinal.replace("%d", number);
},
_ordinal : "%d",
preparse : function (string) {
return string;
},
postformat : function (string) {
return string;
},
week : function (mom) {
return weekOfYear(mom, this._week.dow, this._week.doy).week;
},
_week : {
dow : 0, // Sunday is the first day of the week.
doy : 6 // The week that contains Jan 1st is the first week of the year.
},
_invalidDate: 'Invalid date',
invalidDate: function () {
return this._invalidDate;
}
});
// Loads a language definition into the `languages` cache. The function
// takes a key and optionally values. If not in the browser and no values
// are provided, it will load the language file module. As a convenience,
// this function also returns the language values.
function loadLang(key, values) {
values.abbr = key;
if (!languages[key]) {
languages[key] = new Language();
}
languages[key].set(values);
return languages[key];
}
// Remove a language from the `languages` cache. Mostly useful in tests.
function unloadLang(key) {
delete languages[key];
}
// Determines which language definition to use and returns it.
//
// With no parameters, it will return the global language. If you
// pass in a language key, such as 'en', it will return the
// definition for 'en', so long as 'en' has already been loaded using
// moment.lang.
function getLangDefinition(key) {
var i = 0, j, lang, next, split,
get = function (k) {
if (!languages[k] && hasModule) {
try {
require('./lang/' + k);
} catch (e) { }
}
return languages[k];
};
if (!key) {
return moment.fn._lang;
}
if (!isArray(key)) {
//short-circuit everything else
lang = get(key);
if (lang) {
return lang;
}
key = [key];
}
//pick the language from the array
//try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
//substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
while (i < key.length) {
split = normalizeLanguage(key[i]).split('-');
j = split.length;
next = normalizeLanguage(key[i + 1]);
next = next ? next.split('-') : null;
while (j > 0) {
lang = get(split.slice(0, j).join('-'));
if (lang) {
return lang;
}
if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
//the next array item is better than a shallower substring of this one
break;
}
j--;
}
i++;
}
return moment.fn._lang;
}
/************************************
Formatting
************************************/
function removeFormattingTokens(input) {
if (input.match(/\[[\s\S]/)) {
return input.replace(/^\[|\]$/g, "");
}
return input.replace(/\\/g, "");
}
function makeFormatFunction(format) {
var array = format.match(formattingTokens), i, length;
for (i = 0, length = array.length; i < length; i++) {
if (formatTokenFunctions[array[i]]) {
array[i] = formatTokenFunctions[array[i]];
} else {
array[i] = removeFormattingTokens(array[i]);
}
}
return function (mom) {
var output = "";
for (i = 0; i < length; i++) {
output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
}
return output;
};
}
// format date using native date object
function formatMoment(m, format) {
if (!m.isValid()) {
return m.lang().invalidDate();
}
format = expandFormat(format, m.lang());
if (!formatFunctions[format]) {
formatFunctions[format] = makeFormatFunction(format);
}
return formatFunctions[format](m);
}
function expandFormat(format, lang) {
var i = 5;
function replaceLongDateFormatTokens(input) {
return lang.longDateFormat(input) || input;
}
localFormattingTokens.lastIndex = 0;
while (i >= 0 && localFormattingTokens.test(format)) {
format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
localFormattingTokens.lastIndex = 0;
i -= 1;
}
return format;
}
/************************************
Parsing
************************************/
// get the regex to find the next token
function getParseRegexForToken(token, config) {
var a, strict = config._strict;
switch (token) {
case 'Q':
return parseTokenOneDigit;
case 'DDDD':
return parseTokenThreeDigits;
case 'YYYY':
case 'GGGG':
case 'gggg':
return strict ? parseTokenFourDigits : parseTokenOneToFourDigits;
case 'Y':
case 'G':
case 'g':
return parseTokenSignedNumber;
case 'YYYYYY':
case 'YYYYY':
case 'GGGGG':
case 'ggggg':
return strict ? parseTokenSixDigits : parseTokenOneToSixDigits;
case 'S':
if (strict) { return parseTokenOneDigit; }
/* falls through */
case 'SS':
if (strict) { return parseTokenTwoDigits; }
/* falls through */
case 'SSS':
if (strict) { return parseTokenThreeDigits; }
/* falls through */
case 'DDD':
return parseTokenOneToThreeDigits;
case 'MMM':
case 'MMMM':
case 'dd':
case 'ddd':
case 'dddd':
return parseTokenWord;
case 'a':
case 'A':
return getLangDefinition(config._l)._meridiemParse;
case 'X':
return parseTokenTimestampMs;
case 'Z':
case 'ZZ':
return parseTokenTimezone;
case 'T':
return parseTokenT;
case 'SSSS':
return parseTokenDigits;
case 'MM':
case 'DD':
case 'YY':
case 'GG':
case 'gg':
case 'HH':
case 'hh':
case 'mm':
case 'ss':
case 'ww':
case 'WW':
return strict ? parseTokenTwoDigits : parseTokenOneOrTwoDigits;
case 'M':
case 'D':
case 'd':
case 'H':
case 'h':
case 'm':
case 's':
case 'w':
case 'W':
case 'e':
case 'E':
return parseTokenOneOrTwoDigits;
case 'Do':
return parseTokenOrdinal;
default :
a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), "i"));
return a;
}
}
function timezoneMinutesFromString(string) {
string = string || "";
var possibleTzMatches = (string.match(parseTokenTimezone) || []),
tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [],
parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0],
minutes = +(parts[1] * 60) + toInt(parts[2]);
return parts[0] === '+' ? -minutes : minutes;
}
// function to convert string input to date
function addTimeToArrayFromToken(token, input, config) {
var a, datePartArray = config._a;
switch (token) {
// QUARTER
case 'Q':
if (input != null) {
datePartArray[MONTH] = (toInt(input) - 1) * 3;
}
break;
// MONTH
case 'M' : // fall through to MM
case 'MM' :
if (input != null) {
datePartArray[MONTH] = toInt(input) - 1;
}
break;
case 'MMM' : // fall through to MMMM
case 'MMMM' :
a = getLangDefinition(config._l).monthsParse(input);
// if we didn't find a month name, mark the date as invalid.
if (a != null) {
datePartArray[MONTH] = a;
} else {
config._pf.invalidMonth = input;
}
break;
// DAY OF MONTH
case 'D' : // fall through to DD
case 'DD' :
if (input != null) {
datePartArray[DATE] = toInt(input);
}
break;
case 'Do' :
if (input != null) {
datePartArray[DATE] = toInt(parseInt(input, 10));
}
break;
// DAY OF YEAR
case 'DDD' : // fall through to DDDD
case 'DDDD' :
if (input != null) {
config._dayOfYear = toInt(input);
}
break;
// YEAR
case 'YY' :
datePartArray[YEAR] = moment.parseTwoDigitYear(input);
break;
case 'YYYY' :
case 'YYYYY' :
case 'YYYYYY' :
datePartArray[YEAR] = toInt(input);
break;
// AM / PM
case 'a' : // fall through to A
case 'A' :
config._isPm = getLangDefinition(config._l).isPM(input);
break;
// 24 HOUR
case 'H' : // fall through to hh
case 'HH' : // fall through to hh
case 'h' : // fall through to hh
case 'hh' :
datePartArray[HOUR] = toInt(input);
break;
// MINUTE
case 'm' : // fall through to mm
case 'mm' :
datePartArray[MINUTE] = toInt(input);
break;
// SECOND
case 's' : // fall through to ss
case 'ss' :
datePartArray[SECOND] = toInt(input);
break;
// MILLISECOND
case 'S' :
case 'SS' :
case 'SSS' :
case 'SSSS' :
datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000);
break;
// UNIX TIMESTAMP WITH MS
case 'X':
config._d = new Date(parseFloat(input) * 1000);
break;
// TIMEZONE
case 'Z' : // fall through to ZZ
case 'ZZ' :
config._useUTC = true;
config._tzm = timezoneMinutesFromString(input);
break;
// WEEKDAY - human
case 'dd':
case 'ddd':
case 'dddd':
a = getLangDefinition(config._l).weekdaysParse(input);
// if we didn't get a weekday name, mark the date as invalid
if (a != null) {
config._w = config._w || {};
config._w['d'] = a;
} else {
config._pf.invalidWeekday = input;
}
break;
// WEEK, WEEK DAY - numeric
case 'w':
case 'ww':
case 'W':
case 'WW':
case 'd':
case 'e':
case 'E':
token = token.substr(0, 1);
/* falls through */
case 'gggg':
case 'GGGG':
case 'GGGGG':
token = token.substr(0, 2);
if (input) {
config._w = config._w || {};
config._w[token] = toInt(input);
}
break;
case 'gg':
case 'GG':
config._w = config._w || {};
config._w[token] = moment.parseTwoDigitYear(input);
}
}
function dayOfYearFromWeekInfo(config) {
var w, weekYear, week, weekday, dow, doy, temp, lang;
w = config._w;
if (w.GG != null || w.W != null || w.E != null) {
dow = 1;
doy = 4;
// TODO: We need to take the current isoWeekYear, but that depends on
// how we interpret now (local, utc, fixed offset). So create
// a now version of current config (take local/utc/offset flags, and
// create now).
weekYear = dfl(w.GG, config._a[YEAR], weekOfYear(moment(), 1, 4).year);
week = dfl(w.W, 1);
weekday = dfl(w.E, 1);
} else {
lang = getLangDefinition(config._l);
dow = lang._week.dow;
doy = lang._week.doy;
weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year);
week = dfl(w.w, 1);
if (w.d != null) {
// weekday -- low day numbers are considered next week
weekday = w.d;
if (weekday < dow) {
++week;
}
} else if (w.e != null) {
// local weekday -- counting starts from begining of week
weekday = w.e + dow;
} else {
// default to begining of week
weekday = dow;
}
}
temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow);
config._a[YEAR] = temp.year;
config._dayOfYear = temp.dayOfYear;
}
// convert an array to a date.
// the array should mirror the parameters below
// note: all values past the year are optional and will default to the lowest possible value.
// [year, month, day , hour, minute, second, millisecond]
function dateFromConfig(config) {
var i, date, input = [], currentDate, yearToUse;
if (config._d) {
return;
}
currentDate = currentDateArray(config);
//compute day of the year from weeks and weekdays
if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
dayOfYearFromWeekInfo(config);
}
//if the day of the year is set, figure out what it is
if (config._dayOfYear) {
yearToUse = dfl(config._a[YEAR], currentDate[YEAR]);
if (config._dayOfYear > daysInYear(yearToUse)) {
config._pf._overflowDayOfYear = true;
}
date = makeUTCDate(yearToUse, 0, config._dayOfYear);
config._a[MONTH] = date.getUTCMonth();
config._a[DATE] = date.getUTCDate();
}
// Default to current date.
// * if no year, month, day of month are given, default to today
// * if day of month is given, default month and year
// * if month is given, default only year
// * if year is given, don't default anything
for (i = 0; i < 3 && config._a[i] == null; ++i) {
config._a[i] = input[i] = currentDate[i];
}
// Zero out whatever was not defaulted, including time
for (; i < 7; i++) {
config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
}
// add the offsets to the time to be parsed so that we can have a clean array for checking isValid
input[HOUR] += toInt((config._tzm || 0) / 60);
input[MINUTE] += toInt((config._tzm || 0) % 60);
config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input);
}
function dateFromObject(config) {
var normalizedInput;
if (config._d) {
return;
}
normalizedInput = normalizeObjectUnits(config._i);
config._a = [
normalizedInput.year,
normalizedInput.month,
normalizedInput.day,
normalizedInput.hour,
normalizedInput.minute,
normalizedInput.second,
normalizedInput.millisecond
];
dateFromConfig(config);
}
function currentDateArray(config) {
var now = new Date();
if (config._useUTC) {
return [
now.getUTCFullYear(),
now.getUTCMonth(),
now.getUTCDate()
];
} else {
return [now.getFullYear(), now.getMonth(), now.getDate()];
}
}
// date from string and format string
function makeDateFromStringAndFormat(config) {
config._a = [];
config._pf.empty = true;
// This array is used to make a Date, either with `new Date` or `Date.UTC`
var lang = getLangDefinition(config._l),
string = '' + config._i,
i, parsedInput, tokens, token, skipped,
stringLength = string.length,
totalParsedInputLength = 0;
tokens = expandFormat(config._f, lang).match(formattingTokens) || [];
for (i = 0; i < tokens.length; i++) {
token = tokens[i];
parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
if (parsedInput) {
skipped = string.substr(0, string.indexOf(parsedInput));
if (skipped.length > 0) {
config._pf.unusedInput.push(skipped);
}
string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
totalParsedInputLength += parsedInput.length;
}
// don't parse if it's not a known token
if (formatTokenFunctions[token]) {
if (parsedInput) {
config._pf.empty = false;
}
else {
config._pf.unusedTokens.push(token);
}
addTimeToArrayFromToken(token, parsedInput, config);
}
else if (config._strict && !parsedInput) {
config._pf.unusedTokens.push(token);
}
}
// add remaining unparsed input length to the string
config._pf.charsLeftOver = stringLength - totalParsedInputLength;
if (string.length > 0) {
config._pf.unusedInput.push(string);
}
// handle am pm
if (config._isPm && config._a[HOUR] < 12) {
config._a[HOUR] += 12;
}
// if is 12 am, change hours to 0
if (config._isPm === false && config._a[HOUR] === 12) {
config._a[HOUR] = 0;
}
dateFromConfig(config);
checkOverflow(config);
}
function unescapeFormat(s) {
return s.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
return p1 || p2 || p3 || p4;
});
}
// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
function regexpEscape(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
// date from string and array of format strings
function makeDateFromStringAndArray(config) {
var tempConfig,
bestMoment,
scoreToBeat,
i,
currentScore;
if (config._f.length === 0) {
config._pf.invalidFormat = true;
config._d = new Date(NaN);
return;
}
for (i = 0; i < config._f.length; i++) {
currentScore = 0;
tempConfig = extend({}, config);
tempConfig._pf = defaultParsingFlags();
tempConfig._f = config._f[i];
makeDateFromStringAndFormat(tempConfig);
if (!isValid(tempConfig)) {
continue;
}
// if there is any input that was not parsed add a penalty for that format
currentScore += tempConfig._pf.charsLeftOver;
//or tokens
currentScore += tempConfig._pf.unusedTokens.length * 10;
tempConfig._pf.score = currentScore;
if (scoreToBeat == null || currentScore < scoreToBeat) {
scoreToBeat = currentScore;
bestMoment = tempConfig;
}
}
extend(config, bestMoment || tempConfig);
}
// date from iso format
function makeDateFromString(config) {
var i, l,
string = config._i,
match = isoRegex.exec(string);
if (match) {
config._pf.iso = true;
for (i = 0, l = isoDates.length; i < l; i++) {
if (isoDates[i][1].exec(string)) {
// match[5] should be "T" or undefined
config._f = isoDates[i][0] + (match[6] || " ");
break;
}
}
for (i = 0, l = isoTimes.length; i < l; i++) {
if (isoTimes[i][1].exec(string)) {
config._f += isoTimes[i][0];
break;
}
}
if (string.match(parseTokenTimezone)) {
config._f += "Z";
}
makeDateFromStringAndFormat(config);
}
else {
moment.createFromInputFallback(config);
}
}
function makeDateFromInput(config) {
var input = config._i,
matched = aspNetJsonRegex.exec(input);
if (input === undefined) {
config._d = new Date();
} else if (matched) {
config._d = new Date(+matched[1]);
} else if (typeof input === 'string') {
makeDateFromString(config);
} else if (isArray(input)) {
config._a = input.slice(0);
dateFromConfig(config);
} else if (isDate(input)) {
config._d = new Date(+input);
} else if (typeof(input) === 'object') {
dateFromObject(config);
} else if (typeof(input) === 'number') {
// from milliseconds
config._d = new Date(input);
} else {
moment.createFromInputFallback(config);
}
}
function makeDate(y, m, d, h, M, s, ms) {
//can't just apply() to create a date:
//http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
var date = new Date(y, m, d, h, M, s, ms);
//the date constructor doesn't accept years < 1970
if (y < 1970) {
date.setFullYear(y);
}
return date;
}
function makeUTCDate(y) {
var date = new Date(Date.UTC.apply(null, arguments));
if (y < 1970) {
date.setUTCFullYear(y);
}
return date;
}
function parseWeekday(input, language) {
if (typeof input === 'string') {
if (!isNaN(input)) {
input = parseInt(input, 10);
}
else {
input = language.weekdaysParse(input);
if (typeof input !== 'number') {
return null;
}
}
}
return input;
}
/************************************
Relative Time
************************************/
// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
function substituteTimeAgo(string, number, withoutSuffix, isFuture, lang) {
return lang.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
}
function relativeTime(milliseconds, withoutSuffix, lang) {
var seconds = round(Math.abs(milliseconds) / 1000),
minutes = round(seconds / 60),
hours = round(minutes / 60),
days = round(hours / 24),
years = round(days / 365),
args = seconds < relativeTimeThresholds.s && ['s', seconds] ||
minutes === 1 && ['m'] ||
minutes < relativeTimeThresholds.m && ['mm', minutes] ||
hours === 1 && ['h'] ||
hours < relativeTimeThresholds.h && ['hh', hours] ||
days === 1 && ['d'] ||
days <= relativeTimeThresholds.dd && ['dd', days] ||
days <= relativeTimeThresholds.dm && ['M'] ||
days < relativeTimeThresholds.dy && ['MM', round(days / 30)] ||
years === 1 && ['y'] || ['yy', years];
args[2] = withoutSuffix;
args[3] = milliseconds > 0;
args[4] = lang;
return substituteTimeAgo.apply({}, args);
}
/************************************
Week of Year
************************************/
// firstDayOfWeek 0 = sun, 6 = sat
// the day of the week that starts the week
// (usually sunday or monday)
// firstDayOfWeekOfYear 0 = sun, 6 = sat
// the first week is the week that contains the first
// of this day of the week
// (eg. ISO weeks use thursday (4))
function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {
var end = firstDayOfWeekOfYear - firstDayOfWeek,
daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),
adjustedMoment;
if (daysToDayOfWeek > end) {
daysToDayOfWeek -= 7;
}
if (daysToDayOfWeek < end - 7) {
daysToDayOfWeek += 7;
}
adjustedMoment = moment(mom).add('d', daysToDayOfWeek);
return {
week: Math.ceil(adjustedMoment.dayOfYear() / 7),
year: adjustedMoment.year()
};
}
//http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {
var d = makeUTCDate(year, 0, 1).getUTCDay(), daysToAdd, dayOfYear;
d = d === 0 ? 7 : d;
weekday = weekday != null ? weekday : firstDayOfWeek;
daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0);
dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1;
return {
year: dayOfYear > 0 ? year : year - 1,
dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear
};
}
/************************************
Top Level Functions
************************************/
function makeMoment(config) {
var input = config._i,
format = config._f;
if (input === null || (format === undefined && input === '')) {
return moment.invalid({nullInput: true});
}
if (typeof input === 'string') {
config._i = input = getLangDefinition().preparse(input);
}
if (moment.isMoment(input)) {
config = cloneMoment(input);
config._d = new Date(+input._d);
} else if (format) {
if (isArray(format)) {
makeDateFromStringAndArray(config);
} else {
makeDateFromStringAndFormat(config);
}
} else {
makeDateFromInput(config);
}
return new Moment(config);
}
moment = function (input, format, lang, strict) {
var c;
if (typeof(lang) === "boolean") {
strict = lang;
lang = undefined;
}
// object construction must be done this way.
// https://github.com/moment/moment/issues/1423
c = {};
c._isAMomentObject = true;
c._i = input;
c._f = format;
c._l = lang;
c._strict = strict;
c._isUTC = false;
c._pf = defaultParsingFlags();
return makeMoment(c);
};
moment.suppressDeprecationWarnings = false;
moment.createFromInputFallback = deprecate(
"moment construction falls back to js Date. This is " +
"discouraged and will be removed in upcoming major " +
"release. Please refer to " +
"https://github.com/moment/moment/issues/1407 for more info.",
function (config) {
config._d = new Date(config._i);
});
// Pick a moment m from moments so that m[fn](other) is true for all
// other. This relies on the function fn to be transitive.
//
// moments should either be an array of moment objects or an array, whose
// first element is an array of moment objects.
function pickBy(fn, moments) {
var res, i;
if (moments.length === 1 && isArray(moments[0])) {
moments = moments[0];
}
if (!moments.length) {
return moment();
}
res = moments[0];
for (i = 1; i < moments.length; ++i) {
if (moments[i][fn](res)) {
res = moments[i];
}
}
return res;
}
moment.min = function () {
var args = [].slice.call(arguments, 0);
return pickBy('isBefore', args);
};
moment.max = function () {
var args = [].slice.call(arguments, 0);
return pickBy('isAfter', args);
};
// creating with utc
moment.utc = function (input, format, lang, strict) {
var c;
if (typeof(lang) === "boolean") {
strict = lang;
lang = undefined;
}
// object construction must be done this way.
// https://github.com/moment/moment/issues/1423
c = {};
c._isAMomentObject = true;
c._useUTC = true;
c._isUTC = true;
c._l = lang;
c._i = input;
c._f = format;
c._strict = strict;
c._pf = defaultParsingFlags();
return makeMoment(c).utc();
};
// creating with unix timestamp (in seconds)
moment.unix = function (input) {
return moment(input * 1000);
};
// duration
moment.duration = function (input, key) {
var duration = input,
// matching against regexp is expensive, do it on demand
match = null,
sign,
ret,
parseIso;
if (moment.isDuration(input)) {
duration = {
ms: input._milliseconds,
d: input._days,
M: input._months
};
} else if (typeof input === 'number') {
duration = {};
if (key) {
duration[key] = input;
} else {
duration.milliseconds = input;
}
} else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) {
sign = (match[1] === "-") ? -1 : 1;
duration = {
y: 0,
d: toInt(match[DATE]) * sign,
h: toInt(match[HOUR]) * sign,
m: toInt(match[MINUTE]) * sign,
s: toInt(match[SECOND]) * sign,
ms: toInt(match[MILLISECOND]) * sign
};
} else if (!!(match = isoDurationRegex.exec(input))) {
sign = (match[1] === "-") ? -1 : 1;
parseIso = function (inp) {
// We'd normally use ~~inp for this, but unfortunately it also
// converts floats to ints.
// inp may be undefined, so careful calling replace on it.
var res = inp && parseFloat(inp.replace(',', '.'));
// apply sign while we're at it
return (isNaN(res) ? 0 : res) * sign;
};
duration = {
y: parseIso(match[2]),
M: parseIso(match[3]),
d: parseIso(match[4]),
h: parseIso(match[5]),
m: parseIso(match[6]),
s: parseIso(match[7]),
w: parseIso(match[8])
};
}
ret = new Duration(duration);
if (moment.isDuration(input) && input.hasOwnProperty('_lang')) {
ret._lang = input._lang;
}
return ret;
};
// version number
moment.version = VERSION;
// default format
moment.defaultFormat = isoFormat;
// Plugins that add properties should also add the key here (null value),
// so we can properly clone ourselves.
moment.momentProperties = momentProperties;
// This function will be called whenever a moment is mutated.
// It is intended to keep the offset in sync with the timezone.
moment.updateOffset = function () {};
// This function allows you to set a threshold for relative time strings
moment.relativeTimeThreshold = function(threshold, limit) {
if (relativeTimeThresholds[threshold] === undefined) {
return false;
}
relativeTimeThresholds[threshold] = limit;
return true;
};
// This function will load languages and then set the global language. If
// no arguments are passed in, it will simply return the current global
// language key.
moment.lang = function (key, values) {
var r;
if (!key) {
return moment.fn._lang._abbr;
}
if (values) {
loadLang(normalizeLanguage(key), values);
} else if (values === null) {
unloadLang(key);
key = 'en';
} else if (!languages[key]) {
getLangDefinition(key);
}
r = moment.duration.fn._lang = moment.fn._lang = getLangDefinition(key);
return r._abbr;
};
// returns language data
moment.langData = function (key) {
if (key && key._lang && key._lang._abbr) {
key = key._lang._abbr;
}
return getLangDefinition(key);
};
// compare moment object
moment.isMoment = function (obj) {
return obj instanceof Moment ||
(obj != null && obj.hasOwnProperty('_isAMomentObject'));
};
// for typechecking Duration objects
moment.isDuration = function (obj) {
return obj instanceof Duration;
};
for (i = lists.length - 1; i >= 0; --i) {
makeList(lists[i]);
}
moment.normalizeUnits = function (units) {
return normalizeUnits(units);
};
moment.invalid = function (flags) {
var m = moment.utc(NaN);
if (flags != null) {
extend(m._pf, flags);
}
else {
m._pf.userInvalidated = true;
}
return m;
};
moment.parseZone = function () {
return moment.apply(null, arguments).parseZone();
};
moment.parseTwoDigitYear = function (input) {
return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
};
/************************************
Moment Prototype
************************************/
extend(moment.fn = Moment.prototype, {
clone : function () {
return moment(this);
},
valueOf : function () {
return +this._d + ((this._offset || 0) * 60000);
},
unix : function () {
return Math.floor(+this / 1000);
},
toString : function () {
return this.clone().lang('en').format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ");
},
toDate : function () {
return this._offset ? new Date(+this) : this._d;
},
toISOString : function () {
var m = moment(this).utc();
if (0 < m.year() && m.year() <= 9999) {
return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
} else {
return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
}
},
toArray : function () {
var m = this;
return [
m.year(),
m.month(),
m.date(),
m.hours(),
m.minutes(),
m.seconds(),
m.milliseconds()
];
},
isValid : function () {
return isValid(this);
},
isDSTShifted : function () {
if (this._a) {
return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0;
}
return false;
},
parsingFlags : function () {
return extend({}, this._pf);
},
invalidAt: function () {
return this._pf.overflow;
},
utc : function () {
return this.zone(0);
},
local : function () {
this.zone(0);
this._isUTC = false;
return this;
},
format : function (inputString) {
var output = formatMoment(this, inputString || moment.defaultFormat);
return this.lang().postformat(output);
},
add : function (input, val) {
var dur;
// switch args to support add('s', 1) and add(1, 's')
if (typeof input === 'string') {
dur = moment.duration(+val, input);
} else {
dur = moment.duration(input, val);
}
addOrSubtractDurationFromMoment(this, dur, 1);
return this;
},
subtract : function (input, val) {
var dur;
// switch args to support subtract('s', 1) and subtract(1, 's')
if (typeof input === 'string') {
dur = moment.duration(+val, input);
} else {
dur = moment.duration(input, val);
}
addOrSubtractDurationFromMoment(this, dur, -1);
return this;
},
diff : function (input, units, asFloat) {
var that = makeAs(input, this),
zoneDiff = (this.zone() - that.zone()) * 6e4,
diff, output;
units = normalizeUnits(units);
if (units === 'year' || units === 'month') {
// average number of days in the months in the given dates
diff = (this.daysInMonth() + that.daysInMonth()) * 432e5; // 24 * 60 * 60 * 1000 / 2
// difference in months
output = ((this.year() - that.year()) * 12) + (this.month() - that.month());
// adjust by taking difference in days, average number of days
// and dst in the given months.
output += ((this - moment(this).startOf('month')) -
(that - moment(that).startOf('month'))) / diff;
// same as above but with zones, to negate all dst
output -= ((this.zone() - moment(this).startOf('month').zone()) -
(that.zone() - moment(that).startOf('month').zone())) * 6e4 / diff;
if (units === 'year') {
output = output / 12;
}
} else {
diff = (this - that);
output = units === 'second' ? diff / 1e3 : // 1000
units === 'minute' ? diff / 6e4 : // 1000 * 60
units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60
units === 'day' ? (diff - zoneDiff) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
units === 'week' ? (diff - zoneDiff) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
diff;
}
return asFloat ? output : absRound(output);
},
from : function (time, withoutSuffix) {
return moment.duration(this.diff(time)).lang(this.lang()._abbr).humanize(!withoutSuffix);
},
fromNow : function (withoutSuffix) {
return this.from(moment(), withoutSuffix);
},
calendar : function (time) {
// We want to compare the start of today, vs this.
// Getting start-of-today depends on whether we're zone'd or not.
var now = time || moment(),
sod = makeAs(now, this).startOf('day'),
diff = this.diff(sod, 'days', true),
format = diff < -6 ? 'sameElse' :
diff < -1 ? 'lastWeek' :
diff < 0 ? 'lastDay' :
diff < 1 ? 'sameDay' :
diff < 2 ? 'nextDay' :
diff < 7 ? 'nextWeek' : 'sameElse';
return this.format(this.lang().calendar(format, this));
},
isLeapYear : function () {
return isLeapYear(this.year());
},
isDST : function () {
return (this.zone() < this.clone().month(0).zone() ||
this.zone() < this.clone().month(5).zone());
},
day : function (input) {
var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
if (input != null) {
input = parseWeekday(input, this.lang());
return this.add({ d : input - day });
} else {
return day;
}
},
month : makeAccessor('Month', true),
startOf: function (units) {
units = normalizeUnits(units);
// the following switch intentionally omits break keywords
// to utilize falling through the cases.
switch (units) {
case 'year':
this.month(0);
/* falls through */
case 'quarter':
case 'month':
this.date(1);
/* falls through */
case 'week':
case 'isoWeek':
case 'day':
this.hours(0);
/* falls through */
case 'hour':
this.minutes(0);
/* falls through */
case 'minute':
this.seconds(0);
/* falls through */
case 'second':
this.milliseconds(0);
/* falls through */
}
// weeks are a special case
if (units === 'week') {
this.weekday(0);
} else if (units === 'isoWeek') {
this.isoWeekday(1);
}
// quarters are also special
if (units === 'quarter') {
this.month(Math.floor(this.month() / 3) * 3);
}
return this;
},
endOf: function (units) {
units = normalizeUnits(units);
return this.startOf(units).add((units === 'isoWeek' ? 'week' : units), 1).subtract('ms', 1);
},
isAfter: function (input, units) {
units = typeof units !== 'undefined' ? units : 'millisecond';
return +this.clone().startOf(units) > +moment(input).startOf(units);
},
isBefore: function (input, units) {
units = typeof units !== 'undefined' ? units : 'millisecond';
return +this.clone().startOf(units) < +moment(input).startOf(units);
},
isSame: function (input, units) {
units = units || 'ms';
return +this.clone().startOf(units) === +makeAs(input, this).startOf(units);
},
min: deprecate(
"moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",
function (other) {
other = moment.apply(null, arguments);
return other < this ? this : other;
}
),
max: deprecate(
"moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",
function (other) {
other = moment.apply(null, arguments);
return other > this ? this : other;
}
),
// keepTime = true means only change the timezone, without affecting
// the local hour. So 5:31:26 +0300 --[zone(2, true)]--> 5:31:26 +0200
// It is possible that 5:31:26 doesn't exist int zone +0200, so we
// adjust the time as needed, to be valid.
//
// Keeping the time actually adds/subtracts (one hour)
// from the actual represented time. That is why we call updateOffset
// a second time. In case it wants us to change the offset again
// _changeInProgress == true case, then we have to adjust, because
// there is no such time in the given timezone.
zone : function (input, keepTime) {
var offset = this._offset || 0;
if (input != null) {
if (typeof input === "string") {
input = timezoneMinutesFromString(input);
}
if (Math.abs(input) < 16) {
input = input * 60;
}
this._offset = input;
this._isUTC = true;
if (offset !== input) {
if (!keepTime || this._changeInProgress) {
addOrSubtractDurationFromMoment(this,
moment.duration(offset - input, 'm'), 1, false);
} else if (!this._changeInProgress) {
this._changeInProgress = true;
moment.updateOffset(this, true);
this._changeInProgress = null;
}
}
} else {
return this._isUTC ? offset : this._d.getTimezoneOffset();
}
return this;
},
zoneAbbr : function () {
return this._isUTC ? "UTC" : "";
},
zoneName : function () {
return this._isUTC ? "Coordinated Universal Time" : "";
},
parseZone : function () {
if (this._tzm) {
this.zone(this._tzm);
} else if (typeof this._i === 'string') {
this.zone(this._i);
}
return this;
},
hasAlignedHourOffset : function (input) {
if (!input) {
input = 0;
}
else {
input = moment(input).zone();
}
return (this.zone() - input) % 60 === 0;
},
daysInMonth : function () {
return daysInMonth(this.year(), this.month());
},
dayOfYear : function (input) {
var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1;
return input == null ? dayOfYear : this.add("d", (input - dayOfYear));
},
quarter : function (input) {
return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
},
weekYear : function (input) {
var year = weekOfYear(this, this.lang()._week.dow, this.lang()._week.doy).year;
return input == null ? year : this.add("y", (input - year));
},
isoWeekYear : function (input) {
var year = weekOfYear(this, 1, 4).year;
return input == null ? year : this.add("y", (input - year));
},
week : function (input) {
var week = this.lang().week(this);
return input == null ? week : this.add("d", (input - week) * 7);
},
isoWeek : function (input) {
var week = weekOfYear(this, 1, 4).week;
return input == null ? week : this.add("d", (input - week) * 7);
},
weekday : function (input) {
var weekday = (this.day() + 7 - this.lang()._week.dow) % 7;
return input == null ? weekday : this.add("d", input - weekday);
},
isoWeekday : function (input) {
// behaves the same as moment#day except
// as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
// as a setter, sunday should belong to the previous week.
return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);
},
isoWeeksInYear : function () {
return weeksInYear(this.year(), 1, 4);
},
weeksInYear : function () {
var weekInfo = this._lang._week;
return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
},
get : function (units) {
units = normalizeUnits(units);
return this[units]();
},
set : function (units, value) {
units = normalizeUnits(units);
if (typeof this[units] === 'function') {
this[units](value);
}
return this;
},
// If passed a language key, it will set the language for this
// instance. Otherwise, it will return the language configuration
// variables for this instance.
lang : function (key) {
if (key === undefined) {
return this._lang;
} else {
this._lang = getLangDefinition(key);
return this;
}
}
});
function rawMonthSetter(mom, value) {
var dayOfMonth;
// TODO: Move this out of here!
if (typeof value === 'string') {
value = mom.lang().monthsParse(value);
// TODO: Another silent failure?
if (typeof value !== 'number') {
return mom;
}
}
dayOfMonth = Math.min(mom.date(),
daysInMonth(mom.year(), value));
mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
return mom;
}
function rawGetter(mom, unit) {
return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]();
}
function rawSetter(mom, unit, value) {
if (unit === 'Month') {
return rawMonthSetter(mom, value);
} else {
return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
}
}
function makeAccessor(unit, keepTime) {
return function (value) {
if (value != null) {
rawSetter(this, unit, value);
moment.updateOffset(this, keepTime);
return this;
} else {
return rawGetter(this, unit);
}
};
}
moment.fn.millisecond = moment.fn.milliseconds = makeAccessor('Milliseconds', false);
moment.fn.second = moment.fn.seconds = makeAccessor('Seconds', false);
moment.fn.minute = moment.fn.minutes = makeAccessor('Minutes', false);
// Setting the hour should keep the time, because the user explicitly
// specified which hour he wants. So trying to maintain the same hour (in
// a new timezone) makes sense. Adding/subtracting hours does not follow
// this rule.
moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true);
// moment.fn.month is defined separately
moment.fn.date = makeAccessor('Date', true);
moment.fn.dates = deprecate("dates accessor is deprecated. Use date instead.", makeAccessor('Date', true));
moment.fn.year = makeAccessor('FullYear', true);
moment.fn.years = deprecate("years accessor is deprecated. Use year instead.", makeAccessor('FullYear', true));
// add plural methods
moment.fn.days = moment.fn.day;
moment.fn.months = moment.fn.month;
moment.fn.weeks = moment.fn.week;
moment.fn.isoWeeks = moment.fn.isoWeek;
moment.fn.quarters = moment.fn.quarter;
// add aliased format methods
moment.fn.toJSON = moment.fn.toISOString;
/************************************
Duration Prototype
************************************/
extend(moment.duration.fn = Duration.prototype, {
_bubble : function () {
var milliseconds = this._milliseconds,
days = this._days,
months = this._months,
data = this._data,
seconds, minutes, hours, years;
// The following code bubbles up values, see the tests for
// examples of what that means.
data.milliseconds = milliseconds % 1000;
seconds = absRound(milliseconds / 1000);
data.seconds = seconds % 60;
minutes = absRound(seconds / 60);
data.minutes = minutes % 60;
hours = absRound(minutes / 60);
data.hours = hours % 24;
days += absRound(hours / 24);
data.days = days % 30;
months += absRound(days / 30);
data.months = months % 12;
years = absRound(months / 12);
data.years = years;
},
weeks : function () {
return absRound(this.days() / 7);
},
valueOf : function () {
return this._milliseconds +
this._days * 864e5 +
(this._months % 12) * 2592e6 +
toInt(this._months / 12) * 31536e6;
},
humanize : function (withSuffix) {
var difference = +this,
output = relativeTime(difference, !withSuffix, this.lang());
if (withSuffix) {
output = this.lang().pastFuture(difference, output);
}
return this.lang().postformat(output);
},
add : function (input, val) {
// supports only 2.0-style add(1, 's') or add(moment)
var dur = moment.duration(input, val);
this._milliseconds += dur._milliseconds;
this._days += dur._days;
this._months += dur._months;
this._bubble();
return this;
},
subtract : function (input, val) {
var dur = moment.duration(input, val);
this._milliseconds -= dur._milliseconds;
this._days -= dur._days;
this._months -= dur._months;
this._bubble();
return this;
},
get : function (units) {
units = normalizeUnits(units);
return this[units.toLowerCase() + 's']();
},
as : function (units) {
units = normalizeUnits(units);
return this['as' + units.charAt(0).toUpperCase() + units.slice(1) + 's']();
},
lang : moment.fn.lang,
toIsoString : function () {
// inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
var years = Math.abs(this.years()),
months = Math.abs(this.months()),
days = Math.abs(this.days()),
hours = Math.abs(this.hours()),
minutes = Math.abs(this.minutes()),
seconds = Math.abs(this.seconds() + this.milliseconds() / 1000);
if (!this.asSeconds()) {
// this is the same as C#'s (Noda) and python (isodate)...
// but not other JS (goog.date)
return 'P0D';
}
return (this.asSeconds() < 0 ? '-' : '') +
'P' +
(years ? years + 'Y' : '') +
(months ? months + 'M' : '') +
(days ? days + 'D' : '') +
((hours || minutes || seconds) ? 'T' : '') +
(hours ? hours + 'H' : '') +
(minutes ? minutes + 'M' : '') +
(seconds ? seconds + 'S' : '');
}
});
function makeDurationGetter(name) {
moment.duration.fn[name] = function () {
return this._data[name];
};
}
function makeDurationAsGetter(name, factor) {
moment.duration.fn['as' + name] = function () {
return +this / factor;
};
}
for (i in unitMillisecondFactors) {
if (unitMillisecondFactors.hasOwnProperty(i)) {
makeDurationAsGetter(i, unitMillisecondFactors[i]);
makeDurationGetter(i.toLowerCase());
}
}
makeDurationAsGetter('Weeks', 6048e5);
moment.duration.fn.asMonths = function () {
return (+this - this.years() * 31536e6) / 2592e6 + this.years() * 12;
};
/************************************
Default Lang
************************************/
// Set default language, other languages will inherit from English.
moment.lang('en', {
ordinal : function (number) {
var b = number % 10,
output = (toInt(number % 100 / 10) === 1) ? 'th' :
(b === 1) ? 'st' :
(b === 2) ? 'nd' :
(b === 3) ? 'rd' : 'th';
return number + output;
}
});
/* EMBED_LANGUAGES */
/************************************
Exposing Moment
************************************/
function makeGlobal(shouldDeprecate) {
/*global ender:false */
if (typeof ender !== 'undefined') {
return;
}
oldGlobalMoment = globalScope.moment;
if (shouldDeprecate) {
globalScope.moment = deprecate(
"Accessing Moment through the global scope is " +
"deprecated, and will be removed in an upcoming " +
"release.",
moment);
} else {
globalScope.moment = moment;
}
}
// CommonJS module is defined
if (hasModule) {
module.exports = moment;
} else if (typeof define === "function" && define.amd) {
define("moment", function (require, exports, module) {
if (module.config && module.config() && module.config().noGlobal === true) {
// release the global variable
globalScope.moment = oldGlobalMoment;
}
return moment;
});
makeGlobal(true);
} else {
makeGlobal();
}
}).call(this);
// <script src="/Scripts/bootstrap-datepicker/bootstrap-datepicker.js?3ba151" type="text/javascript"></script>
/* =========================================================
* bootstrap-datepicker.js
* Repo: https://github.com/eternicode/bootstrap-datepicker/
* Demo: http://eternicode.github.io/bootstrap-datepicker/
* Docs: http://bootstrap-datepicker.readthedocs.org/
* Forked from http://www.eyecon.ro/bootstrap-datepicker
* =========================================================
* Started by Stefan Petre; improvements by Andrew Rowls + contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================= */
(function ($, undefined) {
var $window = $(window);
function UTCDate() {
return new Date(Date.UTC.apply(Date, arguments));
}
function UTCToday() {
var today = new Date();
return UTCDate(today.getFullYear(), today.getMonth(), today.getDate());
}
function alias(method) {
return function () {
return this[method].apply(this, arguments);
};
}
var DateArray = (function () {
var extras = {
get: function (i) {
return this.slice(i)[0];
},
contains: function (d) {
// Array.indexOf is not cross-browser;
// $.inArray doesn't work with Dates
var val = d && d.valueOf();
for (var i = 0, l = this.length; i < l; i++)
if (this[i].valueOf() === val)
return i;
return -1;
},
remove: function (i) {
this.splice(i, 1);
},
replace: function (new_array) {
if (!new_array)
return;
if (!$.isArray(new_array))
new_array = [new_array];
this.clear();
this.push.apply(this, new_array);
},
clear: function () {
this.length = 0;
},
copy: function () {
var a = new DateArray();
a.replace(this);
return a;
}
};
return function () {
var a = [];
a.push.apply(a, arguments);
$.extend(a, extras);
return a;
};
})();
// Picker object
var Datepicker = function (element, options) {
this.dates = new DateArray();
this.viewDate = UTCToday();
this.focusDate = null;
this._process_options(options);
this.element = $(element);
this.isInline = false;
this.isInput = this.element.is('input');
this.component = this.element.is('.date') ? this.element.find('.add-on, .input-group-addon, .btn') : false;
this.hasInput = this.component && this.element.find('input').length;
if (this.component && this.component.length === 0)
this.component = false;
this.picker = $(DPGlobal.template);
this._buildEvents();
this._attachEvents();
if (this.isInline) {
this.picker.addClass('datepicker-inline').appendTo(this.element);
}
else {
this.picker.addClass('datepicker-dropdown dropdown-menu');
}
if (this.o.rtl) {
this.picker.addClass('datepicker-rtl');
}
this.viewMode = this.o.startView;
if (this.o.calendarWeeks)
this.picker.find('tfoot th.today')
.attr('colspan', function (i, val) {
return parseInt(val) + 1;
});
this._allow_update = false;
this.setStartDate(this._o.startDate);
this.setEndDate(this._o.endDate);
this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled);
this.fillDow();
this.fillMonths();
this._allow_update = true;
this.update();
this.showMode();
if (this.isInline) {
this.show();
}
};
Datepicker.prototype = {
constructor: Datepicker,
_process_options: function (opts) {
// Store raw options for reference
this._o = $.extend({}, this._o, opts);
// Processed options
var o = this.o = $.extend({}, this._o);
// Check if "de-DE" style date is available, if not language should
// fallback to 2 letter code eg "de"
var lang = o.language;
if (!dates[lang]) {
lang = lang.split('-')[0];
if (!dates[lang])
lang = defaults.language;
}
o.language = lang;
switch (o.startView) {
case 2:
case 'decade':
o.startView = 2;
break;
case 1:
case 'year':
o.startView = 1;
break;
default:
o.startView = 0;
}
switch (o.minViewMode) {
case 1:
case 'months':
o.minViewMode = 1;
break;
case 2:
case 'years':
o.minViewMode = 2;
break;
default:
o.minViewMode = 0;
}
o.startView = Math.max(o.startView, o.minViewMode);
// true, false, or Number > 0
if (o.multidate !== true) {
o.multidate = Number(o.multidate) || false;
if (o.multidate !== false)
o.multidate = Math.max(0, o.multidate);
}
o.multidateSeparator = String(o.multidateSeparator);
o.weekStart %= 7;
o.weekEnd = ((o.weekStart + 6) % 7);
var format = DPGlobal.parseFormat(o.format);
if (o.startDate !== -Infinity) {
if (!!o.startDate) {
if (o.startDate instanceof Date)
o.startDate = this._local_to_utc(this._zero_time(o.startDate));
else
o.startDate = DPGlobal.parseDate(o.startDate, format, o.language);
}
else {
o.startDate = -Infinity;
}
}
if (o.endDate !== Infinity) {
if (!!o.endDate) {
if (o.endDate instanceof Date)
o.endDate = this._local_to_utc(this._zero_time(o.endDate));
else
o.endDate = DPGlobal.parseDate(o.endDate, format, o.language);
}
else {
o.endDate = Infinity;
}
}
o.daysOfWeekDisabled = o.daysOfWeekDisabled || [];
if (!$.isArray(o.daysOfWeekDisabled))
o.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\s]*/);
o.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function (d) {
return parseInt(d, 10);
});
var plc = String(o.orientation).toLowerCase().split(/\s+/g),
_plc = o.orientation.toLowerCase();
plc = $.grep(plc, function (word) {
return (/^auto|left|right|top|bottom$/).test(word);
});
o.orientation = { x: 'auto', y: 'auto' };
if (!_plc || _plc === 'auto')
; // no action
else if (plc.length === 1) {
switch (plc[0]) {
case 'top':
case 'bottom':
o.orientation.y = plc[0];
break;
case 'left':
case 'right':
o.orientation.x = plc[0];
break;
}
}
else {
_plc = $.grep(plc, function (word) {
return (/^left|right$/).test(word);
});
o.orientation.x = _plc[0] || 'auto';
_plc = $.grep(plc, function (word) {
return (/^top|bottom$/).test(word);
});
o.orientation.y = _plc[0] || 'auto';
}
},
_events: [],
_secondaryEvents: [],
_applyEvents: function (evs) {
for (var i = 0, el, ch, ev; i < evs.length; i++) {
el = evs[i][0];
if (evs[i].length === 2) {
ch = undefined;
ev = evs[i][1];
}
else if (evs[i].length === 3) {
ch = evs[i][1];
ev = evs[i][2];
}
el.on(ev, ch);
}
},
_unapplyEvents: function (evs) {
for (var i = 0, el, ev, ch; i < evs.length; i++) {
el = evs[i][0];
if (evs[i].length === 2) {
ch = undefined;
ev = evs[i][1];
}
else if (evs[i].length === 3) {
ch = evs[i][1];
ev = evs[i][2];
}
el.off(ev, ch);
}
},
_buildEvents: function () {
if (this.isInput) { // single input
this._events = [
[this.element, {
focus: $.proxy(this.show, this),
keyup: $.proxy(function (e) {
if ($.inArray(e.keyCode, [27, 37, 39, 38, 40, 32, 13, 9]) === -1)
this.update();
}, this),
keydown: $.proxy(this.keydown, this)
}]
];
}
else if (this.component && this.hasInput) { // component: input + button
this._events = [
// For components that are not readonly, allow keyboard nav
[this.element.find('input'), {
focus: $.proxy(this.show, this),
keyup: $.proxy(function (e) {
if ($.inArray(e.keyCode, [27, 37, 39, 38, 40, 32, 13, 9]) === -1)
this.update();
}, this),
keydown: $.proxy(this.keydown, this)
}],
[this.component, {
click: $.proxy(this.show, this)
}]
];
}
else if (this.element.is('div')) { // inline datepicker
this.isInline = true;
}
else {
this._events = [
[this.element, {
click: $.proxy(this.show, this)
}]
];
}
this._events.push(
// Component: listen for blur on element descendants
[this.element, '*', {
blur: $.proxy(function (e) {
this._focused_from = e.target;
}, this)
}],
// Input: listen for blur on element
[this.element, {
blur: $.proxy(function (e) {
this._focused_from = e.target;
}, this)
}]
);
this._secondaryEvents = [
[this.picker, {
click: $.proxy(this.click, this)
}],
[$(window), {
resize: $.proxy(this.place, this)
}],
[$(document), {
'mousedown touchstart': $.proxy(function (e) {
// Clicked outside the datepicker, hide it
if (!(
this.element.is(e.target) ||
this.element.find(e.target).length ||
this.picker.is(e.target) ||
this.picker.find(e.target).length
)) {
this.hide();
}
}, this)
}]
];
},
_attachEvents: function () {
this._detachEvents();
this._applyEvents(this._events);
},
_detachEvents: function () {
this._unapplyEvents(this._events);
},
_attachSecondaryEvents: function () {
this._detachSecondaryEvents();
this._applyEvents(this._secondaryEvents);
},
_detachSecondaryEvents: function () {
this._unapplyEvents(this._secondaryEvents);
},
_trigger: function (event, altdate) {
var date = altdate || this.dates.get(-1),
local_date = this._utc_to_local(date);
this.element.trigger({
type: event,
date: local_date,
dates: $.map(this.dates, this._utc_to_local),
format: $.proxy(function (ix, format) {
if (arguments.length === 0) {
ix = this.dates.length - 1;
format = this.o.format;
}
else if (typeof ix === 'string') {
format = ix;
ix = this.dates.length - 1;
}
format = format || this.o.format;
var date = this.dates.get(ix);
return DPGlobal.formatDate(date, format, this.o.language);
}, this)
});
},
show: function () {
//this.focusDate = this.focusDate || this.viewDate;
if (!this.isInline)
this.picker.appendTo('body');
this.place();
this._attachSecondaryEvents();
this.picker.show();
this._trigger('show');
},
hide: function () {
if (this.isInline)
return;
if (!this.picker.is(':visible'))
return;
this.focusDate = null;
this.picker.hide().detach();
this._detachSecondaryEvents();
this.viewMode = this.o.startView;
this.showMode();
if (
this.o.forceParse &&
(
this.isInput && this.element.val() ||
this.hasInput && this.element.find('input').val()
)
)
// Removing line: 'this.setValue();' as a click/keyboard will already have triggered this.
// When this line is in, it's impossible to set the datepicker to start off with a date other than today.
//this.setValue();
this._trigger('hide');
},
remove: function () {
this.hide();
this._detachEvents();
this._detachSecondaryEvents();
this.picker.remove();
delete this.element.data().datepicker;
if (!this.isInput) {
delete this.element.data().date;
}
},
_utc_to_local: function (utc) {
return utc && new Date(utc.getTime() + (utc.getTimezoneOffset() * 60000));
},
_local_to_utc: function (local) {
return local && new Date(local.getTime() - (local.getTimezoneOffset() * 60000));
},
_zero_time: function (local) {
return local && new Date(local.getFullYear(), local.getMonth(), local.getDate());
},
_zero_utc_time: function (utc) {
return utc && new Date(Date.UTC(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate()));
},
getDates: function () {
return $.map(this.dates, this._utc_to_local);
},
getUTCDates: function () {
return $.map(this.dates, function (d) {
return new Date(d);
});
},
getDate: function () {
return this._utc_to_local(this.getUTCDate());
},
getUTCDate: function () {
return new Date(this.dates.get(-1));
},
setDates: function () {
var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
this.update.apply(this, args);
this._trigger('changeDate');
this.setValue();
},
setUTCDates: function () {
var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
this.update.apply(this, $.map(args, this._utc_to_local));
this._trigger('changeDate');
this.setValue();
},
setDate: alias('setDates'),
setUTCDate: alias('setUTCDates'),
setValue: function () {
var formatted = this.getFormattedDate();
if (!this.isInput) {
if (this.component) {
this.element.find('input').val(formatted).change();
}
}
else {
this.element.val(formatted).change();
}
},
getFormattedDate: function (format) {
if (format === undefined)
format = this.o.format;
var lang = this.o.language;
return $.map(this.dates, function (d) {
return DPGlobal.formatDate(d, format, lang);
}).join(this.o.multidateSeparator);
},
setStartDate: function (startDate) {
this._process_options({ startDate: startDate });
this.update();
this.updateNavArrows();
},
setEndDate: function (endDate) {
this._process_options({ endDate: endDate });
this.update();
this.updateNavArrows();
},
setDaysOfWeekDisabled: function (daysOfWeekDisabled) {
this._process_options({ daysOfWeekDisabled: daysOfWeekDisabled });
this.update();
this.updateNavArrows();
},
place: function () {
if (this.isInline)
return;
var calendarWidth = this.picker.outerWidth(),
calendarHeight = this.picker.outerHeight(),
visualPadding = 10,
windowWidth = $window.width(),
windowHeight = $window.height(),
scrollTop = $window.scrollTop();
var zIndex = parseInt(this.element.parents().filter(function () {
return $(this).css('z-index') !== 'auto';
}).first().css('z-index')) + 10;
var offset = this.component ? this.component.parent().offset() : this.element.offset();
var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false);
var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false);
var left = offset.left,
top = offset.top;
this.picker.removeClass(
'datepicker-orient-top datepicker-orient-bottom ' +
'datepicker-orient-right datepicker-orient-left'
);
if (this.o.orientation.x !== 'auto') {
this.picker.addClass('datepicker-orient-' + this.o.orientation.x);
if (this.o.orientation.x === 'right')
left -= calendarWidth - width;
}
// auto x orientation is best-placement: if it crosses a window
// edge, fudge it sideways
else {
// Default to left
this.picker.addClass('datepicker-orient-left');
if (offset.left < 0)
left -= offset.left - visualPadding;
else if (offset.left + calendarWidth > windowWidth)
left = windowWidth - calendarWidth - visualPadding;
}
// auto y orientation is best-situation: top or bottom, no fudging,
// decision based on which shows more of the calendar
var yorient = this.o.orientation.y,
top_overflow, bottom_overflow;
if (yorient === 'auto') {
top_overflow = -scrollTop + offset.top - calendarHeight;
bottom_overflow = scrollTop + windowHeight - (offset.top + height + calendarHeight);
if (Math.max(top_overflow, bottom_overflow) === bottom_overflow)
yorient = 'top';
else
yorient = 'bottom';
}
this.picker.addClass('datepicker-orient-' + yorient);
if (yorient === 'top')
top += height;
else
top -= calendarHeight + parseInt(this.picker.css('padding-top'));
this.picker.css({
top: top,
left: left,
zIndex: zIndex
});
},
_allow_update: true,
update: function () {
if (!this._allow_update)
return;
var oldDates = this.dates.copy(),
dates = [],
fromArgs = false;
if (arguments.length) {
$.each(arguments, $.proxy(function (i, date) {
if (date instanceof Date)
date = this._local_to_utc(date);
dates.push(date);
}, this));
fromArgs = true;
}
else {
dates = this.isInput
? this.element.val()
: this.element.data('date') || this.element.find('input').val();
if (dates && this.o.multidate)
dates = dates.split(this.o.multidateSeparator);
else
dates = [dates];
delete this.element.data().date;
}
dates = $.map(dates, $.proxy(function (date) {
return DPGlobal.parseDate(date, this.o.format, this.o.language);
}, this));
dates = $.grep(dates, $.proxy(function (date) {
return (
date < this.o.startDate ||
date > this.o.endDate ||
!date
);
}, this), true);
this.dates.replace(dates);
if (this.dates.length)
this.viewDate = new Date(this.dates.get(-1));
else if (this.viewDate < this.o.startDate)
this.viewDate = new Date(this.o.startDate);
else if (this.viewDate > this.o.endDate)
this.viewDate = new Date(this.o.endDate);
if (fromArgs) {
// setting date by clicking
this.setValue();
}
else if (dates.length) {
// setting date by typing
if (String(oldDates) !== String(this.dates))
this._trigger('changeDate');
}
if (!this.dates.length && oldDates.length)
this._trigger('clearDate');
this.fill();
},
fillDow: function () {
var dowCnt = this.o.weekStart,
html = '<tr>';
if (this.o.calendarWeeks) {
var cell = '<th class="cw"> </th>';
html += cell;
this.picker.find('.datepicker-days thead tr:first-child').prepend(cell);
}
while (dowCnt < this.o.weekStart + 7) {
html += '<th class="dow">' + dates[this.o.language].daysMin[(dowCnt++) % 7] + '</th>';
}
html += '</tr>';
this.picker.find('.datepicker-days thead').append(html);
},
fillMonths: function () {
var html = '',
i = 0;
while (i < 12) {
html += '<span class="month">' + dates[this.o.language].monthsShort[i++] + '</span>';
}
this.picker.find('.datepicker-months td').html(html);
},
setRange: function (range) {
if (!range || !range.length)
delete this.range;
else
this.range = $.map(range, function (d) {
return d.valueOf();
});
this.fill();
},
getClassNames: function (date) {
var cls = [],
year = this.viewDate.getUTCFullYear(),
month = this.viewDate.getUTCMonth(),
today = new Date();
if (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)) {
cls.push('old');
}
else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)) {
cls.push('new');
}
if (this.focusDate && date.valueOf() === this.focusDate.valueOf())
cls.push('focused');
// Compare internal UTC date with local today, not UTC today
if (this.o.todayHighlight &&
date.getUTCFullYear() === today.getFullYear() &&
date.getUTCMonth() === today.getMonth() &&
date.getUTCDate() === today.getDate()) {
cls.push('today');
}
if (this.dates.contains(date) !== -1)
cls.push('active');
if (date.valueOf() < this.o.startDate || date.valueOf() > this.o.endDate ||
$.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1) {
cls.push('disabled');
}
if (this.range) {
if (date > this.range[0] && date < this.range[this.range.length - 1]) {
cls.push('range');
}
if ($.inArray(date.valueOf(), this.range) !== -1) {
cls.push('selected');
}
}
return cls;
},
fill: function () {
var d = new Date(this.viewDate),
year = d.getUTCFullYear(),
month = d.getUTCMonth(),
startYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity,
startMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity,
endYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity,
endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity,
todaytxt = dates[this.o.language].today || dates['en'].today || '',
cleartxt = dates[this.o.language].clear || dates['en'].clear || '',
tooltip;
this.picker.find('.datepicker-days thead th.datepicker-switch')
.text(dates[this.o.language].months[month] + ' ' + year);
this.picker.find('tfoot th.today')
.text(todaytxt)
.toggle(this.o.todayBtn !== false);
this.picker.find('tfoot th.clear')
.text(cleartxt)
.toggle(this.o.clearBtn !== false);
this.updateNavArrows();
this.fillMonths();
var prevMonth = UTCDate(year, month - 1, 28),
day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
prevMonth.setUTCDate(day);
prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7) % 7);
var nextMonth = new Date(prevMonth);
nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
nextMonth = nextMonth.valueOf();
var html = [];
var clsName;
while (prevMonth.valueOf() < nextMonth) {
if (prevMonth.getUTCDay() === this.o.weekStart) {
html.push('<tr>');
if (this.o.calendarWeeks) {
// ISO 8601: First week contains first thursday.
// ISO also states week starts on Monday, but we can be more abstract here.
var
// Start of current week: based on weekstart/current date
ws = new Date(+prevMonth + (this.o.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),
// Thursday of this week
th = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),
// First Thursday of year, year from thursday
yth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay()) % 7 * 864e5),
// Calendar week: ms between thursdays, div ms per day, div 7 days
calWeek = (th - yth) / 864e5 / 7 + 1;
html.push('<td class="cw">' + calWeek + '</td>');
}
}
clsName = this.getClassNames(prevMonth);
clsName.push('day');
if (this.o.beforeShowDay !== $.noop) {
var before = this.o.beforeShowDay(this._utc_to_local(prevMonth));
if (before === undefined)
before = {};
else if (typeof (before) === 'boolean')
before = { enabled: before };
else if (typeof (before) === 'string')
before = { classes: before };
if (before.enabled === false)
clsName.push('disabled');
if (before.classes)
clsName = clsName.concat(before.classes.split(/\s+/));
if (before.tooltip)
tooltip = before.tooltip;
}
clsName = $.unique(clsName);
html.push('<td class="' + clsName.join(' ') + '"' + (tooltip ? ' title="' + tooltip + '"' : '') + '>' + prevMonth.getUTCDate() + '</td>');
if (prevMonth.getUTCDay() === this.o.weekEnd) {
html.push('</tr>');
}
prevMonth.setUTCDate(prevMonth.getUTCDate() + 1);
}
this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
var months = this.picker.find('.datepicker-months')
.find('th:eq(1)')
.text(year)
.end()
.find('span').removeClass('active');
$.each(this.dates, function (i, d) {
if (d.getUTCFullYear() === year)
months.eq(d.getUTCMonth()).addClass('active');
});
if (year < startYear || year > endYear) {
months.addClass('disabled');
}
if (year === startYear) {
months.slice(0, startMonth).addClass('disabled');
}
if (year === endYear) {
months.slice(endMonth + 1).addClass('disabled');
}
html = '';
year = parseInt(year / 10, 10) * 10;
var yearCont = this.picker.find('.datepicker-years')
.find('th:eq(1)')
.text(year + '-' + (year + 9))
.end()
.find('td');
year -= 1;
var years = $.map(this.dates, function (d) {
return d.getUTCFullYear();
}),
classes;
for (var i = -1; i < 11; i++) {
classes = ['year'];
if (i === -1)
classes.push('old');
else if (i === 10)
classes.push('new');
if ($.inArray(year, years) !== -1)
classes.push('active');
if (year < startYear || year > endYear)
classes.push('disabled');
html += '<span class="' + classes.join(' ') + '">' + year + '</span>';
year += 1;
}
yearCont.html(html);
},
updateNavArrows: function () {
if (!this._allow_update)
return;
var d = new Date(this.viewDate),
year = d.getUTCFullYear(),
month = d.getUTCMonth();
switch (this.viewMode) {
case 0:
if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() && month <= this.o.startDate.getUTCMonth()) {
this.picker.find('.prev').css({ visibility: 'hidden' });
}
else {
this.picker.find('.prev').css({ visibility: 'visible' });
}
if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() && month >= this.o.endDate.getUTCMonth()) {
this.picker.find('.next').css({ visibility: 'hidden' });
}
else {
this.picker.find('.next').css({ visibility: 'visible' });
}
break;
case 1:
case 2:
if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear()) {
this.picker.find('.prev').css({ visibility: 'hidden' });
}
else {
this.picker.find('.prev').css({ visibility: 'visible' });
}
if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear()) {
this.picker.find('.next').css({ visibility: 'hidden' });
}
else {
this.picker.find('.next').css({ visibility: 'visible' });
}
break;
}
},
click: function (e) {
e.preventDefault();
var target = $(e.target).closest('span, td, th'),
year, month, day;
if (target.length === 1) {
switch (target[0].nodeName.toLowerCase()) {
case 'th':
switch (target[0].className) {
case 'datepicker-switch':
this.showMode(1);
break;
case 'prev':
case 'next':
var dir = DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1);
switch (this.viewMode) {
case 0:
this.viewDate = this.moveMonth(this.viewDate, dir);
this._trigger('changeMonth', this.viewDate);
break;
case 1:
case 2:
this.viewDate = this.moveYear(this.viewDate, dir);
if (this.viewMode === 1)
this._trigger('changeYear', this.viewDate);
break;
}
this.fill();
break;
case 'today':
var date = new Date();
date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
this.showMode(-2);
var which = this.o.todayBtn === 'linked' ? null : 'view';
this._setDate(date, which);
break;
case 'clear':
var element;
if (this.isInput)
element = this.element;
else if (this.component)
element = this.element.find('input');
if (element)
element.val("").change();
this.update();
this._trigger('changeDate');
if (this.o.autoclose)
this.hide();
break;
}
break;
case 'span':
if (!target.is('.disabled')) {
this.viewDate.setUTCDate(1);
if (target.is('.month')) {
day = 1;
month = target.parent().find('span').index(target);
year = this.viewDate.getUTCFullYear();
this.viewDate.setUTCMonth(month);
this._trigger('changeMonth', this.viewDate);
if (this.o.minViewMode === 1) {
this._setDate(UTCDate(year, month, day));
}
}
else {
day = 1;
month = 0;
year = parseInt(target.text(), 10) || 0;
this.viewDate.setUTCFullYear(year);
this._trigger('changeYear', this.viewDate);
if (this.o.minViewMode === 2) {
this._setDate(UTCDate(year, month, day));
}
}
this.showMode(-1);
this.fill();
}
break;
case 'td':
if (target.is('.day') && !target.is('.disabled')) {
day = parseInt(target.text(), 10) || 1;
year = this.viewDate.getUTCFullYear();
month = this.viewDate.getUTCMonth();
if (target.is('.old')) {
if (month === 0) {
month = 11;
year -= 1;
}
else {
month -= 1;
}
}
else if (target.is('.new')) {
if (month === 11) {
month = 0;
year += 1;
}
else {
month += 1;
}
}
this._setDate(UTCDate(year, month, day));
}
break;
}
}
if (this.picker.is(':visible') && this._focused_from) {
$(this._focused_from).focus();
}
delete this._focused_from;
},
_toggle_multidate: function (date) {
var ix = this.dates.contains(date);
if (!date) {
this.dates.clear();
}
else if (this.o.multidate === false) {
this.dates.clear();
this.dates.push(date);
}
else {
if (ix !== -1) {
this.dates.remove(ix);
}
else {
this.dates.push(date);
}
if (typeof this.o.multidate === 'number')
while (this.dates.length > this.o.multidate)
this.dates.remove(0);
}
},
_setDate: function (date, which) {
if (!which || which === 'date')
this._toggle_multidate(date && new Date(date));
if (!which || which === 'view')
this.viewDate = date && new Date(date);
this.fill();
this.setValue();
this._trigger('changeDate');
var element;
if (this.isInput) {
element = this.element;
}
else if (this.component) {
element = this.element.find('input');
}
if (element) {
element.change();
}
if (this.o.autoclose && (!which || which === 'date')) {
this.hide();
}
},
moveMonth: function (date, dir) {
if (!date)
return undefined;
if (!dir)
return date;
var new_date = new Date(date.valueOf()),
day = new_date.getUTCDate(),
month = new_date.getUTCMonth(),
mag = Math.abs(dir),
new_month, test;
dir = dir > 0 ? 1 : -1;
if (mag === 1) {
test = dir === -1
// If going back one month, make sure month is not current month
// (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02)
? function () {
return new_date.getUTCMonth() === month;
}
// If going forward one month, make sure month is as expected
// (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02)
: function () {
return new_date.getUTCMonth() !== new_month;
};
new_month = month + dir;
new_date.setUTCMonth(new_month);
// Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11
if (new_month < 0 || new_month > 11)
new_month = (new_month + 12) % 12;
}
else {
// For magnitudes >1, move one month at a time...
for (var i = 0; i < mag; i++)
// ...which might decrease the day (eg, Jan 31 to Feb 28, etc)...
new_date = this.moveMonth(new_date, dir);
// ...then reset the day, keeping it in the new month
new_month = new_date.getUTCMonth();
new_date.setUTCDate(day);
test = function () {
return new_month !== new_date.getUTCMonth();
};
}
// Common date-resetting loop -- if date is beyond end of month, make it
// end of month
while (test()) {
new_date.setUTCDate(--day);
new_date.setUTCMonth(new_month);
}
return new_date;
},
moveYear: function (date, dir) {
return this.moveMonth(date, dir * 12);
},
dateWithinRange: function (date) {
return date >= this.o.startDate && date <= this.o.endDate;
},
keydown: function (e) {
if (this.picker.is(':not(:visible)')) {
if (e.keyCode === 27) // allow escape to hide and re-show picker
this.show();
return;
}
var dateChanged = false,
dir, newDate, newViewDate,
focusDate = this.focusDate || this.viewDate;
switch (e.keyCode) {
case 27: // escape
if (this.focusDate) {
this.focusDate = null;
this.viewDate = this.dates.get(-1) || this.viewDate;
this.fill();
}
else
this.hide();
e.preventDefault();
break;
case 37: // left
case 39: // right
if (!this.o.keyboardNavigation)
break;
dir = e.keyCode === 37 ? -1 : 1;
if (e.ctrlKey) {
newDate = this.moveYear(this.dates.get(-1) || UTCToday(), dir);
newViewDate = this.moveYear(focusDate, dir);
this._trigger('changeYear', this.viewDate);
}
else if (e.shiftKey) {
newDate = this.moveMonth(this.dates.get(-1) || UTCToday(), dir);
newViewDate = this.moveMonth(focusDate, dir);
this._trigger('changeMonth', this.viewDate);
}
else {
newDate = new Date(this.dates.get(-1) || UTCToday());
newDate.setUTCDate(newDate.getUTCDate() + dir);
newViewDate = new Date(focusDate);
newViewDate.setUTCDate(focusDate.getUTCDate() + dir);
}
if (this.dateWithinRange(newDate)) {
this.focusDate = this.viewDate = newViewDate;
this.setValue();
this.fill();
e.preventDefault();
}
break;
case 38: // up
case 40: // down
if (!this.o.keyboardNavigation)
break;
dir = e.keyCode === 38 ? -1 : 1;
if (e.ctrlKey) {
newDate = this.moveYear(this.dates.get(-1) || UTCToday(), dir);
newViewDate = this.moveYear(focusDate, dir);
this._trigger('changeYear', this.viewDate);
}
else if (e.shiftKey) {
newDate = this.moveMonth(this.dates.get(-1) || UTCToday(), dir);
newViewDate = this.moveMonth(focusDate, dir);
this._trigger('changeMonth', this.viewDate);
}
else {
newDate = new Date(this.dates.get(-1) || UTCToday());
newDate.setUTCDate(newDate.getUTCDate() + dir * 7);
newViewDate = new Date(focusDate);
newViewDate.setUTCDate(focusDate.getUTCDate() + dir * 7);
}
if (this.dateWithinRange(newDate)) {
this.focusDate = this.viewDate = newViewDate;
this.setValue();
this.fill();
e.preventDefault();
}
break;
case 32: // spacebar
// Spacebar is used in manually typing dates in some formats.
// As such, its behavior should not be hijacked.
break;
case 13: // enter
focusDate = this.focusDate || this.dates.get(-1) || this.viewDate;
this._toggle_multidate(focusDate);
dateChanged = true;
this.focusDate = null;
this.viewDate = this.dates.get(-1) || this.viewDate;
this.setValue();
this.fill();
if (this.picker.is(':visible')) {
e.preventDefault();
if (this.o.autoclose)
this.hide();
}
break;
case 9: // tab
this.focusDate = null;
this.viewDate = this.dates.get(-1) || this.viewDate;
this.fill();
this.hide();
break;
}
if (dateChanged) {
if (this.dates.length)
this._trigger('changeDate');
else
this._trigger('clearDate');
var element;
if (this.isInput) {
element = this.element;
}
else if (this.component) {
element = this.element.find('input');
}
if (element) {
element.change();
}
}
},
showMode: function (dir) {
if (dir) {
this.viewMode = Math.max(this.o.minViewMode, Math.min(2, this.viewMode + dir));
}
this.picker
.find('>div')
.hide()
.filter('.datepicker-' + DPGlobal.modes[this.viewMode].clsName)
.css('display', 'block');
this.updateNavArrows();
}
};
var DateRangePicker = function (element, options) {
this.element = $(element);
this.inputs = $.map(options.inputs, function (i) {
return i.jquery ? i[0] : i;
});
delete options.inputs;
$(this.inputs)
.datepicker(options)
.bind('changeDate', $.proxy(this.dateUpdated, this));
this.pickers = $.map(this.inputs, function (i) {
return $(i).data('datepicker');
});
this.updateDates();
};
DateRangePicker.prototype = {
updateDates: function () {
this.dates = $.map(this.pickers, function (i) {
return i.getUTCDate();
});
this.updateRanges();
},
updateRanges: function () {
var range = $.map(this.dates, function (d) {
return d.valueOf();
});
$.each(this.pickers, function (i, p) {
p.setRange(range);
});
},
dateUpdated: function (e) {
// `this.updating` is a workaround for preventing infinite recursion
// between `changeDate` triggering and `setUTCDate` calling. Until
// there is a better mechanism.
if (this.updating)
return;
this.updating = true;
var dp = $(e.target).data('datepicker'),
new_date = dp.getUTCDate(),
i = $.inArray(e.target, this.inputs),
l = this.inputs.length;
if (i === -1)
return;
$.each(this.pickers, function (i, p) {
if (!p.getUTCDate())
p.setUTCDate(new_date);
});
if (new_date < this.dates[i]) {
// Date being moved earlier/left
while (i >= 0 && new_date < this.dates[i]) {
this.pickers[i--].setUTCDate(new_date);
}
}
else if (new_date > this.dates[i]) {
// Date being moved later/right
while (i < l && new_date > this.dates[i]) {
this.pickers[i++].setUTCDate(new_date);
}
}
this.updateDates();
delete this.updating;
},
remove: function () {
$.map(this.pickers, function (p) { p.remove(); });
delete this.element.data().datepicker;
}
};
function opts_from_el(el, prefix) {
// Derive options from element data-attrs
var data = $(el).data(),
out = {}, inkey,
replace = new RegExp('^' + prefix.toLowerCase() + '([A-Z])');
prefix = new RegExp('^' + prefix.toLowerCase());
function re_lower(_, a) {
return a.toLowerCase();
}
for (var key in data)
if (prefix.test(key)) {
inkey = key.replace(replace, re_lower);
out[inkey] = data[key];
}
return out;
}
function opts_from_locale(lang) {
// Derive options from locale plugins
var out = {};
// Check if "de-DE" style date is available, if not language should
// fallback to 2 letter code eg "de"
if (!dates[lang]) {
lang = lang.split('-')[0];
if (!dates[lang])
return;
}
var d = dates[lang];
$.each(locale_opts, function (i, k) {
if (k in d)
out[k] = d[k];
});
return out;
}
var old = $.fn.datepicker;
$.fn.datepicker = function (option) {
var args = Array.apply(null, arguments);
args.shift();
var internal_return;
this.each(function () {
var $this = $(this),
data = $this.data('datepicker'),
options = typeof option === 'object' && option;
if (!data) {
var elopts = opts_from_el(this, 'date'),
// Preliminary otions
xopts = $.extend({}, defaults, elopts, options),
locopts = opts_from_locale(xopts.language),
// Options priority: js args, data-attrs, locales, defaults
opts = $.extend({}, defaults, locopts, elopts, options);
if ($this.is('.input-daterange') || opts.inputs) {
var ropts = {
inputs: opts.inputs || $this.find('input').toArray()
};
$this.data('datepicker', (data = new DateRangePicker(this, $.extend(opts, ropts))));
}
else {
$this.data('datepicker', (data = new Datepicker(this, opts)));
}
}
if (typeof option === 'string' && typeof data[option] === 'function') {
internal_return = data[option].apply(data, args);
if (internal_return !== undefined)
return false;
}
});
if (internal_return !== undefined)
return internal_return;
else
return this;
};
var defaults = $.fn.datepicker.defaults = {
autoclose: false,
beforeShowDay: $.noop,
calendarWeeks: false,
clearBtn: false,
daysOfWeekDisabled: [],
endDate: Infinity,
forceParse: true,
format: 'mm/dd/yyyy',
keyboardNavigation: true,
language: 'en',
minViewMode: 0,
multidate: false,
multidateSeparator: ',',
orientation: "auto",
rtl: false,
startDate: -Infinity,
startView: 0,
todayBtn: false,
todayHighlight: false,
weekStart: 0
};
var locale_opts = $.fn.datepicker.locale_opts = [
'format',
'rtl',
'weekStart'
];
$.fn.datepicker.Constructor = Datepicker;
var dates = $.fn.datepicker.dates = {
en: {
days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
today: "Today",
clear: "Clear"
}
};
var DPGlobal = {
modes: [
{
clsName: 'days',
navFnc: 'Month',
navStep: 1
},
{
clsName: 'months',
navFnc: 'FullYear',
navStep: 1
},
{
clsName: 'years',
navFnc: 'FullYear',
navStep: 10
}],
isLeapYear: function (year) {
return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
},
getDaysInMonth: function (year, month) {
return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
},
validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g,
nonpunctuation: /[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g,
parseFormat: function (format) {
// IE treats \0 as a string end in inputs (truncating the value),
// so it's a bad format delimiter, anyway
var separators = format.replace(this.validParts, '\0').split('\0'),
parts = format.match(this.validParts);
if (!separators || !separators.length || !parts || parts.length === 0) {
throw new Error("Invalid date format.");
}
return { separators: separators, parts: parts };
},
parseDate: function (date, format, language) {
if (!date)
return undefined;
if (date instanceof Date)
return date;
if (typeof format === 'string')
format = DPGlobal.parseFormat(format);
var part_re = /([\-+]\d+)([dmwy])/,
parts = date.match(/([\-+]\d+)([dmwy])/g),
part, dir, i;
if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)) {
date = new Date();
for (i = 0; i < parts.length; i++) {
part = part_re.exec(parts[i]);
dir = parseInt(part[1]);
switch (part[2]) {
case 'd':
date.setUTCDate(date.getUTCDate() + dir);
break;
case 'm':
date = Datepicker.prototype.moveMonth.call(Datepicker.prototype, date, dir);
break;
case 'w':
date.setUTCDate(date.getUTCDate() + dir * 7);
break;
case 'y':
date = Datepicker.prototype.moveYear.call(Datepicker.prototype, date, dir);
break;
}
}
return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 0, 0, 0);
}
parts = date && date.match(this.nonpunctuation) || [];
date = new Date();
var parsed = {},
setters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'],
setters_map = {
yyyy: function (d, v) {
return d.setUTCFullYear(v);
},
yy: function (d, v) {
return d.setUTCFullYear(2000 + v);
},
m: function (d, v) {
if (isNaN(d))
return d;
v -= 1;
while (v < 0) v += 12;
v %= 12;
d.setUTCMonth(v);
while (d.getUTCMonth() !== v)
d.setUTCDate(d.getUTCDate() - 1);
return d;
},
d: function (d, v) {
return d.setUTCDate(v);
}
},
val, filtered;
setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];
setters_map['dd'] = setters_map['d'];
date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
var fparts = format.parts.slice();
// Remove noop parts
if (parts.length !== fparts.length) {
fparts = $(fparts).filter(function (i, p) {
return $.inArray(p, setters_order) !== -1;
}).toArray();
}
// Process remainder
function match_part() {
var m = this.slice(0, parts[i].length),
p = parts[i].slice(0, m.length);
return m === p;
}
if (parts.length === fparts.length) {
var cnt;
for (i = 0, cnt = fparts.length; i < cnt; i++) {
val = parseInt(parts[i], 10);
part = fparts[i];
if (isNaN(val)) {
switch (part) {
case 'MM':
filtered = $(dates[language].months).filter(match_part);
val = $.inArray(filtered[0], dates[language].months) + 1;
break;
case 'M':
filtered = $(dates[language].monthsShort).filter(match_part);
val = $.inArray(filtered[0], dates[language].monthsShort) + 1;
break;
}
}
parsed[part] = val;
}
var _date, s;
for (i = 0; i < setters_order.length; i++) {
s = setters_order[i];
if (s in parsed && !isNaN(parsed[s])) {
_date = new Date(date);
setters_map[s](_date, parsed[s]);
if (!isNaN(_date))
date = _date;
}
}
}
return date;
},
formatDate: function (date, format, language) {
if (!date)
return '';
if (typeof format === 'string')
format = DPGlobal.parseFormat(format);
var val = {
d: date.getUTCDate(),
D: dates[language].daysShort[date.getUTCDay()],
DD: dates[language].days[date.getUTCDay()],
m: date.getUTCMonth() + 1,
M: dates[language].monthsShort[date.getUTCMonth()],
MM: dates[language].months[date.getUTCMonth()],
yy: date.getUTCFullYear().toString().substring(2),
yyyy: date.getUTCFullYear()
};
val.dd = (val.d < 10 ? '0' : '') + val.d;
val.mm = (val.m < 10 ? '0' : '') + val.m;
date = [];
var seps = $.extend([], format.separators);
for (var i = 0, cnt = format.parts.length; i <= cnt; i++) {
if (seps.length)
date.push(seps.shift());
date.push(val[format.parts[i]]);
}
return date.join('');
},
headTemplate: '<thead>' +
'<tr>' +
'<th class="prev">«</th>' +
'<th colspan="5" class="datepicker-switch"></th>' +
'<th class="next">»</th>' +
'</tr>' +
'</thead>',
contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>',
footTemplate: '<tfoot>' +
'<tr>' +
'<th colspan="7" class="today"></th>' +
'</tr>' +
'<tr>' +
'<th colspan="7" class="clear"></th>' +
'</tr>' +
'</tfoot>'
};
DPGlobal.template = '<div class="datepicker">' +
'<div class="datepicker-days">' +
'<table class=" table-condensed">' +
DPGlobal.headTemplate +
'<tbody></tbody>' +
DPGlobal.footTemplate +
'</table>' +
'</div>' +
'<div class="datepicker-months">' +
'<table class="table-condensed">' +
DPGlobal.headTemplate +
DPGlobal.contTemplate +
DPGlobal.footTemplate +
'</table>' +
'</div>' +
'<div class="datepicker-years">' +
'<table class="table-condensed">' +
DPGlobal.headTemplate +
DPGlobal.contTemplate +
DPGlobal.footTemplate +
'</table>' +
'</div>' +
'</div>';
$.fn.datepicker.DPGlobal = DPGlobal;
/* DATEPICKER NO CONFLICT
* =================== */
$.fn.datepicker.noConflict = function () {
$.fn.datepicker = old;
return this;
};
/* DATEPICKER DATA-API
* ================== */
$(document).on(
'focus.datepicker.data-api click.datepicker.data-api',
'[data-provide="datepicker"]',
function (e) {
var $this = $(this);
if ($this.data('datepicker'))
return;
e.preventDefault();
// component click requires us to explicitly show it
$this.datepicker('show');
}
);
$(function () {
$('[data-provide="datepicker-inline"]').datepicker();
});
}(window.jQuery));
// <script type="text/javascript" src="/Content/js/app/bDatepicker-directive.js?3ba152" type="text/javascript"></script>
/*jshint globalstrict: true*/
/*jshint sub: true*/
/*jslint vars: true*/
/*jslint es5: true */
/*jslint devel: true */
/*jslint bitwise: true */
/*jslint plusplus: true */
/*global angular: false*/
"use strict";
(function () {
var module = angular.module('bDatepicker', []);
module.directive('bDatepicker', function () {
return {
restrict: 'A',
link: function (scope, el, attr) { //ignore jslint
//el.datepicker({});
var component = el.siblings('[data-toggle="datepicker"]');
if (component.length) {
component.on('click', function () {
el.trigger('focus');
});
}
}
};
})
.directive('bDatepicker', ['$filter', '$timeout', function ($filter, $timeout) {
return {
require: '?ngModel',
priority: 100,
restrict: 'A',
link: function ($scope, element, attrs, controller) {
if (!controller) { return; } // do nothing if no ng-model
$scope.parseYYYYMMDD = function (str) {
// validate year as 4 digits, month as 01-12, and day as 01-31
if ((str = str.match(/^(\d{4})(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])$/))) {
str[0] = new Date(+str[1], +str[2] - 1, +str[3]);
// check if month stayed the same (ie that day number is valid)
if (str[0].getMonth() === +str[2] - 1)
return str[0];
}
return undefined;
};
var updateModel;
updateModel = function (ev) {
if (ev.date !== undefined) {
// convert to string if attribute ui-date-format exists
var newValue = ev.date;
if (typeof attrs.uiDateFormat !== 'undefined') {
newValue = $filter('date')(ev.date, attrs.dateFormat);
}
$timeout(function () {
controller.$setViewValue(newValue);
$scope.$apply();
element.datepicker('hide');
element.blur();
});
} else {
$timeout(function () {
controller.$setViewValue(element.datepicker().data().datepicker.date);
$scope.$apply();
element.datepicker('hide');
element.blur();
});
}
};
controller.$render = function () {
// ensure we're not inside a $digest loop
$timeout(function () {
element.datepicker().data().datepicker.date = controller.$viewValue;
if (typeof attrs.dateFormat !== 'undefined') {
element.datepicker('update',
moment(
controller.$viewValue,
attrs.dateFormat.toUpperCase()
).toDate());
} else {
element.datepicker('update', controller.$viewValue);
}
$scope.$apply();
});
return controller.$viewValue;
};
return attrs.$observe('bDatepicker', function (value) {
var options;
options = {};
if (angular.isObject(value)) {
options = value;
}
if (typeof (value) === "string" && value.length > 0) {
options = angular.fromJson(value);
}
return element.datepicker(options).on('changeDate',
function (event) {
updateModel(event);
});
});
}
};
}]);
})();
<!-- <script src="/Scripts/bootstrap-modal/bootstrap-modal.js?3ba151" type="text/javascript"></script> -->
/* ===========================================================
* bootstrap-modal.js v2.2.5
* ===========================================================
* Copyright 2012 Jordan Schroter
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */
!function ($) {
"use strict"; // jshint ;_;
/* MODAL CLASS DEFINITION
* ====================== */
var Modal = function (element, options) {
this.init(element, options);
};
Modal.prototype = {
constructor: Modal,
init: function (element, options) {
var that = this;
this.options = options;
this.$element = $(element)
.delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this));
this.options.remote && this.$element.find('.modal-body').load(this.options.remote, function () {
var e = $.Event('loaded');
that.$element.trigger(e);
});
var manager = typeof this.options.manager === 'function' ?
this.options.manager.call(this) : this.options.manager;
manager = manager.appendModal ?
manager : $(manager).modalmanager().data('modalmanager');
manager.appendModal(this);
},
toggle: function () {
return this[!this.isShown ? 'show' : 'hide']();
},
show: function () {
var e = $.Event('show');
if (this.isShown) return;
this.$element.trigger(e);
if (e.isDefaultPrevented()) return;
this.escape();
this.tab();
this.options.loading && this.loading();
},
hide: function (e) {
e && e.preventDefault();
e = $.Event('hide');
this.$element.trigger(e);
if (!this.isShown || e.isDefaultPrevented()) return;
this.isShown = false;
this.escape();
this.tab();
this.isLoading && this.loading();
$(document).off('focusin.modal');
this.$element
.removeClass('in')
.removeClass('animated')
.removeClass(this.options.attentionAnimation)
.removeClass('modal-overflow')
.attr('aria-hidden', true);
$.support.transition && this.$element.hasClass('fade') ?
this.hideWithTransition() :
this.hideModal();
},
layout: function () {
var prop = this.options.height ? 'height' : 'max-height',
value = this.options.height || this.options.maxHeight;
if (this.options.width){
this.$element.css('width', this.options.width);
var that = this;
this.$element.css('margin-left', function () {
if (/%/ig.test(that.options.width)){
return -(parseInt(that.options.width) / 2) + '%';
} else {
return -($(this).width() / 2) + 'px';
}
});
} else {
this.$element.css('width', '');
this.$element.css('margin-left', '');
}
this.$element.find('.modal-body')
.css('overflow', '')
.css(prop, '');
if (value){
this.$element.find('.modal-body')
.css('overflow', 'auto')
.css(prop, value);
}
var modalOverflow = $(window).height() - 10 < this.$element.height();
if (modalOverflow || this.options.modalOverflow) {
this.$element
.css('margin-top', 0)
.addClass('modal-overflow');
} else {
this.$element
.css('margin-top', 0 - this.$element.height() / 2)
.removeClass('modal-overflow');
}
},
tab: function () {
var that = this;
if (this.isShown && this.options.consumeTab) {
this.$element.on('keydown.tabindex.modal', '[data-tabindex]', function (e) {
if (e.keyCode && e.keyCode == 9){
var $next = $(this),
$rollover = $(this);
that.$element.find('[data-tabindex]:enabled:not([readonly])').each(function (e) {
if (!e.shiftKey){
$next = $next.data('tabindex') < $(this).data('tabindex') ?
$next = $(this) :
$rollover = $(this);
} else {
$next = $next.data('tabindex') > $(this).data('tabindex') ?
$next = $(this) :
$rollover = $(this);
}
});
$next[0] !== $(this)[0] ?
$next.focus() : $rollover.focus();
e.preventDefault();
}
});
} else if (!this.isShown) {
this.$element.off('keydown.tabindex.modal');
}
},
escape: function () {
var that = this;
if (this.isShown && this.options.keyboard) {
if (!this.$element.attr('tabindex')) this.$element.attr('tabindex', -1);
this.$element.on('keyup.dismiss.modal', function (e) {
e.which == 27 && that.hide();
});
} else if (!this.isShown) {
this.$element.off('keyup.dismiss.modal')
}
},
hideWithTransition: function () {
var that = this
, timeout = setTimeout(function () {
that.$element.off($.support.transition.end);
that.hideModal();
}, 500);
this.$element.one($.support.transition.end, function () {
clearTimeout(timeout);
that.hideModal();
});
},
hideModal: function () {
var prop = this.options.height ? 'height' : 'max-height';
var value = this.options.height || this.options.maxHeight;
if (value){
this.$element.find('.modal-body')
.css('overflow', '')
.css(prop, '');
}
this.$element
.hide()
.trigger('hidden');
},
removeLoading: function () {
this.$loading.remove();
this.$loading = null;
this.isLoading = false;
},
loading: function (callback) {
callback = callback || function () {};
var animate = this.$element.hasClass('fade') ? 'fade' : '';
if (!this.isLoading) {
var doAnimate = $.support.transition && animate;
this.$loading = $('<div class="loading-mask ' + animate + '">')
.append(this.options.spinner)
.appendTo(this.$element);
if (doAnimate) this.$loading[0].offsetWidth; // force reflow
this.$loading.addClass('in');
this.isLoading = true;
doAnimate ?
this.$loading.one($.support.transition.end, callback) :
callback();
} else if (this.isLoading && this.$loading) {
this.$loading.removeClass('in');
var that = this;
$.support.transition && this.$element.hasClass('fade')?
this.$loading.one($.support.transition.end, function () { that.removeLoading() }) :
that.removeLoading();
} else if (callback) {
callback(this.isLoading);
}
},
focus: function () {
var $focusElem = this.$element.find(this.options.focusOn);
$focusElem = $focusElem.length ? $focusElem : this.$element;
$focusElem.focus();
},
attention: function (){
// NOTE: transitionEnd with keyframes causes odd behaviour
if (this.options.attentionAnimation){
this.$element
.removeClass('animated')
.removeClass(this.options.attentionAnimation);
var that = this;
setTimeout(function () {
that.$element
.addClass('animated')
.addClass(that.options.attentionAnimation);
}, 0);
}
this.focus();
},
destroy: function () {
var e = $.Event('destroy');
this.$element.trigger(e);
if (e.isDefaultPrevented()) return;
this.$element
.off('.modal')
.removeData('modal')
.removeClass('in')
.attr('aria-hidden', true);
if (this.$parent !== this.$element.parent()) {
this.$element.appendTo(this.$parent);
} else if (!this.$parent.length) {
// modal is not part of the DOM so remove it.
this.$element.remove();
this.$element = null;
}
this.$element.trigger('destroyed');
}
};
/* MODAL PLUGIN DEFINITION
* ======================= */
$.fn.modal = function (option, args) {
return this.each(function () {
var $this = $(this),
data = $this.data('modal'),
options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option);
if (!data) $this.data('modal', (data = new Modal(this, options)));
if (typeof option == 'string') data[option].apply(data, [].concat(args));
else if (options.show) data.show()
})
};
$.fn.modal.defaults = {
keyboard: true,
backdrop: true,
loading: false,
show: true,
width: null,
height: null,
maxHeight: null,
modalOverflow: false,
consumeTab: true,
focusOn: null,
replace: false,
resize: false,
attentionAnimation: 'shake',
manager: 'body',
spinner: '<div class="loading-spinner" style="width: 200px; margin-left: -100px;"><div class="progress progress-striped active"><div class="bar" style="width: 100%;"></div></div></div>',
backdropTemplate: '<div class="modal-backdrop" />'
};
$.fn.modal.Constructor = Modal;
/* MODAL DATA-API
* ============== */
$(function () {
$(document).off('click.modal').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
var $this = $(this),
href = $this.attr('href'),
$target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))), //strip for ie7
option = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data());
e.preventDefault();
$target
.modal(option)
.one('hide', function () {
$this.focus();
})
});
});
}(window.jQuery);
<!-- <script src="/Scripts/bootstrap-modal/bootstrap-modalmanager.js?3ba151" type="text/javascript"></script> -->
/* ===========================================================
* bootstrap-modalmanager.js v2.2.5
* ===========================================================
* Copyright 2012 Jordan Schroter.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */
!function ($) {
"use strict"; // jshint ;_;
/* MODAL MANAGER CLASS DEFINITION
* ====================== */
var ModalManager = function (element, options) {
this.init(element, options);
};
ModalManager.prototype = {
constructor: ModalManager,
init: function (element, options) {
this.$element = $(element);
this.options = $.extend({}, $.fn.modalmanager.defaults, this.$element.data(), typeof options == 'object' && options);
this.stack = [];
this.backdropCount = 0;
if (this.options.resize) {
var resizeTimeout,
that = this;
$(window).on('resize.modal', function(){
resizeTimeout && clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(function(){
for (var i = 0; i < that.stack.length; i++){
that.stack[i].isShown && that.stack[i].layout();
}
}, 10);
});
}
},
createModal: function (element, options) {
$(element).modal($.extend({ manager: this }, options));
},
appendModal: function (modal) {
this.stack.push(modal);
var that = this;
modal.$element.on('show.modalmanager', targetIsSelf(function (e) {
var showModal = function(){
modal.isShown = true;
var transition = $.support.transition && modal.$element.hasClass('fade');
that.$element
.toggleClass('modal-open', that.hasOpenModal())
.toggleClass('page-overflow', $(window).height() < that.$element.height());
modal.$parent = modal.$element.parent();
modal.$container = that.createContainer(modal);
modal.$element.appendTo(modal.$container);
that.backdrop(modal, function () {
modal.$element.show();
if (transition) {
//modal.$element[0].style.display = 'run-in';
modal.$element[0].offsetWidth;
//modal.$element.one($.support.transition.end, function () { modal.$element[0].style.display = 'block' });
}
modal.layout();
modal.$element
.addClass('in')
.attr('aria-hidden', false);
var complete = function () {
that.setFocus();
modal.$element.trigger('shown');
};
transition ?
modal.$element.one($.support.transition.end, complete) :
complete();
});
};
modal.options.replace ?
that.replace(showModal) :
showModal();
}));
modal.$element.on('hidden.modalmanager', targetIsSelf(function (e) {
that.backdrop(modal);
// handle the case when a modal may have been removed from the dom before this callback executes
if (!modal.$element.parent().length) {
that.destroyModal(modal);
} else if (modal.$backdrop){
var transition = $.support.transition && modal.$element.hasClass('fade');
// trigger a relayout due to firebox's buggy transition end event
if (transition) { modal.$element[0].offsetWidth; }
$.support.transition && modal.$element.hasClass('fade') ?
modal.$backdrop.one($.support.transition.end, function () { modal.destroy(); }) :
modal.destroy();
} else {
modal.destroy();
}
}));
modal.$element.on('destroyed.modalmanager', targetIsSelf(function (e) {
that.destroyModal(modal);
}));
},
getOpenModals: function () {
var openModals = [];
for (var i = 0; i < this.stack.length; i++){
if (this.stack[i].isShown) openModals.push(this.stack[i]);
}
return openModals;
},
hasOpenModal: function () {
return this.getOpenModals().length > 0;
},
setFocus: function () {
var topModal;
for (var i = 0; i < this.stack.length; i++){
if (this.stack[i].isShown) topModal = this.stack[i];
}
if (!topModal) return;
topModal.focus();
},
destroyModal: function (modal) {
modal.$element.off('.modalmanager');
if (modal.$backdrop) this.removeBackdrop(modal);
this.stack.splice(this.getIndexOfModal(modal), 1);
var hasOpenModal = this.hasOpenModal();
this.$element.toggleClass('modal-open', hasOpenModal);
if (!hasOpenModal){
this.$element.removeClass('page-overflow');
}
this.removeContainer(modal);
this.setFocus();
},
getModalAt: function (index) {
return this.stack[index];
},
getIndexOfModal: function (modal) {
for (var i = 0; i < this.stack.length; i++){
if (modal === this.stack[i]) return i;
}
},
replace: function (callback) {
var topModal;
for (var i = 0; i < this.stack.length; i++){
if (this.stack[i].isShown) topModal = this.stack[i];
}
if (topModal) {
this.$backdropHandle = topModal.$backdrop;
topModal.$backdrop = null;
callback && topModal.$element.one('hidden',
targetIsSelf( $.proxy(callback, this) ));
topModal.hide();
} else if (callback) {
callback();
}
},
removeBackdrop: function (modal) {
modal.$backdrop.remove();
modal.$backdrop = null;
},
createBackdrop: function (animate, tmpl) {
var $backdrop;
if (!this.$backdropHandle) {
$backdrop = $(tmpl)
.addClass(animate)
.appendTo(this.$element);
} else {
$backdrop = this.$backdropHandle;
$backdrop.off('.modalmanager');
this.$backdropHandle = null;
this.isLoading && this.removeSpinner();
}
return $backdrop;
},
removeContainer: function (modal) {
modal.$container.remove();
modal.$container = null;
},
createContainer: function (modal) {
var $container;
$container = $('<div class="modal-scrollable">')
.css('z-index', getzIndex('modal', this.getOpenModals().length))
.appendTo(this.$element);
if (modal && modal.options.backdrop != 'static') {
$container.on('click.modal', targetIsSelf(function (e) {
modal.hide();
}));
} else if (modal) {
$container.on('click.modal', targetIsSelf(function (e) {
modal.attention();
}));
}
return $container;
},
backdrop: function (modal, callback) {
var animate = modal.$element.hasClass('fade') ? 'fade' : '',
showBackdrop = modal.options.backdrop &&
this.backdropCount < this.options.backdropLimit;
if (modal.isShown && showBackdrop) {
var doAnimate = $.support.transition && animate && !this.$backdropHandle;
modal.$backdrop = this.createBackdrop(animate, modal.options.backdropTemplate);
modal.$backdrop.css('z-index', getzIndex( 'backdrop', this.getOpenModals().length ));
if (doAnimate) modal.$backdrop[0].offsetWidth; // force reflow
modal.$backdrop.addClass('in');
this.backdropCount += 1;
doAnimate ?
modal.$backdrop.one($.support.transition.end, callback) :
callback();
} else if (!modal.isShown && modal.$backdrop) {
modal.$backdrop.removeClass('in');
this.backdropCount -= 1;
var that = this;
$.support.transition && modal.$element.hasClass('fade')?
modal.$backdrop.one($.support.transition.end, function () { that.removeBackdrop(modal) }) :
that.removeBackdrop(modal);
} else if (callback) {
callback();
}
},
removeSpinner: function(){
this.$spinner && this.$spinner.remove();
this.$spinner = null;
this.isLoading = false;
},
removeLoading: function () {
this.$backdropHandle && this.$backdropHandle.remove();
this.$backdropHandle = null;
this.removeSpinner();
},
loading: function (callback) {
callback = callback || function () { };
this.$element
.toggleClass('modal-open', !this.isLoading || this.hasOpenModal())
.toggleClass('page-overflow', $(window).height() < this.$element.height());
if (!this.isLoading) {
this.$backdropHandle = this.createBackdrop('fade', this.options.backdropTemplate);
this.$backdropHandle[0].offsetWidth; // force reflow
var openModals = this.getOpenModals();
this.$backdropHandle
.css('z-index', getzIndex('backdrop', openModals.length + 1))
.addClass('in');
var $spinner = $(this.options.spinner)
.css('z-index', getzIndex('modal', openModals.length + 1))
.appendTo(this.$element)
.addClass('in');
this.$spinner = $(this.createContainer())
.append($spinner)
.on('click.modalmanager', $.proxy(this.loading, this));
this.isLoading = true;
$.support.transition ?
this.$backdropHandle.one($.support.transition.end, callback) :
callback();
} else if (this.isLoading && this.$backdropHandle) {
this.$backdropHandle.removeClass('in');
var that = this;
$.support.transition ?
this.$backdropHandle.one($.support.transition.end, function () { that.removeLoading() }) :
that.removeLoading();
} else if (callback) {
callback(this.isLoading);
}
}
};
/* PRIVATE METHODS
* ======================= */
// computes and caches the zindexes
var getzIndex = (function () {
var zIndexFactor,
baseIndex = {};
return function (type, pos) {
if (typeof zIndexFactor === 'undefined'){
var $baseModal = $('<div class="modal hide" />').appendTo('body'),
$baseBackdrop = $('<div class="modal-backdrop hide" />').appendTo('body');
baseIndex['modal'] = +$baseModal.css('z-index');
baseIndex['backdrop'] = +$baseBackdrop.css('z-index');
zIndexFactor = baseIndex['modal'] - baseIndex['backdrop'];
$baseModal.remove();
$baseBackdrop.remove();
$baseBackdrop = $baseModal = null;
}
return baseIndex[type] + (zIndexFactor * pos);
}
}());
// make sure the event target is the modal itself in order to prevent
// other components such as tabsfrom triggering the modal manager.
// if Boostsrap namespaced events, this would not be needed.
function targetIsSelf(callback){
return function (e) {
if (e && this === e.target){
return callback.apply(this, arguments);
}
}
}
/* MODAL MANAGER PLUGIN DEFINITION
* ======================= */
$.fn.modalmanager = function (option, args) {
return this.each(function () {
var $this = $(this),
data = $this.data('modalmanager');
if (!data) $this.data('modalmanager', (data = new ModalManager(this, option)));
if (typeof option === 'string') data[option].apply(data, [].concat(args))
})
};
$.fn.modalmanager.defaults = {
backdropLimit: 999,
resize: true,
spinner: '<div class="loading-spinner fade" style="width: 200px; margin-left: -100px;"><div class="progress progress-striped active"><div class="bar" style="width: 100%;"></div></div></div>',
backdropTemplate: '<div class="modal-backdrop" />'
};
$.fn.modalmanager.Constructor = ModalManager
// ModalManager handles the modal-open class so we need
// to remove conflicting bootstrap 3 event handlers
$(function () {
$(document).off('show.bs.modal').off('hidden.bs.modal');
});
}(jQuery);
/* ===========================================================
* bootstrap-tooltip.js v2.3.2
* http://getbootstrap.com/2.3.2/javascript.html#tooltips
* Inspired by the original jQuery.tipsy by Jason Frame
* ===========================================================
* Copyright 2013 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================== */
!function ($) {
"use strict"; // jshint ;_;
/* TOOLTIP PUBLIC CLASS DEFINITION
* =============================== */
var Tooltip = function (element, options) {
this.init('tooltip', element, options)
}
Tooltip.prototype = {
constructor: Tooltip
, init: function (type, element, options) {
var eventIn
, eventOut
, triggers
, trigger
, i
this.type = type
this.$element = $(element)
this.options = this.getOptions(options)
this.enabled = true
triggers = this.options.trigger.split(' ')
for (i = triggers.length; i--;) {
trigger = triggers[i]
if (trigger == 'click') {
this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
} else if (trigger != 'manual') {
eventIn = trigger == 'hover' ? 'mouseenter' : 'focus'
eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'
this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
}
}
this.options.selector ?
(this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
this.fixTitle()
}
, getOptions: function (options) {
options = $.extend({}, $.fn[this.type].defaults, this.$element.data(), options)
if (options.delay && typeof options.delay == 'number') {
options.delay = {
show: options.delay
, hide: options.delay
}
}
return options
}
, enter: function (e) {
var defaults = $.fn[this.type].defaults
, options = {}
, self
this._options && $.each(this._options, function (key, value) {
if (defaults[key] != value) options[key] = value
}, this)
self = $(e.currentTarget)[this.type](options).data(this.type)
if (!self.options.delay || !self.options.delay.show) return self.show()
clearTimeout(this.timeout)
self.hoverState = 'in'
this.timeout = setTimeout(function() {
if (self.hoverState == 'in') self.show()
}, self.options.delay.show)
}
, leave: function (e) {
var self = $(e.currentTarget)[this.type](this._options).data(this.type)
if (this.timeout) clearTimeout(this.timeout)
if (!self.options.delay || !self.options.delay.hide) return self.hide()
self.hoverState = 'out'
this.timeout = setTimeout(function() {
if (self.hoverState == 'out') self.hide()
}, self.options.delay.hide)
}
, show: function () {
var $tip
, pos
, actualWidth
, actualHeight
, placement
, tp
, e = $.Event('show')
if (this.hasContent() && this.enabled) {
this.$element.trigger(e)
if (e.isDefaultPrevented()) return
$tip = this.tip()
this.setContent()
if (this.options.animation) {
$tip.addClass('fade')
}
placement = typeof this.options.placement == 'function' ?
this.options.placement.call(this, $tip[0], this.$element[0]) :
this.options.placement
$tip
.detach()
.css({ top: 0, left: 0, display: 'block' })
this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
pos = this.getPosition()
actualWidth = $tip[0].offsetWidth
actualHeight = $tip[0].offsetHeight
switch (placement) {
case 'bottom':
tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
break
case 'top':
tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
break
case 'left':
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
break
case 'right':
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
break
}
this.applyPlacement(tp, placement)
this.$element.trigger('shown')
}
}
, applyPlacement: function(offset, placement){
var $tip = this.tip()
, width = $tip[0].offsetWidth
, height = $tip[0].offsetHeight
, actualWidth
, actualHeight
, delta
, replace
$tip
.offset(offset)
.addClass(placement)
.addClass('in')
actualWidth = $tip[0].offsetWidth
actualHeight = $tip[0].offsetHeight
if (placement == 'top' && actualHeight != height) {
offset.top = offset.top + height - actualHeight
replace = true
}
if (placement == 'bottom' || placement == 'top') {
delta = 0
if (offset.left < 0){
delta = offset.left * -2
offset.left = 0
$tip.offset(offset)
actualWidth = $tip[0].offsetWidth
actualHeight = $tip[0].offsetHeight
}
this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')
} else {
this.replaceArrow(actualHeight - height, actualHeight, 'top')
}
if (replace) $tip.offset(offset)
}
, replaceArrow: function(delta, dimension, position){
this
.arrow()
.css(position, delta ? (50 * (1 - delta / dimension) + "%") : '')
}
, setContent: function () {
var $tip = this.tip()
, title = this.getTitle()
$tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
$tip.removeClass('fade in top bottom left right')
}
, hide: function () {
var that = this
, $tip = this.tip()
, e = $.Event('hide')
this.$element.trigger(e)
if (e.isDefaultPrevented()) return
$tip.removeClass('in')
function removeWithAnimation() {
var timeout = setTimeout(function () {
$tip.off($.support.transition.end).detach()
}, 500)
$tip.one($.support.transition.end, function () {
clearTimeout(timeout)
$tip.detach()
})
}
$.support.transition && this.$tip.hasClass('fade') ?
removeWithAnimation() :
$tip.detach()
this.$element.trigger('hidden')
return this
}
, fixTitle: function () {
var $e = this.$element
if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
$e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
}
}
, hasContent: function () {
return this.getTitle()
}
, getPosition: function () {
var el = this.$element[0]
return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {
width: el.offsetWidth
, height: el.offsetHeight
}, this.$element.offset())
}
, getTitle: function () {
var title
, $e = this.$element
, o = this.options
title = $e.attr('data-original-title')
|| (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
return title
}
, tip: function () {
return this.$tip = this.$tip || $(this.options.template)
}
, arrow: function(){
return this.$arrow = this.$arrow || this.tip().find(".tooltip-arrow")
}
, validate: function () {
if (!this.$element[0].parentNode) {
this.hide()
this.$element = null
this.options = null
}
}
, enable: function () {
this.enabled = true
}
, disable: function () {
this.enabled = false
}
, toggleEnabled: function () {
this.enabled = !this.enabled
}
, toggle: function (e) {
var self = e ? $(e.currentTarget)[this.type](this._options).data(this.type) : this
self.tip().hasClass('in') ? self.hide() : self.show()
}
, destroy: function () {
this.hide().$element.off('.' + this.type).removeData(this.type)
}
}
/* TOOLTIP PLUGIN DEFINITION
* ========================= */
var old = $.fn.tooltip
$.fn.tooltip = function ( option ) {
return this.each(function () {
var $this = $(this)
, data = $this.data('tooltip')
, options = typeof option == 'object' && option
if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
if (typeof option == 'string') data[option]()
})
}
$.fn.tooltip.Constructor = Tooltip
$.fn.tooltip.defaults = {
animation: true
, placement: 'top'
, selector: false
, template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
, trigger: 'hover focus'
, title: ''
, delay: 0
, html: false
, container: false
}
/* TOOLTIP NO CONFLICT
* =================== */
$.fn.tooltip.noConflict = function () {
$.fn.tooltip = old
return this
}
}(window.jQuery);
/*
xtForm
--------------------------------------------------------------------------
Creates validators and attaches them to inputs
Handles client side validation in tooltips
Allows for custom error message overrides
*/
(function(angular) {
"use strict";
function DefaultErrorMessages() {
this.minlength = 'Needs to be at least {{minlength}} characters long';
this.maxlength = 'Can be no longer than {{maxlength}} characters long';
this.required = 'This field is required';
this.number = 'Must be a number';
this.min = 'Must be at least {{min}}';
this.max = 'Must be no greater than {{max}}';
this.email = 'Invalid Email';
this.pattern = 'Illegal value';
}
function ErrorMessages() {}
ErrorMessages.prototype = new DefaultErrorMessages();
ErrorMessages.prototype.constructor = ErrorMessages;
function InputValidator(scope, element, attrs, ngModel, formCtrl) {
var self = this, // capture scope,
prop;
this.errorMessages = new ErrorMessages();
this.formCtrl = formCtrl;
this.scope = scope;
this.element = element;
this.ngModel = ngModel;
this.attrs = attrs;
var observe = function(prop) {
var innerProp = prop;
attrs.$observe(innerProp, function(val) {
self.errorMessages[innerProp.substring(3, innerProp.length).toLowerCase()] = val;
});
};
for (prop in attrs) {
if (attrs.hasOwnProperty(prop) && prop.indexOf('msg') === 0) {
observe(prop);
}
}
this.ngModel.$parsers.unshift(function(value) {
return value === '' ? null : value;
});
// tried viewListeners, parsers, different watches.. seems this is the best
scope.$watch(function() {
return ngModel.$error;
}, function(valid) {
if (ngModel.$dirty) {
self.showErrors();
} else {
self.resetValidity();
}
}, true);
}
InputValidator.prototype.setDirty = function(value) {
this.ngModel.$dirty = value;
this.ngModel.$pristine = !value;
this.element
.toggleClass('ng-dirty', value)
.toggleClass('ng-pristine', !value);
};
InputValidator.prototype.showErrors = function(isSubmit) {
var ngModel = this.ngModel;
this.setDirty(true);
if (!ngModel.$valid) {
// build error summary
var errors = "",
propCount = 0;
// calculated here as it could be variable
var bounds = {
minlength: this.attrs.ngMinlength,
maxlength: this.attrs.ngMaxlength,
min: this.attrs.min,
max: this.attrs.max,
};
for (var prop in ngModel.$error) {
var key = prop.toLowerCase();
if (prop != 'required' && ngModel.$error[prop] === true && this.errorMessages[key]) {
propCount++;
var errString = this.errorMessages[key] + "";
for (var bound in bounds) {
errString = errString.replace('{{' + bound + '}}', bounds[bound]);
}
errors += errString + '<br>';
}
}
if (propCount === 0 && ngModel.$error.required === true) {
errors += this.errorMessages.required + '<br>';
}
if (ngModel.$error.messages !== undefined) {
errors += ngModel.$error.messages;
}
if (this.tooltipSet === true) {
this.element.tooltip("destroy");
}
// create tooltip
this.element.tooltip({
html: true,
title: errors,
placement: this.attrs.placement || 'bottom',
trigger: this.attrs.trigger || 'focus hover',
container: this.attrs.container || 'body'
});
if (this.profile === 'showAll' || !isSubmit) {
this.element.tooltip('show');
}
this.tooltipSet = true;
this.element.addClass('xt-error');
} else {
this.resetValidity();
}
};
InputValidator.prototype.resetValidity = function () {
var that = this;
setTimeout(function () {
// remove tooltip if needed
if (that.tooltipSet) {
that.ngModel.$error.messages = undefined;
that.element.removeClass('xt-error');
that.element.tooltip('destroy');
that.tooltipSet = false;
that.scope.$apply();
}
});
};
angular.module('xtForm', [])
.directive('xtForm', ['$parse', function($parse) {
return {
require: ['form', 'xtForm'],
controller: [
"$scope",
"$element",
"$attrs",
function($scope, $element, $attrs) {
// Holds all validators
this.validators = {
_validators: {},
registerValidator: function(name, validator) {
validator.profile = $attrs.profile || 'default';
this._validators[name] = validator;
},
deregisterValidator: function(name) {
this._validators[name].ngModel.$valid = true;
this._validators[name].showErrors();
delete this._validators[name];
},
hasValidator: function(name) {
return this._validators[name] !== undefined;
},
getValidator: function(name) {
return this._validators[name];
},
resetValidity: function() {
angular.forEach(this._validators, function(validator) {
validator.resetValidity(false);
});
},
showAllErrors: function() {
angular.forEach(this._validators, function(validator) {
validator.showErrors(true);
});
}
};
this.$element = $element;
}
],
link: function(scope, element, attrs, ctrl) {
var control = {
onSubmit: function () {}
},
formCtrl = ctrl[0],
xtFormCtrl = ctrl[1];
function submit() {
formCtrl.$setDirty();
if (!formCtrl.$valid) {
xtFormCtrl.validators.showAllErrors();
control.onSubmit(false);
return;
}
//reset
xtFormCtrl.validators.resetValidity();
control.onSubmit(true);
}
function validate() {
formCtrl.$setDirty();
if (!formCtrl.$valid) {
xtFormCtrl.validators.showAllErrors();
return false;
} else {
return true;
}
}
function reset() {
xtFormCtrl.validators.resetValidity();
}
// add save functionality to the form control
// (i got this style from angular-ui. I kind of think it looks like an antipattern but
// but I can't find a cleaner way of controller/directive comm)
if (attrs.xtForm) {
var temp = scope.$eval(attrs.xtForm);
if (temp !== undefined) {
control = temp;
var that = this;
control.submit = function () {
submit.apply(that, arguments);
};
control.reset = function () {
reset.apply(that, arguments);
};
control.validate = function () {
validate.apply(that, arguments);
};
}
}
// wire up default submit of form to save function
element.on('submit', function(evt) {
submit();
evt.preventDefault();
return false;
});
element.on('$destroy', function () {
xtFormCtrl.$element = null;
xtFormCtrl.validators = null;
});
}
};
}])
.directive('xtValidate', function() {
return {
require: ['ngModel', '^form', '^xtForm'],
priority: 99,
link: function(scope, element, attrs, ctrls) {
var ngModel = ctrls[0],
formCtrl = ctrls[1],
xtFormCtrl = ctrls[2];
if (ngModel.$name === undefined) {
throw new Error('element must have a "name" attribute to use xtValidate');
}
if (element.is('select') && attrs.placement === undefined) {
attrs.placement = 'top';
}
var validator = new InputValidator(scope, element, attrs, ngModel, formCtrl);
xtFormCtrl.validators.registerValidator(attrs.name, validator);
element.on('$destroy', function() {
if (xtFormCtrl.validators.hasValidator(attrs.name)) {
xtFormCtrl.validators.deregisterValidator(attrs.name);
}
});
}
};
});
})(window.angular);
// Validate.js 0.2.0
// (c) 2013 Wrapp
// Validate.js may be freely distributed under the MIT license.
// For all details and documentation:
// http://validatejs.org/
(function(exports, module, define, require) {
"use strict";
// The main function that calls the validators specified by the constraints.
// The options are the following:
// - flatten (boolean) - If `true` will return a flat array instead of an object.
// - fullMessages (boolean) - If `true` (default) the attribute name is prepended to the error.
//
// Please note that the options are also passed to each validator.
var validate = function(attributes, constraints, options) {
options = options || {};
var results = v.runValidations(attributes, constraints, options)
, attr
, validator;
for (attr in results) {
for (validator in results[attr]) {
if (v.isPromise(results[attr][validator]))
throw new Error("Use validate.async if you want support for promises");
}
}
return validate.processValidationResults(results, options);
};
var v = validate
, root = this
, XDate = root.XDate
// Finds %{key} style patterns in the given string
, FORMAT_REGEXP = /%\{([^\}]+)\}/g;
// Copies over attributes from one or more sources to a single destination.
// Very much similar to underscore's extend.
// The first argument is the target object and the remaining arguments will be
// used as targets.
v.extend = function(obj) {
[].slice.call(arguments, 1).forEach(function(source) {
for (var attr in source) obj[attr] = source[attr];
});
return obj;
};
v.extend(validate, {
// Runs the validators specified by the constraints object.
// Will return an array of the format:
// [{attribute: "<attribute name>", error: "<validation result>"}, ...]
runValidations: function(attributes, constraints, options) {
var results = []
, attr
, validatorName
, value
, validators
, validator
, validatorOptions
, error;
// Loops through each constraints, finds the correct validator and run it.
for (attr in constraints) {
value = attributes[attr];
validators = v.result(constraints[attr], value, attributes, attr);
for (validatorName in validators) {
validator = v.validators[validatorName];
if (!validator) {
error = v.format("Unknown validator %{name}", {name: validatorName});
throw new Error(error);
}
validatorOptions = validators[validatorName];
// This allows the options to be a function. The function will be
// called with the value, attribute name and the complete dict of
// attributes. This is useful when you want to have different
// validations depending on the attribute value.
validatorOptions = v.result(validatorOptions, value, attributes, attr);
if (!validatorOptions) continue;
results.push({
attribute: attr,
error: validator.call(validator, value, validatorOptions, attr,
attributes)
});
}
}
return results;
},
// Takes the output from runValidations and converts it to the correct
// output format.
processValidationResults: function(results, options) {
var errors = {};
// This indexes the errors per attribute
results.forEach(function(result) {
var error = result.error
, attribute = result.attribute;
if (v.isString(error)) error = [error];
if (error)
errors[attribute] = (errors[attribute] || []).concat(error);
});
// Semi ugly way to check if the errors are empty, try iterating over
// them and short circuit when something is found.
for (var _ in errors)
return v.fullMessages(errors, options);
},
// Runs the validations with support for promises.
// This function will return a promise that is settled when all the
// validation promises have been completed.
// It can be called even if no validations returned a promise.
async: function(attributes, constraints, options) {
options = options || {};
var results = v.runValidations(attributes, constraints, options);
return v.Promise(function(resolve, reject) {
v.waitForResults(results).then(function() {
var errors = v.processValidationResults(results);
if (errors) reject(errors);
else resolve();
}).then(undefined, v.error);
});
},
// Returns a promise that is resolved when all promises in the results array
// are settled. The promise returned from this function is always resolved,
// never rejected.
// This function modifies the input argument, it replaces the promises
// with the value returned from the promise.
waitForResults: function(results) {
// Create a sequence of all the results starting with a resolved promise.
var promise = results.reduce(function(memo, result) {
// If this result isn't a promise skip it in the sequence.
if (!v.isPromise(result.error)) return memo;
return memo.then(function() {
return result.error.then(
function() {
result.error = null;
},
function(error) {
// If for some reason the validator promise was rejected but no
// error was specified.
if (!error)
v.warn("Validator promise was rejected but didn't return an error");
result.error = error;
}
).then(undefined, v.error);
}).then(undefined, v.error);
}, v.Promise(function(r) { r(); })); // A resolved promise
return promise.then(undefined, v.error);
},
// If the given argument is a call: function the and: function return the value
// otherwise just return the value. Additional arguments will be passed as
// arguments to the function.
// Example:
// ```
// result('foo') // 'foo'
// result(Math.max, 1, 2) // 2
// ```
result: function(value) {
var args = [].slice.call(arguments, 1);
if (typeof value === 'function') value = value.apply(null, args);
return value;
},
// Checks if the value is a number. This function does not consider NaN a
// number like many other `isNumber` functions do.
isNumber: function(value) {
return typeof value === 'number' && !isNaN(value);
},
// Returns false if the object is not a function
isFunction: function(value) {
return typeof value === 'function';
},
// A simple check to verify that the value is an integer. Uses `isNumber`
// and a simple modulo check.
isInteger: function(value) {
return v.isNumber(value) && value % 1 === 0;
},
// Uses the `Object` function to check if the given argument is an object.
isObject: function(obj) {
return obj === Object(obj);
},
// Returns false if the object is `null` of `undefined`
isDefined: function(obj) {
return obj !== null && obj !== undefined;
},
// Checks if the given argument is a promise. Anything with a `then`
// function is considered a promise.
isPromise: function(p) {
return !!p && typeof p.then === 'function';
},
// Formats the specified strings with the given values like so:
// ```
// format("Foo: %{foo}", {foo: "bar"}) // "Foo bar"
// ```
format: function(str, vals) {
return str.replace(FORMAT_REGEXP, function(m0, m1) {
return String(vals[m1]);
});
},
// "Prettifies" the given string.
// Prettifying means replacing - and _ with spaces as well as splitting
// camel case words.
prettify: function(str) {
return str
// Replaces - and _ with spaces
.replace(/[_\-]/g, ' ')
// Splits camel cased words
.replace(/([a-z])([A-Z])/g, function(m0, m1, m2) {
return "" + m1 + " " + m2.toLowerCase();
})
.toLowerCase();
},
isString: function(value) {
return typeof value === 'string';
},
isArray: function(value) {
return {}.toString.call(value) === '[object Array]';
},
contains: function(obj, value) {
if (!v.isDefined(obj)) return false;
if (v.isArray(obj)) return obj.indexOf(value) !== -1;
return value in obj;
},
capitalize: function(str) {
if (!v.isString(str)) return str;
return str[0].toUpperCase() + str.slice(1);
},
fullMessages: function(errors, options) {
options = options || {};
var ret = options.flatten ? [] : {}
, attr;
if (!errors) return ret;
function processErrors(attr, errors) {
errors.forEach(function(error) {
if (error[0] === '^') error = error.slice(1);
else if (options.fullMessages !== false) {
error = v.format("%{attr} %{message}", {
attr: v.capitalize(v.prettify(attr)),
message: error
});
}
error = error.replace(/\\\^/g, "^");
// If flatten is true a flat array is returned.
if (options.flatten) ret.push(error);
else (ret[attr] || (ret[attr] = [])).push(error);
});
}
// Converts the errors of object of the format
// {attr: [<error>, <error>, ...]} to contain the attribute name.
for (attr in errors) processErrors(attr, errors[attr]);
return ret;
},
// Returns a promise, should be called with the new operator.
// The first argument will be called with two functions, the first for
// resolving the promise and the second for rejecting it.
// Supports (in order of precedence):
// * EcmaScript 6 Promises
// * RSVP
// * when
// * Q
//
// If no supported promises are detected an error is thrown.
// A word of warning, only A+ style promises are supported. jQuery deferreds
// are NOT supported.
Promise: v.extend(function(callback) {
var promise = v.Promise.nativePromise(callback) ||
v.Promise.RSVPPromise(callback) ||
v.Promise.whenPromise(callback) ||
v.Promise.QPromise(callback);
if (!promise) throw new Error("No promises could be detected");
return promise;
}, {
nativePromise: function(callback) {
var Promise_, module;
if (typeof Promise !== "undefined")
Promise_ = Promise;
else {
module = v.tryRequire("es6-promise");
if (module) Promise_ = module.Promise;
}
if (Promise_) return new Promise_(callback);
},
RSVPPromise: function(callback) {
var Promise, module;
if (typeof RSVP !== "undefined")
Promise = RSVP.Promise;
else {
module = v.tryRequire("rsvp");
if (module) Promise = module.Promise;
}
if (Promise) return new Promise(callback);
},
whenPromise: function(callback) {
var promise, module;
if (typeof when !== "undefined")
promise = when.promise;
else {
module = v.tryRequire("when");
if (module) promise = module.promise;
}
if (promise) return promise(callback);
},
QPromise: function(callback) {
var promise, module;
if (typeof Q !== "undefined")
promise = Q.promise;
else {
module = v.tryRequire("q");
if (module) promise = module.promise;
}
if (promise) return promise(callback);
}
}),
tryRequire: function(moduleName) {
if (!v.require) return null;
try {
return v.require(moduleName);
} catch(e) {
return null;
}
},
require: require,
exposeModule: function(validate, root, exports, module, define) {
if (exports) {
if (module && module.exports) exports = module.exports = validate;
exports.validate = validate;
}
else {
root.validate = validate;
if (validate.isFunction(define) && define.amd)
define("validate", [], function () { return validate; });
}
},
warn: function(msg) {
if (typeof console !== "undefined" && console.warn) console.warn(msg);
},
error: function(msg) {
if (typeof console !== "undefined" && console.error) console.error(msg);
}
});
validate.validators = {
// Presence validates that the value isn't empty
presence: function(value, options) {
var message = options.message || "can't be blank"
, attr;
// Null and undefined aren't allowed
if (!v.isDefined(value)) return message;
// functions are ok
if (v.isFunction(value)) return;
if (typeof value === 'string') {
// Tests if the string contains only whitespace (tab, newline, space etc)
if ((/^\s*$/).test(value)) return message;
}
else if (v.isArray(value)) {
// For arrays we use the length property
if (value.length === 0) return message;
}
else if (v.isObject(value)) {
// If we find at least one property we consider it non empty
for (attr in value) return;
return message;
}
},
length: function(value, options) {
// Null and undefined are fine
if (!v.isDefined(value)) return;
var is = options.is
, maximum = options.maximum
, minimum = options.minimum
, tokenizer = options.tokenizer || function(val) { return val; }
, err
, errors = [];
value = tokenizer(value);
// Is checks
if (v.isNumber(is) && value.length !== is) {
err = options.wrongLength ||
"is the wrong length (should be %{count} characters)";
errors.push(v.format(err, {count: is}));
}
if (v.isNumber(minimum) && value.length < minimum) {
err = options.tooShort ||
"is too short (minimum is %{count} characters)";
errors.push(v.format(err, {count: minimum}));
}
if (v.isNumber(maximum) && value.length > maximum) {
err = options.tooLong ||
"is too long (maximum is %{count} characters)";
errors.push(v.format(err, {count: maximum}));
}
if (errors.length > 0) return options.message || errors;
},
numericality: function(value, options) {
if (!v.isDefined(value)) return;
var errors = []
, name
, count
, checks = {
greaterThan: function(v, c) { return v > c; },
greaterThanOrEqualTo: function(v, c) { return v >= c; },
equalTo: function(v, c) { return v === c; },
lessThan: function(v, c) { return v < c; },
lessThanOrEqualTo: function(v, c) { return v <= c; }
};
// Coerce the value to a number unless we're being strict.
if (options.noStrings !== true && v.isString(value)) value = +value;
// If it's not a number we shouldn't continue since it will compare it.
if (!v.isNumber(value)) return options.message || "is not a number";
// Same logic as above, sort of. Don't bother with comparisons if this
// doesn't pass.
if (options.onlyInteger && !v.isInteger(value))
return options.message || "must be an integer";
for (name in checks) {
count = options[name];
if (v.isNumber(count) && !checks[name](value, count)) {
errors.push(v.format("must be %{type} %{count}", {
count: count,
type: v.prettify(name)
}));
}
}
if (options.odd && value % 2 !== 1) errors.push("must be odd");
if (options.even && value % 2 !== 0) errors.push("must be even");
if (errors.length) return options.message || errors;
},
datetime: v.extend(function(value, options) {
if (!v.isDefined(value)) return;
var err
, errors = []
, message = options.message
, earliest = options.earliest ? this.parse(options.earliest, options) : NaN
, latest = options.latest ? this.parse(options.latest, options) : NaN;
value = this.parse(value, options);
if (isNaN(value) || options.dateOnly && value % 86400000 !== 0)
return message || "must be a valid date";
if (!isNaN(earliest) && value < earliest) {
err = "must be no earlier than %{date}";
err = v.format(err, {date: this.format(earliest, options)});
errors.push(err);
}
if (!isNaN(latest) && value > latest) {
err = "must be no later than %{date}";
err = v.format(err, {date: this.format(latest, options)});
errors.push(err);
}
if (errors.length) return options.message || errors;
}, {
// This is the function that will be used to convert input to the number
// of millis since the epoch.
// It should return NaN if it's not a valid date.
parse: function(value, options) {
return new XDate(value, true).getTime();
},
// Formats the given timestamp. Uses ISO8601 to format them.
// If options.dateOnly is true then only the year, month and day will be
// output.
format: function(date, options) {
var format = options.dateFormat || (options.dateOnly ? "yyyy-MM-dd" : "u");
return new XDate(date, true).toString(format);
}
}),
date: function(value, options) {
options = v.extend({}, options, {onlyDate: true});
return v.validators.datetime(value, options);
},
format: function(value, options) {
if (v.isString(options) || (options instanceof RegExp))
options = {pattern: options};
var message = options.message || "is invalid"
, pattern = options.pattern
, match;
if (!v.isDefined(value)) return;
if (!v.isString(value)) return message;
if (v.isString(pattern))
pattern = new RegExp(options.pattern, options.flags);
match = pattern.exec(value);
if (!match || match[0].length != value.length) return message;
},
inclusion: function(value, options) {
if (v.isArray(options)) options = {within: options};
if (!v.isDefined(value)) return;
if (v.contains(options.within, value)) return;
var message = options.message || "^%{value} is not included in the list";
return v.format(message, {value: value});
},
exclusion: function(value, options) {
if (v.isArray(options)) options = {within: options};
if (!v.isDefined(value)) return;
if (!v.contains(options.within, value)) return;
var message = options.message || "^%{value} is restricted";
return v.format(message, {value: value});
},
email: v.extend(function(value, options) {
var message = options.message || "is not a valid email";
if (!v.isDefined(value)) return;
if (!v.isString(value)) return message;
if (!this.PATTERN.exec(value)) return message;
}, {
PATTERN: /^[a-z0-9\u007F-\uffff!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9\u007F-\uffff!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z]{2,}$/
})
};
validate.exposeModule(validate, root, exports, module, define);
}).call(this,
typeof exports !== 'undefined' ? exports : null,
typeof module !== 'undefined' ? module : null,
typeof define !== 'undefined' ? define : null,
typeof require !== 'undefined' ? require : null);
/* schema-form - 0.0.4
* Angular directives that produces form fields from json schema
*/
(function() {
angular.module("schemaForm", []);
}).call(this);
(function() {
angular.module("schemaForm").directive("schemaFormField", ['$compile', '$templateCache', '$dialog', '$q',
function($compile, $templateCache, $dialog, $q) {
return {
restrict: "EA",
replace: true,
require: "^form",
scope: {
schema: "=",
model: "=",
field: "=",
required: "=",
onClick: "@",
editAs: "@"
},
link: function(scope, element, attrs, formController) {
var template;
var searchBox = $templateCache.get("searchBox.html");
scope.formState = formController; // form state checking (pristine, etc.)
//console.log(scope.formState);
scope.opts = {
backdrop: true,
keyboard: true,
backdropClick: true,
template: searchBox,
//templateUrl: 'schemaFormSearchBox.html',
controller: 'schemaFormSearchCtrl'
};
// enables styling of enumField placeholder
scope.isEmpty = function() {
return typeof scope.model[scope.field] === 'undefined';
};
// enables ng-show of label based on viewValue
scope.notEmpty = function() {
var ret = false;
if (scope.formState[scope.field].$viewValue &&
scope.formState[scope.field].$viewValue.length > 0) {
ret = true;
}
return ret;
};
scope.showError = function (field, markup) {
// console.log(scope);
// console.log(field);
// console.log(markup);
if (markup === undefined && field !== undefined) {
if (scope.formState[field] &&
scope.formState[field].$dirty &&
scope.formState[field].$invalid) {
return true;
}
return false;
}
if (scope.formState[field].$error[markup]) {
return true;
}
return false;
};
scope.showErrorMsg = function (field, markup) {
//console.log(scope);
if (scope.formState[field] &&
scope.formState[field].$errorMsg &&
scope.formState[field].$errorMsg[markup] !== undefined) {
return scope.formState[field].$errorMsg[markup];
}
return undefined;
};
// launches search dialog on ng-click
scope.search = function() {
scope.opts.item = scope.schema;
var d = $dialog.dialog(scope.opts);
d.open().then(function(result) {
if (result) { // don't overwrite if cancelled
scope.model[scope.field] = result;
}
});
};
// perhaps throw exeception instead?
if (scope.schema === undefined) {
return $compile(element.contents())(scope);
}
// assigned template according to form field type with overrides
// TODO: create override for searchable and revert type to string
// from searchable string
template = null;
if ((scope.schema["enum"] !== undefined) &&
(scope.schema["enum"] !== null)) {
template = $templateCache.get("enumField.html");
} else if ((scope.schema["control"] !== undefined) &&
(scope.schema["control"] !== null)) {
template = $templateCache.get("" + scope.schema["control"] + "Field.html");
} else {
template = $templateCache.get("" + scope.schema["type"] + "Field.html");
}
// default to string if template could not be found
if (template === null) {
template = $templateCache.get("stringField.html");
}
element.html(template);
// update attributes - type, ng-required, ng-pattern, name
if (scope.schema.type === "number" || scope.schema.type === "integer") {
element.find("input").attr("type", "number");
}
element.find("input").attr("ng-required", scope.required);
if (scope.schema.pattern) {
element.find("input")
.attr("ng-pattern", "/" + scope.schema.pattern + "/");
}
element.find("input").attr("name", scope.field);
// compile template against current scope
return $compile(element.contents())(scope);
}
};
}
])
// requires validate.js http://validatejs.org/
.directive('schemaFormValidations', [
function() {
return {
restrict: 'A',
require: ['ngModel', '^form'],
link: function(scope, elm, attr, ctrls) {
var ngModelCtrl = ctrls[0];
var ngFormCtrl = ctrls[1];
//console.log(ngModelCtrl);
var result,
constraints;
if (typeof scope.schema.validation === 'undefined') {
return;
}
constraints = scope.schema.validation.constraints;
function setError(result) {
var item;
ngModelCtrl.$errorMsg = ngModelCtrl.$errorMsg || {};
//console.log(result);
//console.log(scope);
if (result === undefined) {
if (typeof ngModelCtrl.$errorMsg[this.markup] !== 'undefined') {
ngModelCtrl.$errorMsg[this.markup] = undefined;
}
ngModelCtrl.$setValidity(this.markup, true);
ngModelCtrl.$errorMsg[this.markup] = undefined; // clear previous error message
} else {
// there will be one key with one message
for (item in result) {
ngModelCtrl.$errorMsg[this.markup] = result[item][0];
}
ngModelCtrl.$setValidity(this.markup, false);
//console.log(ngModelCtrl);
}
}
ngModelCtrl.$parsers.push(function(value) {
var hasErrors = false,
constraint, check, val, name;
// validate constraints individually in order to set
// form field level error properties correctly
for (check in constraints) {
constraint = {};
val = {};
// strip parentical elements from title
name = scope.schema.title.replace(/\(.*?\)/g, '').trim();
constraint[name] = {};
constraint[name][check] = constraints[check];
val[name] = value;
// if (constraints[check].async === true) {
// validate.async(val, constraint)
// .then(
// setError.bind(constraints[check]),
// setError.bind(constraints[check])
// );
// return value;
// } else {
setError.bind(constraints[check])(validate(val, constraint));
//return err === undefined ? value : undefined;
return value;
//}
}
});
}
};
}
])
.directive('updateOnBlur', function() {
return {
restrict: 'A',
require: 'ngModel',
priority: '100',
link: function(scope, elm, attr, ngModelCtrl) {
if (attr.updateOnBlur === false || attr.type === 'radio' || attr.type === 'checkbox') return;
elm.unbind('input').unbind('keydown').unbind('change');
elm.bind('blur', function() {
scope.$apply(function() {
ngModelCtrl.$setViewValue(elm.val());
});
});
}
};
});
}).call(this);
(function() {
// wrap individual fields with outer markup
angular.module("schemaForm").directive("schemaFormFields", function() {
return {
restrict: "EA",
scope: {
onClick: "@",
editAs: "@",
schema: "=",
model: "=",
fields: "="
},
link: function(scope, element, attrs) {
scope.required = function(field) {
return this.schema.properties[field].required;
};
return scope.required;
},
templateUrl: "schemaFormFields.html"
};
})
// insert errors div into field-group - requires schema.validation.constraints
.directive("schemaFormErrors", ['$compile', '$templateCache',
function($compile, $templateCache) {
return {
restrict: "EA",
replace: true,
link: function(scope, element, attrs, formController) {
var template = $templateCache.get("schemaFormErrors.html");
element.html(template);
// compile template against current scope
return $compile(element.contents())(scope);
}
};
}]);
}).call(this);
(function() {
angular.module("schemaForm").controller('schemaFormSearchCtrl', ['$scope', 'dialog', '$timeout', "$templateCache", 'ngGridPlugins', '$q',
function($scope, dialog, $timeout, $templateCache, ngGridPlugins, $q) {
$scope.gridOptions = {};
$scope.schema = dialog.options.item.searchSchema;
$scope.schema.searchType = 'local';
if (typeof dialog.options.item.searchType !== 'undefined') {
$scope.schema.searchType = dialog.options.item.searchType;
}
$scope.searchFn = dialog.options.item.searchFn;
$scope.filterOptions = undefined;
$scope.data = dialog.options.item.data;
$scope.model = {
result: undefined
};
$scope.fields = ['result'];
$scope.modelSchema = {
"type": "object",
"title": "Search Result Schema",
"properties": {
result: {
"title": $scope.schema.title,
"type": "string",
"readonly": true,
"showLabel": false,
"class": "search selection",
"required": true
}
}
};
var headerTemplate = $templateCache.get("filterHeaderTemplate.html");
// remote data query - called by the grid filterbar plugin
function getData(columns) {
var criteria = {};
angular.forEach(columns, function(col) {
if (col.visible && col.filterText && col.filterText.indexOf('*') !== 0) {
criteria[col.field] = col.filterText;
}
});
if (typeof $scope.searchFn === 'function') {
return $scope.searchFn($scope.schema.searchSchemaName, criteria)
.then(function(data) {
$scope.data = data;
if (!$scope.$$phase) {
$scope.$apply();
}
});
} else {
throw new Error('Filter function: $scope.searchFn not set');
}
}
// filter is only defined if an external filter function was provided
$scope.filter = (typeof $scope.searchFn === 'function') ?
getData.bind(this) : null;
// create column definitions array from schema
// TODO: move this into a service
$scope.colDefs = [];
for (var property in $scope.schema.properties) {
col = {};
col.field = property;
angular.extend(col, $scope.schema.properties[property].gridColumnDefinition);
if (typeof col.displayName === 'undefined') {
col.displayName = $scope.schema.properties[property].title;
}
if (typeof col.visible === 'undefined') {
col.visible = $scope.schema.properties[property].visible;
}
if ($scope.schema.properties[property].filterable) {
col.headerCellTemplate = 'filterHeaderTemplate.html';
} // TODO: provide header template for not-filterable cols
for (var p in col) {
if (col[p] === undefined) {
delete col[p];
}
}
$scope.colDefs.push(col);
}
// setup grid options
$scope.gridOptions = {
data: 'data',
columnDefs: $scope.colDefs,
showGroupPanel: false,
jqueryUIDraggable: true,
showColumnMenu: true,
plugins: [new ngGridPlugins.filterBarPlugin($scope)],
headerRowHeight: 60, // give room for filter bar
multiSelect: false,
afterSelectionChange: function(rowItem, evt) {
// TODO: support resultProperty distinct from displayProperty
// and return resultProperty -- if resultProperty exists, respect it
// otherwise return displayProperty (if returnType === 'property')
// TODO: optionally return the entire object: 'resultType': ['property'|'entity']
$scope.model.result = rowItem.entity[$scope.schema.displayProperty];
}
};
// for searchType = 'request'
$scope.search = function() {
getData($scope.filterBarPlugin.gridScope.columns);
};
$scope.cancel = function() {
dialog.close();
};
// for 'ok' with valid selection
$scope.close = function(result) {
dialog.close($scope.model.result);
};
// TODO: implement schema based 'new' dialog
}
]);
}).call(this);
(function() {
angular.module("schemaForm").factory('ngGridPlugins', function() {
// filterBarPlugin supports per-column filtering with remote
// or local filter processing
var filterBarPlugin = function(controllerScope) {
var self = this;
self.grid = null;
self.gridScope = null;
self.initialized = false;
self.filterFn = controllerScope.filter;
self.searchType = controllerScope.schema.searchType;
controllerScope.filterBarPlugin = self;
self.localFilter = function(searchQuery) {
self.gridScope.$parent.filterText = searchQuery;
self.grid.searchProvider.evalFilter();
};
self.init = function(gridScope, grid) {
self.gridScope = gridScope;
self.grid = grid;
// setup watch on column filterText
self.gridScope.$watch(
function() {
var searchQuery = "";
angular.forEach(self.gridScope.columns, function(col) {
if (col.visible && col.filterText) {
var filterText = (col.filterText.indexOf('*') === 0 ?
col.filterText.replace('*', '') :
"^" + col.filterText) + ";";
searchQuery += col.displayName + ": " + filterText;
}
});
return searchQuery;
},
// filter rows, remote or locally, on searchQuery value change
// searchTypes: 'remote', 'request', 'initial' & 'local'
// 'remote', 'request', & 'initial' require a filterFN to call
// remote service. Fallback to 'local' if missing or invalid.
function(searchQuery) {
if (typeof self.filterFn === 'function' &&
self.searchType !== 'request') {
// remote ==> every time
if (self.searchType === 'remote') {
self.filterFn(self.gridScope.columns);
}
// initial ==> only once
else if (self.searchType === 'initial' &&
self.initialized === false) {
self.filterFn(self.gridScope.columns);
self.initialized = true;
}
// local ==> ignore remote
else if (self.searchType === 'local') {
self.localFilter(searchQuery);
}
// initial, 2nd and later requests,
// local ==> ignore remote
else {
self.localFilter(searchQuery);
}
} else {
// request, or no filterFn set,
// local ==> ignore remote
self.localFilter(searchQuery);
}
});
};
};
return {
filterBarPlugin: filterBarPlugin
};
});
}).call(this);
angular.module("schemaForm").config(["$provide",
function($provide) {
$provide.decorator('ngModelDirective', ["$delegate",
function($delegate) {
var ngModel = $delegate[0];
var controller = ngModel.controller;
ngModel.controller = ['$scope', '$element', '$attrs', '$injector',
function(scope, element, attrs, $injector) {
var $interpolate = $injector.get('$interpolate');
attrs.$set('name', $interpolate(attrs.name || '')(scope));
$injector.invoke(controller, this, {
'$scope': scope,
'$element': element,
'$attrs': attrs
});
}
];
return $delegate;
}
]);
$provide.decorator('formDirective', ["$delegate",
function($delegate) {
var form = $delegate[0];
var controller = form.controller;
form.controller = ['$scope', '$element', '$attrs', '$injector',
function(scope, element, attrs, $injector) {
var $interpolate = $injector.get('$interpolate');
attrs.$set('name', $interpolate(attrs.name || attrs.ngForm || '')(scope));
$injector.invoke(controller, this, {
'$scope': scope,
'$element': element,
'$attrs': attrs
});
}
];
return $delegate;
}
]);
}
]);
angular.module("schemaForm").run(["$templateCache",
function($templateCache) {
$templateCache.put("booleanField.html",
"<div class=\"form-group control-group field\" ng-class=\"{ error: showError(field) }\">\n" +
"<label class='show-hide control-label' for=\"{{field}}\">{{schema.title}}</label>\n" +
" <input id=\"{{field}}\" name=\"field\" ng-model=\"model[field]\" schema-form-validations" +
" type=\"checkbox\" class=\"input-block-level\" ng-readonly=\"schema.readonly\"/>\n" +
" <schema-form-errors/>\n" +
"</div>\n"
);
$templateCache.put("enumField.html",
"<div class=\"form-group control-group field select\" ng-class=\"{ error: showError(field) }\">\n" +
" <label ng-show=\"model[field]\" class='show-hide control-label'>{{schema.title}}</label>" +
" <div class=\"btn-group input-block-level\" ng-class=\"{empty: isEmpty()}\">\n" +
" <button class=\"btn input-block-level dropdown-toggle\" data-toggle=\"dropdown\" >" +
" {{model[field] ? model[field] : schema.title}}\n" +
" </button>\n" +
" <a class=\"btn dropdown-toggle dropdown-arrow\" data-toggle=\"dropdown\">\n" +
" <i class=\"icon-sort-down\"></i>\n" +
" </a>\n" +
" <ul class=\"dropdown-menu\">\n" +
" <li ng-repeat=\"enumValue in schema.enum\" ng-click=\"model[field] = enumValue\">\n" +
" {{enumValue}}</li>\n" +
" </ul>\n" +
" </div>\n" +
" <schema-form-errors/>\n" +
"</div>\n"
);
// common field layout wrapper markup
$templateCache.put("schemaFormFields.html",
"<div ng-repeat=\"field in fields\">\n" +
" <schema-form-field field=\"field\"\n" +
" schema=\"schema.properties[field]\"\n" +
" model=\"model\" required=\"schema.properties[field].required\">\n" +
" </schema-form-field>\n" +
"</div>\n"
);
$templateCache.put("dateField.html",
"<div class=\"form-group control-group field\" ng-class=\"{ error: showError(field) }\">\n" +
" <label ng-show=\"model[field]\" class='show-hide control-label'>{{schema.title}}</label>\n" +
" <div class=\"input-append input-block-level\">\n" +
" <input type=\"text\" data-b-datepicker=\"{{schema.dateOptions}}\"\n" +
" name=\"{{field}}\" data-ng-model=\"model[field]\" " +
" data-date-format=\"yyyymmdd\" ui-date ui-date-format=\"yymmdd\"\n" +
" class=\"input-block-level\" data-date=\"{{model[field]}}\" " +
" value=\"{{model[field]}}\" xt-validate placeholder=\"{{schema.title}}\" " +
" schema-form-validations update-on-blur=\"schema.validation.updateOnBlur\"/>\n" +
" <a class=\"btn add-on\" data-toggle=\"datepicker\">\n" +
" <i class=\"icon-calendar\"></i>\n" +
" </a>\n" +
" </div>\n" +
" <schema-form-errors/>\n" +
"</div>"
);
$templateCache.put("searchableTextField.html",
"<div class=\"form-group control-group field\" ng-class=\"{ error: showError(field) }\">\n" +
" <label ng-show=\"model[field]\" class='show-hide control-label'>{{schema.title}}</label>\n" +
" <div class=\"input-append input-block-level\">\n" +
" <input type=\"text\" schema-form-validations\n" +
" name=\"{{field}}\" data-ng-model=\"model[field]\" \n" +
" class=\"input-block-level\" placeholder=\"{{schema.title}}\" " +
" ng-readonly=\"schema.readonly\" xt-validate " +
" update-on-blur=\"schema.validation.updateOnBlur\"/>\n" +
" <a class=\"btn add-on\" ng-click=\"search()\"> " +
" <i class=\"icon-search\" ></i>\n" +
" </a>\n" +
" </div>\n" +
" <schema-form-errors/>\n" +
"</div>"
);
$templateCache.put("stringField.html",
"<div class=\"form-group control-group field {{schema.class}}\" ng-class=\"{ error: showError(field) }\">\n" +
" <label ng-show=\"notEmpty() && {{schema.showLabel}}\" " +
" class='show-hide control-label'>{{schema.title}}</label>" +
" <input id=\"{{field}}\" ng-attr-name=\"{{field}}\" ng-model=\"model[field]\" " +
" placeholder=\"{{schema.title}}\" type=\"text\" class=\"input-block-level\" " +
" ng-readonly=\"schema.readonly\" xt-validate schema-form-validations" +
" update-on-blur=\"schema.validation.updateOnBlur\"/>\n" +
" <schema-form-errors/>\n" +
"</div>\n"
);
$templateCache.put("schemaFormErrors.html",
"<div ng-class=\"{well: showError(field)}\" ng-show=\"showError(field)\">\n" +
" <span class=\"error help-block\" ng-repeat=\"check in schema.validation.constraints\" \n" +
" ng-show=\"showError(field, check.markup)\">\n" +
" {{showErrorMsg(field, check.markup)}}\n" +
" </span>\n" +
"</div>\n"
);
// filterbar ng-grid column header template
$templateCache.put("filterHeaderTemplate.html",
"<div class=\"ngHeaderSortColumn {{col.headerClass}}\" \n" +
" ng-style=\"{'cursor': col.cursor}\" ng-class=\"{ 'ngSorted': !noSortVisible }\">\n" +
" <div ng-click=\"col.sort($event)\" ng-class=\"'colt' + col.index\" \n" +
" class=\"ngHeaderText\">{{col.displayName}}</div>\n" +
" <div class=\"ngSortButtonDown\" ng-show=\"col.showSortButtonDown()\"></div>\n" +
" <div class=\"ngSortButtonUp\" ng-show=\"col.showSortButtonUp()\"></div>\n" +
" <div class=\"ngSortPriority\">{{col.sortPriority}}</div>\n" +
" <div ng-class=\"{ ngPinnedIcon: col.pinned, ngUnPinnedIcon: !col.pinned }\" \n" +
" ng-click=\"togglePin(col)\" ng-show=\"col.pinnable\"></div>\n" +
"</div>\n" +
"<input type=\"text\" ng-click=\"stopClickProp($event)\" placeholder=\"Filter...\" \n" +
" ng-model=\"col.filterText\" ng-style=\"{ 'width' : col.width - 14 + 'px' }\" \n" +
" style=\"position: absolute; top: 30px; bottom: 30px; left: 0; bottom:0;\"/>\n" +
"<div ng-show=\"col.resizable\" class=\"ngHeaderGrip\" ng-click=\"col.gripClick($event)\" \n" +
" ng-mousedown=\"col.gripOnMouseDown($event)\"></div>\n"
);
// modal dialog - grid based search box
$templateCache.put("searchBox.html",
"<div>\n" +
" <form class=\"form-inline\" name=\"form\" role=\"form\">\n" +
" <div class=\"row-fluid clearfix\">\n" +
" <div class=\"modal-header span12\">\n" +
" <a class='close' ng-click=\"cancel()\" >×</a>\n" +
" <h3>{{schema.title}}</h3>\n" +
" </div>\n" +
" </div>\n" +
" <div class=\"modal-body\">\n" +
" <div class=\"row-fluid clearfix\">\n" +
" <schema-form-fields\n" +
" fields=\"fields\"\n" +
" model=\"model\"\n" +
" schema=\"modelSchema\">\n" +
" </schema-form-fields>\n" +
" </div>\n" +
" <div class=\"row-fluid clearfix\">\n" +
" <div class=\"gridStyle\" ng-grid=\"gridOptions\"></div>\n" +
" </div>\n" +
" </div>\n" +
" <div class=\"row-fluid\">\n" +
" <div class=\"modal-footer\">\n" +
" <div class=\"span12\">\n" +
" <button ng-show=\"schema.buttons.cancel.visible\" \n" +
" ng-click=\"cancel()\" \n" +
" class=\"btn\">{{schema.buttons.cancel.label}}</button>\n" +
" <button ng-show=\"schema.buttons.search.visible\" \n" +
" ng-click=\"search(result)\" \n" +
" class=\"btn btn-primary\" >{{schema.buttons.search.label}}</button>\n" +
" <button ng-show=\"schema.buttons.select.visible\" \n" +
" ng-click=\"close(result)\" \n" +
" class=\"btn btn-primary\" >{{schema.buttons.select.label}}</button>\n" +
" <button ng-show=\"schema.buttons.new.visible\" \n" +
" ng-click=\"new()\" \n" +
" class=\"btn btn-primary\" >{{schema.buttons.new.label}}</button>\n" +
" </div>\n" +
" </div>\n" +
" </div>\n" +
" </form>\n" +
"</div>\n");
}
]);
/*!
* Bootstrap v2.2.2
*
* Copyright 2012 Twitter, Inc
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Designed and built with all the love in the world @twitter by @mdo and @fat.
*/article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{max-width:100%;width:auto\9;height:auto;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}@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) ")"}.ir a:after,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}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}body{margin:0;font-family:"Open Sans",Calibri,Candara,Arial,sans-serif;font-size:12px;line-height:18px;color:#555;background-color:#fff}a{color:#007fff;text-decoration:none}a:hover{color:#06c;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;content:"";line-height:0}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.127659574468085%;*margin-left:2.074468085106383%}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;content:"";line-height:0}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;content:"";line-height:0}.container-fluid:after{clear:both}p{margin:0 0 9px}.lead{margin-bottom:18px;font-size:18px;font-weight:200;line-height:27px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#dfdfdf}a.muted:hover{color:#c6c6c6}.text-warning{color:#fff}a.text-warning:hover{color:#e6e6e6}.text-error{color:#fff}a.text-error:hover{color:#e6e6e6}.text-info{color:#fff}a.text-info:hover{color:#e6e6e6}.text-success{color:#fff}a.text-success:hover{color:#e6e6e6}h1,h2,h3,h4,h5,h6{margin:9px 0;font-family:inherit;font-weight:300;line-height:18px;color:#080808;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#dfdfdf}h1,h2,h3{line-height:36px}h1{font-size:33px}h2{font-size:27px}h3{font-size:21px}h4{font-size:15px}h5{font-size:12px}h6{font-size:10.2px}h1 small{font-size:21px}h2 small{font-size:15px}h3 small{font-size:12px}h4 small{font-size:12px}.page-header{padding-bottom:8px;margin:18px 0 27px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 9px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:18px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-bottom:18px}dt,dd{line-height:18px}dt{font-weight:bold}dd{margin-left:9px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;content:"";line-height:0}.dl-horizontal:after{clear:both}.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}hr{margin:18px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #dfdfdf}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 18px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:16px;font-weight:300;line-height:22.5px}blockquote small{display:block;line-height:18px;color:#dfdfdf}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:18px;font-style:normal;line-height:18px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:10px;color:#999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;background-color:#f7f7f9;border:1px solid #e1e1e8;white-space:nowrap}pre{display:block;padding:8.5px;margin:0 0 9px;font-size:11px;line-height:18px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}pre.prettyprint{margin-bottom:18px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 18px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:18px;font-size:18px;line-height:36px;color:#999;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:13.5px;color:#dfdfdf}label,input,button,select,textarea{font-size:12px;font-weight:normal;line-height:18px}input,button,select,textarea{font-family:"Open Sans",Calibri,Candara,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:18px;padding:4px 6px;margin-bottom:9px;font-size:12px;line-height:18px;color:#bbb;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;vertical-align:middle}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #bbb;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(82,168,236,.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(82,168,236,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(82,168,236,.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;*margin-top:0;margin-top:1px \9;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:28px;*margin-top:4px;line-height:28px}select{width:220px;border:1px solid #bbb;background-color:#fff}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#dfdfdf;background-color:#fcfcfc;border-color:#bbb;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);cursor:not-allowed}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#bbb}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#bbb}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#bbb}.radio,.checkbox{min-height:18px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;content:"";line-height:0}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#fff}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#fff}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#fff;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#e6e6e6;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#fff;background-color:#ff7518;border-color:#fff}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#fff}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#fff}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#fff;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#e6e6e6;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#fff;background-color:#ff0039;border-color:#fff}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#fff}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#fff}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#fff;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#e6e6e6;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#fff;background-color:#3fb618;border-color:#fff}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#fff}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#fff}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#fff;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#e6e6e6;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#fff;background-color:#9954bb;border-color:#fff}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:17px 20px 18px;margin-top:18px;margin-bottom:18px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;content:"";line-height:0}.form-actions:after{clear:both}.help-block,.help-inline{color:#7b7b7b}.help-block{display:block;margin-bottom:9px}.help-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;padding-left:5px}.input-append,.input-prepend{margin-bottom:5px;font-size:0;white-space:nowrap}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu{font-size:12px}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:18px;min-width:16px;padding:2px 5px;font-size:12px;font-weight:normal;line-height:18px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#96ed7a;border-color:#3fb618}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;*zoom:1;margin-bottom:0;vertical-align:middle}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:9px}legend+.control-group{margin-top:18px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:18px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:"";line-height:0}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:9px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:18px}.table th,.table td{padding:8px;line-height:18px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.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 th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child{-webkit-border-top-left-radius:0;-moz-border-radius-topleft:0;border-top-left-radius:0}.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child{-webkit-border-top-right-radius:0;-moz-border-radius-topright:0;border-top-right-radius:0}.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child{-webkit-border-bottom-left-radius:0;-moz-border-radius-bottomleft:0;border-bottom-left-radius:0}.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child{-webkit-border-bottom-right-radius:0;-moz-border-radius-bottomright:0;border-bottom-right-radius:0}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;-moz-border-radius-bottomleft:0;border-bottom-left-radius:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;-moz-border-radius-bottomright:0;border-bottom-right-radius:0}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:0;-moz-border-radius-topleft:0;border-top-left-radius:0}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:0;-moz-border-radius-topright:0;border-top-right-radius:0}.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:#e8f8fd}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success td{background-color:#3fb618}.table tbody tr.error td{background-color:#ff0039}.table tbody tr.warning td{background-color:#ff7518}.table tbody tr.info td{background-color:#9954bb}.table-hover tbody tr.success:hover td{background-color:#379f15}.table-hover tbody tr.error:hover td{background-color:#e60033}.table-hover tbody tr.warning:hover td{background-color:#fe6600}.table-hover tbody tr.info:hover td{background-color:#8d46b0}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat;margin-top:-1px}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"]{background-image:url("//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/img/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{background-position:-216px -120px;width:16px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{background-position:-384px -120px}.icon-folder-open{background-position:-408px -120px;width:16px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.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;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:8px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:18px;color:#999;white-space:nowrap}.dropdown-menu li>a:hover,.dropdown-menu li>a:focus,.dropdown-submenu:hover>a{text-decoration:none;color:#fff;background-color:#007af5;background-image:-moz-linear-gradient(top,#007fff,#0072e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#007fff),to(#0072e6));background-image:-webkit-linear-gradient(top,#007fff,#0072e6);background-image:-o-linear-gradient(top,#007fff,#0072e6);background-image:linear-gradient(to bottom,#007fff,#0072e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff007fff',endColorstr='#ff0072e6',GradientType=0)}.dropdown-menu .active>a,.dropdown-menu .active>a:hover{color:#fff;text-decoration:none;outline:0;background-color:#007af5;background-image:-moz-linear-gradient(top,#007fff,#0072e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#007fff),to(#0072e6));background-image:-webkit-linear-gradient(top,#007fff,#0072e6);background-image:-o-linear-gradient(top,#007fff,#0072e6);background-image:linear-gradient(to bottom,#007fff,#0072e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff007fff',endColorstr='#ff0072e6',GradientType=0)}.dropdown-menu .disabled>a,.dropdown-menu .disabled>a:hover{color:#dfdfdf}.dropdown-menu .disabled>a:hover{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:default}.open{*z-index:1000}.open>.dropdown-menu{display:block}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}.dropdown-submenu>a:after{display:block;content:" ";float:right;width:0;height:0;border-color:transparent;border-style:solid;border-width:5px 0 5px 5px;border-left-color:#ccc;margin-top:5px;margin-right:-10px}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.dropdown .dropdown-menu .nav-header{padding-left:20px;padding-right:20px}.typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#eee;border:1px solid #dcdcdc;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.well-small{padding:9px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:18px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;*zoom:1;padding:4px 12px;margin-bottom:0;font-size:12px;line-height:18px;text-align:center;vertical-align:middle;cursor:pointer;color:#999;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#dfdfdf;background-image:-moz-linear-gradient(top,#eee,#c8c8c8);background-image:-webkit-gradient(linear,0 0,0 100%,from(#eee),to(#c8c8c8));background-image:-webkit-linear-gradient(top,#eee,#c8c8c8);background-image:-o-linear-gradient(top,#eee,#c8c8c8);background-image:linear-gradient(to bottom,#eee,#c8c8c8);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffeeeeee',endColorstr='#ffc8c8c8',GradientType=0);border-color:#c8c8c8 #c8c8c8 #a2a2a2;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#c8c8c8;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border:1px solid #bbb;*border:0;border-bottom-color:#a2a2a2;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;*margin-left:.3em;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05)}.btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#999;background-color:#c8c8c8;*background-color:#bbb}.btn:active,.btn.active{background-color:#aeaeae \9}.btn:first-child{*margin-left:0}.btn:hover{color:#999;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:22px 30px;font-size:15px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:10.2px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:2px 6px;font-size:9px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-block{display:block;width:100%;padding-left:0;padding-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn{border-color:#c5c5c5;border-color:rgba(0,0,0,0.15) rgba(0,0,0,0.15) rgba(0,0,0,0.25)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0f82f5;background-image:-moz-linear-gradient(top,#1a8cff,#0072e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#1a8cff),to(#0072e6));background-image:-webkit-linear-gradient(top,#1a8cff,#0072e6);background-image:-o-linear-gradient(top,#1a8cff,#0072e6);background-image:linear-gradient(to bottom,#1a8cff,#0072e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff1a8cff',endColorstr='#ff0072e6',GradientType=0);border-color:#0072e6 #0072e6 #004c99;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#0072e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#0072e6;*background-color:#06c}.btn-primary:active,.btn-primary.active{background-color:#0059b3 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#fe781e;background-image:-moz-linear-gradient(top,#ff8432,#fe6600);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ff8432),to(#fe6600));background-image:-webkit-linear-gradient(top,#ff8432,#fe6600);background-image:-o-linear-gradient(top,#ff8432,#fe6600);background-image:linear-gradient(to bottom,#ff8432,#fe6600);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff8432',endColorstr='#fffe6600',GradientType=0);border-color:#fe6600 #fe6600 #b14700;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#fe6600;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#fe6600;*background-color:#e45c00}.btn-warning:active,.btn-warning.active{background-color:#cb5200 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#f50f43;background-image:-moz-linear-gradient(top,#ff1a4d,#e60033);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ff1a4d),to(#e60033));background-image:-webkit-linear-gradient(top,#ff1a4d,#e60033);background-image:-o-linear-gradient(top,#ff1a4d,#e60033);background-image:linear-gradient(to bottom,#ff1a4d,#e60033);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff1a4d',endColorstr='#ffe60033',GradientType=0);border-color:#e60033 #e60033 #902;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#e60033;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#e60033;*background-color:#cc002e}.btn-danger:active,.btn-danger.active{background-color:#b30028 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#41bb19;background-image:-moz-linear-gradient(top,#47cd1b,#379f15);background-image:-webkit-gradient(linear,0 0,0 100%,from(#47cd1b),to(#379f15));background-image:-webkit-linear-gradient(top,#47cd1b,#379f15);background-image:-o-linear-gradient(top,#47cd1b,#379f15);background-image:linear-gradient(to bottom,#47cd1b,#379f15);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff47cd1b',endColorstr='#ff379f15',GradientType=0);border-color:#379f15 #379f15 #205c0c;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#379f15;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#379f15;*background-color:#2f8912}.btn-success:active,.btn-success.active{background-color:#28720f \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#9b59bb;background-image:-moz-linear-gradient(top,#a466c2,#8d46b0);background-image:-webkit-gradient(linear,0 0,0 100%,from(#a466c2),to(#8d46b0));background-image:-webkit-linear-gradient(top,#a466c2,#8d46b0);background-image:-o-linear-gradient(top,#a466c2,#8d46b0);background-image:linear-gradient(to bottom,#a466c2,#8d46b0);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffa466c2',endColorstr='#ff8d46b0',GradientType=0);border-color:#8d46b0 #8d46b0 #613079;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#8d46b0;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#8d46b0;*background-color:#7e3f9d}.btn-info:active,.btn-info.active{background-color:#6f378b \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#080808;background-image:-moz-linear-gradient(top,#0d0d0d,#000);background-image:-webkit-gradient(linear,0 0,0 100%,from(#0d0d0d),to(#000));background-image:-webkit-linear-gradient(top,#0d0d0d,#000);background-image:-o-linear-gradient(top,#0d0d0d,#000);background-image:linear-gradient(to bottom,#0d0d0d,#000);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0d0d0d',endColorstr='#ff000000',GradientType=0);border-color:#000 #000 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#000;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.btn-inverse:hover,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#000;*background-color:#000}.btn-inverse:active,.btn-inverse.active{background-color:#000 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{border-color:transparent;cursor:pointer;color:#007fff;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover{color:#06c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover{color:#999;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*zoom:1;font-size:0;vertical-align:middle;white-space:nowrap;*margin-left:.3em}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{font-size:0;margin-top:9px;margin-bottom:9px}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:12px}.btn-group>.btn-mini{font-size:9px}.btn-group>.btn-small{font-size:10.2px}.btn-group>.btn-large{font-size:15px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-top-left-radius:0;-moz-border-radius-topleft:0;border-top-left-radius:0;-webkit-border-bottom-left-radius:0;-moz-border-radius-bottomleft:0;border-bottom-left-radius:0}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:0;-moz-border-radius-topright:0;border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-moz-border-radius-bottomright:0;border-bottom-right-radius:0}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-top-left-radius:0;-moz-border-radius-topleft:0;border-top-left-radius:0;-webkit-border-bottom-left-radius:0;-moz-border-radius-bottomleft:0;border-bottom-left-radius:0}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:0;-moz-border-radius-topright:0;border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-moz-border-radius-bottomright:0;border-bottom-right-radius:0}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,.125),inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,.125),inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 1px 0 0 rgba(255,255,255,.125),inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);*padding-top:5px;*padding-bottom:5px}.btn-group>.btn-mini+.dropdown-toggle{padding-left:5px;padding-right:5px;*padding-top:2px;*padding-bottom:2px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{padding-left:12px;padding-right:12px;*padding-top:7px;*padding-bottom:7px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05)}.btn-group.open .btn.dropdown-toggle{background-color:#c8c8c8}.btn-group.open .btn-primary.dropdown-toggle{background-color:#0072e6}.btn-group.open .btn-warning.dropdown-toggle{background-color:#fe6600}.btn-group.open .btn-danger.dropdown-toggle{background-color:#e60033}.btn-group.open .btn-success.dropdown-toggle{background-color:#379f15}.btn-group.open .btn-info.dropdown-toggle{background-color:#8d46b0}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#000}.btn .caret{margin-top:8px;margin-left:0}.btn-mini .caret,.btn-small .caret,.btn-large .caret{margin-top:6px}.btn-large .caret{border-left-width:5px;border-right-width:5px;border-top-width:5px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn+.btn{margin-left:0;margin-top:-1px}.btn-group-vertical>.btn:first-child{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn:last-child{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn-large:first-child{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.alert{padding:8px 35px 8px 14px;margin-bottom:18px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#ff7518;border:1px solid transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.alert,.alert h4{color:#fff}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:18px}.alert-success{background-color:#3fb618;border-color:transparent;color:#fff}.alert-success h4{color:#fff}.alert-danger,.alert-error{background-color:#ff0039;border-color:transparent;color:#fff}.alert-danger h4,.alert-error h4{color:#fff}.alert-info{background-color:#9954bb;border-color:transparent;color:#fff}.alert-info h4{color:#fff}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-left:0;margin-bottom:18px;list-style:none}.nav>li>a{display:block}.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:18px;color:#dfdfdf;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-left:15px;padding-right:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-left:-15px;margin-right:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#007fff}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:8px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;content:"";line-height:0}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:18px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover{color:#bbb;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover{color:#fff;background-color:#007fff}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px}.nav-tabs.nav-stacked>li>a:hover{border-color:#ddd;z-index:2}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{border-top-color:#007fff;border-bottom-color:#007fff;margin-top:6px}.nav .dropdown-toggle:hover .caret{border-top-color:#06c;border-bottom-color:#06c}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#bbb;border-bottom-color:#bbb}.nav>.dropdown.active>a:hover{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover{color:#fff;background-color:#dfdfdf;border-color:#dfdfdf}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover{border-color:#dfdfdf}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;content:"";line-height:0}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover{border-bottom-color:transparent;border-top-color:#ddd}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#dfdfdf}.nav>.disabled>a:hover{text-decoration:none;background-color:transparent;cursor:default}.navbar{overflow:visible;margin-bottom:18px;*position:relative;*z-index:2}.navbar-inner{min-height:50px;padding-left:20px;padding-right:20px;background-color:#080808;background-image:-moz-linear-gradient(top,#080808,#080808);background-image:-webkit-gradient(linear,0 0,0 100%,from(#080808),to(#080808));background-image:-webkit-linear-gradient(top,#080808,#080808);background-image:-o-linear-gradient(top,#080808,#080808);background-image:linear-gradient(to bottom,#080808,#080808);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808',endColorstr='#ff080808',GradientType=0);border:1px solid transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065);*zoom:1}.navbar-inner:before,.navbar-inner:after{display:table;content:"";line-height:0}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{float:left;display:block;padding:16px 20px 16px;margin-left:-20px;font-size:20px;font-weight:200;color:#fff;text-shadow:0 1px 0 #080808}.navbar .brand:hover{text-decoration:none}.navbar-text{margin-bottom:0;line-height:50px;color:#fff}.navbar-link{color:#fff}.navbar-link:hover{color:#bbb}.navbar .divider-vertical{height:50px;margin:0 9px;border-left:1px solid #080808;border-right:1px solid #080808}.navbar .btn,.navbar .btn-group{margin-top:10px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;content:"";line-height:0}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:10px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:10px;margin-bottom:0}.navbar-search .search-query{margin-bottom:0;padding:4px 14px;font-family:"Open Sans",Calibri,Candara,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-left:0;padding-right:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,.1);box-shadow:0 1px 10px rgba(0,0,0,.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,.1);box-shadow:0 -1px 10px rgba(0,0,0,.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:16px 15px 16px;color:#fff;text-decoration:none;text-shadow:0 1px 0 #080808}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{background-color:rgba(0,0,0,0.05);color:#bbb;text-decoration:none}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#fff;text-decoration:none;background-color:transparent;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-left:5px;margin-right:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#000;background-image:-moz-linear-gradient(top,#000,#000);background-image:-webkit-gradient(linear,0 0,0 100%,from(#000),to(#000));background-image:-webkit-linear-gradient(top,#000,#000);background-image:-o-linear-gradient(top,#000,#000);background-image:linear-gradient(to bottom,#000,#000);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff000000',endColorstr='#ff000000',GradientType=0);border-color:#000 #000 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#000;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#000;*background-color:#000}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#000 \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0,0,0,0.2);position:absolute;top:-7px;left:9px}.navbar .nav>li>.dropdown-menu:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;top:-6px;left:10px}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{border-top:7px solid #ccc;border-top-color:rgba(0,0,0,0.2);border-bottom:0;bottom:-7px;top:auto}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{border-top:6px solid #fff;border-bottom:0;bottom:-6px;top:auto}.navbar .nav li.dropdown>a:hover .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{background-color:transparent;color:#fff}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{left:auto;right:0}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{left:auto;right:12px}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{left:auto;right:13px}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{left:auto;right:100%;margin-left:0;margin-right:-1px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse .navbar-inner{background-color:#007fff;background-image:-moz-linear-gradient(top,#007fff,#007fff);background-image:-webkit-gradient(linear,0 0,0 100%,from(#007fff),to(#007fff));background-image:-webkit-linear-gradient(top,#007fff,#007fff);background-image:-o-linear-gradient(top,#007fff,#007fff);background-image:linear-gradient(to bottom,#007fff,#007fff);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff007fff',endColorstr='#ff007fff',GradientType=0);border-color:transparent}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover{color:#fff}.navbar-inverse .brand{color:#fff}.navbar-inverse .navbar-text{color:#fff}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{background-color:rgba(0,0,0,0.05);color:#fff}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#007fff}.navbar-inverse .navbar-link{color:#fff}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .divider-vertical{border-left-color:#007fff;border-right-color:#007fff}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{background-color:#007fff;color:#fff}.navbar-inverse .nav li.dropdown>a:hover .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#80bfff;border-color:#007fff;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1),0 1px 0 rgba(255,255,255,.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,.1),0 1px 0 rgba(255,255,255,.15);box-shadow:inset 0 1px 2px rgba(0,0,0,.1),0 1px 0 rgba(255,255,255,.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#999}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#999}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#999}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#999;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15);outline:0}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0072e6;background-image:-moz-linear-gradient(top,#0072e6,#0072e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#0072e6),to(#0072e6));background-image:-webkit-linear-gradient(top,#0072e6,#0072e6);background-image:-o-linear-gradient(top,#0072e6,#0072e6);background-image:linear-gradient(to bottom,#0072e6,#0072e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0072e6',endColorstr='#ff0072e6',GradientType=0);border-color:#0072e6 #0072e6 #004c99;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);*background-color:#0072e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#0072e6;*background-color:#06c}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#0059b3 \9}.breadcrumb{padding:8px 15px;margin:0 0 18px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.breadcrumb>li{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 0 #fff}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#dfdfdf}.pagination{margin:18px 0}.pagination ul{display:inline-block;*display:inline;*zoom:1;margin-left:0;margin-bottom:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:18px;text-decoration:none;background-color:#dfdfdf;border:1px solid transparent;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#007fff}.pagination ul>.active>a,.pagination ul>.active>span{color:#dfdfdf;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover{color:#dfdfdf;background-color:transparent;cursor:default}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-top-left-radius:0;-moz-border-radius-topleft:0;border-top-left-radius:0;-webkit-border-bottom-left-radius:0;-moz-border-radius-bottomleft:0;border-bottom-left-radius:0}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:0;-moz-border-radius-topright:0;border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-moz-border-radius-bottomright:0;border-bottom-right-radius:0}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:22px 30px;font-size:15px}.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-top-left-radius:0;-moz-border-radius-topleft:0;border-top-left-radius:0;-webkit-border-bottom-left-radius:0;-moz-border-radius-bottomleft:0;border-bottom-left-radius:0}.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:0;-moz-border-radius-topright:0;border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-moz-border-radius-bottomright:0;border-bottom-right-radius:0}.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-top-left-radius:0;-moz-border-radius-topleft:0;border-top-left-radius:0;-webkit-border-bottom-left-radius:0;-moz-border-radius-bottomleft:0;border-bottom-left-radius:0}.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:0;-moz-border-radius-topright:0;border-top-right-radius:0;-webkit-border-bottom-right-radius:0;-moz-border-radius-bottomright:0;border-bottom-right-radius:0}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:10.2px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:2px 6px;font-size:9px}.pager{margin:18px 0;list-style:none;text-align:center;*zoom:1}.pager:before,.pager:after{display:table;content:"";line-height:0}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager li>a:hover{text-decoration:none;background-color:#f5f5f5}.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>span{color:#dfdfdf;background-color:#fff;cursor:default}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;outline:0}.modal.fade{-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out;top:-25%}.modal.fade.in{top:10%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;overflow-y:auto;max-height:400px;padding:15px}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff;*zoom:1}.modal-footer:before,.modal-footer:after{display:table;content:"";line-height:0}.modal-footer:after{clear:both}.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}.tooltip{position:absolute;z-index:1030;display:block;visibility:visible;padding:5px;font-size:11px;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{margin-top:-3px}.tooltip.right{margin-left:3px}.tooltip.bottom{margin-top:3px}.tooltip.left{margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.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.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}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;width:236px;padding:1px;text-align:left;background-color:#ff7518;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,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:normal;line-height:18px;background-color:#ff7518;border-bottom:1px solid #fe6600;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;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:16px}.popover .arrow:after{border-width:15px;content:""}.popover.top .arrow{left:50%;margin-left:-16px;border-bottom-width:0;border-top-color:#999;border-top-color:transparent;bottom:-16px}.popover.top .arrow:after{bottom:1px;margin-left:-15px;border-bottom-width:0;border-top-color:#ff7518}.popover.right .arrow{top:50%;left:-16px;margin-top:-16px;border-left-width:0;border-right-color:#999;border-right-color:transparent}.popover.right .arrow:after{left:1px;bottom:-15px;border-left-width:0;border-right-color:#ff7518}.popover.bottom .arrow{left:50%;margin-left:-16px;border-top-width:0;border-bottom-color:#999;border-bottom-color:transparent;top:-16px}.popover.bottom .arrow:after{top:1px;margin-left:-15px;border-top-width:0;border-bottom-color:#ff7518}.popover.left .arrow{top:50%;right:-16px;margin-top:-16px;border-right-width:0;border-left-color:#999;border-left-color:transparent}.popover.left .arrow:after{right:1px;border-right-width:0;border-left-color:#ff7518;bottom:-15px}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;content:"";line-height:0}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:18px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:18px;border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover{border-color:#007fff;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-left:auto;margin-right:auto}.thumbnail .caption{padding:9px;color:#bbb}.media,.media-body{overflow:hidden;*overflow:visible;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{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:10.152px;font-weight:bold;line-height:14px;color:#fff;vertical-align:baseline;white-space:nowrap;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#dfdfdf}.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding-left:9px;padding-right:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#fff}.label-important[href],.badge-important[href]{background-color:#e6e6e6}.label-warning,.badge-warning{background-color:#ff7518}.label-warning[href],.badge-warning[href]{background-color:#e45c00}.label-success,.badge-success{background-color:#fff}.label-success[href],.badge-success[href]{background-color:#e6e6e6}.label-info,.badge-info{background-color:#fff}.label-info[href],.badge-info[href]{background-color:#e6e6e6}.label-inverse,.badge-inverse{background-color:#999}.label-inverse[href],.badge-inverse[href]{background-color:#808080}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{overflow:hidden;height:18px;margin-bottom:18px;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.progress .bar{width:0;height:100%;color:#fff;float:left;font-size:12px;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,.15),inset 0 -1px 0 rgba(0,0,0,.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,.15),inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 1px 0 0 rgba(0,0,0,.15),inset 0 -1px 0 rgba(0,0,0,.15)}.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(to bottom,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(to bottom,#62c462,#57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(to bottom,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar,.progress .bar-warning{background-color:#ff9046;background-image:-moz-linear-gradient(top,#ffa365,#ff7518);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ffa365),to(#ff7518));background-image:-webkit-linear-gradient(top,#ffa365,#ff7518);background-image:-o-linear-gradient(top,#ffa365,#ff7518);background-image:linear-gradient(to bottom,#ffa365,#ff7518);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffa365',endColorstr='#ffff7518',GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#ffa365;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:18px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:18px;line-height:1}.carousel-inner{overflow:hidden;width:100%;position:relative}.carousel-inner>.item{display:none;position:relative;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img{display:block;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:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#080808;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{left:auto;right:15px}.carousel-control:hover{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-caption{position:absolute;left:0;right:0;bottom:0;padding:15px;background:#999;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{color:#fff;line-height:18px}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:27px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;color:inherit;letter-spacing:-1px}.hero-unit li{line-height:27px}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed}
/*!
* Bootstrap Responsive v2.2.2
*
* Copyright 2012 Twitter, Inc
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Designed and built with all the love in the world @twitter by @mdo and @fat.
*/@-ms-viewport{width:device-width}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;content:"";line-height:0}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;content:"";line-height:0}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-left:20px;padding-right:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-left:-20px;margin-right:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;clear:none;width:auto;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{float:none;display:block;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;left:20px;right:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:18px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-left:10px;padding-right:10px}.media .pull-left,.media .pull-right{float:none;display:block;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;left:10px;right:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:18px}.navbar-fixed-bottom{margin-top:18px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-left:10px;padding-right:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 9px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#fff;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#fff;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .dropdown-menu a:hover{background-color:#080808}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#fff}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:hover{background-color:#007fff}.nav-collapse.in .btn-group{margin-top:5px;padding:0}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;float:none;display:none;max-width:none;margin:0 15px;padding:0;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:9px 15px;margin:9px 0;border-top:1px solid #080808;border-bottom:1px solid #080808;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);-moz-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)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#007fff;border-bottom-color:#007fff}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{overflow:hidden;height:0}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-left:10px;padding-right:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}}
/*!
* Bootstrap Modal
*
* Copyright Jordan Schroter
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
*/
.modal-open {
overflow: hidden;
}
/* add a scroll bar to stop page from jerking around */
.modal-open.page-overflow .page-container,
.modal-open.page-overflow .page-container .navbar-fixed-top,
.modal-open.page-overflow .page-container .navbar-fixed-bottom,
.modal-open.page-overflow .modal-scrollable {
overflow-y: scroll;
}
@media (max-width: 979px) {
.modal-open.page-overflow .page-container .navbar-fixed-top,
.modal-open.page-overflow .page-container .navbar-fixed-bottom {
overflow-y: visible;
}
}
.modal-scrollable {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
overflow: auto;
}
.modal {
outline: none;
position: absolute;
margin-top: 0;
top: 50%;
overflow: visible; /* allow content to popup out (i.e tooltips) */
}
.modal.fade {
top: -100%;
-webkit-transition: opacity 0.3s linear, top 0.3s ease-out, bottom 0.3s ease-out, margin-top 0.3s ease-out;
-moz-transition: opacity 0.3s linear, top 0.3s ease-out, bottom 0.3s ease-out, margin-top 0.3s ease-out;
-o-transition: opacity 0.3s linear, top 0.3s ease-out, bottom 0.3s ease-out, margin-top 0.3s ease-out;
transition: opacity 0.3s linear, top 0.3s ease-out, bottom 0.3s ease-out, margin-top 0.3s ease-out;
}
.modal.fade.in {
top: 50%;
}
.modal-body {
max-height: none;
overflow: visible;
}
.modal.modal-absolute {
position: absolute;
z-index: 950;
}
.modal .loading-mask {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: #fff;
border-radius: 6px;
}
.modal-backdrop.modal-absolute{
position: absolute;
z-index: 940;
}
.modal-backdrop,
.modal-backdrop.fade.in{
opacity: 0.7;
filter: alpha(opacity=70);
background: #fff;
}
.modal.container {
width: 940px;
margin-left: -470px;
}
/* Modal Overflow */
.modal-overflow.modal {
top: 1%;
}
.modal-overflow.modal.fade {
top: -100%;
}
.modal-overflow.modal.fade.in {
top: 1%;
}
.modal-overflow .modal-body {
overflow: auto;
-webkit-overflow-scrolling: touch;
}
/* Responsive */
@media (min-width: 1200px) {
.modal.container {
width: 1170px;
margin-left: -585px;
}
}
@media (max-width: 979px) {
.modal,
.modal.container,
.modal.modal-overflow {
top: 1%;
right: 1%;
left: 1%;
bottom: auto;
width: auto !important;
height: auto !important;
margin: 0 !important;
padding: 0 !important;
}
.modal.fade.in,
.modal.container.fade.in,
.modal.modal-overflow.fade.in {
top: 1%;
bottom: auto;
}
.modal-body,
.modal-overflow .modal-body {
position: static;
margin: 0;
height: auto !important;
max-height: none !important;
overflow: visible !important;
}
.modal-footer,
.modal-overflow .modal-footer {
position: static;
}
}
.loading-spinner {
position: absolute;
top: 50%;
left: 50%;
margin: -12px 0 0 -12px;
}
/*
Animate.css - http://daneden.me/animate
Licensed under the ☺ license (http://licence.visualidiot.com/)
Copyright (c) 2012 Dan Eden*/
.animated {
-webkit-animation-duration: 1s;
-moz-animation-duration: 1s;
-o-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: both;
-moz-animation-fill-mode: both;
-o-animation-fill-mode: both;
animation-fill-mode: both;
}
@-webkit-keyframes shake {
0%, 100% {-webkit-transform: translateX(0);}
10%, 30%, 50%, 70%, 90% {-webkit-transform: translateX(-10px);}
20%, 40%, 60%, 80% {-webkit-transform: translateX(10px);}
}
@-moz-keyframes shake {
0%, 100% {-moz-transform: translateX(0);}
10%, 30%, 50%, 70%, 90% {-moz-transform: translateX(-10px);}
20%, 40%, 60%, 80% {-moz-transform: translateX(10px);}
}
@-o-keyframes shake {
0%, 100% {-o-transform: translateX(0);}
10%, 30%, 50%, 70%, 90% {-o-transform: translateX(-10px);}
20%, 40%, 60%, 80% {-o-transform: translateX(10px);}
}
@keyframes shake {
0%, 100% {transform: translateX(0);}
10%, 30%, 50%, 70%, 90% {transform: translateX(-10px);}
20%, 40%, 60%, 80% {transform: translateX(10px);}
}
.shake {
-webkit-animation-name: shake;
-moz-animation-name: shake;
-o-animation-name: shake;
animation-name: shake;
}
/******** Grid Global ********/
.nglabel {
display: block;
float: left;
font-weight: bold;
padding-right: 5px;
}
/******** Grid ********/
.ngGrid{
background-color: rgb(253, 253, 253);
}
.ngGrid.unselectable {
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
user-select: none;
}
/******** Header ********/
.ngGroupPanel{
background-color: rgb(234, 234, 234);
overflow: hidden;
border-bottom: 1px solid rgb(212,212,212);
}
.ngGroupPanelDescription{
margin-top: 5px;
margin-left: 5px;
}
.ngGroupList {
list-style-type: none;
margin: 0;
padding: 0;
}
.ngGroupItem {
float: left;
}
.ngGroupElement {
float: left;
height: 100%;
width: 100%;
}
.ngGroupName {
background-color: rgb(247,247,247);
border: 1px solid rgb(212,212,212);
padding: 3px 10px;
float: left;
margin-left: 0;
margin-top: 2px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
font-weight: bold;
}
.ngGroupItem:first-child{
margin-left: 2px;
}
.ngRemoveGroup {
width: 5px;
-moz-opacity: 0.4;
opacity: 0.4;
margin-top: -1px;
margin-left: 5px;
}
.ngRemoveGroup:hover {
color: black;
text-decoration: none;
cursor: pointer;
-moz-opacity: 0.7;
opacity: 0.7;
}
.ngGroupArrow {
width: 0;
height: 0;
border-top: 6px solid transparent;
border-bottom: 6px solid transparent;
border-left: 6px solid black;
margin-top: 10px;
margin-left: 5px;
margin-right: 5px;
float: right;
}
.ngTopPanel {
position: relative;
z-index: 1;
background-color: rgb(234, 234, 234);
border-bottom: 1px solid rgb(212,212,212);
}
.ngHeaderContainer {
position: relative;
overflow: hidden;
font-weight: bold;
background-color: inherit;
}
.ngHeaderScroller {
position:absolute;
background-color: inherit;
}
.ngHeaderSortColumn{
position:absolute;
overflow: hidden;
}
.ngHeaderCell{
border-right: 1px solid rgb(212,212,212);
border-left: 1px solid rgb(212,212,212);
position: absolute;
top: 0;
bottom: 0;
background-color: inherit;
}
.ngHeaderCell:first-child{
border-left: 0;
}
.ngHeaderCell.pinned {
z-index: 1;
}
.ngSortButtonUp {
position: absolute;
top: 3px;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
border-color: gray transparent;
border-style: solid;
border-width: 0 5px 5px 5px;
height: 0;
width: 0;
}
.ngSortButtonDown {
position: absolute;
top: 3px;
left: 0;
right: 0;
margin-left: auto;
margin-right: auto;
border-color: gray transparent;
border-style: solid;
border-width: 5px 5px 0 5px;
height: 0;
width: 0;
}
.ngSortPriority {
position: absolute;
top: -5px;
left: 1px;
font-size: 6pt;
font-weight: bold;
}
.ngHeaderGrip {
cursor: col-resize;
width: 10px;
right: -5px;
top: 0;
height: 100%;
position: absolute;
background-color: transparent;
}
.ngHeaderText {
padding: 5px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
white-space: nowrap;
-ms-text-overflow: ellipsis;
-o-text-overflow: ellipsis;
text-overflow: ellipsis;
overflow: hidden;
}
/******** Viewport ********/
.ngViewport{
overflow: auto;
min-height: 20px;
}
.ngCanvas{
position: relative;
}
/******** Rows ********/
.ngRow {
position: absolute;
border-bottom: 1px solid rgb(229, 229, 229);
}
.ngRow.even {
background-color: rgb(243, 243, 243);
}
.ngRow.odd {
background-color: rgb(253, 253, 253);
}
.ngRow.selected {
background-color: rgb(201, 221, 225);
}
.ngRow.canSelect {
cursor: pointer;
}
/******** Cells ********/
.ngCell {
overflow: hidden;
position: absolute;
border-right: 1px solid rgb(212,212,212);
border-left: 1px solid rgb(212,212,212);
top: 0;
bottom: 0;
background-color: inherit;
}
.ngCell:first-child{
border-left: 0;
}
.ngCell.pinned {
z-index: 1;
}
.ngCellElement:focus {
outline: 0;
background-color: rgb(179, 196, 199);
}
.ngCellText {
padding: 5px;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
white-space: nowrap;
-ms-text-overflow: ellipsis;
-o-text-overflow: ellipsis;
text-overflow: ellipsis;
overflow: hidden;
}
.ngSelectionHeader {
position: absolute;
top: 11px;
left: 6px;
}
.ngGrid input[type="checkbox"] {
margin: 0;
padding: 0;
}
.ngGrid input {
vertical-align:top;
}
.ngSelectionCell{
margin-top: 9px;
margin-left: 6px;
}
.ngSelectionCheckbox{
margin-top: 9px;
margin-left: 6px;
}
.ngNoSort {
cursor:default;
}
/******** Footer ********/
.ngFooterPanel{
background-color: rgb(234, 234, 234);
padding: 0;
border-top: 1px solid rgb(212,212,212);
position: relative;
}
.ngTotalSelectContainer {
float: left;
margin: 5px;
margin-top: 7px;
}
.ngFooterSelectedItems {
padding: 2px;
}
.ngFooterTotalItems {
padding: 2px;
}
.ngFooterTotalItems.ngnoMultiSelect {
padding: 0 !important;
}
/* Aggregates */
.ngAggHeader {
position: absolute;
border: none;
}
.ngAggregate {
position: absolute;
background-color: rgb(201, 221, 225);
border-bottom: 1px solid beige;
overflow: hidden;
top: 0;
bottom: 0;
right: -1px;
left: 0;
}
.ngAggregateText {
position: absolute;
left: 27px;
top: 5px;
line-height: 20px;
white-space:nowrap;
}
.ngAggArrowExpanded {
position: absolute;
left: 8px;
bottom: 10px;
width: 0;
height: 0;
border-style: solid;
border-width: 0 0 9px 9px;
border-color: transparent transparent #000000 transparent;
}
.ngAggArrowCollapsed {
position: absolute;
left: 8px;
bottom: 10px;
width: 0;
height: 0;
border-style: solid;
border-width: 5px 0 5px 8.7px;
border-color: transparent transparent transparent #000000;
}
.ngHeaderButton {
position: absolute;
right: 2px;
top: 8px;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
border-radius: 50%;
width: 14px;
height: 14px;
z-index: 1;
background-color: rgb(179, 191, 188);
cursor: pointer;
/* width and height can be anything, as long as they're equal */
}
.ngHeaderButtonArrow {
position: absolute;
top: 4px;
left: 3px;
width: 0;
height: 0;
border-style: solid;
border-width: 6.5px 4.5px 0 4.5px;
border-color: #000 transparent transparent transparent;
/* width and height can be anything, as long as they're equal */
}
.ngColMenu {
right: 2px;
padding: 5px;
top: 25px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
background-color: #BDD0CB;
position: absolute;
border: 2px solid rgb(212,212,212);
z-index: 1;
}
.ngMenuText {
position: relative;
top: 2px;
left: 2px;
}
.ngColList {
list-style-type: none;
}
.ngColListItem {
position: relative;
right: 17px;
top: 2px;
white-space:nowrap;
}
.ngColListCheckbox {
position: relative;
right: 3px;
top: 4px;
}
/********Paging Styles **********/
.ngPagerButton{
height: 25px;
min-width: 26px;
}
.ngPagerFirstTriangle{
width: 0;
height: 0;
border-style: solid;
border-width: 5px 8.7px 5px 0;
border-color: transparent #000000 transparent transparent;
margin-left: 2px;
}
.ngPagerFirstBar{
width: 10px;
border-left: 2px solid black;
margin-top: -6px;
height: 12px;
margin-left: -3px;
}
.ngPagerLastTriangle{
width: 0;
height: 0;
border-style: solid;
border-width: 5px 0 5px 8.7px;
border-color: transparent transparent transparent #000000;
margin-left: -1px;
}
.ngPagerLastBar{
width: 10px;
border-left: 2px solid black;
margin-top: -6px;
height: 12px;
margin-left: 1px;
}
.ngPagerPrevTriangle{
margin-left: 0;
}
.ngPagerNextTriangle{
margin-left: 1px;
}
.ngGroupIcon {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAANCAYAAACZ3F9/AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAEFJREFUKFNjoAhISkr+h2J5JDZODNXGwGBsbPwfhIGAA8bGh6HaGBiAGhxAGJmND4M1gQCSM0adCsVQbcPcqQwMALWDGyDvWPefAAAAAElFTkSuQmCC);
background-repeat:no-repeat;
height: 15px;
width: 15px;
position: absolute;
right: -2px;
top: 2px;
}
.ngGroupedByIcon {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAANCAYAAACZ3F9/AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAElJREFUKFNjoAhISkr+R8LyaHwMDNXGwGBsbPwfhoGAA5mPDUO1oWpE52PDYE0gALTFAYbR+dgwWBMIoPlh1I9ADNU2NPzIwAAAFQYI9E4OLvEAAAAASUVORK5CYII=);
background-repeat:no-repeat;
height: 15px;
width: 15px;
position: absolute;
right: -2px;
top: 2px;
}
.ngPinnedIcon {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAmElEQVQoU33PQapBURjA8UtkwJuaWYGSgfQWYBMvczPmTCzAAGVuaA228BZhRCkDGSmE31FucuRfvzq3vr5zT/JSjSU7DsypEPXDkDVn2hSIytJhw4kWGaLCxgHh2gt/RBuLzNhz5caWPjnSqqw4EraFfwznf8qklWjwy4IRTerkiQoPGtPl40OehcEJvcfXl8LglLfBJLkDcMgbgHlHhK8AAAAASUVORK5CYII=);
background-repeat: no-repeat;
position: absolute;
right: 5px;
top: 5px;
height: 10px;
width: 10px;
}
.ngUnPinnedIcon {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAlElEQVQoU33PPQrCQBRF4fFnI2KfZVi5ARvdgo1l6mwmkCJVOgluwd5OwUoDtnoOxAei8cLXTN7cvEl/skCNDCMPfsUPO5zQwOHIDEvYtMURHe6wOVLgigvOePRyeDkyR4ln7wZ//7XfFBu8B23+aDJjrHGAwza7hjtHJvDmHg7b7Bru7AMjK7Rw2ObBVHDY5oGk9AKQNB2zy8MBTgAAAABJRU5ErkJggg==);
background-repeat: no-repeat;
position: absolute;
height: 10px;
width: 10px;
right: 5px;
top: 5px;
}
.ngGroupingNumber {
position: absolute;
right: -10px;
top: -2px;
}
.ng-table th {
text-align: center;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.ng-table th.sortable {
cursor: pointer;
}
.ng-table th.sortable div {
padding-right: 18px;
position: relative;
}
.ng-table th.sortable div:after,
.ng-table th.sortable div:before {
content: "";
border-width: 0 4px 4px;
border-style: solid;
border-color: #000 transparent;
visibility: visible;
right: 8px;
top: 50%;
position: absolute;
opacity: .3;
margin-top: -4px;
}
.ng-table th.sortable div:before {
margin-top: 2px;
border-bottom: none;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 4px solid #000;
}
.ng-table th.sortable div:hover:after,
.ng-table th.sortable div:hover:before {
opacity: 1;
visibility: visible;
}
.ng-table th.sortable.sort-desc,
.ng-table th.sortable.sort-asc {
background-color: rgba(141, 192, 219, 0.25);
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
}
.ng-table th.sortable.sort-desc div:after,
.ng-table th.sortable.sort-asc div:after {
margin-top: -2px;
}
.ng-table th.sortable.sort-desc div:before,
.ng-table th.sortable.sort-asc div:before {
visibility: hidden;
}
.ng-table th.sortable.sort-asc div:after,
.ng-table th.sortable.sort-asc div:hover:after {
visibility: visible;
filter: alpha(opacity=60);
-khtml-opacity: 0.6;
-moz-opacity: 0.6;
opacity: 0.6;
}
.ng-table th.sortable.sort-desc div:after {
border-bottom: none;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 4px solid #000;
visibility: visible;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
filter: alpha(opacity=60);
-khtml-opacity: 0.6;
-moz-opacity: 0.6;
opacity: 0.6;
}
.ng-table th.filter .input-filter {
margin: 0;
display: block;
width: 100%;
min-height: 30px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.ng-table + .pagination {
margin-top: 0;
}
@media only screen and (max-width: 800px) {
.ng-table-responsive {
border-bottom: 1px solid #999999;
}
.ng-table-responsive tr {
border-top: 1px solid #999999;
border-left: 1px solid #999999;
border-right: 1px solid #999999;
}
.ng-table-responsive td:before {
position: absolute;
padding: 8px;
left: 0;
top: 0;
width: 50%;
white-space: nowrap;
text-align: left;
font-weight: bold;
}
.ng-table-responsive thead tr th {
text-align: left;
}
.ng-table-responsive thead tr.ng-table-filters th {
padding: 0;
}
.ng-table-responsive thead tr.ng-table-filters th form > div {
padding: 8px;
}
.ng-table-responsive td {
border: none;
border-bottom: 1px solid #eeeeee;
position: relative;
padding-left: 50%;
white-space: normal;
text-align: left;
}
.ng-table-responsive td:before {
content: attr(data-title-text);
}
.ng-table-responsive,
.ng-table-responsive thead,
.ng-table-responsive tbody,
.ng-table-responsive th,
.ng-table-responsive td,
.ng-table-responsive tr {
display: block;
}
}
## WIP: Schema Form Directive
Generates form layout from a Json Schema of your model. Optionally generates
search box lookup dialog for searchable text fields. Forked from [angular-schema-form](https://github.com/gaslight/angular-schema-form)
Features:
- Bootstrap 2.2 markup
- Float label and placeholder support
- Responsive, including input append icons
- Datepicker for date type
- Split button dropdowns for enum fields (avoid select styling limitations)
- Generates grid based lookup dialogs for searchable string types
- with filter bar for per-column filtering
- filter modes: 'remote', 'request', 'initial' and 'local'
- filter supports optional promise returning remote query function
(function(exports){
/*global exports: false*/
"use strict";
// Test if javascript object is empty or has zero length.
function isEmpty(obj) {
// Speed up calls to hasOwnProperty
var hasOwnProp = Object.prototype.hasOwnProperty;
// null and undefined are "empty"
if (obj === null) { return true; }
// Assume if it has a length property with a non-zero value
// that that property is correct.
if (obj.length > 0) { return false; }
if (obj.length === 0) { return true; }
// Otherwise, does it have any properties of its own?
// Note that this doesn't handle
// toString and valueOf enumeration bugs in IE < 9
for (var key in obj) {
if (hasOwnProp.call(obj, key)) { return false; }
}
return true;
}
// de-serializes settings object from string
function parseSettings(settingsStr) {
var settings = {};
if (settingsStr.length > 0) {
settings = JSON.parse(settingsStr);
}
return settings;
}
// removes duplicate items from array
function arrayUnique(array) {
var a = array.concat();
for (var i = 0; i < a.length; ++i) {
for (var j = i + 1; j < a.length; ++j) {
if (a[i] === a[j]) {
a.splice(j--, 1);
}
}
}
return a;
}
// Returns a random integer between min and max
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
// given an array of properties, copy values from source to target
function getProperties(source, target, properties, useNullWhenMissing, toString) {
useNullWhenMissing = useNullWhenMissing !== false;
toString = toString || false;
for (var j = 0; j < properties.length; ++j) {
if (typeof source[properties[j]] !== 'undefined') {
if (toString) {
target[properties[j]] = String(source[properties[j]]);
} else {
target[properties[j]] = source[properties[j]];
}
} else {
if (useNullWhenMissing) {
target[properties[j]] = null;
}
}
}
}
// validate presense of an array of properties in a source object
function validateProperties(source, properties) {
var missing = [];
for (var j = 0; j < properties.length; ++j) {
if (!source.hasOwnProperty(properties[j])) {
missing.push(properties[j]);
}
}
return missing;
}
function makeHttpError(status, code, msg) {
var errors = {};
errors.status = status;
errors.errorCode = code;
errors.message = msg.replace(/(\r\n|\n|\r)/gm, ' ').trim();
return errors;
}
function makeHttpError(status, code, msg) {
var errors = {};
errors.status = status;
errors.errorCode = code;
errors.message = msg.replace(/(\r\n|\n|\r)/gm, ' ').trim();
return errors;
}
// left pad a string to width using padding
function pad(width, string, padding) {
return (width <= string.length) ? string : pad(width, padding + string, padding);
}
function isObject(value) {
return Object.prototype.toString.call(value) === '[object Object]';
}
function parseIfJson(str) {
try {
return JSON.parse(str);
} catch (e) {
return str;
}
}
// returns a sequence of values from min to max (inclusive)
// incremented by step, which defaults to 1
// i.e.: sequence(0, 8, 2) returns [0,2,4,8]
function sequence(min, max, step) {
var x = [min];
step = step || 1;
while (x.push(min += step) <= max) { }
return x; //ignore jslint (empty block)
}
exports['sequence'] = sequence;
exports['parseIfJson'] = parseIfJson;
exports['isObject'] = isObject;
exports['pad'] = pad;
exports['makeHttpError'] = makeHttpError;
exports['parseSettings'] = parseSettings;
exports['arrayUnique'] = arrayUnique;
exports['getRandomInt'] = getRandomInt;
exports['getProperties'] = getProperties;
exports['isEmpty'] = isEmpty;
exports['validateProperties'] = validateProperties;
})(typeof exports === 'undefined'? this['MfmUtils']={}: exports);